#clojure logs

2009-03-27

02:08yangsxI have an extended assert that print some additional info for debug purpose, but sometimes there is an assertion failure without preventing any such info at all at repl if the assertion is buried in some depth.
02:08yangsxIs that expected behavior?
02:08yangsxs/printing/preventing
02:36hiredmanwhat kind of try/catch stuff do you have around the assertion?
05:10RaynesWeee my Clojure text editor is almost complete. Ya know. Creating substitutes for the basic applications that come with Windows is a great way to learn a language let me tell ya.
05:16antifuchsRaynes: congratulations
05:47AWizzArdRaynes: sounds nice
06:13antifuchsnow to hack some more on the 3d modeller plugin - I think I should be able to print a clojure-generated 3d model in very few days (:
07:27durka42antifuchs: awesome, what library are you using?
07:27antifuchsI'm writing a plugin for Art of Illusion. this lets me interactively (in slime) write code that creates 3d models
07:28antifuchsthat's inspired by a friend's MetaCADEvaluator plugin for same
07:28durka42nice
07:29antifuchsit is! it's rewarding on its own already, but since it's for a 3d printer, I even get to play with the stuff this creates afterwards (:
07:30durka423d printers are nearly as cool as clojure
07:31durka42silly me i figured you meant "print" to screen
07:31antifuchsheh. I'm not yet decided on the ordering on coolness; but both are pretty awesome (:
07:31durka42but you meant print to _reality_
07:31antifuchsoh no. print to toy (-:
07:57noidiis there a function like nth that counds from the end of the collection instead of the beginning?
07:58noidicounts
07:58noidiin python i could use my_list[-2] to get the second-to-last item from a list
07:59Carki dion't think there is
08:01Carkactually this might be a good sign you need a vector rather than a list
08:02noidii'm using a vector, actually
08:03Carkah well tyhen it's (get my-vector (- (count my-vector) 2)
08:03noidithanks!
08:04Cark,(let [v [1 2 3 4 5]] (v (- (count v) 2)))
08:04clojurebot4
08:06noidii'd like (nth [1 2 3 4 5] -2) better :)
08:07Carkyou may write a function to do this =)
08:07noidiyeah, i know
09:01antifuchshm, is there a way to get a more meaningful backtrace from clojure than what I'm seeing in slime right now? the top frame is always clojure.lang.Compiler.eval, followed by similarly useless ones /-:
09:03antifuchs(I got the issue resolved eventually, but it would have helped enormously to know which function the breakage was in)
09:09drewrantifuchs: Hit 1 to see expand each cause.
09:10antifuchsOH. wow. (:
09:10antifuchsI was so used to seeing one useful and one useless restart from sbcl that I completely ignored the second one
09:10antifuchsthanks!
09:10selloutantifuchs: Zing!
09:11antifuchshey sellout (-:
10:29AWizzArdDo we have an expert for regular expressions here?
10:30AWizzArdI want to know what follows an underscore, but only if the string contains exactly one underscore
10:30AWizzArd(re-find #"" "hello_world") ==> world
10:30AWizzArd(re-find #"" "hello_sweet_world") ==> nil
10:31hiredman,(re-find #"{^_]_[^_]" "hello_world")
10:31clojurebotIllegal repetition {^_]_[^_]
10:31hiredman,(re-find #"{^\_]\_[^\_]" "hello_world")
10:31clojurebotIllegal repetition {^\_]\_[^\_]
10:31hiredman,(re-find #"[^_]_[^_]" "hello_world")
10:31clojurebot"o_w"
10:32hiredman,(re-find #"[^_]+_[^_]+" "hello_world")
10:32clojurebot"hello_world"
10:32hiredman,(re-find #"[^_]+_[^_]+" "hello_world_sweet")
10:32clojurebot"hello_world"
10:33AWizzArdI was thinking about negative lookaheads: an _ not followed by an underscore (re-find #"_(?!_)" some-string), but that does not work out
10:38hiredman,(re-find #"_[^_]+" "hello_world_sweet")
10:38clojurebot"_world"
10:38hiredman,(re-find #"_[^_]+" "hello_world")
10:38clojurebot"_world"
10:39AWizzArdThey are all pretty close.
10:39AWizzArdThese damn regexps ;)
10:43hiredman,(re-find #"_[^_]+$" "hello_world_sweet")
10:43clojurebot"_sweet"
10:43hiredmanbah
10:43hiredman,(re-find #"[^_]_[^_]+$" "hello_world_sweet")
10:43clojurebot"d_sweet"
10:43hiredmansnort
10:44AWizzArdI will do it manually
10:45AWizzArdhiredman: thanks for your suggestions
10:46Chousuke(re-find #"_[^_]([^_])*" "hello_word_test")
10:46Chousuke,(re-find #"_[^_]([^_])*" "hello_word_test")
10:46clojurebot["_word" "d"]
10:46Chousukehm, interesting :P
10:48Chousuke,(re-find #"_[^_]([^_])+" "hello_word_test")
10:48clojurebot["_word" "d"]
10:52Holcxjo,(re-find #"^[^_]*_([^_]+)$" "hello_word")
10:52clojurebot["hello_word" "word"]
10:52Holcxjo,(re-find #"^[^_]*_([^_]+)$" "hello_word_test")
10:52clojurebotnil
10:52Holcxjo,(re-find #"^[^_]*_([^_]+)$" "helloword")
10:52clojurebotnil
10:53Holcxjo,(re-find #"^[^_]*_([^_]+)$" "_world")
10:53clojurebot["_world" "world"]
11:00Holcxjo,(map (fn [text] (let [match (re-find #"^[^_]*_([^_]+)$" text)] (list text (if match (nth match 1))))) (list "" "hello" "hello_" "hello_world" "hello__world" "hello_world_test"))
11:00clojurebot(("" nil) ("hello" nil) ("hello_" nil) ("hello_world" "world") ("hello__world" nil) ("hello_world_test" nil))
11:03AWizzArdThis regexp which solves this "simple task" is protected against being found.
11:03HolcxjoAWizzArd?!?
11:04AWizzArdI mean, we can't find it.
11:04HolcxjoThis one: #"^[^_]*_([^_]+)$" ?
11:04AWizzArd"Return what follows an underscore. Match only if the string contains exactly one underscore".
11:05HolcxjoThat's what mine does. Or not?
11:05AWizzArd,(re-find #"^[^_]*_([^_]+)$" "hello_a_xyz")
11:05clojurebotnil
11:05AWizzArd,(re-find #"^[^_]*_([^_]+)$" "hello_a")
11:05clojurebot["hello_a" "a"]
11:06AWizzArdyes okay, this one is doing it, it seems
11:06HolcxjoMight want to make the last "+" a "*" in case the empty string is acceptable as being after the underscore
11:06AWizzArd,(re-find #"^[^_]*_([^_]*)$" "hello_")
11:06clojurebot["hello_" ""]
11:07AWizzArdHolcxjo: grats :)
11:07Holcxjonp
11:14AWizzArdclojurebot: max people
11:14clojurebotmax people is 164
12:05tsdhDoes anyone have an example of :let in a for comprehension?
12:05hiredman,(for [x (range 10) :let [y (* x x)]] y)
12:05clojurebot(0 1 4 9 16 25 36 49 64 81)
12:06tsdhThans, hiredman.
12:22scottj_Is anyone able to run the code from this genetic mona lisp solution? (http://npcontemplation.blogspot.com/2009/01/clojure-genetic-mona-lisa-problem-in.html) I get "java.lang.Exception: Unable to resolve symbol: draw-polygon in this context"
12:24kefkaI asked this question last night and couldn't get a conclusive answer. Does Clojure have the problem of keywords and strings getting interned on reads, the way CL does?
12:24kefkaThe reason I'm asking is that I'm worried about memory leakage.
12:24kefka(Almost no one was on last night when I asked.)
12:25scottj_kefka: I think I remember Rich talking about that in one of his screencasts, probably the lisp one.
12:25scottj_strings are java strings, if that helps answer the question
12:28scottj_see fourth paragraph, http://netzhansa.blogspot.com/2008/10/trying-clojure.html
12:29danlarkinkefka: the reader does not intern
12:30danlarkinsymbols, I know, at least
12:31hiredmandepends what you mean by "intern"
12:32hiredmanwell
12:32hiredmanhmm
12:35brianh2kefka: i've been poking around a little
12:35brianh2found this http://www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/
12:36brianh2which pointed to this http://www.javaworld.com/javaworld/javaqa/2003-12/01-qa-1212-intern.html
12:39kefkaOk, so it looks like there's nothing to worry about with symbols piling up and eating memory. Is the same true of keywords?
12:39clojurebothttp://clojure.org/data_structures#toc10
12:40brianh2best i can tell, keywords are symbols & therefor interned in the permgen space
12:41hiredmanerm
12:41hiredmanI am pretty sure what gets interned is the string behind the keyword or symbol
12:41hiredman~def c.l.Keyword
12:44cemericksymbol and keyword strings are interned, and keywords themselves are interned as well (of course, using a separate facility from the standard lib's String.intern())
12:45cemerickOf course, there's nothing keeping you from creating a symbol whose string isn't interned.
12:45cemerick,(identical? 'foo 'foo)
12:45clojurebotfalse
12:45brianh2that's semantics. but ok. to be precise. it would appear that every keyword that is created generates a symbol that is then placed into a map as the key to the keyword itself
12:46cemerickyeah.
12:47brianh2that symbol causes the ns name & the keyword name to be interned into the permgen space
12:47cemerickThe direct Keyword constructor is private right now, but if there was a compelling case for the non-interned keyword strings, I'll bet that could be changed.
12:47clojurebotfor is not used often enough.
12:47cemerickYes.
12:48cemerickI'd be surprised if that was somehow absolutely a requirement, though. Likely just a way to ensure good space/performance tradeoffs by default in maps, etc.
12:49brianh2& since the keyword table is private & nothing ever, as far as i can tell, removes anything from it, keyword strings will never be GCd
13:04rsynnottwhat do you want non-interned keyword strings for?
13:08brianh2rsynnott: i don't ;) i was just interested in the implications of using the String.intern() feature for keywords/symbols
14:26Lau_of_DKGood evening gents
14:28pjstadiggood afternoon
14:29mozinatorI would like to ask a question, I tried to search for it, but I couldn't find it.
14:29mozinatorIs it possible to inherit a java class and override methods ?
14:29hiredman,(doc proxy)
14:29clojurebot"([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid
14:30hiredmanif you want to add new methods you need to use gen-class or gen-interface
14:30mozinatorhiredman, thanks for the pointer!
14:30clojurebotfor is not a loop
14:33durka42why did clojurebot start speaking when he is not being spoken to
14:33durka42test:
14:34durka42he suddenly became sentient!
14:34durka42~he suddenly became sentient!
14:34clojurebotCLABANGO!
14:34durka42so just "for"
14:34selloutdurka42, I think it's the comma
14:34sellouteh, guess not
14:34pjstadighiredman, suddenly he became sentient!
14:34pjstadighuh
14:35cmvkk_~
14:35clojurebotBDFL is Benevolent Dictator For Life (a.k.a. Rich Hickey)
14:35cmvkk_hmm
14:36cemerickhe says something without prompting once every 20 messages or something now
14:36selloutThat's a long time!
14:36hiredmaneverytime (= 1 (rand-int 20))
14:36cmvkk_just anything? or something relating to the last message
14:37hiredmanit treats the last message as if it was addressed to it
14:37clojurebotit is too
14:37hiredman^-
14:37cemerickhiredman == crazy mad social scientist ;-)
14:41p_lmarkov model, eh?
14:41pjstadigsorry
14:41pjstadigi was trying to teach clojurebot to argue with me
14:41pjstadigit is too/it is not/it is too
14:42pjstadigbut everytime i tried to get it to learn to respond to "it is too" he thought (= 'it 'too)
14:42hiredmanheh
14:42hiredmanclojurebot: it is too?
14:42clojurebotit is too
14:48Lau_of_DKmozinator...
14:48Lau_of_DK~proxy?
14:48clojurebotproxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.
14:48Lau_of_DKConsider reading up on gen-class instead :)
14:48hiredman*shrug*
14:48mozinatorLau_of_DK, will do, thanks
14:48hiredman~works on my machine
14:48clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
14:50pjstadig~is too!
14:50clojurebotis not!
14:50pjstadig~is not!
14:50clojurebotis too!
14:50pjstadigsweet
14:51pjstadigclojurebot has sass
14:53pjstadig~is not!
14:53clojurebotis too!
14:53pjstadig~is not!
14:53clojurebotis too!
14:53pjstadig~is not infinity!
14:53clojurebotis too infinity +1!
14:53pjstadigd'oh
14:54pjstadigbeaten by a bot
15:11AWizzArdSome days ago Rich gave a talk. A lot of twitter users were writing about it. Is there an audio/video file available?
15:11selloutAWizzArd: It was definitely recorded.
15:12selloutDon't know when/where the video will be available.
15:12hiredmanthe infoq is not yet, it maybe a while before they put it up, the skillsmatters is up
15:12selloutIt was (I think) 5 hours.
15:12hiredmanclojurebot: skillsmatter?
15:12clojurebotTitim gan �ir� ort.
15:12pjstadiginfoq will probably release video from qcon, but they dribble it out
15:13pjstadigmay not be months
15:13sellouthiredman: I think he's referring to the ILC one, but not sure.
15:13hiredmanoh
15:13pjstadigoh ILC would be nice
15:13hiredmanwhat?
15:13clojurebot?Que?
15:14Raynes<3
15:14rhickey_in past 2 weeks - 2 talks + 1 interview at QCon, a talk at Java group in London, a short talk at semantic web meetup in NYC, 5 hour tutorial and a panel at ILC
15:14pjstadighttp://skillsmatter.com/podcast/java-jee/clojure-for-java-programmers
15:15hiredmanzouch
15:15RaynesBeen busy.
15:17Raynes\o/
15:17rhickey_Raynes: awesome!
15:17RaynesWe all know, Java totally needs moar IDE's.
15:18Raynes:D
15:19mrsolo_well eclipse clojure plug in is badly needed :-)
15:20Raynesmrsolo_: Clojure-dev already exists.
15:20pjstadighttp://www.swnyc.org/index.php?title=AllegroGraph%2C_the_Semantic_Web_%26_Clojure_Updates
15:20AWizzArdRaynes: very good, you make my point. I am argumenting since months that Clojure *will* open job opportunities. Clojurists will sneak into Java companies, probably Startups, who will be willing to trade "cryptic code" (Clojure *g*) for the increased productivity.
15:20mrsolo_raynes: exists last time i checked few months back it is still not working too good
15:20mrsolo_slime is sufficient imho if you stay inside clojure
15:20mrsolo_but when you start doing java interop stuffs....
15:20clojurebot?
15:21Raynesmrsolo_: It's working better now, but with no offense to Laurent as I know he tries hard, Enclojure is better.
15:21AWizzArdpjstadig: thanks for this video link
15:21pjstadigAWizzArd: np
15:22AWizzArdRaynes: Enclojure still has to fight with the enormous complexity of NetBeans.
15:22dysingerThere already is a clojure IDE - it's called emacs + slime :P
15:23RaynesEnclojure works for me. That's my disclaimer.
15:23AWizzArdit's what I am using too
15:23mrsolo_raynes: it takes resources to get plug in working; i don't envy him :-)
15:23AWizzArdbut Enclojure will hopefully catch up over time
15:23mrsolo_as for enclojure that is the thing
15:23mrsolo_i don't use netbeans and really don't want to learn another ide
15:23mrsolo_again
15:23dysingerI tried both the eclipse & netbeans flavors yesterday - no thanks
15:24dysingerI can appreciate they are good for the java crowd though
15:24dysingeremacs + slime + jswat is all I need for now.
15:24brianh2rhickey_: how were you and Clojure received at ILC?
15:24AWizzArddysinger: after using slime+CL for some years it is difficult to use something else, but I think sooner or later Enclojure will be able to do all that nice stuff too, and then even more.
15:25hiredmandurka42 has edged out cconstantine url wise
15:25dysingeryeah - I won't give up emacs' awesome for now.
15:25dysingerbut I can see how a Java IDE _could_ do better on the java parts.
15:25dysinger(debugging etc)
15:26AWizzArdthe nice thing is that the debugger is already included in NetBeans, as well as the Gui builder.
15:26dysingerjswat is the netbeans debugging AFAIK
15:26dysingertrue - I guess I'll be happy to play with it all.
15:28AWizzArdIt is just very very complicated to program NetBeans. The guys who implement plugins for emails or vi for Clojure editing have a way easier job.
15:28clojurebotfor is not a loop
15:34jwinter_1What am I doing wrong with loop/recur here http://gist.github.com/86841 ?
15:35cmvkk_your recur is inside a vector, so it's not in tail-call position.
15:36pjstadighttp://gist.github.com/86844
15:36jwinter_1ah, thx very much
15:37selloutjwinter_1: You can't just wrap [] to put a block in your if branch
15:37cmvkk_well you can, provided you don't care about the return value...and provided you aren't trying to recur
15:37selloutIf that did do something, I don't think it's what you'd want.
15:38selloutcmvkk_: ah, true enough
15:38selloutis that a common idiom in clojure?
15:38cmvkk_no
15:38sellout*phew*
15:38cmvkk_it's bad practice of course, and i've never seen anyone do it before...i was just pointing out that it does technically work
15:39jwinter_1the do block was what I was looking for, I just stumbled onto the fact that that vector would execute what's inside
15:40selloutcmvkk_: I thought it was a mistake akin to the CL newbie one of (if foo bar ((print baz) quux))
15:40selloutbut it seems to be of a different kind
15:41cmvkk_yeah, although that example at least doesn't work at all
15:42selloutcmvkk_: Yeah, thankfully.
15:48arohnermore and more, I find myself using refs of maps instead of plain maps, just so I can validate them
15:48arohnervalidators are awesome
15:49AWizzArdarohner: do you have a minimal example?
15:50arohnerhrm, not a short one
15:50AWizzArdWhat is a validator?
15:51arohnerit is a function that can be attached to a ref
15:51arohnerif you try to change the ref, the validator is called
15:51hiredmanarohner: you could write a validating version of assoc
15:51hiredmanthat uses a validator from the maps metadata
15:51arohnerif the validator throws an exception or returns false, the transaction fails
15:52arohnerhiredman: that's interesting. I was thinking of a validating struct-map
15:52arohner,(doc ref)
15:52clojurebot"([x] [x & options]); Creates and returns a Ref with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will be come the metadata on the ref. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return fa
15:53selloutarohner: But you don't need a validator if you're not going to modify the map, so why would you use a ref rather than the map directly?
15:54hiredmanmetadata and map destructuring are my features of the week
15:54selloutRather, in which cases where you would have used the map directly in the past do you now use a ref?
15:55arohnerI have a few different places where I create instances of the same kind of struct map
15:55arohnerand I sometimes I find bugs where one fn that creates the struct map was doing it incorrectly
15:56arohnerso maybe I want a validating struct-map
15:56hiredmanvery interesting
15:59antifuchsso - here's my finished 3d-printable part: http://github.com/antifuchs/aoi-swank-plugin/blob/1987fb6d3477fc5835d1c37b2762ac2cf82c5696/examples/dishwasher-part.clj (the exact same thing was printed before, as http://reprap.soup.io/post/15859377 (:
15:59hiredman~def defstruct
16:00AWizzArdantifuchs: sounds nice
16:00AWizzArdapropos bugs, please check out my posting in the Google Group: http://groups.google.com/group/clojure/browse_frm/thread/7a48f48e4b197a15/bcaf06d233cde839
16:00antifuchsI'm still not entirely happy with the surface syntax and the repeated need to transform by (90 0 0), but I'm optimistic that this will be very nice soon (:
16:00AWizzArdwow
16:02selloutantifuchs: You integrated with aol to make a dishwasher knob?
16:02selloutantifuchs: And you have a RepRap?
16:02antifuchssellout: we have one at the metalab (:
16:02AWizzArdarohner: if rhickey decide to implement gradual typing, then you could catch some hard to find bugs
16:03selloutantifuchs: I'd ask you to print me one if I was near Austria.
16:03arohnerAWizzArd: what is gradual typing?
16:03selloutarohner: see Typed Scheme
16:03antifuchssellout: sure thing! new york may be easier for you (:
16:03antifuchssellout: nyc resistor sell kits with space for 10x10x10cm models for $750
16:04selloutNice, danke.
16:04AWizzArdarohner: it is mentioned in that Google Posting. But the basic idea is: it is extremly granular static typing. You can have as few or as much you want.
16:04antifuchsthey're very good, apparently (and I am pondering buying one of their extruders) (:
16:04AWizzArdBetween 100% dynamic typing and a 100% statically typed program everything is possible.
16:04arohnerAWizzArd: interesting. thanks
16:04AWizzArdAnd with a global switch one could even turn it off, if one really does not like static typing and a lib one is using supports it.
16:05AWizzArdClojure could simply use metadata for communicating what it wants the compiler to treat as static code
16:05AWizzArdYou could for example have one function in your whole code base which can perform type checks for one of its 4 parameters
16:06AWizzArdThis would allow the compiler to let you know that you made a type error at some point or not. You would do this only for code that you want to be static (= not changeable during runtime).
16:08AWizzArdand this is also nice for editing source code
16:08AWizzArdThe IDE could access the type information as well, and allow you several nice completions/checks during edit time.
16:09arohnervery cool
19:52zakwilsonI'm trying to use contrib.json.read. There seems to be no documentation. If I have a URL and want a PushbackReader, what's the standard way to get one?
19:53danlarkinyou know what /is/ documented... :-o
19:55zakwilsonI know the Java API has lots of docs, but I'm not finding what I need because I don't know where to look. I'm trying to use the URL class, but that doesn't seem do what I need.
19:57zakwilsonAhh... I think I figured it out. That has to go through way too many classes.
20:04danlarkinoh, nah I was just plugging clojure-json
20:04danlarkinbut I'm glad you got it working
20:04slashus2danlarkin: I do like your json library.
20:06danlarkincool
20:06danlarkinthanks
20:07lpetitHello, is the fact that thread-local bindings are not propagated to child threads a design choice, a tradeoff made for performance considerations, both ?
20:08lpetitI meant thread local bindings of vars, of course
20:08zakwilsonI think it's because they wouldn't be thread-local if they were.
20:08slashus2danlarkin: The decode-from-string is a nice feature to have.
20:10lpetitI meant thread-local values, with the same property a thread-local binding has towards the stack of bindings : changes done via new 'binding or set! calls would not affect threads higher on the stack call
20:10rhickey_lpetit: it's a design choice - closures in general are created without knowing the context in which the thread that will run them has been created - there are perf issues too
20:18lpetitrhickey_: what is the expected set of use cases for global vars ? A recent post on the ml made what I have considered a valid point. Say I'm the user of an interesting library's function called foo. foo accepts a closure. For debugging purposes, I place some (println) calls in my closure, and create in my thread a thread local binding for *out* to a proper value. Now if the next version of...
20:18lpetit...the library has optimized its foo function for using several threads (maybe replacing a call to map by a call to pmap ...), suddenly I loose some traces in my log.
20:19rhickey_lpetit: you can always create a closure that includes whatever bindings you need
20:21rhickey_but every closure creation can't capture every dynamic binding
20:23lpetitrhickey_: yes, and I remember Christophe Grand already posted such a solution (macroified for ease of use) in his blog. But then one has to know in advance which bindings to further propagate. That may be impractical with a big code base, or code written by big teams ?
20:25lpetitrhickey_: again, please: when you write "but every closure creation can't capture every dynamic binding", are you saying "that would be ideal solution, but it is just impossible to do it efficiently", or are you saying "it is not affordable to impose to users that each closure creation capture the current dynamic binding" ?
20:26rhickey_there are as many reasons why you might want to return a closure that leverages the dynamic context in which it is run - threads are not really relevant - dynamic context is just that - the context in which you are run, not the one in which you are created
20:27rhickey_i.e. any function that prints would capture the state of *out* at its definition point
20:27rhickey_not what you want
20:28grosourshi
20:29lpetitrhickey_: yes, my concern is about making the vars behavior recursive among the thread hierarchy, not only between the thread that holds the root bindings (but is there one anyway that can be distinguished as such), and a thread where I rebind the var.
20:30lpetitrhickey_;ok concerning closures and the capture of values of global variables, because then it would just be lexical binding considering that global vars are in the "outermost" lexical scope. And I agree they would certainly not deserve the "dynamic" qualificative then :-)
20:32rhickey_lpetit: what thread hierarchy?
20:32rhickey_thread pool threads aren't 'under' specific application threads
20:33lpetitrhickey_: argh, you're right
20:33rhickey_it's best to leave threads out when thinking about this
20:33rhickey_it has to do with the meaning of dynamic scope
20:34rhickey_which is a runtime, not definition-time, thing
20:37lpetitSorry I don't understand, the main concern of my question is precisely to think about this thread stuff. Considering that threads created e.g. by pmap aren't technically child threads of the application thread, one might still consider they can be "logically" considered child threads, and inherit for their vars the bindings of the "logically" parent thread ? Technical and performance...
20:38lpetit...problems set apart, would it make sense if such a change could be made possible ?
20:39rhickey_no - imagine you create a closure that prints, and return it to someone that later binds *out* and calls it - what do you expect to happen? it has nothing to do with threads or pmap
20:40cmvkk_i thought you meant like (binding [*foo* true] (send-off ag some-fn)) then expecting some-fn to see *foo* as true.
20:43rhickey_(send-off ag #(binding [*foo* true] (some-fn %)))
21:01lpetitrhickey_: if as the closure creator I write it so that it prints, then at the time I write the closure, I'm OK to go with the normal behavior of dynamic variables: I don't know what the binding will be at call time, it will be set by the context. Now, as the user of the closure, I may want to specify a binding. As you just posted, I then have the possibility to add a clojure above the...
21:01lpetit...function to rebind the value. But please admit it's far from ideal for at least 3 reasons:
21:01lpetit1) I must repeat (and think about it) every time I have to make such a call. Even with some macro it's subject to errors. And if I have the value in a global already, I think I must write this if I want it to work : (send-off ag (let [let-foo
21:01lpetit*foo*] #(binding [*foo* let-foo] (some-fn %))))
21:01lpetit2) Sometimes I guess it will be difficult to remember all the bindings that *must* be passed as in the example aboe with send-off. And I fear things may get worse with big code base where one uses a closure created by lib B, passing it to lib C ...
21:01lpetit3) sort of leaky abstraction: if a user of a function provided by a lib must know if it is possible the function will split the work in separate threads for performance reasons or not, then I guess the technique of enclosing in a closure that will rebind before ... may well become "the way" to be sure it will work as expected.
21:01lpetitSo then again: if closures or even classic functions should not rely on global vars because the *user* of the closure or the function call can't be sure the binding it placed on the needed vars went away for a good reason and in a predictable way, how to blindlessly rely on them on my code ? And if the answer to be systematically certain that I will not have surprises is to rebind in a...
21:01lpetit...wrapper closure, would propagating the global vars values to "logical" child threads (if ideally possible) be a good thing compared to the current state of the art (technical, performance considerations set apart)
21:05lpetitrhickey_: a final word and I go to sleep and don't bother you more tonight : I'm asking that because I wanted to play with clojure java code, trying some implementations ideas that could solve the technical and performance problems. But then, if at the end of the road it is not interesting for design considerations I haven't understood yet, I'll be a little bit disappointed by myself...
21:09lpetitrhickey_: anyway, thanks for having exchanged ideas and knowledge with me, regards, Laurent.
21:55duderdoHi
21:57duderdoWhat would be the best way to let slime know my CLASSPATH? The function in the clojure wiki seems a bit verbose
22:07sudoerhi all,if i want to start on some web programming for clojure ,should I use compojure/other library or just do my own thing? I am learning clojure currently