#clojure log - Oct 22 2008

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

0:00 lukego: so I want the repl and my Emacs buffers to be in the scope of a common binding. doable? alternative?

0:00 arohner: (binding [foo 2] ...)

0:00 you might be able to use a ref

0:00 lukego: I want to write a series of commands at the prompt that will each update the value of this var. so it won't do to wrap each in a separate binding

0:00 arohner: (def foo (ref 1))

0:00 then to read it, @foo

0:01 though I'm slightly confused by emacs buffers being inside the scope of anything clojure

0:02 lukego: I mean slime commands in emacs buffers

0:02 the slime support is pretty impressive btw kudos to the author

0:05 repeatedly calling def seems to work too..

0:06 arohner: oh, so you want the repl and the slime thread to share the same scope

0:06 (I know almost nothing about slime or clojure-swank btw)

0:06 but yeah, sounds like you need a ref then

0:06 or an agent

0:06 yeah, that will work but rhickey has called it bad style to use that for anything except for C-c C-l

0:08 lukego: well to start with its nice that the bad style works. I'd rather make something run now and improve style later than bang my head on IllegalThreadStateExceptions

0:08 arohner: definitely

0:09 what are you working on?

0:09 lukego: same as this http://mitpress.mit.edu/sicp/full-text/sicp/book/node64.html

0:12 wow even M-. works! I'm very impressed with swank-clojure :)

0:13 arohner: partial is faster and better than returning a new fn, right?

0:18 danlarkin: arohner: how is partial implemented? I'm guessing it just returns a function itself...

0:19 arohner: danlarkin: yup. you're right

0:19 (fn [] ... (apply ...))

0:25 alvin-x: are there any known problems with (format)? I'm using clojure_20080916 and using (format "%10s: %s\n" "a" "b") for example gives me "java.lang.Exception: Unable to resolve symbol: format in this context"

0:28 danlarkin: alvin-x: can you do #'format in your REPL?

0:30 lukego: (symbol "foo" (create-ns 'myns)) faileth - why?

0:31 alvin-x: danlarkin: you want me to just run "#format (sorry, _very_ new to clojure and not familiar at all with reader-related stuff)

0:33 danlarkin: alvin-x: yup

0:33 does that throw an exception?

0:33 alvin-x: yep, No dispatch macro for: f

0:34 java.lang.Exception: Unable to resolve symbol: ormat in this context

0:34 danlarkin: oh, single quote, sorry

0:34 not double

0:34 #'format

0:34 alvin-x: didn't see the quote there :)

0:35 java.lang.Exception: Unable to resolve var: format in this context

0:36 danlarkin: alvin-x: time to update your checkout :-D

0:36 alvin-x: (. String format "%d" 1) gives java.lang.ClassCastException

0:36 svn time...

0:43 danlarkin: (. String format "%d" 1) doesn't work because it isn't the right syntax... it'd have to be (. String (format "%d" 1)) or (String/format "%d" 1) -- but that doesn't work because String doesn't have a format static method? (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html says it does, so I'm slightly confused now TBH)

0:45 alvin-x: i'm getting the same behaviour from svn trunk

0:46 danlarkin: so #'format still bonkers out for you?

0:46 alvin-x: aha... java.lang.Exception: Unable to resolve var: format in this context

0:47 arohner: what ns are you in?

0:47 user=> (format "%10s: %s\n" "a" "b")

0:47 " a: b\n"

0:48 your example worked perfectly on my box, running svn trunk

0:48 alvin-x: arohner: how do i find it out the current ns?

0:48 danlarkin: arohner: his ns shouldn't matter, clojure builtins are automatically injected into every ns

0:49 arohner: danlarkin: not every ns. there are a couple of ways around it, like (in-ns)

0:49 alvin-x: the prompt should tell you

0:49 i.e.

0:49 user=>

0:49 alvin-x: arohner: ok, i'm in the user ns

0:50 arohner: danlarkin: user=> format

0:50 #=(clojure.format__1709. "clojure.format__1709@8f57d2")

0:50 user=> (in-ns 'bogus)

0:50 #=(find-ns bogus)

0:50 bogus=> format

0:50 java.lang.Exception: Unable to resolve symbol: format in this context (NO_SOURCE_FILE:0)

0:50 alvin-x: try typing clojure/format

0:51 what does that print?

0:52 alvin-x: No such var: clojure/format

0:52 arohner: ok, that's weird

0:53 alvin-x: brb

0:53 arohner: try something that is obviously built in, like clojure/print

0:54 danlarkin: arohner: neat trick! does clojure/ns do that symbol insertion?

0:54 alvin-x: user error :) i had an old clojure.jar stuck in the JRE's lib/ext dir :)

0:54 sorry guys

0:55 arohner: alvin-x: np

0:55 danlarkin: what do you mean by symbol insertion?

0:55 clojure/print just refers to the function print in the clojure namespace

0:55 danlarkin: arohner: sorry, I mean that #'format resolves to #'clojure/format no-matter what namespace I'm in

0:57 arohner: yes, clojure/format means look in the clojure ns for that symbol, regardless of what ns I'm in

0:58 danlarkin: arohner: yes I know... but why does #'format resolve to #'clojure/format when I switch namespaces with (ns foo) but not with (in-ns 'foo)?

0:59 arohner: oh, because ns was created to be used at the top of a file as a convenience

0:59 most everyone was doing (create-ns 'foo) (in-ns 'foo) (refer 'clojure)

1:00 so ns includes the call to (refer 'clojure)

1:01 danlarkin: ah

1:01 there we go

1:02 thanks

1:35 rk98x03: Morning gents

1:48 Lau_of_DK: When someone does something like (use 'clojure.contrib.lazy-seqs), where do I have to put lazy-seq.clj for the reader to be able to get it ?

1:50 danlarkin: in your classpath

1:51 Lau_of_DK: for class pass I specificalyl call java -cp clojure.jar

1:52 parth_m: Lau_of_DK: put clojure-contrib.jar in your CLASSPATH.

1:53 Lau_of_DK: oh, there's a jar... where do I get it ?

1:53 parth_m: once you get the sources for clojure-contrib. run ant. that should create the jar.

1:53 Lau_of_DK: argh ,Im setting here on a lousy windows machine, no ant or anything

1:53 parth_m: Oh.

1:54 I use linux. Maybe someone has created a pre-built jar ..

1:55 One option would be to install ant if thats possible.

1:57 Lau_of_DK: Its not, unfortunately I'll have to wait till I get home

1:57 Thats what you get, for coming to work unprepared :)

2:00 larrytheliquid: im having trouble getting slime/clojure working, anyone know why this might be happening? http://paste.lisp.org/display/68974

2:04 Lau_of_DK: Looks like your on windows?

2:05 larrytheliquid: nope, osx

2:06 Lau_of_DK: oh

2:06 Are you sure that ~/ is accepted ?

2:07 larrytheliquid: hm, i know it is for add-to-list, but maybe not the jar path... let's try it...

2:08 Lau_of_DK: wow, that was it... thanks :)

2:08 Lau_of_DK: no probs :)

2:59 jdz: i use (add-to-list 'load-path (expand-file-name "~/elisp/swank-clojure"))

3:30 Lau_of_DK: Achim - I regret to inform you, that I was unable to run your code, although it looked intruiqing

3:31 Firstly - I lack clojure-contrib.jar - Can you upload it somewhere so that I can get it? Secondly, just pasting the functions into the .clj still throws an exception, not enough args to fn

3:34 achim_p: Lau_of_DK: oh! i'll have a look at it

3:34 re: contrib - you don't need a jar

3:34 Lau_of_DK: then what do I need?

3:35 (use 'clojure.contrib.lazy-seqs) throws a cannot find /clojure/contrib...clj error

3:35 achim_p: have you got svn at hand?

3:35 Lau_of_DK: no, Im at work, so pretty handicapped

3:36 achim_p: ah, never mind. here's a zipped version: http://www.bitbucket.org/shoover/clojure-contrib-mirror/get/41bc3ee83e28.zip

3:36 then do (add-classpath "file:///path/to/src/")

3:38 (after unzipping, of course)

3:40 Lau_of_DK: Thank you sir

3:41 achim_p: ah, stupid mistake. added the "(primerange ..." in the last form without testing it. changing it to "(apply primerange" should work. sorry

3:43 Lau_of_DK: I extracted what you sent me to p:\clojure-contrib\

3:43 (add-classpath "file://p:\\clojure-contrib\\")

3:43 java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure/contrib/lazy_seqs/lazy_seqs.clj

3:44 achim_p: your classpath has to point to the "src" dir

3:47 Lau_of_DK: i haven't got access to a windows machine - you're sure mixing slashes and backlashes in URLs is the right thing?

3:47 Lau_of_DK: No, working on it

3:51 Ive tried every combo in the book

3:51 it still throws

3:51 java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure/contrib/lazy_seqs/lazy_seqs.clj

3:55 parth_m: Lau_of_DK: You could verify your classpath using (seq (.. clojure.lang.RT baseLoader getURLs))

3:56 Lau_of_DK: great tip parth

3:57 (where do you guys get all this stuff?

3:57 Anyway, the class-path is correct, it points to where it should

3:57 parth_m: I got this tip from rhickey on IRC some time back :)

3:57 Lau_of_DK: wait

3:58 I removed (use 'clojure-contrib.lazy_seqs), and then it worked perfectly

3:58 w00t?

3:59 achim, thats some pretty amazing code

3:59 finds a hit in less than 5 secs

4:00 hoeck: Lau_of_DK: isn't it clojure.contrib.lazy_seqs?

4:00 Lau_of_DK: yes, thats what I had, I just got lazy typing it

4:00 hoeck: oh ok

4:04 Lau_of_DK: less than 1 second

4:04 thats pretty god

4:04 good

4:04 I left mine running over night, and it had come up to 9521, target was 997651

4:08 achim_p_: Lau_of_DK: weird ... glad it's working now

4:23 Lau_of_DK: Me too - Would you mind putting the algorithm into english for me? :P

4:35 Oh and achim_p_ did you notice that if you click onto a page on the euler wiki, youve got 4 tabs on top, page, discussion, history and notify

4:35 If you click the little arrow on "page" you can probably choose delete

4:36 for me its grayed out, but if you can, please delete all single and double digit posts, Ive copied them into new holders with new names

4:36 achim_p_: Lau_of_DK: ok, i'll try it in a minute

4:37 Lau_of_DK: first it calculates a sequence of accumulated prime sums and puts it in a vector, thus the sum of a range of primes is easily computed by calculating upper-primesum minus lower-primesum - no need to iterate the range of primes for that

4:38 find-range-for tries to find a range that sums up to a given n. it starts with the first prime, then expands the range (to the right) as much as it can, stops when the sum exceeds n. then it contracts (from the left) as much as it has to. plus: it'll never drop below a range size of minlen

4:38 the loop works down the range of primes, trying to find ranges, adjusting minlen, so it'll never look for anything shorter than already found.

4:40 Lau_of_DK: oh

4:40 thats pretty impressive that you can up with that, thanks a million, quite an eye-opener in terms of producing an effecient algo

4:48 achim_p_: Lau_of_DK: you're welcome! project euler might be fun after all. :)

4:48 there were in the order of 1 000 000 000 000 subsequences to consider, so brute forcing would have taken ages

5:08 Lau_of_DK: Tell me about it :)

5:39 jdz: does anybody have a clue how to speed up clojure.xml/parse? or at least meke it use more of the CPU?

5:48 Lau_of_DK: is it reading directly from a file ?

5:56 jdz: yes

5:56 but it feels like it has a sleep method somewhere in the loop...

5:58 cgrand: jdz: is a doctype specified in your xml? The parser may be downloading the DTD

5:59 jdz: cgrand: oh, that might be the case.

5:59 off to read some SAX Java docs on how to disable it

6:29 Lau_of_DK: If you cant work it out, check out the string that xml/emit shoots out first. Maybe you can just inject it ?

6:31 jdz: huh? i'm parsing XML files, not generating them.

6:33 Lau_of_DK: I know, but you need xml/parse to avoid downloading right? So you can do that by injecting xml-id before the actual file

6:35 jdz: xml-id?

6:57 Lau_of_DK: doctype - i might be way off )

7:02 alvin-x: if I run the (incomplete) snippet here: http://paste.lisp.org/display/68988 in clojure.lang.Repl, it runs fine; but if I run it with clojure.lang.Script, it seems to fall through and just returns me to the OS prompt...

7:03 what should I do to get clojure.lang.Script to run it...?

7:05 achim_p_: alvin-x: for constructs a lazy seq, if you don't use it, it'll never get constructed

7:05 the repl prints it, so it gets constructed there. try wrapping it in doall

7:08 alvin-x: does (for [domain (doall (take 10 (cycle domains)))] look ok?

7:10 no, (doall (for

7:10 achim_p_: no, i meant (doall (for ...))

7:11 yes :)

7:11 alvin-x: thanks :)

7:12 is there a better way to do this? my goals is to cycle through parameters a number of times and print out some values...

7:15 achim_p_: doseq maybe? but it doesn't make much of a difference ...

7:16 alvin-x: hm, when the (prn) is there (as in the example i paster) it works as intended. but i I take it out (so no IO statements in the immediate expression, but only stuck away in print-stcms-info), for seems to wait until all iterations are finished, and prints out all values at once!

7:17 pasted*

7:17 buffering...

7:18 no matter, i'll switch to log4j

7:18 achim_p_: mhh, what does print-stcms-info do?

7:18 ok

7:31 alvin-x: wish there was a way to trace and step into/over forms in the repl... IMHO that would be better that littering the code with log4j trace calls...

7:35 blackdog: http://www.lispcast.com/drupal/node/77

7:36 alvin-x: achim_p_: for my use (doseq is better than (doall (for :) thanks for pointing me there.

7:37 rhickey: alvin-x: step debugging is available via Java debuggers

7:45 alvin-x: rhickey: just tried that with jSwat; very nice

7:45 rhickey: alvin-x: cool

7:46 achim_p_: are there any java debuggers that can handle clj files and work with java 1.5? i saw jswat recommended, but it needs 1.6

7:47 rhickey: There was an older version of JSwat that (still) works with 1.5

7:51 alvin-x: soon i'll be running clojure on AIX, with the J9 VM :D

7:51 achim_p_: rhickey: ah, got it. thanks!

7:57 milanmitrovic: hello

7:58 does clojure support continuations?

7:58 rhickey: milanmitrovic: no

7:59 milanmitrovic: can it?

8:00 was that a design decision, or because of compatibility with java?

8:00 Lau_of_DK: milan, theres a good discussion about that in the google group actually

8:01 milanmitrovic: thanks, i'll look it up

8:03 rhickey: milanmitrovic: the short of it is - Clojure remains call-compatible with Java, esp in its use of the stack. Continutations would require a totally independent notion of the stack. It does this both for speed and interoperability. Continuations are on the speculative feature list for a future JVM, and if they are added there, Clojure will get them.

8:05 I think the Fortress folks want continuations, and probably have more pull at Sun then Clojure, at the moment.

8:06 OTOH, if folks are driven for tail call optimization or continuations, you can lend a hand in the incubator for these things, the Da Vinci Machine multilanguage VM: http://openjdk.java.net/projects/mlvm/

8:11 gnuvince: Nice: "Rich Hickey presented his programming language, Clojure. This was the talk of the day."

8:12 From http://www.lispcast.com/drupal/node/77

8:13 arbscht: I just read that, very encouraging

8:14 congratulations, again, rhickey :)

8:15 rhickey: arbscht: thanks. I really appreciate their including Clojure at Lisp50, it was a great opportunity to connect it with the rest of Lisp

8:15 blackdog: "the torch was passed" good quote :)

8:16 milanmitrovic_: rhickey: thanks for the answer

8:18 arbscht: rhickey: did you get a chance to compare contextl with clojure at any point? I'm curious what you and pascal might think of both systems

8:19 in particular, clojure's dynamic bindings, that is

8:19 rhickey: Pascal and I never got a moment to have a good discussion at OOPSLA, although we had at ECOOP.

8:20 Dynamic bindings let you do context-like things, but ContextL is bound up in the CLOS model

8:20 ContextL definitely lets you do more, but I personally wouldn't want to do some of the things it enables

8:22 arbscht: I see. what are some of those things?

8:23 rhickey: adding fields in dynamic contexts, morphing types in order to morph behavior

8:23 arbscht: right

8:24 rhickey: Clojure's a la carte hierarchies and ability to dispatch on attributes or metadata free you from having to tie these things to classes

8:28 arbscht: I find one pattern turning up often in my clojure code, which is dispatching multimethods on a dynamically bound var. I think it could be factored out a little into a subset of a contextl-like api, but I don't know if it's worth going down that road yet

8:32 Lau_of_DK: Is it possible for me to make something like $"25" -> 25 in Clojure? So that I dont have to call (Integer/parseInt (str %)) every time?

8:34 rhickey: Lau_of_DK: why not just make a helper function?

8:34 (str->int "25")

8:35 Lau_of_DK: Firstly because I'd just like to know all the specifics of clojure and customizing it. I think lots of code can be made more readable with those types of conversions.

8:35 Secondly. What you propose would work of course, just takes up more space

8:35 asbjxrn: I'm trying to attach to my clojure process with jswat. But when I attach jswat becomes unresponsive.

8:36 rhickey: Lau_of_DK: but reader macros don't compose - you want to use $ for one thing and someone else wants to for another

8:37 tWip: I don't think $ has any intrinsic meaning to anyone else reading your code

8:37 rhickey: In real CL programs reader macros are rarely used, for that reason

8:38 Chousuke: If you're worried about having to type too much, you just need proper completion for your editor.

8:38 rhickey: so right now, they ar eall reserved by Clojure, so everyone will share

8:38 Lau_of_DK: Ok Rich.

8:38 Chousuke, yes, tab-completion isnt quite working in emacs/clojure-mode yet

8:38 H4ns: Lau_of_DK: M-/ ftw

8:39 rhickey: H4ns: agreed

8:39 alvin-x: cool

8:40 Chousuke: I can't even figure out how to type that with my finnish macintosh laptop keyboard layout :P

8:40 rhickey: Chousuke: option-/ ?

8:41 Chousuke: on this thing / is shift-7 and alt-shift-7 becomes \ :/

8:41 rhickey: yikes

8:41 tWip: yeah the finnish mac keyboard layout is very poor for most coding

8:41 * hoeck uses dabbrev-expand bound to M--

8:43 asbjxrn: Chousuke: set up english as an additional input language, and you can switch to that when coding

8:43 Chousuke: perhaps I should.

8:45 asbjxrn: Won't be easy to remember where all the keys are though :) I do it the other way around, I sometimes have to write norwegian. But the number of characters I have to remember for that is less than what would be required for coding.

9:03 alvin-x: hm, jswat keeps hitting platform debugger related exceptions...

9:05 rhickey: alvin-x: that keep it from working or just unwanted breakpoints? if the latter, you can probably filter them

9:06 asbjxrn: I tried setting a breakpoint, and I got exceptions, but jswat didn't react. Could it be because it happened in swings render thread?

9:08 alvin-x: rhickey: didn't set any BPs; just attached to a running REPL and tried to set the current thread by double-clicking the system/main/main thread... then JSwat hits unexpectede exceptions, and i'm not sure now what works and what doesn't...

9:10 rhickey: alvin-x: It's been a while, but iirc, you can toggle exception breakpoints by type under breakpoints settings

9:10 it may be breaking on exceptions by default

9:15 asbjxrn: Duh, I was attaching jswat to the slime-swank socket...

9:21 Chouser: I may have to give up on trying to read all the overnight IRC traffic. It's certainly picking up.

10:14 cemerick: the netbeans debugger will step through clojure code just fine, although there's a lot of "intermediate" stack frames that it forces you to step through unnecessarily

10:58 AWizzArd: Moin

11:01 Does it make sense to implement some (general purpose) data structures in Clojure? Like Skiplists or some kinds of trees? Maybe this is not needed, cause most data structures already have a very efficient implementation in Java and one could simply use those?!

11:26 Chouser: you can certainly build trees out of vectors and/or maps.

11:26 Lau_of_DK: Afternoon gents

11:26 AWizzArd: Well, for real programming tasks you have to implement your datastructures for your code specifically. Your own tree, your own (map ..) and whatever.

11:27 Hi Lau

11:27 Chouser: AWizzArd: why? for performance?

11:27 Lau_of_DK: hi

11:27 AWizzArd: for performance, usability, readability, and so on

11:27 danlarkin: AWizzArd: what "real" programming tasks would you have to do this for?

11:28 achim_p_: hmm, what do you use trees for, apart from representing higher-level data structures (which are very efficient in clojure). but if you're taking orders: an immutable doubly-linked list with O(1) cons from both ends, first/rest, last/butlast and reverse would be neat! :)

11:28 AWizzArd: For pretty much every non-trivial hello world program you will need your own data structures

11:29 danlarkin: AWizzArd: I disagree

11:29 AWizzArd: of course in all cases they can be constructed by using already existing data structures

11:29 Chouser: achim_p_: and still Persistent, right? ;-)

11:29 AWizzArd: danlarkin: see even the most basic Clojure examples.. they often begin with a defstruct and then define some operations to work on that struct.

11:29 danlarkin: AWizzArd: a struct is just a hash with a static set of keys

11:30 Chouser: AWizzArd: so are you talking about general purpose data structures, or application-specific data structures?

11:31 AWizzArd: danlarkin: sure... but for your program it is a specific data structure and you don't think about it as a hash table. It is instead your data structure that manages employees or whatever.

11:31 achim_p_: i barely use stuff that's not representable via hashed/sorted sets, vectors or maps, really ...

11:31 AWizzArd: You don't work with hashtable functions on it, but instead use an api for them

11:31 achim_p_: Chouser: of course! :)

11:32 AWizzArd: Chouser: I was talking about general purpose data structures, like Skip Lists. But I see for example this: http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListSet.html

11:33 Chouser: AWizzArd: clojure comes with several general purpose data structures that have some special concurrency features (immutable, persistent, transactionable, etc.)

11:33 danlarkin: AWizzArd: what does that buy you over #{}?

11:34 Chouser: from these you can build your application-specific data structures as in the examples you've sited. What else do you need?

11:35 H4ns: AWizzArd: if you need a skip list, write one or use what java provides. if you write one and if it has a neat api, it might be used by others. what else are you suggesting?

11:35 AWizzArd: H4ns: no suggestion, just asking for opinions

11:38 H4ns: AWizzArd: my opinion is: programming is fun. writing good libraries is great. sometimes i need advanced data structures and i'd rather reuse something that implement myself.

11:38 AWizzArd: H4ns: thanks, and I agree

11:39 What I like to add is that it seems that Java now already has implementations for tons of advanced data structures. So probably most people really don't need to work on general purpose stuff like red black trees when we have maps which already are such kind of tree under the hood, with great improvements by Rich.

11:41 Lau_of_DK: achim_p_, the wiki is looking quite nice now huh? :) Some pretty good stuff in there

11:44 achim_p_: http://lamp.epfl.ch/papers/idealhashtrees.pdf

11:44 these are clojure's, if i'm not mistaken

11:46 AWizzArd: I think yes, and Rich said in one of his videos that those perform even better than the hashtables that come with Java. His words were something like: the fastest I have seen so far...

11:48 achim_p_: Lau_of_DK: good work! a nice repository of example code

11:48 jdz: is wanting a proxy of a proxy the wrong thing?

11:49 i mean, i want to create a proxy for a proxy, but i get exceptions...

11:49 one exception of method isInterface not being defined, to be precise

11:59 Chouser: don't you need a class to make proxy of?

12:02 jdz: well, a proxy (created using proxy macro) is a class...

12:02 or so the doc says

12:02 Chouser: I'm pretty sure it's an instance.

12:03 I mean, calling proxy does create a class (if needed) but what it returns is an instance of that class.

12:04 jdz: yes, you are right.

12:07 Chouser: do you maybe know if the functions provided to proxy macro are added to the class or to the instance? (sorry, my Java knoweledge is lacking)

12:08 anyway i think this discussion should be taken to mailing list for archiving purposes

12:10 shallow look at proxy source tells me the functions are added to the instance...

12:10 Chousuke: methods belong to a class in java though :/

12:10 Chouser: jdz: this channel is archived, though perhaps not as publicly as the mailing list

12:11 Chousuke: as far as I know you can't have two instances of a class with different methods in Java.

12:12 Chouser: going from memory, I think proxy creates only one class per set of parent classes, with method stubs pointing to clojure fns

12:12 jdz: Chouser: well, i have not yet looked at the Java side of the proxy implementation, but there sure is some magic going on.

12:12 Chouser: so calling proxy again with the same base classes but different method implementations reuses the existing class.

12:12 jdz: and update-proxy is called on the instance of created proxy class

12:12 Chouser: but my memory or original understanding may be faulty.

12:13 Chousuke: that makes sense though.

12:13 jdz: Chouser: your memory is consistent with what i see in the source.

12:13 Chouser: ok

12:13 Chousuke: It avoids creating unnecessary classes.

12:14 jdz: so proxy is not what i want, then.

12:14 Chouser: so maybe you could (let [i (proxy ...)] (proxy [(class i)] ...))

12:14 jdz: too bad, i wanted an easy hack of xml parser...

12:14 Chouser: I've not tried that, though.

12:14 jdz: Chouser: i tried, and that does not work. and it shouldnt't because i want the methods of the proxy instance

12:15 so looks like i'll have to look at gen-class...

12:15 Chouser: jdz: have you looked at clojure.xml/parse ?

12:16 jdz: Chouser: that's the one i want to hack to enable me to provide my own implementation of resolveEntity method

12:17 Chouser: or clojure.contrib.lazy-xml/parse-trim

12:17 (shameless plug)

12:17 jdz: Chouser: well, i'd sure be glad to look at it. where do i get it?

12:18 Chouser: jdz: you can just start with a copy of that code and override an extra method?

12:18 er, "can't you just"

12:18 jdz: Chouser: that i did. but it does not solve the problem that the clojure.xml/parser is very limited...

12:18 well, not very, but limited nevertheless.

12:19 Chouser: clojure-contrib is here http://sourceforge.net/projects/clojure-contrib

12:19 jdz: i hate the fact that calling setValidating on the parser factory does not disable validation

12:19 Chouser: svn get that and add clojure-contrib/src to your Java classpath.

12:20 jdz: the SAX API is very unsatisfying.

12:20 I hurts me every time I touch it.

12:20 "It hurts me" sheesh.

12:24 jdz: I always recommend using a pull parser over a SAX parser if it's at all an option: http://www.extreme.indiana.edu/xgws/xsoap/xpp/

12:29 jdz: Chouser: ok, thanks. as i understand it, i have to download xpp for lazy-xml to work?

12:30 Chouser: jdz: no, there's some ugly code in there to provide the same API if all you have is the Java SAX parser.

12:31 I mentioned it though mainly as another example of a proxy of org.xml.sax.helpers.DefaultHandler

12:34 nicknull: is there an easy to use webframework for cloure?

12:34 a webserver

12:36 Chouser: nicknull: compojure and webjure are two options

12:40 nicknull: which is the easier? i want something like webpy, just easy to do simple webapps, not a big kludge like django

12:41 Chouser: dunno, I haven't used either. ;-)

12:42 compojure is newer, and may be trying to be more a lightweight set of libraries than an all-encompassing "framework", but I'm not terribly sure.

12:42 tWip: isn't webjure yours? care to comment?

12:45 jdz: one more question: how do i use a contrib after setting up the classpath?

12:45 say, in the repl

12:46 Chouser: (require '[clojure.contrib.lazy-xml :as lx]) (lx/parse-trim ...)

12:46 wlr: Chouser: tWip kinda did so in advance :-) check the recent overnight logs

12:46 tWip: sorry didn't follow, comment on what?

12:47 Chouser: or in a file, ns is preferred (ns my-namespace (require [cloure.contrib ...]))

12:47 tWip: aah, well webjure isn't really an all-encompassing framework either

12:48 Chouser: ok, sorry. As I said, I haven't used either yet.

12:48 nicknull: a tried compojure, seems easy to grt going, just clone git and run script

12:48 nice

12:48 tWip: it's a no frills approach to making clojure code easy to package and deploy as a servlet

12:49 I did include html generation, some jdbc code and so on, but it's mainly just a servlet that calls clojure

12:51 what I wanted was: (defh "/some/url*" [http param bindings...] ...code...)

12:51 where defh means define handler

12:51 there is also (publish fn url-pattern)

12:51 but that's all you really need to do

12:53 Pupeno: Hello.

13:10 aperotte: Hello all, had a quick question about gen-class. If I want to use gen-and-load-class to subclass an abstract class, is the :methods mapping only for signatures or do you provide the code for the method as well. If not, where do you provide the code for the overridden methods? Lastly, I'm not sure I understand the :exposes mapping and the usage of the getter/setter methods. Does anyone have an example of gen-and-load-class u

13:13 Pupeno: To make a Compojure application, are you supposed to fork Compojure?

13:35 Chouser: aperotte: your post got cut off, but the basic idea is the gen-class creates a class with method stubs for all public methods of the classes it extends or implements.

13:36 the implementation of these should be provided as clojure functions in the appropriate namespace.

13:37 aperotte: oh ok, it only inherits the signatures, not the implementations

13:37 Chouser: so the only reason to use :methods is if you want to make up new methods not defined by any base class

13:38 Here's a totally useless but functional example: http://paste.lisp.org/display/68406

13:39 aperotte: Chouser: Thanks, I'll have a look

14:45 Chouser: If stucture-basis objects implemented IFn, perhaps you could do: (defstruct point :x :y) (point 10 20) instead of (create-struct point 10 20)

14:46 Doesn't that seem pleasant?

14:47 wwmorgan: Chouser: yes

14:47 Chouser: oh, sorry, instead of (struct point 10 20)

14:48 danlarkin: +1

14:50 Lau_of_DK: Does anybody here have some Qt/Clojure code that they'd care to paste ?

14:51 Chouser: Lau_of_DK: jamii posted this a while ago: http://paste.lisp.org/display/66213

14:52 Lau_of_DK: Thanks Chouser !

15:02 AWizzArd: re

15:08 Lau_of_DK: Yo

15:16 cemerick: Chouser: re: struct-defs, that's very CL-y -- I'd be perfectly happy if defstruct emitted the basis obj, as well as point and accessors/"setters" for each slot (point-x, point-foo, etc)

15:17 Chouser: isn't (:x p) better than (point-x p) ?

15:18 gnuvince: I think it is

15:18 Plus, it's less "magic"

15:20 Chouser: gnuvince: what do you think of the struct-basis being callable?

15:21 gnuvince: Chouser: it makes sense.

15:21 Chouser: you're already saying (defstruct point ...) so being able to call (point 1 2) wouldn't be too magic, right?

15:21 gnuvince: I'm just looking hard to see if I can find problems with it.

15:21 Chouser: good!

15:21 find them before I'm tempted to start writing a patch.

15:34 Chousuke: I like that syntax. Trying hard to think of any downsides but unless that conflicts with clojure internals somehow I don't see any reason to reject that.

15:36 Lau_of_DK: Has anybody had some success running Clojurecode on .NET ?

15:37 Chouser: Lau_of_DK: there were just instructions on that posted to the list.

15:37 Lau_of_DK: the list?

15:37 mailling list?

15:38 Chouser: yep

15:38 Lau_of_DK: Not the same as the Google Group ?

15:38 Chouser: same

15:38 http://groups.google.com/group/clojure/browse_thread/thread/9e056bb3d2b078d2

15:39 Lau_of_DK: Thanks Chouser

15:43 cemerick: Chouser: I *really* like (:x p), but one of the key aspects of struct-maps is that you don't have to do a key lookup if you use an accessor fn

15:45 Chouser: oh yeah, the accessor functions. From the docs, those don't appear to give much performance benefit.

15:45 rhickey: cemerick: the perf difference is so slight

15:46 cemerick: rhickey: if you're using struct-maps heavily, then they're not so slight in my experience

15:47 I've actually been fantasizing about what a PSM impl might look like given AOT, where the def'ed slots might become simple java fields, rather than members of an array.

15:48 aperotte: Chouser: I tried using something similar to the example you showed me. It's entirely possible that I messed something up but it seems like gen-and-load-class can't ":exposes" a protected field that is itself inherited in the class I'm extending.

15:49 cemerick: I ended up refactoring a couple of classes away from using PSMs because the init costs are pretty high, compared to having an abstract base class that has the attributes you'd otherwise put in a def. Ensuring that def'ed slots become fields would resolve that.

15:54 drewr: "I may have to give up on trying to read all the overnight IRC |<vasa> soverton=> how can i make it?

15:54 Wow, that pasted poorly.

15:54 Anyway, Chouser: :-)

15:55 * drewr has been at OOPSLA and finding it hard to stay on #clojure

15:55 gnuvince: Oh great

15:55 we got drewc and drewr

15:55 I am *so* gonna confuse the two of them

15:56 altan: im thinking about doing a little music prject in clojure, rhickey i heard you work on some really cool stuff, fingerprints, audion analsysis and stuff, you must have a really cool life. anyway what audio/analysis/composing program do you recommend?

15:58 Lau_of_DK: Anyone here using Vim/Clojure ?

15:58 Chouser: aperotte: that may be -- I think I saw something go by on the google group about how to get to protected fields further up the hierarchy.

15:58 Chousuke: I tried, but emacs offers much better repl integration :/

15:59 aperotte: Chouser: Ok, I'll take a look, thanks!

16:03 nicknull: when i download java-libraries, where should i place them? in the JAVA-path or in clojure? should they be compiled before i can use them?

16:03 Pupeno: I read here, http://www.reddit.com/r/programming/comments/77keg/webjure_simple_web_app_programming_for_clojure/c05w4xh , that compojure is much more active that webjure; would you say that's true?

16:03 Chouser: nicknull: if you download a .jar, add that .jar to your Java classpatch

16:03 nicknull: .jar is ajava library?

16:04 Pupeno: nicknull: yes, a Java ARchive, if I am not mistaken.

16:10 drewr: gnuvince: :-)

16:20 drewc: gnuvince: :)

16:21 Chousuke: drewc: you should've included the nose too.

16:21 Chouser: shouldn't be hard to remember that drewr is the one with a nose.

16:21 Chousuke: ah, you beat me to it.

16:24 drewr: Haha. :)

16:24 Snap!

16:25 AWizzArd: Chouser: I see that (coll? ...) is now in the api :-)

16:25 drewc: I was hoping you'd catch that .. lol thanks guys :-)

16:28 AWizzArd: Why is (let [val (get {:a 1 :b 2} :a)] val) ==> 1 but (if-let [val (get {:a 1 :b 2} :c)] val 10 20) ==> Error, although 20 was what I expected?

16:28 Chouser: if-let doesn't take a vector

16:28 I think this will be changing before the 1.0 release of clojure

16:29 AWizzArd: ah okay, the binding vector, I see

16:29 Chouser: for now, (if-let val (get...) val 10 20)

16:29 sorry, (if-let val (get...) 10 20)

16:30 AWizzArd: but where is the test?

16:30 nicknull: if im looping and (if (not= cond)... is true i need to do 2 things, print and then recur

16:30 AWizzArd: where is the test form?

16:30 nicknull: using when i get complaint must recur from tailposition

16:30 Chouser: AWizzArd: the value assigned to val will be the test

16:30 AWizzArd: good

16:31 nicknull: and using if i can only use one stataemnt

16:31 Chouser: nicknull: you can say (do (print ...) (recur ...)) but I expect you'll get the same error as with "when'

16:31 nicknull: paste your code?

16:33 lisppaste8: nicknull pasted "recur" at http://paste.lisp.org/display/69020

16:35 drewr: nicknull: Try if.

16:36 lisppaste8: Chouser annotated #69020 with "recur in tail position" at http://paste.lisp.org/display/69020#1

16:37 Chouser: nicknull: the problem was the (pr "Not found") you had later.

16:38 Also it's better not to use (not= x nil) unless you really need it. That's the same as just x unless x is sometimes false.

16:39 nicknull: i see thanks

17:55 Lau_of_DK: user=> (map int->seq [12345 54321])

17:55 (#{1 2 3 4 5} #{1 2 3 4 5})

17:55 user=> (apply == (map int->seq [12345 54321]))

17:55 false

17:55 Its 4 minz to midnight here, help a tired brain make this eval to true :)

17:57 nicknull: compojure is very good!

17:57 wwmorgan: Lau_of_DK: why are you using ==?

17:58 Lau_of_DK: argh

17:58 :)

17:58 whats the difference?

17:59 wwmorgan: the docs make me believe that == is for numeric equality

18:00 Lau_of_DK: k

18:00 thanks for pointing that out, works now, bed time

18:00 AWizzArd: Lau_of_DK: (== true true) ==> false

18:16 What is the right way to provide patches for Clojure? Uploading a diff to the google group? Sending Rich an email?

18:37 nicknull: why do people use other webservers than apache?

18:37 i mean what strengths weaknessses does it have?

18:38 wwmorgan: nicknull: I think compojure requires jetty

18:46 AWizzArd: wwmorgan: thanks for your reply about Currying. I just think that partial is not nice enough. In principle it could go away if we had full currying.

18:46 wwmorgan: can you explain the rgb use case? I don't get it

18:48 AWizzArd: rgb is a hypothetical function that returns a color object. Currying is syntactic sugar. It provides nothing that couldn't be done by using fn. Macros are all about syntactical sugar. So in my example I want:

18:48 #(rgb _ 0 255) ==> this creates a new function on-the-fly. This new function takes one argument.

18:48 danlarkin: AWizzArd: isn't partial basically doing currying? Or am I misunderstanding what currying is

18:49 AWizzArd: danlarkin: yes, it is currying and you understand it correctly. I want currying that goes even further. Have a look at the google groups.

18:49 wwmorgan: right now that case is covered by #(rgb % 0 255) right?

18:49 AWizzArd: Yes, this case is covered.

18:49 #(rgb _ _ 255) is't

18:49 isn't

18:50 you need to be a bit more talkative by explicitly listing the argument number

18:51 what I suggest is adding a throw-away underscore _ for arguments about which you don't care. You list only args that you care about. And this happens only if you need to repeat them.

18:51 For example for making a squaring function: #(* %1 %1). I want to keep that.

18:52 Chouser: AWizzArd: Rich only accepts patches if he's received your CA and you submit your patch via google group (attached to a message or uploaded to the files.)

18:52 AWizzArd: Btw, what is a CA?

18:52 Chouser: AWizzArd: it seems to work best to send a description to the group with a diff attached.

18:53 AWizzArd: http://clojure.org/contributing

18:53 hm, I should have just posted that first.

18:54 AWizzArd: thx

19:28 jao: what's the idiomatic way of defining/signalling errors? do i need to use java exceptions?

19:37 Chouser: jao: that's a fine option, or some people are experimenting with calling a fn in a dynamically bound var to signal an error.

19:38 jao: Chouser, aha... i'm not sure i understand the alternative to exceptions: could you give me an example, please?

19:39 Chouser: let me see if I can find the discussion thread.

19:45 nicknull: (import '(javax.imageio.ImageIO)) <- correct right? , how do i then use that?

19:45 static ImageInputStream createImageInputStream(Object input)

19:45 Chouser: nicknull: no. (import '(javax.imageio ImageIO))

19:46 note the space instead of the dot

19:46 (ImageIO/createImageInputStream input)

19:47 nicknull: should it work in the repl? it just retusn nil. an it does so if i import rubbish too

19:48 Chouser: import returns nil

19:49 jao: here is some high-level discussion: http://groups.google.com/group/clojure/browse_thread/thread/90eae0f570989254/951b5f04d53ebca3

19:49 jao: thanks!

19:49 Chouser: jao: and here is some code (possibly not correct): http://groups.google.com/group/clojure/browse_thread/thread/3beb90914b4b5e70/8f4186fc21b73bc2

19:50 jao: excellent

19:53 larrytheliquid: is there an example of this somewhere? "It is possible to create vars that are not interned. These vars will not be found during free symbol resolution, and their values have to be accessed manually. But they can serve as useful thread-local mutable cells."

19:53 Chouser: larrytheliquid: that may be referring to var-local-vars

19:55 larrytheliquid: Chouser: that makes sense, thanks

19:55 Chouser: larrytheliquid: where's the quote from?

19:55 larrytheliquid: http://clojure.org/vars

19:55 under find-var

19:58 lisppaste8: Chouser pasted "with-local-vars example" at http://paste.lisp.org/display/69031

19:59 nicknull: Chouser: if import or uses of JAVA-libraries fail, arent exceptions raised?

20:00 like im using a method that should return a java-object and i just get nil

20:00 Chouser: user=> (import '(foo.bar bang))

20:00 java.lang.ClassNotFoundException: foo.bar.bang (NO_SOURCE_FILE:0)

20:00 nicknull: i dont know id that means failure to open file, find file, to fidn javamethod

20:04 Chouser: if your import returns nil, it succeeded.

20:20 jao: hmm. is there a type predicate for procedures?

20:24 nicknull: new BufferedReader(new FileReader("xanadu.txt"));

20:24 how do i pass that?

20:30 danlarkin: (BufferedReader. (FileReader. "xanadu.txt"))

20:32 alternatively: (new BufferedReader (new FileReader "xanadu.txt))

20:33 nicknull: and i can use them without any prefix?

20:33 like java/BufferedReader?

20:33 danlarkin: first you have to import them

20:33 (import '(java.io BufferedReader FileReader))

20:36 nicknull: the . at the end is the same as new before?

20:37 danlarkin: ya, it's reader syntax

20:38 * jao found it: fn?

20:44 nicknull: http://hpaste.org/11406

20:44 can someone help me here, i get nil back when i should get some sort of strema from JAVA

20:45 man JAVA really seems to complicate evrything to the maximum

20:46 walters: nicknull: you shouldn't use *Reader for binary data

20:47 nicknull: just create a FileInputStream

20:47 nicknull: the imageio docs also say you can just pass it a File

20:47 *Reader is for Unicode text

20:48 (why the imageio API has some sort of magic dispatch-on-Object instead of proper overloads, I have no idea)

20:49 nicknull: how do i create an imageinputstream? im not familiar wth Java very much. or a file? open(path)?

20:50 AWizzArd: Does anyone of you know the Ants example that Rich showed in his concurrency vid?

20:51 abrooks: AWizzArd: What about it? Are you looking for the sources?

20:51 AWizzArd: I have them

20:51 I have a question about it

20:51 walters: nicknull: looks like this works: (ImageIO/createImageInputStream (new File "/usr/share/icons/abiword_48.png"))

20:52 AWizzArd: In the video I think he said that change the behaviour of the ants, as he wishes, at runtime. Is that right?

20:55 nicknull: thanks walters appreciate it

21:45 Chouser: AWizzArd: yep, I think he says that in the video

21:48 AWizzArd: I think I will have to study that code

21:50 cemerick: does anyone recall any detailed discussion of the AOT impl so far on the channel? I'm trying to understand what's going on with #=, but that's pretty hard to search for :-)

21:51 Chouser: AWizzArd: I believe he was refering to re-def'ing behave at the repl while the demo's running.

21:52 cemerick: that's just a new print format for previously unreadable objects

21:56 cemerick: ok, that helps.

21:57 Chouser: I do have a link here -- hang on

21:58 http://clojure-log.n01se.net/date/2008-10-11.html#11:06d-11:48

22:00 cemerick: Chouser: great, thanks

22:00 gotta get those pre-AOT macros workin

22:00 Chouser: hm?

22:07 AWizzArd: Oh nice, the Clojure reader has no side effects, it does not intern symbols, as it does in CL. So this means I can use it as an improved load-xml :-)

22:09 Chouser: you can't use the CL reader to load plain data?

22:11 * arohner` would love a slime button to load current file and run all tests

22:14 AWizzArd: What tests?

22:15 Chouser: CLs reader "interns" symbols. It causes side effects.

22:22 Chouser: I knew rhickey has made a point of how Clojure's reader is free of side-effects, but I didn't realize this mean CL's reader couldn't be used for just reading data.

22:26 arohner`: (let [[a b] {:a 1}]

22:27 bkearns: I wos wondering a little about the output of printing an object.

22:27 after reading http://clojure-log.n01se.net/date/2008-10-11.html#11:06d-11:48

22:28 I thought something like

22:28 #=(Object. "ctor args") ;; 0xADD ; Sess Timestamp

22:29 could potentially be used to point to an existing object in memory

22:29 and then you could run your entire repl session back if the user-> prompt were ;user-> and all expeptions were preceeded by ;'s as well.

22:31 AWizzArd: Do we have access to the byte code that is generated by the compiler?

22:32 Chouser: interesting idea. Currently the older values have probably been garbage collected -- you'd have change the repl to hang onto all those values

22:33 bkearns: I wonder if there's a callback on the GC thread to tell you what the address of the objecst being collected are

22:33 Chouser: the repl currently keeps the last 3 values I think. You could extend that to keep all of them I suppose.

22:34 AWizzArd: not easily. why?

22:35 AWizzArd: (= #(+ 4 %) #(+ 4 %)) ==> true

22:35 Chouser: wow.

22:35 arohner`: is there any reason why set! could not be extended to work on vars created by with-local-vars?

22:35 AWizzArd: you say wow Couser, but in reality the result is false.

22:37 bkearns: It should be false, each of the #() forms gets compiled to a separate class thus generating different objects I think.

22:37 AWizzArd: Then why should (= "hallo" "hallo") ==> true?

22:37 Those are two separate strings, in two different memory locations

22:37 bkearns: because in the JVM strings are interned

22:38 so they point to the same memory location

22:38 Chouser: no, = is a value comparison, not like identical?

22:38 danlarkin: no, = operates on value

22:38 Chouser: what he said. :-)

22:38 AWizzArd: then let's do: (identical? [1] [1]) ==> false

22:38 bkearns: (= (File. "/tmp/foo") (File. "/tmp/foo"))

22:39 ==> true

22:39 walters: bkearns: not always, I don't believe

22:39 maybe Clojure's reader calls .intern() on strings

22:39 bkearns: I think all strings do that's why they're immutable in the JVM.

22:40 AWizzArd: forget strings

22:40 take vectors then instead

22:40 Chouser: Clojure interns strings currently, but I don't think that's guaranteed.

22:40 walters: bkearns: they were originally immutable for security reasons

22:40 AWizzArd: When [1] and [1] are two different objects and (= [1] [1]) yields true, then why shouldn't (= fun1 fun2) yield true if they compiled to the same byte code?

22:41 bkearns: right and then there would be no need for the inter() on the String object...

22:41 walters: AWizzArd: they could be capturing different environments

22:41 danlarkin: AWizzArd: you don't know they're the same bytecode though :-D

22:41 what walters said

22:41 bkearns: I was last dealt with low level messing with Jython and Terracotta and Jython interns strings.

22:41 AWizzArd: danlarkin: that's why I asked if there is a way to get the byte code of an object

22:42 (= (byte-code fun1) (byte-code fun2))

22:42 danlarkin: TBH I don't know how = is defined on functions

22:43 AWizzArd: I think = on functions is like CLs eq

22:43 Chouser: #(+ 4 %) doesn't return bytecode anyway, it returns an instance of Class

22:43 AWizzArd: so it looks if they have the same address in memory

22:43 danlarkin: AWizzArd: no, = is different from identical?

22:43 AWizzArd: Chouser: and can't class instances be represented by byte code

22:43 danlarkin: = is always a value compare, identical? is a pointer compare

22:43 AWizzArd: danlarkin: sure, for most things, but for functions they seem to be the same

22:44 Chouser: I'm not completely sure, but it may be that the Class class doesn't have an equals() method, and thus Clojure's = returns false.

22:45 AWizzArd: danlarkin: can you otherwise provide one example of where (= fun1 fun2) ==> true and at the same time (identical? fun1 fun2) ==> false, or vice versa?

22:46 danlarkin: no, doesn't mean it isn't the case though

22:46 walters: AWizzArd: i don't think you can get the bytecode easily; you might be able to look at the classloader of the class of the method and find the on-disk source if the class came from disk

22:47 but if it was generated at runtime or pulled from the network i'm not sure the JVM is guaranteed to keep it around

22:47 bkearns: doesnt' the JVM make sure the classes of the objects are the same before calling equals()

22:47 walters: bkearns: no

22:47 AWizzArd: okay, so for non-trivial cases we can't compare functions with each other

22:48 I understand that this is for technical reasons, and in practice one does not compare functions with each other often, but this is an irregularity

22:49 Chouser: Hm, all objects provide .equals -- anyway, it appears to be Java that's returning that false.

22:50 rhickey has warned about equality semantics of Java objects.

22:58 msingh: 24~

22:58 oops. sorry!

22:58 arbscht: heh, hi msingh

22:59 channel's growing fast

23:08 AWizzArd: if I don't want to use rationals, is there a way to get abritery precision for floats?

23:09 Chouser: BigDecimal

23:09 AWizzArd: can you give me an example call on how to add two of them?

23:10 Chouser: (+ 12.34M 56.78M)

23:11 clojure.lang.Numbers is crazy.

23:12 AWizzArd: And can I enforce the representation to be human readable? If I type 0.0000001M I will see the printer giving me that one back

23:12 Chouser: Hm, doesn't look like it.

23:12 AWizzArd: ok, I see this only happens to these mana zeros in a row

23:13 0.123456789M shows me the right thing

23:13 Chouser: even 1.000000000001M

23:13 AWizzArd: ok, good then

23:19 Do you have a minimal example which shows that let and binding behave different?

23:20 in the context of concurrency I mean

23:21 of course binding can only bind symbols that were already introduced in the context

23:24 (binding [unknown 10] unknown) ==> error but (let [unknown 10] unknown) ==> 10... but I am talking about http://clojure.org/vars#toc1 and in this example it behaves like let.

23:28 Chouser: (binding [x 2] (send-off (agent nil) (fn [_] (Thread/sleep 100) (prn :x x))))

23:28 arohner`: AWizzArd: you can use set! on vars inside of a (binding [])

23:29 binding can also change the value of a def

23:29 AWizzArd: can't let change the value of a def lexically?

23:29 arohner`: (def x 5) ( binding [x 7] (println x) (set! x 9) (println x))

23:29 that's a different object

23:30 using let, you create a different object with the same name

23:30 AWizzArd: so, inside a (binding ...) I can use (set! ..)

23:30 arohner`: yes

23:30 AWizzArd: What is this good for? :-)

23:30 Chouser: AWizzArd: yes, and that "change" will be "global" for that thread.

23:31 AWizzArd: CL allows for dynamically bound variables, right?

23:31 AWizzArd: yes

23:31 Chouser: that's what binding does.

23:32 arohner`: the effects of set! last until the end of the binding scope, right?

23:32 and leaving the binding resets things?

23:32 Chouser: yep

23:32 AWizzArd: I still don't get what it is good for. Making a thread wide change of that varaible should not have any effects, as nothing runs parallel in a thread.

23:33 Chouser: but again, that's all just for the one thread. Other threads can have their own bindings and be doing their own set!s on the same var

23:33 arohner`: AWizzArd: you can use it 'signal' behavior in other places in the stack

23:33 Chouser: AWizzArd: it can be used to "pass" data down the call stack without it having to be in every parameter list

23:34 AWizzArd: with set! it can be used to "return" extra results back up the stack

23:34 AWizzArd: Can you show a small example for this?

23:34 danlarkin: a set of functions that make modifications to a list, you don't have to pas the list to every function

23:34 Chouser: there was a macro on the google group recently that implemented a sort of multiple-value-bind using binding

23:35 http://paste.lisp.org/display/68919

23:48 AWizzArd: okay, now I got it

23:50 it seems that binding is doing more or less what CLs let is doing

23:51 lisppaste8: AWizzArd pasted "What is (binding ..) good for?" at http://paste.lisp.org/display/69040

23:52 sohail: how the heck do you read in a list of integers without creating N lists?

23:52 AWizzArd: What do you mean by 'read'?

23:52 sohail: from the user

23:52 I guess I should use recursion there

23:53 AWizzArd: Do you mean you use the Clojure reader? As in (read) ?

23:54 sohail: yeah

Logging service provided by n01se.net