#clojure log - Oct 07 2008

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

3:07 cccc: can i raise errors/exceptiosn deliberately in clojure?

3:07 like if i define factorial and someone passes -1 can i have it raised a "factorial not defined for negative numbers"-error then or i should just return nil?

3:26 hoeck: cccc: just like in java, only with parens :) : (throw (Exception. "exception message"))

3:55 Lau_of_DK: Gents - Good morning - Can somehere show me how to apply zip/edit ? I'm not getting the [loc f & args] syntax

4:13 hoeck: Lau_of_DK: good morning, maybe: (apply zip/edit loc f arglist)?

4:22 Lau_of_DK: Its not quite working out for me

4:22 Altering a single node in an xml tree is proving pretty difficult

4:24 hoeck: I'm don't like xml, i try to ignore it where i can

4:25 I'm / I

4:25 Lau_of_DK: oh... I think its quite handy

6:00 user=> (apply (fn [x] (str x)) "clj")

6:00 java.lang.IllegalArgumentException: Wrong number of args passed to: fn

6:00 What wrong with this ?

6:09 Vanessa: i want to be able to: cons (val, result-of-function) to ((hello 10) transfer 20))

6:09 how do i cons a list and have it eval a function inside he list?

6:09 like if i quite it just conses the quoted expression instead of the result of it

6:10 like hello anywhere there?

6:14 Lau_of_DK: You mean something like this:

6:14 (def fib-seq

6:14 (concat

6:14 [0 1]

6:14 ((fn rfib [a b]

6:14 (lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))

6:14 ?

6:14 H4ns: Lau_of_DK: apply expects an argument list to apply to a function, not a single argument

6:14 lisppaste8: url

6:14 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

6:15 H4ns: please use that for pasting code that is longer than one line.

6:15 Lau_of_DK: H4ns, I will submit to your will

6:17 Vanessa: (cons '(1 (* 2 1)) '((3 4) (5 6))) ->

6:17 ((1 (* 2 1)) (3 4) (5 6))

6:17 but i want (* 2 1) to be evaluated

6:17 -> ((1 2) (3 4) (5 6))

6:17 H4ns: Vanessa: you are quoting '(1 (* 2 1)), so nothing in it is evaluated

6:18 Vanessa: (cons (list 1 (* 2 3)) ()) => ((1 6))

6:22 lisppaste8: vanessa pasted "wordcounting" at http://paste.lisp.org/display/68095

6:22 Vanessa: ^^

6:22 Lau_of_DK: Whats a kiteboard?

6:23 Vanessa: wait i changed

6:23 lau: something you danes are quite good

6:23 i changed a little wait

6:24 ^^

6:25 Lau_of_DK: You changed?

6:25 lisppaste8: vanessa pasted "wordc" at http://paste.lisp.org/display/68096

6:27 Vanessa: (cons (list 1 2) '()) doesnt work, that seems to be the problem

6:27 why not?

6:27 (cons 1 '()) enither

6:28 works in other lisps

6:28 Lau_of_DK: Would (cons 1 (list nil)) work for you ?

6:28 Vanessa: nil

6:28 yes

6:30 Lau_of_DK: user=> (zip/edit (first (xml-> xml-data :l1 :l2)) (fn [x] (parse-str x)) (list "<test>new val</test>"))

6:31 Can somebody fill me into, as to why this complains of bad number of args for fn

6:40 rhickey, you wrote this stuff initially, how do I change the content of 1 node in an XML tree, and still keep the rest of the tree?

6:40 hoeck: Lau_of_DK: cause zip/edit expects a function that takes 2 args, but your fn takes only one arg

6:41 Lau_of_DK: How would you set it up ?

6:41 leafw: Lau_of_DK: (fn [x y] ( .... ))

6:42 hoeck: Lau_of_DK: mind pasting a small example with xml testdata?

6:42 Lau_of_DK: sure

6:45 lisppaste8: Lau_of_DK pasted "XML Edit" at http://paste.lisp.org/display/68097

6:45 Lau_of_DK: This hopefully gives you an idea of what Im going for

6:50 Vanessa: how can i set clojure-mode to just load the file into the interpreter in the other window, not start the interpreter in the currecnt window?

7:00 Lau_of_DK: hoeck , you got the idea? :)

7:06 hoeck: yeah, just give me a second

7:10 Lau_of_DK: sure :)

7:18 Vanessa: if i ahve a (apply list is-a-hash-map) and want to sort the result(looking like (["hello" 1] ["transfer" 12]) ) on the second key(the ints), how do i do that?

7:25 rhickey: Vanessa: (sort #(compare (val %1) (val %2)) {"hello" 1 "atransfer" 12})

7:26 you don;t need the apply list

7:27 Vanessa: ok but ^^ is not working

7:28 rhickey: do you have the latest Clojure?

7:28 svn 1053

7:28 Vanessa: : Unable to resolve symbol: compare in this context

7:28 nah from june

7:28 rhickey: ah

7:29 Vanessa: i download the new one

7:29 now

7:40 shouldnt running clojure.jar from the win com prompt start the repl?

7:40 when i do nothign happens

7:40 java clojure...

7:41 exception blarf

7:41 should i be able just unzip and then do java clojure.jar in the directory?

7:41 H4ns: java -cp clojure.jar clojure.lang.Repl

7:42 rhickey: or java -jar clojure.jar

7:42 Vanessa: by latest I meant the latest from svn

7:43 might work with sept release

8:05 Vanessa: how do i sort in descending order so i dont have to reverse

8:05 ah change 1 and 2

8:05 what si it that it does really?

8:06 (sort #(compare (val %2) (val %1)) tuples))

8:06 % is usually mod but not here right

8:07 drewr: #() is alternate reader syntax for an anonymous fn.

8:07 % is bound to the arg, if there is only one.

8:07 %1, %2, etc. are bound to the args for more than one.

8:08 parth_m: Venessa: http://en.wikibooks.org/wiki/Clojure_Programming#Anonymous_Functions

8:08 abrooks: %& is the "rest" argument. I learned about that recently.

8:14 drewr: Cool, didn't know that.

8:17 Chouser: Lau_of_DK: after "changing" a zip node, use zip/root on the result to get the whole tree including any changes.

8:36 Vanessa: how can i sum over this? (("account" 21) ("BUSINESS" 22) ("email" 23) ("money" 27))

8:37 (reduce + #( something?

8:37 iw ant to some the ints obv...

8:37 rhickey: if it was still in a map you could just (reduce + (vals amap))

8:39 lisppaste8: hoeck annotated #68097 with "xml edit" at http://paste.lisp.org/display/68097#1

8:40 hoeck: Lau_of_DK: you're right, using xml this way is really handy

8:42 btw, chouser: you rock! for doing this xml stuff and gen-interface! thanks!

8:45 gnuvince: Vanessa: how about (reduce + (map #(nth % 1) coll))?

8:49 Chouser: hoeck: heh, thanks.

8:52 lisppaste8: glarf pasted "spamfilter" at http://paste.lisp.org/display/68099

8:52 glarf: i posted my spamfilter ^^

8:53 comments on style and stuff is appreciated

8:53 my first lispprogram that actually doesns omething useful :)

8:54 it is a spamfilter that takes a file with spamemails, good emails and then an email to test and then accuracy(how many of the most common words found to compare)

9:26 Chouser: glarf: rather than [w (hd words) wr (tl words)], you could say [[w & wr] words] -- shorter, and doesn't need the non-standard hd and tl

9:36 glarf: cool haskell-like patternmathcin, very nice

9:36 how do i force float-division?

9:37 Chouser: I don't know enough haskell to say, but I think it's a somewhat simpler mechanism -- "destructuring"

9:37 glarf: do i have to convert one of the dividors to float or do * 1.0 ?

9:37 Chouser: yeah, wrap (float) around the whole thing or a divisor

9:37 glarf: ok just (float var)

9:44 Chouser: I think count-all-words could be just (map #(count-word % lst) set)

9:48 glarf: correct, vn

9:49 danlarkin: haskell-like?! more like prolog-like

10:07 Chouser: glarf: and I think count-words could be: (reduce (fn [occ w] (if (> (count w) 4) (assoc occ w 1) (merge-with + occ {w 1}))) {} (split file " "))

10:10 glarf: is there a way to shorten the massive error-messages?

10:11 liek normally the first sentence says something useful, then there is 30 rows of stuff that doesnt tell me anything

10:11 Chouser: at the repl they're only one line

10:12 when generated from code in a file, those other error lines are often helpful for figuring out what lines of code are involved.

10:14 glarf: chouser: count-words, hmm it doesnt give any errors and it the program works however the result is not the same, 0.71 in one case, 0.52 in the other, i will look into it

10:16 glarf2: or merge-with will add values for keys that are equal?

10:23 for some reason your functiond eosnt ignore the short words

10:23 (> (count w) 4)

10:25 Chouser: merge-with uses the given function to merge vals when keys are the same. The function I gave was +

10:26 glarf2: ah now isee the error

10:28 Chouser: note there are no longer any uses of first/rest, so no need to use your aliases.

10:33 glarf2: im switching toa cond within the reduce

10:33 how do i do with else.

10:33 when the word is shorter than 4 chars i dont want to do anything

10:34 Chouser: :else occ

10:35 glarf2: yes

10:36 lisppaste8: glarf pasted "count-words" at http://paste.lisp.org/display/68103

10:37 glarf2: still a little bit shorter

10:38 Chouser: ah, I see what I misunderstood about your algorithm.

10:41 lisppaste8: Chouser annotated #68103 with "filter instead of cond" at http://paste.lisp.org/display/68103#1

10:49 blackdog`: with svn should i not be able to say (supers {}) as map implemetns java.util.Map now?

10:51 glarf2: chouser: isnt that inefficient though, it goes over the list once to filter and another to reduce right?

10:51 wwmorgan_: blackdog: try (supers (class {}))

10:51 blackdog`: ah

10:51 thanks

10:57 Chouser: glarf2: O(n) either way, and since filter is lazy, each word is getting the size check then the reduce step before the next word is taken.

10:58 I bet it's comparable, but feel free to run some time tests and see which is better.

10:59 glarf2: ok thanks is there something i have to think about or when combining map filter and reduce i can count on it being the same as doing it all within a for-loop in an imperative language

10:59 anyway 2*O(n) is still slower than O(n) right?

11:00 but as you said now they re both O(n)

11:02 gnuvince: If it's lazy, it should be pretty much the same performance.

11:02 Chouser: in yours, each word is looked up in occ before either assoc or size test. In mine each gets a size check, only long words go to merge-with. I'm not sure that's 2*the work.

11:04 you'd really have to run some test to see which is faster, as there are several differences. Creating a little hash-map for merge-with might be more expensive in mine than the extra word lookup in yours, for example.

11:04 I'd be surprised is the difference was much either direction.

11:06 glarf2: i was thinking in un-lazy reduce/filter/map iterating twice over the list

11:06 scottj: What's the recommended way to get an integer from a float?

11:07 wwmorgan_: scottj: rounding or truncating?

11:07 scottj: wwmorgan_: truncating

11:07 wwmorgan_: (int x)

11:08 scottj: oh, missed that in the docs. I was searching for integer

11:10 glarf2: is there a time-function?

11:10 or how do you profile?

11:10 with your watch? :)

11:10 Chouser: (doc time)

11:13 glarf2: ok that retuend instantly

11:13 which shoudlt happen

11:13 �m testing ona huge file

11:13 took 20 seconds before

11:13 took 0.03 msec with time...

11:14 Chouser: got the right answer?

11:14 glarf2: no, no answer

11:14 wwmorgan_: glarf2: your function is probably lazy. Wrap it in a doall

11:14 glarf2: "Elapsed time: 0.028774 msecs"

11:14 user.run__2537@15c30f6

11:14 (time run)

11:14 run = (defn run [] (classify f1 f2 f3 50))

11:14 Chouser: try (time (run))

11:14 glarf2: ah ofc

11:28 chouser: the one using cond is slightly faster

11:28 13sec vs 14 sec

11:28 Chouser: ok

11:41 danlarkin: is java 1.5 the same as "Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.x)

11:41 why did they change the naming scheme :'(

11:45 Chouser: I think it is the same, and I have no idea. I think someplaces it's also called 5.0

11:48 scottj: I'm not seeing in the docs how to find the length/size of a collection. ?

11:48 Chouser: (doc count)

11:49 scottj: In this case rick is wrong. There are too many good words :)

11:49 Chouser: :-)

11:52 rhickey: size is relative, and may have units, length implies distance, not a good fit for non-sequences

11:53 count is about number, and also is a verb

11:54 Chouser: rhickey: I can't find anywhere that ever inits the vector held inside LazilyPersistentVector. vestigal feature?

11:54 oh, scratch that, I see it.

11:54 lisppaste8: rgr annotated #68103 with "ignore this" at http://paste.lisp.org/display/68103#2

11:55 glarf2: i never feel like i need macros, are they overhyped? when using imperative languages i miss higher order functions, but never macros

11:55 reddit: http://items.sjbach.com/16/some-notes-about-clojure

11:56 Chouser: in my experience, one very rarely needs to write macros in any language that has them.

11:56 I frequently want them in languages that don't (JavaScript!) but if they exist, someone probably already wrote the macro I want.

11:58 rhickey: they are quite important to keeping the size of Clojure's core down

12:00 scottj: What is the common functional way of doing two for loops, one inside the other?

12:00 Chouser: (for [a [1 2] b [3 4]] (list a b))

12:00 returns: ((1 3) (1 4) (2 3) (2 4))

12:00 cemerick: Macros can be indispensable in a domain-specific setting.

12:15 Chouser: right -- when you need them, there's no substitute.

12:53 scottj: Anyone else running ubuntu? Is the blue text near the bottom of http://clojure.org/reader hard for you to read? I'm wondering if it's just something on my computer setup or if the style for the examples in the docs might be hard for lots of linux users

12:54 It is much easier to read on my Windows computer..

12:54 Chouser: scottj: ubuntu here -- the only blue text I see is the code snippet. looks ok to me.

12:56 blackdog`: how's clojurescript going Chouser?

12:57 still have steam? :)

12:57 Kerris2: hello, I need help with using the Repl with JLine

12:58 I've copied the contents of the jline folder into the clojure folder, but

12:58 java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl doesn't work :|

12:58 Chouser: blackdog`: a bit -- as of last night, trying to fill in some missing pieces in PersistentList and LazilyPersistentVector

12:59 blackdog`: are you going to implement dosync and STM?

12:59 scottj: Chouser: does it look like http://www.mediafire.com/?zimewyqynny for you?

13:00 Kerris2: maybe it'll work if I add both to the classpath

13:00 got to go now

13:02 Chouser: scottj: mine looks a little darker to me.

13:45 blackdog`: would it be possible to add a print method to see an array of java strings? rather than this [Ljava.lang.String;@1465ca2 ?

13:45 kotarak: Try (seq array-here). Help me with the inspector.

13:45 Helped...

13:46 blackdog`: yea, i'm doing it by converting to a vec right now, but at the repl it would be a bit nicer

13:47 i was thinking giving the print multi methods now it could be quite easy to do

13:49 Chouser: (defmethod print-method (Class/forName "[Ljava.lang.String;") [a w] (.write w (str "[" (apply str (interpose " " a)) "]")))

13:49 blackdog`: :) thought so

13:50 Chouser: I guess that's not really right.

13:50 blackdog`: works for ,e

13:50 me

13:50 very neat

13:51 Chouser: maybe:

13:51 (defmethod print-method (Class/forName "[Ljava.lang.String;") [a w] (.write w (str "(into-array" (apply str (map #(str " \"" % \") a)) ")")))

13:51 kotarak: The right is probably to check for .isArray in the :default implementation. At least are Arrays handled like this eg. in nth.

13:51 blackdog`: first one was better :P

13:52 Chouser: kotarak: yeah, this one's pretty specific.

13:52 blackdog`: good enough!

14:13 glarfani: hi i started with the (considering my lisp-noobness) ambitious project of creating an object-system for clojure.

14:13 Chouser: yikes

14:13 glarfani: im not sure about gensyms

14:14 symbol# right?

14:14 hoeck: glarfani: or (gensym)

14:16 H4nsX: is there a way to query a form for its class? the compiler seems to know anyway when it finds out the methods that can be called in a dot expression. is that information available to clojure programs, too?

14:16 kotarak: (class ...) maybe?

14:17 H4nsX: kotarak: that will give me the class of a value. i need to compile-time class so that my macro can introspect into it.

14:17 s/to/the/

14:17 rhickey: H4ns: (resolve 'java.util.HashMap)

14:18 H4nsX: rhickey: ah, cool. trying that, thanks!

14:19 eyeris: Could someone point me to the documentation for how to invoke clojure as a compiler?

14:19 I can only seem to find the `java -cp clojure.jar clojure.lang.Repl`

14:19 kotarak: There is no .clj to bytecode-in-file compiler at the moment.

14:20 eyeris: Is there a "just compile and run this .clj" invocation?

14:20 non-interactive

14:20 Chouser: clojure.lang.Script

14:20 kotarak: clojure.lang.Script

14:20 eyeris: Is there an echo in here? :)

14:21 kotarak: ... echo in here? ... in here? ... here? ;)

14:21 danlarkin: wow the clojure REPL is forming a habit... I'm trying to tab-complete in my emails...

14:22 kotarak: With certain editors this might work...

14:22 H4nsX: rhickey: no, that don't work - i am propably mislead anyway. i wrongly assumed that the method lookup would happen at compile time, whereas it is propably clear that it happens at run time.

14:23 Chouser: H4nsX: if the object type is known at compile time, it is resolved then.

14:23 if not, it's "reflection" and can be flagged with *warn-on-reflection*

14:23 H4nsX: Chouser: ah, ok. thanks. i'll play some more.

14:23 rhickey: H4nsX: I'm not sure what you are trying to do, but Clojure tries to avoid runtime lookup

14:25 If you are trying to write a macro, resolve will give you the class, your macro may need to do some reflection if you are trying to auto-build wrappers, but the code it emits can avoid reflection

14:25 H4nsX: rhickey: i would like to have a more pleasant syntax for getters and setters and am thinking about i could implement that. something in the lines of (getp object :fieldName) and (setp object :fieldName value)

14:26 rhickey: you should look at bean

14:26 H4nsX: ok, will read up on resolve and bean, thanks!

14:26 rhickey: you could make a lazy version of bean

14:27 (bean (java.util.Date.))

14:27 H4nsX: uh, that is cute.

14:28 maybe i can just use that for starters and make it lazy once i feel it hurting me.

14:28 (but my plan is to stay scalable to multiple cores, so it may never hurt me)

14:29 eyeris: Is there a repository of example code I can browse through?

14:30 rhickey: eyeris: there's the wiki, also: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure

14:30 and http://writingcoding.blogspot.com/2008/06/clojure-series-table-of-contents.html

14:31 and clojure-contrib

14:31 and boot.clj

14:31 eyeris: Thanks

14:31 hoeck: and boot.clj

14:31 oops

14:31 shoover: There's a nice chunk of practical clojure in http://github.com/jochu/swank-clojure/tree/master

14:40 gnuvince: Chouser: just a followup on yesterday, the problem was definitely with my network, so fetching pages in my Clojure script is now much faster

14:40 Chouser: gnuvince: ok, good to know.

14:44 glarfani: cant i create a hash-map with a gensym-key or use gensyms outside macros?

14:45 cemerick: glarfani: (gensym) works fine outside of macros

14:45 Hun: what's a use for a hashmap with a gensym-key?

14:46 rhickey: glarfani: sure: (hash-map (gensym) 1 (gensym) 2)

14:50 lisppaste8: rhickey pasted "reader object literals" at http://paste.lisp.org/display/68112

14:50 rhickey: someone was musing about defining print-method for arrays, without read support it's not that useful

14:50 also, for AOT compilation I'll need readable representation of more objects

14:51 Chouser: hey, my string printer kinda worked -- printed (into-array ...)

14:51 but yours is, of course, better. :-)

14:51 rhickey: the paste is what I'm thinking about, would allow print-methods to target this generic constructor form

14:52 Chouser: would print now differentiate between hash-map and sorted-map (for example)?

14:52 rhickey: #<classname ctor args ...>

14:52 Chouser: there might still be special handling for those

14:53 these would be striclty literals - no evaluated args

14:53 strictly

14:55 Chouser: looks pretty good to me. JavaScript knows how to "print" lots of things that the JVM doesn't, and I could drop those into this syntax pretty easily.

14:55 I think.

14:56 rhickey: #[...] would get evaluation support, like the built-in collections

14:56 making it easier to call Java variadics

15:00 chmu: hi, is it possible to add metadata to structs? (with-meta (create-struct :x :y) { :mymeta 123 }) doesn't work (IncompatibleClassChangeError)

15:00 Chouser: is there something that prevents Java variadics from being supported directly?

15:02 chmu: you can put metadata on a struct map

15:02 (defstruct coord :x :y) (with-meta (struct coord 1 2) {:mymeta 123})

15:03 chmu: Chouser: I would like to add metadata to the "type" and not to the instance.

15:04 Chouser: Specifically I would like to add "type information" to members

15:05 rhickey: Chouser: the problem with supporting variadics directly is you can't tell, when being passed an array arg, if that is intended to be the entire set of variadics or simply first of one - in Java you use type casts to help the compiler

15:06 Chouser: rhickey: oh, type casts on the calling side? bleh.

15:06 rhickey: right, bleh

15:06 chmu: right now those struct basis objects are opaque

15:07 Chouser: that's interesting, though, because I think I'm supporting them fine in JavaScript.

15:07 chmu: rhickey: Ok, maybe I should define my own "struct" then?

15:09 rhickey: chmu: you could always stick the basis object inside something else which held your extra data, then define a constructor fn that encapsulated that

15:10 glarfani: i want to make a function assoc! that : (assoc! some_map "hello" 12) -> (def some_map (assoc some_map "hello" 12)). but when i do as that i am returned a new map even if deffing to the variable passed

15:10 do i need to use a macro or this is clojure immutabilti?

15:10 chmu: rhickey: ok, thanks

15:10 rhickey: I also tried to associate metadata with the symbol but ran into a problem with macros and metadata

15:10 rhickey: (defmacro create-bla [name val] `(def #^{:Some :MetaData} ~name ~val))

15:11 Metadata can only be applied to IObjs

15:11 rhickey: chmu: you have to understand the macro output will not be re-read, what you are trying to emit there is reader syntax for metadata - you could instead (with-meta...) the name symbol itself

15:12 see defn in boot.clj

15:13 chmu: rhickey: Alright, so its not possible to "escape" the metadata construct?

15:14 rhickey: chmu: once your are defining the macro reading is over, but code is data and you can produce a form with metadata certainly

15:14 glarfani: I'm not sure anyone will help you do that - what you are trying to do is very much not in the spirit of Clojure

15:15 chmu: rhickey: thnx

15:16 gnuvince: rhickey: does Clojure allow the creation of reader macros?

15:17 rhickey: gnuvince: not so far, and not likely until I figure out how to make them interoperate. Unlike regular macros there are no namespaces to prevent clashes between two sets of reader macros

15:17 gnuvince: ok

15:18 rhickey: of course I could have used up all the good characters by then :)

15:18 glarfani: rhickey: lol ok but im playing with clojure to learn more than anything else. learn about lisp, macros, language design etc.

15:18 Chouser: glarfani: you could write a function that does something like that on a ref

15:19 but just because you can doesn't mean you should.

15:19 rhickey: glarfani: you'll learn the most by trying to avoid doing that :)

15:25 Chouser: rhickey: would you prefer posts with patches to have "PATCH" in the subject or something? Or would that just be ..um... bait.

15:43 rhickey: there are a few things that could be Reversible that aren't (ArraySeq, StringSeq, Range, maybe others).

15:43 Is that on purpose or just because rseq's not likely to be needed on those.

16:01 gnuvince: rhickey: do you think it would be do-able/reasonable to auto-escape backslashes in regex literals? Being able to write #"\d" instead of #"\\d"

16:03 Chouser: gnuvince: this has been discussed at length, but the interested parties gave up before reaching a conclusion.

16:03 (myself included)

16:04 we should give it a good think and come up with a real solution.

16:04 abrooks: gnuvince: Unfortunately, the regex literals are parsed as Java strings. Departing from that MAY be the right thing but it's not a minor departure.

16:05 gnuvince: I admit that I haven't looked at the source code before suggesting this (not that it would help much, I don't know Java.)

16:05 Chouser: I really want to do better. Clojure controls the reader, so we should make regex less painful. But there are edge cases that need to be thought out.

16:06 http://groups.google.com/group/clojure/browse_thread/thread/81b361a4e82602b7/0313c224a480a161

16:06 abrooks: Chouser: Right but there's the concern that a regex literal would look different from a string literal that is turned into a regex (or if they looked the same, they'd act differently). That would be yucky.

16:06 gnuvince: I'll read that tonight.

16:09 Chouser: heh. yeah. good luck. :-)

16:10 seriously though, I suspect there's a nice clean solution in there, but we can't just suspect or suppose, we need to provide sufficient evidence.

16:10 * abrooks wonders if a #/regexhere/ format could use non-string parsing rules and #~#regexhere# (i.e. #~?....?) could be an instance defined delimiter.

16:10 Chouser: ...and do it soon enough that rhickey will consider including what's bound to be a breaking change to the reader.

16:10 * abrooks gets a yucky feeling for suggesting MORE syntax

16:10 gnuvince: Indeed

16:11 Chouser: abrooks: hm, interesting, though it might be hard to get rich to give up more reader chars for regex. :-)

16:11 gnuvince: I don't dislike syntax when it helps, but gratitious additions are just bloat.

16:11 cemerick: I'd think that regex literals could be interpreted as "raw" strings, a la python...

16:11 abrooks: Would it be bad to have three regex syntaxes? I think Rich might balk.

16:11 gnuvince: cemerick: that would prevent somebody from using hex or octal literals

16:12 (though they could use (re-pattern "\xc3")...)

16:12 cemerick: gnuvince: yeah, that's quite the edge case compared to forcing everyone to type \\d

16:12 gnuvince: cemerick: I agree

16:12 Chouser: Java regex knows how to parse hex literals to mean matching only that char

16:12 also octal literals.

16:13 so passing those "raw" into the Java Pattern should Just Work.

16:13 I *think* almost everything works out like this, but someone needs to do the grunt work to demonstrate there aren't nasty corner cases lurking.

16:15 abrooks: Chouser: You're right. Pattern still knows all of the escapes that you'd want to do as string escapes.

16:18 Chouser: Currently Pattern.pattern() returns a string identical to the input: (. #"\\\\dfoo" (pattern))

16:20 Chouser: I'm really torn here. The Java situation is really horrible. Needing to think about more than one escaping level at a time is painful and prone to error. Being out of parity with the printable string form would be bad as well.

16:21 Chouser: I'm not torn at all. I don't care what .pattern returns, as long as clojure prints the same thing it reads.

16:22 In my opinion, the current syntax is not good at all. To match a double quote (single char) you currently have to write #"\\\""

16:22 unacceptible.

16:23 but we want to get it right once, and clearly #""" isn't going to work, so we have to work out the details

16:24 hm, you strike that -- you can also say #"\""

16:25 abrooks: Chouser: ... right. :)

16:25 Chouser: ...which just proves Java Pattern is actually helping us out here -- we can pass in \" as raw and Pattern will do the right thing for us.

16:26 abrooks: As long as a Clojure regex can display the string in the same form as a literal regex or a regex created from a string so user input regexes are the same as user displayed regexes are the same as progammer visible regexes, I'm cool.

16:28 Chouser: whee: (prn-str (str \\))

16:29 abrooks: Ack.

16:29 gnuvince: ouch

16:31 ozzilee: Chouser: Why isn't #""" clearly going to work?

16:33 Nevermind, I was thinking of something else.

16:33 abrooks: ozzilee: Which quote terminates the regex? Consider that #"" " foo" and #""" foo" are the same.

16:33 ozzilee: abrooks: Well, I was thinking of """This is a raw string"""

16:33 abrooks: Ah, heh. Gotcha.

16:35 duck1123: does anyone know why I'm getting the message "java.lang.Exception: Unable to resolve symbol: progn in this context (NO_SOURCE_FILE:1)" when I try to open slime?

16:36 Hun: old slime i guess

16:36 duck1123: I also see this: (progn (load "/usr/share/common-lisp/source/slime/swank-loader.lisp" :verbose t) (funcall (read-from-string "swank-loader:init")) (funcall (read-from-string "swank:start-server") "/tmp/slime.31791" :coding-system "iso-latin-1-unix")) which I think is the problem

16:36 Hun: progn is common lisp

16:36 danlarkin: as for raw strings, I like the way python does it... prefixing the string literal with a lowercase R

16:36 Hun: you need a head cvs to use it in clojure

16:37 danlarkin: so r"raw string", r'raw string', r'''raw string''' and r"""raw string""" are all the same, raw strings

16:37 ozzilee: #"""<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\1>""" looks ok to me.

16:38 duck1123: I'm running a version from git from 2008-10-04

16:38 Chouser: huh. "\\" works, (= (str \\) "\\") is true, but #"\\" breaks

16:39 Hun: duck1123: of slime and swank_clojure

16:39 wwmorgan_: Chouser: I think because \ is not a valid java regex

16:40 duck1123: Hun: the swank_clojure should've been from the same day

16:40 Chouser: ok, I think this may not be too bad.

16:40 Hun: then it might be your slime. it tries to load the common lisp sources in clojure (which obviously fails)

16:40 Chouser: (defn prptn [p w] (.write w "#\"") (.write w (.replace (.pattern p) "\"" "\\\"")) (.write w "\"\n"))

16:41 That prints a Pattern using the proposed new syntax, just like abrooks wants.

16:41 " and \ must be (and when printed, are) escaped with a \

16:42 abrooks: Chouser: Great -- but (.pattern #"foo") should return the right thing by default, IMO.

16:42 Chouser: everything else is raw and literal, and I think you can match anything.

16:42 abrooks: can't, that's Java's method

16:42 abrooks: Is there a Pattern interface?

16:42 Chouser: but (prn #"foo") can be made to use the implementation of prptn.

16:45 abrooks: Chouser: Would it be reasonable for an arity-1 prptn just return the apropriate string instead of write()ing?

16:46 Chouser: replace "defn prptn" with "defmethod print-method java.util.regex.Pattern" to plug it in (and throughly confuse yourself as you now have a non-standard prn)

16:50 abrooks: By appropriate string, I mean the form that you'd use in the literal format, not the What Would Java Do string.

16:51 Chouser: abrooks: it would just be confusing, because the printer of the repl will stick a bunch of backslashes in there so it can be read by the current reader.

16:53 abrooks: Chouser: I'm now confused. I was assuming you were talking about the future modified reader which didn't require slashing everything to death.

16:54 Chouser: prptn writes out a string that a proposed future reader could just read.

16:54 defining it today as a print-method allows you to use today's prn to print out these future reader strings.

16:55 I thought you were asking for a prptn-1 that takes a single arg and returns a string -- this would not be useful today for the reason I gave.

16:57 abrooks: Chouser: I was asking for that but I wanted it for the future usefulness. Also for other things (str "My pattern -->" (prptn #"foo") "<--")

16:57 prptn is probably not a useful name in that case.

16:58 Chouser: prptn is not meant to be a name that would ever be using in the proposed future clojure.

16:58 abrooks: Perhaps would be a separate function which would do what I want.

16:58 Chouser: Ah. AH HA!

16:58 Chouser: you could use (prn "My pattern -->" #"foo" "<--")

16:59 abrooks: Chouser: Only if I wanted to prn it. If I wanted to do something else with it (such as stick it in XHTML or a database do other processing) I'd want a string.

17:00 Chouser: gah, well, then you'd probably get what .pattern produces. Why would you do that?

17:00 no, if you want to represent code as data in a string, use prn

17:01 or prn-str or whatever.

17:01 (str [1 2]) ==> "<vector: - 2 items>"

17:12 persi: I it possible to compile and load .java files into closure?

17:12 clojure/closure

17:12 Hun: you can just import classes

17:13 persi: does that work for iterative development?

17:13 i.e. can I reimport?

17:13 Hun: haven't tried, but i think so

17:14 persi: thanks. will try.

17:14 Chouser: I don't think so -- once a class is loaded, I think it's done.

17:15 which is part of why gen-class works the way it does, allowing you to swap in new method implementations even though Java doesn't let you actually change the class.

17:16 persi: darn.

17:16 so not really any help for developing java code.

17:16 really was hoping for a repl around my java library development.

17:16 Hun: bean shell?

17:18 persi: bean?

17:18 i'm a lisper, not a java person.

17:18 Hun: ah, ok :)

17:18 persi: need to develop some java and just wished for iterative development.

17:18 thought clojure could help.

17:19 Chouser: persi: it's a JVM restriction, I think.

17:19 Maybe you could something with creating new classloaders on the fly or something, but that's all over my head.

17:20 persi: Chouser: yea, figured that much. just going to go back to the stoneages of compile run rinse-repeat.

17:24 kotarak: persi: as long as you handle your object from clojure, you could do (YourClass-possible-method your-obj with some args). When you are satisfied, create a corresponding gen-class and its available from Java.

17:30 persi: katarak: But i'm developing a .java and using javac to make a .class. Can I do what your saying with this?

17:30 kotarak: But i'm developing a .java and using javac to make a .class. Can I do what your saying with this?

17:31 kotarak: Probably not. But why do you need Clojure then? My idea was: create a Java class via gen-class. If you have a new method, but are not sure, test from the clojure side as described. Then finally add the definition of the method to gen-class call and it is available.

17:56 scottj: Is there a function I'm missing that's like (first-that pred coll) and returns the first value in coll that satisfies the predicate?

17:58 Chouser: (doc some)

18:00 wwmorgan_: some is slightly different: it returns the first true value of (map pred coll)

18:01 scottj: I think the best you can do is (first (filter pred coll))

18:02 duck1123: we need a clojure bot in here like what fsbot does in #emacs

18:02 Chouser: wwmorgan_: ah, good point.

18:03 scottj: I think first-that could be written as a macro by wrapping the predicate in an if that returns the arg if true

18:04 * scottj has never written a macro

18:04 Chouser: wouldn't need a macro, just wwmorgan_'s code

18:04 wwmorgan_: yeah, laziness saves the day there, you fall out at the first true result

18:04 Chouser: yup

18:04 scottj: wwmorgan_: even if your collection is not lazy?

18:05 wwmorgan_: scottj: right, because filter is lazy

18:05 scottj: oh cool

18:11 duck1123: is there an easy way to add a folder to the classpath within clojure?

18:11 Chouser: (doc add-classpath)

18:13 duck1123: thanks, I must have missed that one

18:13 Chouser: np

18:14 scottj: Chouser: after running that should (. System (getProperty "java.class.path")) return anything different?

18:14 Chouser: scottj: not sure -- I wouldn't be surprised if it didn't. I think it changes the classpath of some other classloader.

18:16 scottj: ok, I don't think it changes

18:17 duck1123: I'm not seeing it change

18:18 Chouser: but does it work?

18:18 as in, can you load the class you want?

18:53 scottj: From a basic clojure setup what has to be done to use psummary and inspect-table? I tried the following but it gives a class not found exception I think on ParallelArray (I'm not sure if slime modifies the error messages)

18:53 (ns foo (:require [clojure.parallel :as par]) (:use clojure.inspector)

20:32 rntz: is there some sort of searchable documentation for clojure? (like hoogle for haskell)

20:45 rhickey: rntz: there's (find-doc "regex string"), also http://clojure.googlegroups.com/web/manual.pdf

21:09 rntz: rhickey: thank you

Logging service provided by n01se.net