2009-03-27
| 02:08 | yangsx | I 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:08 | yangsx | Is that expected behavior? |
| 02:08 | yangsx | s/printing/preventing |
| 02:36 | hiredman | what kind of try/catch stuff do you have around the assertion? |
| 05:10 | Raynes | Weee 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:16 | antifuchs | Raynes: congratulations |
| 05:47 | AWizzArd | Raynes: sounds nice |
| 06:13 | antifuchs | now 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:27 | durka42 | antifuchs: awesome, what library are you using? |
| 07:27 | antifuchs | I'm writing a plugin for Art of Illusion. this lets me interactively (in slime) write code that creates 3d models |
| 07:28 | antifuchs | that's inspired by a friend's MetaCADEvaluator plugin for same |
| 07:28 | durka42 | nice |
| 07:29 | antifuchs | it 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:30 | durka42 | 3d printers are nearly as cool as clojure |
| 07:31 | durka42 | silly me i figured you meant "print" to screen |
| 07:31 | antifuchs | heh. I'm not yet decided on the ordering on coolness; but both are pretty awesome (: |
| 07:31 | durka42 | but you meant print to _reality_ |
| 07:31 | antifuchs | oh no. print to toy (-: |
| 07:57 | noidi | is there a function like nth that counds from the end of the collection instead of the beginning? |
| 07:58 | noidi | counts |
| 07:58 | noidi | in python i could use my_list[-2] to get the second-to-last item from a list |
| 07:59 | Cark | i dion't think there is |
| 08:01 | Cark | actually this might be a good sign you need a vector rather than a list |
| 08:02 | noidi | i'm using a vector, actually |
| 08:03 | Cark | ah well tyhen it's (get my-vector (- (count my-vector) 2) |
| 08:03 | noidi | thanks! |
| 08:04 | Cark | ,(let [v [1 2 3 4 5]] (v (- (count v) 2))) |
| 08:04 | clojurebot | 4 |
| 08:06 | noidi | i'd like (nth [1 2 3 4 5] -2) better :) |
| 08:07 | Cark | you may write a function to do this =) |
| 08:07 | noidi | yeah, i know |
| 09:01 | antifuchs | hm, 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:03 | antifuchs | (I got the issue resolved eventually, but it would have helped enormously to know which function the breakage was in) |
| 09:09 | drewr | antifuchs: Hit 1 to see expand each cause. |
| 09:10 | antifuchs | OH. wow. (: |
| 09:10 | antifuchs | I was so used to seeing one useful and one useless restart from sbcl that I completely ignored the second one |
| 09:10 | antifuchs | thanks! |
| 09:10 | sellout | antifuchs: Zing! |
| 09:11 | antifuchs | hey sellout (-: |
| 10:29 | AWizzArd | Do we have an expert for regular expressions here? |
| 10:30 | AWizzArd | I want to know what follows an underscore, but only if the string contains exactly one underscore |
| 10:30 | AWizzArd | (re-find #"" "hello_world") ==> world |
| 10:30 | AWizzArd | (re-find #"" "hello_sweet_world") ==> nil |
| 10:31 | hiredman | ,(re-find #"{^_]_[^_]" "hello_world") |
| 10:31 | clojurebot | Illegal repetition {^_]_[^_] |
| 10:31 | hiredman | ,(re-find #"{^\_]\_[^\_]" "hello_world") |
| 10:31 | clojurebot | Illegal repetition {^\_]\_[^\_] |
| 10:31 | hiredman | ,(re-find #"[^_]_[^_]" "hello_world") |
| 10:31 | clojurebot | "o_w" |
| 10:32 | hiredman | ,(re-find #"[^_]+_[^_]+" "hello_world") |
| 10:32 | clojurebot | "hello_world" |
| 10:32 | hiredman | ,(re-find #"[^_]+_[^_]+" "hello_world_sweet") |
| 10:32 | clojurebot | "hello_world" |
| 10:33 | AWizzArd | I was thinking about negative lookaheads: an _ not followed by an underscore (re-find #"_(?!_)" some-string), but that does not work out |
| 10:38 | hiredman | ,(re-find #"_[^_]+" "hello_world_sweet") |
| 10:38 | clojurebot | "_world" |
| 10:38 | hiredman | ,(re-find #"_[^_]+" "hello_world") |
| 10:38 | clojurebot | "_world" |
| 10:39 | AWizzArd | They are all pretty close. |
| 10:39 | AWizzArd | These damn regexps ;) |
| 10:43 | hiredman | ,(re-find #"_[^_]+$" "hello_world_sweet") |
| 10:43 | clojurebot | "_sweet" |
| 10:43 | hiredman | bah |
| 10:43 | hiredman | ,(re-find #"[^_]_[^_]+$" "hello_world_sweet") |
| 10:43 | clojurebot | "d_sweet" |
| 10:43 | hiredman | snort |
| 10:44 | AWizzArd | I will do it manually |
| 10:45 | AWizzArd | hiredman: thanks for your suggestions |
| 10:46 | Chousuke | (re-find #"_[^_]([^_])*" "hello_word_test") |
| 10:46 | Chousuke | ,(re-find #"_[^_]([^_])*" "hello_word_test") |
| 10:46 | clojurebot | ["_word" "d"] |
| 10:46 | Chousuke | hm, interesting :P |
| 10:48 | Chousuke | ,(re-find #"_[^_]([^_])+" "hello_word_test") |
| 10:48 | clojurebot | ["_word" "d"] |
| 10:52 | Holcxjo | ,(re-find #"^[^_]*_([^_]+)$" "hello_word") |
| 10:52 | clojurebot | ["hello_word" "word"] |
| 10:52 | Holcxjo | ,(re-find #"^[^_]*_([^_]+)$" "hello_word_test") |
| 10:52 | clojurebot | nil |
| 10:52 | Holcxjo | ,(re-find #"^[^_]*_([^_]+)$" "helloword") |
| 10:52 | clojurebot | nil |
| 10:53 | Holcxjo | ,(re-find #"^[^_]*_([^_]+)$" "_world") |
| 10:53 | clojurebot | ["_world" "world"] |
| 11:00 | Holcxjo | ,(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:00 | clojurebot | (("" nil) ("hello" nil) ("hello_" nil) ("hello_world" "world") ("hello__world" nil) ("hello_world_test" nil)) |
| 11:03 | AWizzArd | This regexp which solves this "simple task" is protected against being found. |
| 11:03 | Holcxjo | AWizzArd?!? |
| 11:04 | AWizzArd | I mean, we can't find it. |
| 11:04 | Holcxjo | This one: #"^[^_]*_([^_]+)$" ? |
| 11:04 | AWizzArd | "Return what follows an underscore. Match only if the string contains exactly one underscore". |
| 11:05 | Holcxjo | That's what mine does. Or not? |
| 11:05 | AWizzArd | ,(re-find #"^[^_]*_([^_]+)$" "hello_a_xyz") |
| 11:05 | clojurebot | nil |
| 11:05 | AWizzArd | ,(re-find #"^[^_]*_([^_]+)$" "hello_a") |
| 11:05 | clojurebot | ["hello_a" "a"] |
| 11:06 | AWizzArd | yes okay, this one is doing it, it seems |
| 11:06 | Holcxjo | Might want to make the last "+" a "*" in case the empty string is acceptable as being after the underscore |
| 11:06 | AWizzArd | ,(re-find #"^[^_]*_([^_]*)$" "hello_") |
| 11:06 | clojurebot | ["hello_" ""] |
| 11:07 | AWizzArd | Holcxjo: grats :) |
| 11:07 | Holcxjo | np |
| 11:14 | AWizzArd | clojurebot: max people |
| 11:14 | clojurebot | max people is 164 |
| 12:05 | tsdh | Does anyone have an example of :let in a for comprehension? |
| 12:05 | hiredman | ,(for [x (range 10) :let [y (* x x)]] y) |
| 12:05 | clojurebot | (0 1 4 9 16 25 36 49 64 81) |
| 12:06 | tsdh | Thans, hiredman. |
| 12:22 | scottj_ | 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:24 | kefka | I 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:24 | kefka | The reason I'm asking is that I'm worried about memory leakage. |
| 12:24 | kefka | (Almost no one was on last night when I asked.) |
| 12:25 | scottj_ | kefka: I think I remember Rich talking about that in one of his screencasts, probably the lisp one. |
| 12:25 | scottj_ | strings are java strings, if that helps answer the question |
| 12:28 | scottj_ | see fourth paragraph, http://netzhansa.blogspot.com/2008/10/trying-clojure.html |
| 12:29 | danlarkin | kefka: the reader does not intern |
| 12:30 | danlarkin | symbols, I know, at least |
| 12:31 | hiredman | depends what you mean by "intern" |
| 12:32 | hiredman | well |
| 12:32 | hiredman | hmm |
| 12:35 | brianh2 | kefka: i've been poking around a little |
| 12:35 | brianh2 | found this http://www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/ |
| 12:36 | brianh2 | which pointed to this http://www.javaworld.com/javaworld/javaqa/2003-12/01-qa-1212-intern.html |
| 12:39 | kefka | Ok, so it looks like there's nothing to worry about with symbols piling up and eating memory. Is the same true of keywords? |
| 12:39 | clojurebot | http://clojure.org/data_structures#toc10 |
| 12:40 | brianh2 | best i can tell, keywords are symbols & therefor interned in the permgen space |
| 12:41 | hiredman | erm |
| 12:41 | hiredman | I am pretty sure what gets interned is the string behind the keyword or symbol |
| 12:41 | hiredman | ~def c.l.Keyword |
| 12:44 | cemerick | symbol 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:45 | cemerick | Of course, there's nothing keeping you from creating a symbol whose string isn't interned. |
| 12:45 | cemerick | ,(identical? 'foo 'foo) |
| 12:45 | clojurebot | false |
| 12:45 | brianh2 | that'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:46 | cemerick | yeah. |
| 12:47 | brianh2 | that symbol causes the ns name & the keyword name to be interned into the permgen space |
| 12:47 | cemerick | The 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:47 | clojurebot | for is not used often enough. |
| 12:47 | cemerick | Yes. |
| 12:48 | cemerick | I'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:49 | brianh2 | & 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:04 | rsynnott | what do you want non-interned keyword strings for? |
| 13:08 | brianh2 | rsynnott: i don't ;) i was just interested in the implications of using the String.intern() feature for keywords/symbols |
| 14:26 | Lau_of_DK | Good evening gents |
| 14:28 | pjstadig | good afternoon |
| 14:29 | mozinator | I would like to ask a question, I tried to search for it, but I couldn't find it. |
| 14:29 | mozinator | Is it possible to inherit a java class and override methods ? |
| 14:29 | hiredman | ,(doc proxy) |
| 14:29 | clojurebot | "([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:30 | hiredman | if you want to add new methods you need to use gen-class or gen-interface |
| 14:30 | mozinator | hiredman, thanks for the pointer! |
| 14:30 | clojurebot | for is not a loop |
| 14:33 | durka42 | why did clojurebot start speaking when he is not being spoken to |
| 14:33 | durka42 | test: |
| 14:34 | durka42 | he suddenly became sentient! |
| 14:34 | durka42 | ~he suddenly became sentient! |
| 14:34 | clojurebot | CLABANGO! |
| 14:34 | durka42 | so just "for" |
| 14:34 | sellout | durka42, I think it's the comma |
| 14:34 | sellout | eh, guess not |
| 14:34 | pjstadig | hiredman, suddenly he became sentient! |
| 14:34 | pjstadig | huh |
| 14:35 | cmvkk_ | ~ |
| 14:35 | clojurebot | BDFL is Benevolent Dictator For Life (a.k.a. Rich Hickey) |
| 14:35 | cmvkk_ | hmm |
| 14:36 | cemerick | he says something without prompting once every 20 messages or something now |
| 14:36 | sellout | That's a long time! |
| 14:36 | hiredman | everytime (= 1 (rand-int 20)) |
| 14:36 | cmvkk_ | just anything? or something relating to the last message |
| 14:37 | hiredman | it treats the last message as if it was addressed to it |
| 14:37 | clojurebot | it is too |
| 14:37 | hiredman | ^- |
| 14:37 | cemerick | hiredman == crazy mad social scientist ;-) |
| 14:41 | p_l | markov model, eh? |
| 14:41 | pjstadig | sorry |
| 14:41 | pjstadig | i was trying to teach clojurebot to argue with me |
| 14:41 | pjstadig | it is too/it is not/it is too |
| 14:42 | pjstadig | but everytime i tried to get it to learn to respond to "it is too" he thought (= 'it 'too) |
| 14:42 | hiredman | heh |
| 14:42 | hiredman | clojurebot: it is too? |
| 14:42 | clojurebot | it is too |
| 14:48 | Lau_of_DK | mozinator... |
| 14:48 | Lau_of_DK | ~proxy? |
| 14:48 | clojurebot | proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays. |
| 14:48 | Lau_of_DK | Consider reading up on gen-class instead :) |
| 14:48 | hiredman | *shrug* |
| 14:48 | mozinator | Lau_of_DK, will do, thanks |
| 14:48 | hiredman | ~works on my machine |
| 14:48 | clojurebot | http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png |
| 14:50 | pjstadig | ~is too! |
| 14:50 | clojurebot | is not! |
| 14:50 | pjstadig | ~is not! |
| 14:50 | clojurebot | is too! |
| 14:50 | pjstadig | sweet |
| 14:51 | pjstadig | clojurebot has sass |
| 14:53 | pjstadig | ~is not! |
| 14:53 | clojurebot | is too! |
| 14:53 | pjstadig | ~is not! |
| 14:53 | clojurebot | is too! |
| 14:53 | pjstadig | ~is not infinity! |
| 14:53 | clojurebot | is too infinity +1! |
| 14:53 | pjstadig | d'oh |
| 14:54 | pjstadig | beaten by a bot |
| 15:11 | AWizzArd | Some days ago Rich gave a talk. A lot of twitter users were writing about it. Is there an audio/video file available? |
| 15:11 | sellout | AWizzArd: It was definitely recorded. |
| 15:12 | sellout | Don't know when/where the video will be available. |
| 15:12 | hiredman | the infoq is not yet, it maybe a while before they put it up, the skillsmatters is up |
| 15:12 | sellout | It was (I think) 5 hours. |
| 15:12 | hiredman | clojurebot: skillsmatter? |
| 15:12 | clojurebot | Titim gan �ir� ort. |
| 15:12 | pjstadig | infoq will probably release video from qcon, but they dribble it out |
| 15:13 | pjstadig | may not be months |
| 15:13 | sellout | hiredman: I think he's referring to the ILC one, but not sure. |
| 15:13 | hiredman | oh |
| 15:13 | pjstadig | oh ILC would be nice |
| 15:13 | hiredman | what? |
| 15:13 | clojurebot | ?Que? |
| 15:14 | Raynes | <3 |
| 15:14 | rhickey_ | 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:14 | pjstadig | http://skillsmatter.com/podcast/java-jee/clojure-for-java-programmers |
| 15:15 | hiredman | zouch |
| 15:15 | Raynes | Been busy. |
| 15:17 | Raynes | \o/ |
| 15:17 | rhickey_ | Raynes: awesome! |
| 15:17 | Raynes | We all know, Java totally needs moar IDE's. |
| 15:18 | Raynes | :D |
| 15:19 | mrsolo_ | well eclipse clojure plug in is badly needed :-) |
| 15:20 | Raynes | mrsolo_: Clojure-dev already exists. |
| 15:20 | pjstadig | http://www.swnyc.org/index.php?title=AllegroGraph%2C_the_Semantic_Web_%26_Clojure_Updates |
| 15:20 | AWizzArd | Raynes: 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:20 | mrsolo_ | raynes: exists last time i checked few months back it is still not working too good |
| 15:20 | mrsolo_ | slime is sufficient imho if you stay inside clojure |
| 15:20 | mrsolo_ | but when you start doing java interop stuffs.... |
| 15:20 | clojurebot | ? |
| 15:21 | Raynes | mrsolo_: It's working better now, but with no offense to Laurent as I know he tries hard, Enclojure is better. |
| 15:21 | AWizzArd | pjstadig: thanks for this video link |
| 15:21 | pjstadig | AWizzArd: np |
| 15:22 | AWizzArd | Raynes: Enclojure still has to fight with the enormous complexity of NetBeans. |
| 15:22 | dysinger | There already is a clojure IDE - it's called emacs + slime :P |
| 15:23 | Raynes | Enclojure works for me. That's my disclaimer. |
| 15:23 | AWizzArd | it's what I am using too |
| 15:23 | mrsolo_ | raynes: it takes resources to get plug in working; i don't envy him :-) |
| 15:23 | AWizzArd | but Enclojure will hopefully catch up over time |
| 15:23 | mrsolo_ | as for enclojure that is the thing |
| 15:23 | mrsolo_ | i don't use netbeans and really don't want to learn another ide |
| 15:23 | mrsolo_ | again |
| 15:23 | dysinger | I tried both the eclipse & netbeans flavors yesterday - no thanks |
| 15:24 | dysinger | I can appreciate they are good for the java crowd though |
| 15:24 | dysinger | emacs + slime + jswat is all I need for now. |
| 15:24 | brianh2 | rhickey_: how were you and Clojure received at ILC? |
| 15:24 | AWizzArd | dysinger: 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:25 | hiredman | durka42 has edged out cconstantine url wise |
| 15:25 | dysinger | yeah - I won't give up emacs' awesome for now. |
| 15:25 | dysinger | but I can see how a Java IDE _could_ do better on the java parts. |
| 15:25 | dysinger | (debugging etc) |
| 15:26 | AWizzArd | the nice thing is that the debugger is already included in NetBeans, as well as the Gui builder. |
| 15:26 | dysinger | jswat is the netbeans debugging AFAIK |
| 15:26 | dysinger | true - I guess I'll be happy to play with it all. |
| 15:28 | AWizzArd | It 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:28 | clojurebot | for is not a loop |
| 15:34 | jwinter_1 | What am I doing wrong with loop/recur here http://gist.github.com/86841 ? |
| 15:35 | cmvkk_ | your recur is inside a vector, so it's not in tail-call position. |
| 15:36 | pjstadig | http://gist.github.com/86844 |
| 15:36 | jwinter_1 | ah, thx very much |
| 15:37 | sellout | jwinter_1: You can't just wrap [] to put a block in your if branch |
| 15:37 | cmvkk_ | well you can, provided you don't care about the return value...and provided you aren't trying to recur |
| 15:37 | sellout | If that did do something, I don't think it's what you'd want. |
| 15:38 | sellout | cmvkk_: ah, true enough |
| 15:38 | sellout | is that a common idiom in clojure? |
| 15:38 | cmvkk_ | no |
| 15:38 | sellout | *phew* |
| 15:38 | cmvkk_ | 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:39 | jwinter_1 | the do block was what I was looking for, I just stumbled onto the fact that that vector would execute what's inside |
| 15:40 | sellout | cmvkk_: I thought it was a mistake akin to the CL newbie one of (if foo bar ((print baz) quux)) |
| 15:40 | sellout | but it seems to be of a different kind |
| 15:41 | cmvkk_ | yeah, although that example at least doesn't work at all |
| 15:42 | sellout | cmvkk_: Yeah, thankfully. |
| 15:48 | arohner | more and more, I find myself using refs of maps instead of plain maps, just so I can validate them |
| 15:48 | arohner | validators are awesome |
| 15:49 | AWizzArd | arohner: do you have a minimal example? |
| 15:50 | arohner | hrm, not a short one |
| 15:50 | AWizzArd | What is a validator? |
| 15:51 | arohner | it is a function that can be attached to a ref |
| 15:51 | arohner | if you try to change the ref, the validator is called |
| 15:51 | hiredman | arohner: you could write a validating version of assoc |
| 15:51 | hiredman | that uses a validator from the maps metadata |
| 15:51 | arohner | if the validator throws an exception or returns false, the transaction fails |
| 15:52 | arohner | hiredman: that's interesting. I was thinking of a validating struct-map |
| 15:52 | arohner | ,(doc ref) |
| 15:52 | clojurebot | "([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:53 | sellout | arohner: 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:54 | hiredman | metadata and map destructuring are my features of the week |
| 15:54 | sellout | Rather, in which cases where you would have used the map directly in the past do you now use a ref? |
| 15:55 | arohner | I have a few different places where I create instances of the same kind of struct map |
| 15:55 | arohner | and I sometimes I find bugs where one fn that creates the struct map was doing it incorrectly |
| 15:56 | arohner | so maybe I want a validating struct-map |
| 15:56 | hiredman | very interesting |
| 15:59 | antifuchs | so - 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:59 | hiredman | ~def defstruct |
| 16:00 | AWizzArd | antifuchs: sounds nice |
| 16:00 | AWizzArd | apropos bugs, please check out my posting in the Google Group: http://groups.google.com/group/clojure/browse_frm/thread/7a48f48e4b197a15/bcaf06d233cde839 |
| 16:00 | antifuchs | I'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:00 | AWizzArd | wow |
| 16:02 | sellout | antifuchs: You integrated with aol to make a dishwasher knob? |
| 16:02 | sellout | antifuchs: And you have a RepRap? |
| 16:02 | antifuchs | sellout: we have one at the metalab (: |
| 16:02 | AWizzArd | arohner: if rhickey decide to implement gradual typing, then you could catch some hard to find bugs |
| 16:03 | sellout | antifuchs: I'd ask you to print me one if I was near Austria. |
| 16:03 | arohner | AWizzArd: what is gradual typing? |
| 16:03 | sellout | arohner: see Typed Scheme |
| 16:03 | antifuchs | sellout: sure thing! new york may be easier for you (: |
| 16:03 | antifuchs | sellout: nyc resistor sell kits with space for 10x10x10cm models for $750 |
| 16:04 | sellout | Nice, danke. |
| 16:04 | AWizzArd | arohner: 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:04 | antifuchs | they're very good, apparently (and I am pondering buying one of their extruders) (: |
| 16:04 | AWizzArd | Between 100% dynamic typing and a 100% statically typed program everything is possible. |
| 16:04 | arohner | AWizzArd: interesting. thanks |
| 16:04 | AWizzArd | And 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:05 | AWizzArd | Clojure could simply use metadata for communicating what it wants the compiler to treat as static code |
| 16:05 | AWizzArd | You could for example have one function in your whole code base which can perform type checks for one of its 4 parameters |
| 16:06 | AWizzArd | This 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:08 | AWizzArd | and this is also nice for editing source code |
| 16:08 | AWizzArd | The IDE could access the type information as well, and allow you several nice completions/checks during edit time. |
| 16:09 | arohner | very cool |
| 19:52 | zakwilson | I'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:53 | danlarkin | you know what /is/ documented... :-o |
| 19:55 | zakwilson | I 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:57 | zakwilson | Ahh... I think I figured it out. That has to go through way too many classes. |
| 20:04 | danlarkin | oh, nah I was just plugging clojure-json |
| 20:04 | danlarkin | but I'm glad you got it working |
| 20:04 | slashus2 | danlarkin: I do like your json library. |
| 20:06 | danlarkin | cool |
| 20:06 | danlarkin | thanks |
| 20:07 | lpetit | Hello, is the fact that thread-local bindings are not propagated to child threads a design choice, a tradeoff made for performance considerations, both ? |
| 20:08 | lpetit | I meant thread local bindings of vars, of course |
| 20:08 | zakwilson | I think it's because they wouldn't be thread-local if they were. |
| 20:08 | slashus2 | danlarkin: The decode-from-string is a nice feature to have. |
| 20:10 | lpetit | I 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:10 | rhickey_ | 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:18 | lpetit | rhickey_: 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:18 | lpetit | ...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:19 | rhickey_ | lpetit: you can always create a closure that includes whatever bindings you need |
| 20:21 | rhickey_ | but every closure creation can't capture every dynamic binding |
| 20:23 | lpetit | rhickey_: 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:25 | lpetit | rhickey_: 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:26 | rhickey_ | 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:27 | rhickey_ | i.e. any function that prints would capture the state of *out* at its definition point |
| 20:27 | rhickey_ | not what you want |
| 20:28 | grosours | hi |
| 20:29 | lpetit | rhickey_: 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:30 | lpetit | rhickey_;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:32 | rhickey_ | lpetit: what thread hierarchy? |
| 20:32 | rhickey_ | thread pool threads aren't 'under' specific application threads |
| 20:33 | lpetit | rhickey_: argh, you're right |
| 20:33 | rhickey_ | it's best to leave threads out when thinking about this |
| 20:33 | rhickey_ | it has to do with the meaning of dynamic scope |
| 20:34 | rhickey_ | which is a runtime, not definition-time, thing |
| 20:37 | lpetit | Sorry 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:38 | lpetit | ...problems set apart, would it make sense if such a change could be made possible ? |
| 20:39 | rhickey_ | 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:40 | cmvkk_ | i thought you meant like (binding [*foo* true] (send-off ag some-fn)) then expecting some-fn to see *foo* as true. |
| 20:43 | rhickey_ | (send-off ag #(binding [*foo* true] (some-fn %))) |
| 21:01 | lpetit | rhickey_: 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:01 | lpetit | ...function to rebind the value. But please admit it's far from ideal for at least 3 reasons: |
| 21:01 | lpetit | 1) 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:01 | lpetit | *foo*] #(binding [*foo* let-foo] (some-fn %)))) |
| 21:01 | lpetit | 2) 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:01 | lpetit | 3) 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:01 | lpetit | So 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:01 | lpetit | ...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:05 | lpetit | rhickey_: 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:09 | lpetit | rhickey_: anyway, thanks for having exchanged ideas and knowledge with me, regards, Laurent. |
| 21:55 | duderdo | Hi |
| 21:57 | duderdo | What would be the best way to let slime know my CLASSPATH? The function in the clojure wiki seems a bit verbose |
| 22:07 | sudoer | hi 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 |