#clojure log - Apr 14 2009

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

0:50 djkthx: is there a way to return multiple values in clojure?

0:50 like with (values) in common lisp?

0:50 cmvkk: no, other than with lists or vectors like usual

0:51 pervasive destructuring makes this more convenient

0:51 Raynes: djkthx: Return a vector of those values.

0:51 djkthx: alright, cool

1:30 Raynes: I really wish llya would fix La Clojure's identation. :\ It's annoying having to backspace 3 times after the closing bracket in a let form :|

1:36 djkthx: is there a way to do exponents that will automatically overflow to BigDecimal?

1:36 Math/pow just overflows java.lang.Double

1:38 cmvkk: other than the terrible way of rolling your own pow function

1:38 Raynes: POW!

1:41 hiredman: ,(BigDecimal. 1)

1:41 clojurebot: 1M

1:41 hiredman: ,(.pow (BigDecimal. 3) 3)

1:41 clojurebot: 27M

1:41 cmvkk: ,(Math/pow (BigDecimal. 2) 2222)

1:41 clojurebot: Infinity

1:41 hiredman: ,(.pow 27M 3)

1:41 clojurebot: 19683M

1:42 hiredman: ,(.pow 27M 10000000)

1:42 clojurebot: Execution Timed Out

1:42 hiredman: ,(.pow 27M 1000000)

1:43 clojurebot: Execution Timed Out

1:44 djkthx: hmm

1:44 writing miller-rabin is proving to be a tad more complicated than i originally thought

1:50 oh cool, someone already wrote it for me :P

1:51 hiredman: that always helps

6:49 Lau_of_DK: Compojure guys, is there a way to do (html (format "Server running on IP %s and port %s" ??? ???)) ?

6:51 AWizzArd: Lau_of_DK: could you give me 1-3 links of the best manuals/howtos for Compojure?

7:29 * Raynes pokes hiredman

8:05 cemerick: ooh, r1350 sounds delicious!

8:08 Raynes: Oh no. I missed r1337

8:13 Lau_of_DK: AWizzArd, Sorry for the late reply, all I've got is the projects wiki and their googlegroup

8:25 AWizzArd: oki, thx

9:47 rahul: Wanna get your pic on magazine cover??? http://techbuddha.blog.co.in/2009/04/14/wanna-get-your-pic-on-magazine-cover/ -- http://techmaharshi.blogspot.com/

9:50 Chouser: huh. ircspam

9:50 cemerick: I've seen that handle before, legitimately, I think.

9:51 maybe someone's got a worm.

9:51 Chouser: irc seems like a pretty weak attack vector for link propogation. ...but what do I know?

9:53 cemerick: that's what I've always thought about email as an advertising route for viagra...apparently, it's a very profitable biz, though.

9:53 Chouser: good point

11:14 twopoint718: ,(+ 1 2)

11:14 clojurebot: 3

11:58 Drakeson: how can I create a lazy sequence of cummulative-sum of another seq? (?? [1 2 3 4]) -> (1 3 6 10)

11:59 Chouser: clojure.contrib.lseq-utils/reductions

11:59 clojure.contrib.seq-utils/reductions

12:01 Drakeson: thanks :)

12:01 Chouser: certainly

12:02 * Drakeson dreams of when Chouser's contributions are in core :)

12:04 Chouser: contrib's good enough for me, though I'm a bit sad it requires a build step now.

12:05 Cark: bah how is it a problem ?

12:05 you mean for newcomers ?

12:06 Chouser: compiling? it's a hitch in the development cycle when fetching new or making my own changes in contrib.

12:06 Cark: ah right

12:06 anyways this pprint thing is very much worth it =)

12:06 rhickey_: Chouser: what's changed?

12:07 Chouser: pprint's the main thing -- doesn't depend on any external libs, but uses gen-class internally

12:07 and I want it, so I compile.

12:07 dakrone_hb: ,(show-doc "pprint")

12:07 clojurebot: java.lang.Exception: Unable to resolve symbol: show-doc in this context

12:07 rhickey_: it needs to use gen-class?

12:08 Cark: i'm not sure why it does, but yes

12:08 Chouser: I've brought it up with Tom Faulhaber a couple times -- apparently the alternatives would be a bit messy.

12:09 rhickey_: can you point me to the discussion?

12:09 Chouser: I haven't looked at it myself.

12:09 I'll try -- just a sec.

12:10 rhickey_: hmm.. extends Writer

12:11 Chouser: yeah, he wants extra state without wrapping the Writer in a separate object (struct-map or whatever)

12:11 so proxying on Writer and IDeref might get you somewhere, but it also might be a bit messy

12:12 rhickey_: why not just close over an atom with proxy?

12:12 ctors aren't needed

12:12 Cark: this reminds me of a question i had : is using proxy incuring a runtime cost as opposed to genclass ?

12:13 rhickey_: Cark: similar costs - there's an indirection to a fn - in neither case is the code in the method body

12:13 cemerick: Cark: not anymore, AFAIK

12:13 Cark: allright thanks

12:14 Chouser: here's some discussion, but I don't see a conclusion to use genclass over proxy: http://groups.google.com/group/clojure/browse_thread/thread/e51f75750da6cbb8/ab03fa5e5245194a

12:17 rhickey_: Chouser: thanks

12:18 :methods is evil

12:18 Chouser: http://clojure-log.n01se.net/date/2009-04-06.html#18:29

12:19 Neronus: load-file returns the result of the last evaluation. Is this just a coincidence and will disappear in the near future, or will it remain this way?

12:21 Chouser: it's hard to imagine how proxy on Writer+IDeref closing over a (mutable if necessary) Reference would be insufficient for this kind of use case.

12:21 rhickey_: Chouser: I don't get the IDeref part

12:21 Chouser: but I haven't dug into pprint specifically to see what it would look like.

12:22 rhickey_: I see it as interface + proxy

12:22 Chouser: oh, custom interface? like gen-interface?

12:22 rhickey_: yes

12:22 Chouser: that would do, but still requires a compile step

12:23 rhickey_: once and forever - just put the resulting .class in the lib

12:23 Chouser: IDeref gives you a kind of generic way to get at a single value -- @foo returns the value (mutable if needed) so that utility functions can do things with it

12:23 rhickey_: methods not inherited from interfaces are generally bad

12:24 IDeref seems like a hole in this case

12:25 Chouser: *giggles* you said "hole"!

12:25 sorry, I don't know what you mean.

12:25 rhickey_: in encapsulation

12:26 Chouser: oh. yes, definitely.

12:26 rhickey_: I'm kind of sad all this build stuff negates what I always saw as the simplest path - use gen-and-save-interface once and reuse the .clas sfile from then on

12:27 cemerick: putting classfiles in SCM is Bad(TM(TM)

12:28 Chouser: yes, (ns .. (:gen-class ...)) feels very static, even with the ability to change method bodies at runtime

12:28 rhickey_: cemerick: maybe, but consumers of interfaces shouldn't have to build them

12:29 classes and interfaces are static, and the latter especially should be highly stable

12:29 cemerick: well, *someone* has to build them. contrib is not an "end user" library that people are just linking to...everyone is "building from source" when using it.

12:30 Chouser: if gen-interface was allowed to run at runtime (instead of just compile-time), wouldn't that solve a lot of this?

12:30 rhickey_: cemerick: but tho Chouser's point, if the interface def was somewhere else, he wouldn't have to recompile when working on contrib libs

12:30 cemerick: insofar as it would allow one to back-door a method into a proxy, yeah

12:30 Chouser: then libs that used gen-interface + proxy instead of gen-class wouldn't require a build step

12:31 the interface would be compiled on first runtime load, and you're off an running.

12:31 rhickey_: the whole point of an interface is that it's a contract - you don't rewrite them over and over, and thus shouldn't need to rebuild them over and over

12:32 Chouser: I don't want to rebuild them over and over, as I'm sure you know. I just want my call to 'require' to build whatever the lib needs on its way in.

12:32 cemerick: contracts do change though, and you don't want to suddenly have a build failing for (from the viewpoint of someone who's unaware of the classfiles-in-scm approach) no reason.

12:33 rhickey_: Chouser: there are so many issues relating to making dynamic named classes visible everywhere you might need tham - I want to move away from that - if you need the name, it must be static - that's a java thing

12:33 cemerick: I don't see how its different from how we consume the JDK

12:33 not from source

12:34 cemerick: it's not -- but we're never pulling the JDK source in order to use it. We always pull contrib's source in order to use it. Working around that by putting build artifacts into source control isn't a good idea, IMO.

12:34 rhickey_: Chouser: the beauty of proxy is you don't care about the name - you implement the stable, named contract

12:35 cemerick: I always build contrib (and everything else), so I'm just a noisy observer here. :-)

12:35 rhickey_: cemerick: I don't want to get distracted by the .class/scm bit - that's not the real issue here. It could be built once from source - I guess it more a matter of separation - putting something stable that requires building rarely amongst the dynamic stuff

12:36 Chouser: many uses of gen-interface don't *really* need the name, they just need some way to point proxy at it.

12:36 rhickey_: Chouser: really? I don't think that's the argument he was making in the thread - i.e. he argued someone might want to know they had a column-aware writer

12:37 Chouser: I don't see how someone consumes an unnamed interface

12:39 This is really important - I'd like to see much greater usage of interfaces + proxy/implements/whatever-it-gets-called

12:39 Chouser: couldn't proxy theortically take gen-interface-like specs for new methods? I thought the main problem with that was just the messiness of having those kinds of declarations mixed into alogrithmic code.

12:39 hiredman: ~gen-class

12:39 clojurebot: No, hiredman, you want gen-interface + proxy

12:39 rhickey_: but without gen-interface raining on the otherwise dynamic parade

12:40 Chouser: how does it get consumed? via reflection?

12:40 (def x (some-proxy-making-thing-that-adds-methods)) ... (? x)

12:41 Chouser: hm. refelction would of course work. ...and I guess that's the only possible way. :-(

12:43 rhickey_: that's the crux - but interfaces are largely stable and rarely changed. defining and building them occasionally should be painless, but maybe isn't now

12:44 I really like the 'the only static/named parts are these interfaces, now have fun' model

12:46 maybe it's just splitting the build or something

12:51 and keeping gen-interface out of the lib loading process

12:59 cemerick: Chouser: why do you need to rebuild contrib, anyway? Unless you're tweaking PrettyWriter, it shouldn't be necessary....?

13:01 Chouser: I guess it makes me nervous to know I have compiled .class files in a jar that are out of date with the .clj files in a directory. Does clojure do the "right thing" every time?

13:02 how stable is that behavior? do I dare rely on that to the point of accepting the half hour of confusion it will generate if my .clj changes aren't getting picked up?

13:03 I suppose if that's really my primary objection then splitting the build might be sufficient. "ant build-interfaces" to make a .jar that has only interfaces, no real code.

13:04 Cark: more complexity

13:05 hiredman: at what price?

13:05 Chouser: more complexity in the build.xml, less in my head.

13:05 hiredman: ?

13:06 ~whose job is it to handle Chouser's complexity?

13:06 clojurebot: that is replaca's job

13:10 cemerick: Chouser: I'm still confused. If you haven't changed PrettyWriter.clj, then the classfile it generated when you compiled it three weeks ago is still "good".

13:18 Chouser: cemerick: but I don't compile just PrettyWriter, I run 'ant' which compiles all of contrib

13:35 lispbliss: How come (nil) gives a different error ("Can't call nil") than ((:type 1)) which just says NullPointerException?

13:36 is it because the first error is from the reader?

13:37 cp2: (something ....) is trying to invoke a function

13:37 ,(:type 1)

13:37 clojurebot: nil

13:37 cp2: you are trying to invoke nil in both examples

13:37 lispbliss:

13:38 oh

13:38 i see what you are asking now

13:38 lispbliss: yeah, so I'm wondering why one gives a clear error, and the other gives a nonclear error

13:38 cp2: yeah, i have no idea

13:38 ,((:type 1)

13:38 clojurebot: EOF while reading

13:38 cp2: ,((:type 1))

13:38 clojurebot: java.lang.NullPointerException

13:38 lispbliss: ,(nil)

13:38 clojurebot: java.lang.IllegalArgumentException: Can't call nil

13:39 cp2: ,`((:type 1))

13:39 clojurebot: ((:type 1))

13:39 cp2: er

13:39 whatever

13:42 Chouser: "Can't call nil" is when the compiler detects it

13:43 it would have examined the thing to see if it's the name of a var that's marked as a macro, or if it's an expression that returns a fn, etc.

13:43 ...but it's just nil, so it throws an error.

13:47 cp2: makes sense

13:49 Chouser: clojure often does. :-)

13:51 djkthx: is there any function that converts a string->number that will automatically use BigInteger if it needs to?

13:53 Lau_of_DK: Hey guys

13:53 djkthx: howdy

13:53 cp2: djkthx: there are no string->number functions in the clojure api. the java api has Integer.parseInt(...) and such

13:53 not sure if those will automagically convert, but i assume not

13:54 djkthx: yeah, they don't

13:55 cp2: so then, you will probably just have to play it safe and just use BigInteger

14:00 Chouser: ,(class (read-string "9876543210000000000000"))

14:00 clojurebot: java.math.BigInteger

14:01 Chouser: but I'm not sure I'd trust read-string with unsafe data

14:02 ,(read-string "#=(java.lang.System/exit 0) 99")

14:02 clojurebot: java.lang.RuntimeException: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

14:02 Lau_of_DK: ,(class (read-string "987654321000000000000898324098230948230940239840923804982304982394839888888888888888888888888888888888888888888882039482309842039840239840928340980"))

14:02 clojurebot: java.math.BigInteger

14:02 Lau_of_DK: ,(class (read-string "9876543210000000000008983240982309482309402398409238049823049823948398888888888888888888888888888888888888888888820394823098420398402398409283409809876543210000000000008983240982309482309402398409238049823049823948398888888888888888888888888888888888888888888820394823098420398402398409283409809876543210000000000008983240982309482309402398409238049823049823948398888888888888888888888888888888888888888888820394823098420

14:02 39840239840928340980"))

14:02 clojurebot: EOF while reading string

14:03 Lau_of_DK: No integeroverflow?

14:03 stuhood: your irc client split that into 2 lines

14:04 djkthx: oh

14:04 nice!

14:04 thanks Chouser

14:04 cemerick: Sorry, lunch interrupted. :-)

14:04 Chouser: even so, PW.class won't be modified unless PW.clj has a newer moddate on it than PW.class

14:04 technomancy: is there really no recursive delete for directories in Java?

14:05 cemerick: All I'm saying is, if you're in a REPL, there's no need to bounce it unless PW.clj changes (or, probably more specifically, unless PW.clj's :gen-class spec changes).

14:05 technomancy: I'm not finding anything, but I'm having a hard time believing that they left something like that out.

14:05 cemerick: technomancy: nope. That's what libraries are for, I guess. :-/

14:05 technomancy: wow.

14:06 it boggles the mind.

14:06 kotarak: most programming languages don't have a recursive directory delete built-in...

14:07 technomancy: I guess that's why I don't program in most lanugages. =)

14:09 kotarak: technomancy: apache commons... FileUtils.deleteDirectory

14:09 cp2: technomancy: JSR 203(?) has much better fs operations, etc

14:09 cemerick: There's also a very nice filesystem API in the netbeans platform.

14:09 cp2: but thats due in java 7, so...

14:10 cemerick: cp2: wasn't that (effectively?) on hold?

14:10 cp2: cemerick: im not sure, i havent looked _too_ much into it, i just know that it provides some better io operations

14:12 technomancy: cp2: ah, the jdk7. sounds like it's got a lot of good stuff.

14:12 cp2: yeah, seems interesting

14:32 Chouser: rhickey said something about eventually targetting Objective C, to allow writing Clojure for iPhones. But there's no GC there, right? How's that going to work?

14:33 djkthx: objc2.0 has a gc

14:33 i don't know if that's what the iphone supports now

14:33 but the standard one for osx development has a gc now

14:35 Chouser: ah, interesting.

14:36 djkthx: that would be quite cool if something comes of it

14:38 Hun: the iphone can't use the GC. you have to use ye olde refcounting there

14:38 djkthx: really? that sucks

14:39 Hun: objective C is pretty usable even without a gc. you have autorelease-pools

14:39 which decrease the ref just a bit later

14:39 djkthx: i've done some objc development myself

14:39 before the gc, and it wasn't too bad

14:40 i'm saying it sucks in the context of having clojure target objc

14:40 Hun: true

14:54 hiredman: ~botsnack

14:54 clojurebot: thanks; that was delicious. (nom nom nom)

14:59 cp2: objc, yuck

15:04 Lau_of_DK: Is there any way to do hard realtime with the jvm ?

15:06 djkthx: i remember reading about it in an acm crossroads issue

15:06 i believe

15:15 danlarkin: hiredman: https://twitter.com/clojurebot/status/1518882399 ha

15:15 hiredman: damn

15:16 I was hoping to delete that before anyone noticed

15:23 danlarkin: I'm too quick!

15:24 cp2: heh

15:36 stuhood: i'm going to be hurt if clojurebot doesn't follow me back =P

15:39 cemerick: wow, contrib has really grown since I took a big-picture look at it some time back!

15:47 durka42: kotarak: does vimclojure require ivy now?

15:47 kotarak: durka42: at the moment, yes, but it will optional in the future.

15:48 Just working on the setup

15:48 durka42: maybe i should stay off the bleeding-edge branch for a little bit :)

15:48 or if i install ivy somewhere, will it work?

15:48 kotarak: durka42: it should.

15:49 durka42: try the commit I just pushed.

15:49 It will download the ivy.jar for you. Put it in ~/.ant/lib and you should be fine for the future.

15:49 Beware, that it will also try to download clojure and parts of contrib.

15:49 durka42: um

15:49 kotarak: This is still in the "future" part.

15:50 durka42: ivy NPE'd

15:50 kotarak: Hmm.. Let me check.

15:50 Just a sec.

15:50 durka42: in Hashtable

15:53 kotarak: Hmmm... It works for me. Which Java do you use? I just installed soylatte, so this is maybe in issue?

15:54 durka42: when does it segfault? At which step?

15:55 Hmm... works also for stock Java on OSX:

15:55 lisppaste8: durka42 pasted "kotarak" at http://paste.lisp.org/display/78569

15:58 durka42 annotated #78569 "verbose mode" at http://paste.lisp.org/display/78569#1

16:04 kotarak: durka42: can you try to remove the cache (rm -r ~/.ivy2/cache) and try again? This is just guessing, but the problem doesn't show up here.

16:04 durka42: I updated the ivysettings.xml on the server.

16:04 durka42: all right, i'll remove that directory and pull

16:05 kotarak: durka42: I mean the kotka.de/ivy/ivysettings.xml. The xml in the repo includes that one.

16:05 durka42: i just discovered what you meant

16:05 it's downloading clojure

16:05 so that's a good sign

16:05 * kotarak hates problems he can't reproduce.....

16:06 durka42: ech

16:06 BUILD FAILED

16:07 /Users/alex/Programming/vimclojure/build.xml:54: java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V

16:07 worked after ant clean

16:10 hiredman: ok

16:10 has anyone here written some clojure that can post to twitter without using anything besides what comes with the jre?

16:11 this is killing me

16:15 dakrone_hb: can someone give me an example of how 'while' is used, I can't find any examples and I'm trying to do (while [line (.readLine stdout)] <dosomestuff>

16:17 hiredman: http://gist.github.com/95395 this is what I have, and it doesn't work

16:17 ,(doc while)

16:17 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

16:17 hiredman: dakrone_hb: use line-seq

16:18 ,(doc line-seq)

16:18 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:18 kotarak: dakrone_hb: How about: (doseq [line (line-seq *in*)] ...)

16:18 dakrone_hb: hiredman, yea, I read the doc, hence my code, I get " Unable to resolve symbol: line in this context"

16:18 hiredman: dakrone_hb: because you are doing it wrong

16:18 dakrone_hb: hiredman, kotarak doesn't that read the *entire* thing into memory before grabbing a single line?

16:18 hiredman: while is not a loopish binding form

16:19 dakrone_hb: I'm trying to write an equivalent to Chouser's shell-out that won't load the entire stdout into memory for million-line output

16:19 hiredman: dakrone_hb: please read the line-seq docstring

16:20 dakrone_hb: hiredman, I read it, I just don't exactly understand what "lazy" means in terms of memory-management, etc. In the implementation, this won't kill the memory, right?

16:20 I also have no doubt that I'm doing it wrong :)

16:20 hiredman: lazy means it creates a seq of readLine calls

16:21 dakrone_hb: while doesn't take a binding form

16:21 while takes a predicate

16:21 dakrone_hb: if it creates a seq of 1m readLine calls, won't that still take up 1m * (size of readline call) in memory?

16:21 hiredman: dakrone_hb: lazy-seq

16:21 dakrone_hb: or does it not do the entire length at once?

16:21 hiredman: *lazy* seq

16:23 dakrone_hb: I only know what *lazy* means from a somewhat conceptual perspective, not from an implementation perspective, like I said, so do you have any good resources I can read about the _exact_ meaning of 'lazy'?

16:23 hiredman: ,(let [a (atom 0)] (while (> 10 @a) (swap! a inc)) (println @a))

16:23 clojurebot: 10

16:23 hiredman: dakrone_hb: lazy means you do it later

16:23 dakrone_hb: right now 'lazy' is a word associated with lisps that means "good performance for some things" to me

16:24 hiredman: *snort*

16:24 lazy has nothing to do with performance

16:24 dakrone_hb: see? I knew I was mistaken somewhere :)

16:24 stuhood: dakrone_hb: it means that the next item in the sequence is actually a function that can generate the result

16:24 dakrone_hb: okay, so it's just putting off the evaluation

16:25 from a memory-perspective, none of this is loaded in advance, right?

16:25 stuhood: dakrone_hb: and the function itself isn't generated until you ask for it

16:25 dakrone_hb: alright

16:26 stuhood: dakrone_hb: a sequence in memory is (current_item, fn for next item)

16:26 dakrone_hb: so very memory efficient then

16:26 stuhood: yea

16:26 except for the weird "holding onto the head case" where every item that has already been generated gets cached and stays in memory

16:26 dakrone_hb: that brings me to the next question, if I rebind *in* to be my buffered reader, will I run into problems in a threaded program that expects the default value of *in* to be there since it's global?

16:27 stuhood, oh, so once it's generated, is it going to be stored?

16:27 hiredman: ,(doc binding)

16:27 clojurebot: "([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before."

16:27 hiredman: huh

16:27 dakrone_hb: so if I have a lazy-seq of 1m items, once they're all generated, will they still all be in memory?

16:27 hiredman: only if you hold on the head of the sequence

16:27 stuhood: dakrone_hb: only if you keep a copy of the sequence pointing at an earlier item in the list: it is effectively a linked list, so any pointers you hold onto will cause the remainder to stay in memory

16:28 hiredman: anyway

16:28 binding is thead local

16:28 thread

16:28 dakrone_hb: so if I have it in a doseq that calls a function with the line as an argument, that isn't keeping a copy when it goes to the next line, right?

16:28 hiredman, okay, thanks for clearing that up

16:28 kotarak: dakrone_hb: burning yourself with concurrency is hard in Clojure...

16:29 stuhood: no, doseq explicitly doesn't hold onto the head

16:29 hiredman: ,(binding [*out* (java.io.StringWriter.)] (println :foo) *out*)

16:29 clojurebot: #<StringWriter :foo >

16:29 hiredman: which is effectively what print-str does

16:29 or pr-str or whatever it's called

16:30 dakrone_hb: hiredman, okay, that's elegant then

16:30 I will do it that way, thanks hiredman, kotarak, stuhood

16:30 please excuse my ignorance :)

16:33 so, another question, why would you want a non-lazy sequence over a lazy-sequence in some cases? Because you want to lock down the value of the sequence?

16:34 kotarak: What is a "non-lazy sequence"?

16:35 There might be cases, when external resources are involved, that you want to do a "doall" on the seq.

16:35 dakrone_hb: okay, that makes sense

16:38 kotarak: dakrone_hb: for example: (with-open [some-file (open-some "file")] (doall (line-seq some-file))) When you access the sequence produced by line-seq the file will already be closed by the with-open. Hence you need the doall in such a situation.

16:39 dakrone_hb: okay

16:39 that's a good example

16:39 thanks!

16:40 hiredman: so

16:40 anyone want to fix my twitter?

16:43 Hun: Man Builds Chair That Tweets His Farts, Single-Handedly Justifies Twitter's Existence

16:43 * kotarak finds the Tweeting Cat Door cool. :)

16:53 stuhood: kotarak: that won't hold onto the head, will it?

16:54 kotarak: stuhood: what?

16:54 stuhood: your last example for dakrone

16:54 kotarak: It will, but without doall it will blow up.

16:55 You must not leak a lazy-seq outside of the scope of the resources it uses.

16:55 stuhood: nothing holds onto the lazy seq returned by line-seq though

16:55 oooh

16:55 sorry, i was missing the context

16:55 kotarak: stuhood: this is just a snippet.

16:56 something outside might use the line-seq

16:56 stuhood: yea, great example... apologies

16:57 hiredman: lisppaste8: url?

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

16:58 hiredman pasted "with-open-proc" at http://paste.lisp.org/display/78573

17:02 dakrone_hb: hiredman, so would you use that like (with-open-proc "ls -l" stdin stdout stderr (doseq [line (lazy-seq stdout)] (println line))) ?

17:02 hiredman: user=> (with-open-proc "echo hello world" [out in er] (apply str (line-seq out)))

17:02 "hello world"

17:02 user=>

17:03 dakrone_hb: awesome, thanks for the example on how to use it correctly

17:03 hiredman: or (with-open-proc "echo hello world" [out _ _] ...) if you are ignoring in and er

17:04 stuhood: just watch out that you start a thread to read from stderr if you are going to block reading on stdout

17:04 dakrone_hb: is _ a keyword for discarding the value then?

17:05 slashus2: Just an idiom for an argument that is not used.

17:05 stuhood: its a convention, but i don't think it does anything special to the variable

17:06 lisppaste8: kotarak annotated #78573 "More flexible approach" at http://paste.lisp.org/display/78573#1

17:07 dakrone_hb: what makes that one more flexible, it looks about the same in function

17:07 ?

17:08 kotarak: dakrone_hb: When you update the function, you have the updated version immediately.

17:08 dakrone_hb: with a macro every user must be recompiled.

17:08 dakrone_hb: functions can be map'd, apply'd, etc.

17:08 dakrone_hb: although this is not very interesting in this case...

17:09 dakrone_hb: okay, that's really useful

17:10 by the way, how does something get into clojure-contrib, it seems like that would be a useful macro to go into the contrib

17:10 kotarak: dakrone_hb: one example is binding: I really needed binding* because I want to build the Var/Value pairs programmatically. But there is no binding*. Only the binding macro. So I have to re-invent binding* everywhere....

17:14 dakrone_hb: okay, I think I understand

17:15 Chouser: there may be performance consequences for a thunk like that, which might matter for something like binding. for shelling out, though, it should be fine. :-)

17:17 kotarak: Hmm... I was always told that creating a fn in Clojure is fast...

17:17 slashus2: (with-open-proc "ls -la" [out _ _] (line-seq out)) This doesn't work?

17:17 hiredman: line-seq is lazy

17:17 Chouser: sure it's fast, as is calling one. But is creating and then calling a function likely to be faster than doing neither?

17:18 hiredman: so the iostream has been closed by the time you go to read it

17:18 slashus2: (with-open-proc "ls -la" [out _ _] (doall (line-seq out)))

17:18 this works

17:18 hiredman: so you need to a. do the work inside with-open-proc b. use doall

17:18 slashus2: Yup, I got it.

17:19 lisppaste8: dakrone_hb annotated #78573 "kotarak's with fixed gensyms" at http://paste.lisp.org/display/78573#2

17:19 hiredman: erm

17:19 you cannot use gensyms like that

17:20 or unquote in the function

17:20 kotarak: Chouser: ok. Of course not calling a function is faster than creating and calling one. When binding is used really in low-level stuff, it might be reasonable. I still miss binding*. And I still think speed is overrated....

17:20 dakrone_hb: hiredman, are you talking about the annotation?

17:20 hiredman: yes

17:21 dakrone_hb: without it was getting Unable to resolve symbol: proc in this context

17:21 clojurebot: this is not a bug

17:21 dakrone_hb: oh, should the bound proc# just be proc instead?

17:21 slashus2: yes and there shouldn't be a ~ in front of cmd

17:22 kotarak: dakrone_hb: oops. the proc# and ~cmd in my version where cut'n'paste errors. Should be w/o # and ~.

17:22 lisppaste8: hiredman annotated #78573 "actually fixed" at http://paste.lisp.org/display/78573#3

17:22 dakrone_hb: hiredman, thank you for the correction

17:24 hiredman: actually

17:24 still doesn't work

17:24 oh

17:24 I was using it frong

17:24 wrong

17:25 things are completely different, but the same

17:26 kotarak: Nothing is more lasting than change.

17:28 dakrone_hb: is not being able to use that for something like "ls -l | grep r*" a java thing then?

17:29 I think I remember not being able to do that exec-ing things from Java before

17:29 kotarak: the pipe (|) is a shell thing.

17:29 stuhood: and the *

17:29 dakrone_hb: and since it doesn't spawn a shell, no piping

17:29 kotarak: You will have to build this on your own.

17:29 walters: or exec /bin/sh -c "whatever"

17:29 kotarak: Eg. scsh does this. (| (cmd1) (cmd2) (cmd3)) .....

17:30 hiredman: so no dice on my non-working twitter code?

17:30 walters: if you want shell script, run a shell

17:30 hiredman: walters: makes sense to me

17:30 dakrone_hb: okay, thanks

17:30 cp2: scheme shell eh

17:30 interesting

17:33 Chouser: would you want with-open-proc to bind *in* *out* and *err* for you?

17:34 hiredman: no

17:34 maybe err

17:34 Chouser: no, you're right. it's all backwards

17:34 kotarak: cp2: scsh is quite nice. I always suffered from the limited library problem, though...

17:35 cp2: im not sure i love scheme enough to use it as my primary shell

17:35 stuhood: hiredman: i don't think you flush your streams

17:35 kotarak: cp2: Well... It's not for interactive use, but for scripts.

17:35 cp2: oops, didnt think of that

17:36 yeah, in that case, woosh; awesome

17:36 hiredman: stuhood: I disgree on principle, but I am willing to add a .flush

17:36 cp2: then again you can kinda-sorta use clojure for the same reason

17:36 witht hat whole metadata hackish thing :

17:36 Chouser: you might, however, find yourself doing (with-open-proc "foo" [out in err] (binding [*out* in] (println ...) (line-seq out) ...))

17:37 hiredman: Chouser: you might

17:37 Chouser: you might not

17:37 Chouser: right

17:40 hiredman: you could provide *proc-in* *proc-out* *proc-err* and just have with-open-proc bind those

17:44 flushing the streams does nothing

17:44 the error I am gettting is 401 which is not authorized

17:44 stuhood: yea, i'm seeing that now

17:45 javadocs say you actually need to call .connect at some point

17:46 hiredman: *shrug*

17:46 stuhood: nevermind, same thing

17:46 hiredman: this is code is based on reading the java source of 4 or 5 different java implementations that were basically the same thing

17:49 http://www.psychicorigami.com/2008/12/22/a-5k-twitter-client/ this client is pretty impressive

17:50 which, ah, thats right, I was looking at the source when this computer fell offline yesterday and I lost my state

17:53 stuhood: hiredman: i found one issue, but it didn't solve the problem: the space between "Basic" and creds is missing

17:54 hiredman: yeah, I tried that too

17:54 a lot of the java code did not put a space their either

17:55 there

18:08 well, now it's changed to a 403

18:12 stuhood: oh? i'm still seeing 401

18:16 er...

18:17 that code appears to work, but i was using the wrong password

18:17 *facepalm

18:22 hiredman: :(

18:22 stuhood: you too?

18:22 hiredman: no

18:22 I am still getting a 403 now

18:25 stuhood: i also removed the 's' from https

18:27 shoot... it was the flush

18:30 hiredman: i added a flush after the write, before reading: http://gist.github.com/95473

18:35 hiredman: !

18:35 stuhood: thanks!

18:53 twansit: hmm ...is there a global modifier for regexes?

18:54 or am i missing something

18:55 cmvkk: what do you mean by that

18:55 cp2: i think he means like

18:55 s/..../..../g

18:55 cmvkk: oh, so #"..." ?

18:55 cp2: no, in perl regexs //g implies a global search

18:56 meaning if it finds one match it wont stop, it will search the rest of the string too

18:56 cmvkk: ohhh, now i understand. a global modifier.

18:56 twansit: #"(?i)... thats the insensitive case

18:56 but i found a solutiong though

18:56 using re-gsub

18:56 in contrib

18:57 thanks for your time

18:57 cp2: yep

19:02 * hiredman tweets out clojurebot's delicious password

19:02 hiredman: whoops

19:46 dysinger: help plz

19:47 How can I access a static member of a static class of an interface ?

19:47 http://www.rabbitmq.com/releases/rabbitmq-java-client/v1.5.4/rabbitmq-java-client-javadoc-1.5.4/com/rabbitmq/client/AMQP.PROTOCOL.html

19:47 I need com.rabbitmq.client.AMQP.PROTOCOL.PORT

19:48 AMQP is an interface, PROTOCOL is a class of the interface and PORT is a static member of PROTOCOL

19:48 I tried com.rabbitmq.client.AMQP/PROTOCOL/PORT

19:48 but no luck

19:48 (import '(com.rabbitmq.client.AMQP.PROTOCOL)) blows out too

19:49 leave it to erlang programmers to write a java interface :P

19:50 !clojurebot do something

19:50 :)

19:52 It looks to me like I have stumped clojure

19:53 :D

19:53 someone tell me "your doing it wrong" plz

19:53 arohner: dysinger: have you tried (import '(com.rabbitmq.client.AMQP.PROTOCOL))?

19:53 and do you know that everything is in your classpath?

19:53 dysinger: y above

19:53 yes have a good classpath

19:54 arohner: sorry, misread your comment about trying exactly what I suggested. :-)

19:54 dysinger: user> (import '(com.rabbitmq.client.AMQP))

19:54 nil

19:54 user>

19:54 It's an "self-contained" interface

19:54 how tricky of them

19:54 arohner: returning nil on import is good

19:55 you get exceptions when things blow up

19:55 dysinger: y tells me classpath is fine

19:55 arohner: user=> (import 'foo.bogus)

19:55 (import 'foo.bogus)

19:55 java.lang.ClassNotFoundException: foo.bogus (NO_SOURCE_FILE:0)

19:55 dysinger: but I have no access to static classes of that interface

19:55 blows up

19:56 arohner: what is the error on just evaluating com.rabbitmq.client.AMQP.PROTOCOL/PORT ?

19:56 dysinger: It may just be that rhickey didn't see this one coming. He's smart though I better knock on wood or be hit by lightning.

19:57 Cark: dysinger if i refer to your description it would be something like : com.rabbitmq/AMQP$PORT/PROTOCOL ?

19:57 dysinger: (import 'com.rabbitmq.client.AMQP.PROTOCOL) -> class not found

19:57 oh that's right

19:57 the $

19:57 I have been gone from java too long

19:57 lemmie try that.

19:57 Cark: i missed a part of it

19:57 .client

19:58 dysinger: bingo

19:58 user> com.rabbitmq.client.AMQP$PROTOCOL/PORT

19:58 5672

19:58 user>

19:58 fugly but works

19:58 Cark: easy on the eye =P

19:58 dysinger: thanks guys

19:59 arohner: sorry for my fumbling. What does the $ mean?

19:59 Cark: $ is to access contained classes

19:59 internal classes ?

19:59 dysinger: y

19:59 Cark: don't know how they call these in java

20:00 dysinger: static inner class in this clase

20:00 case

20:00 sorry public static inner class

20:00 You don't see that everyday

20:00 tis why I was joking around about the erlang devs writing a java client.

20:01 arohner: and you can tell that because the javadoc declares that com.rabbitmq.client.AMQP has a static class AMQP.PROTOCOL member?

20:01 dysinger: y

20:01 normally you don't see a lot of interfaces with inner classes

20:01 It's a hack that it works IMO

20:02 Cark: though nothing as bad as this enumeration nonsense they came up with

20:02 dysinger: who Sun ?

20:02 Cark: yes

20:03 dysinger: if (enum.iCanHasNextCheesburger)

20:04 y i am happy to write clojure code - won't be going back to java any time soon.

20:04 spent 3 nice years doing ruby and lisp / erlang

20:04 after 10 on java

20:04 eye opener

20:05 Cark: i found erlang pretty annoying because of its syntax

20:05 arohner: my day job is in Ruby now. I can't stand it, esp compared to clojure

20:06 djkthx: erlang is fun, but i'm a little used to the syntax thanks to prolog

20:06 Cark: ah right

20:07 dysinger: I use the Lisp Flavored Erlang syntax

20:07 which is fun

20:07 rhickey: arohner: sorry I missed your question the other day - I think some sort of external/gradual typing could be interesting

20:08 Cark: rhickey : you mean as a library ? or as an external tool ?

20:09 some kinde of preprocessor (yuk!)

20:09 arohner: rhickey: np

20:10 yeah, I find it interesting as a nice way to catch bugs. I find myself writing assert a lot to catch things that could be caught by typing

20:10 rhickey: Cark: just an analyzer that can tell you when things are type-inconsistent or undecidable without necessarily preventing your program from running

20:11 Cark: looks like one hell of a work

20:13 arohner: Cark: it doesn't have to be

20:14 you "just" attach metadata to objects as they're used

20:14 Cark: but that would be at runtime then

20:15 i thought the point was to have "compile time" errors ?

20:17 arohner: but clojure resolves symbols at compile time

20:17 Cark: don't you need to go check inside functions for type errors ?

20:17 djkthx: how can you do optional arguments in defn?

20:18 like &optional (val 3) ...

20:18 in common lisp?

20:18 Cark: djkthx : use a map

20:18 err no

20:18 (defn bleh [arg1 & args] ....

20:19 djkthx: doesn't that just bind everything to a list called args?

20:19 Cark: everything but the first one

20:20 you could also do (fn blah ([arg1] body here) ([arg1 optional-arg2] body here))

20:20 arohner: Cark; start with the basics. Assume you know how to infer type errors on just simple functions, like +

20:20 so if the compiler sees (+ foo bar), you can infer that foo and bar should both be numbers

20:21 so if you see (assoc foo :key 42), then you can say "hmm, that looks weird. previously foo was used as a number, and now it's being used as an associative"

20:21 Cark: you still need a code walker for that very first step

20:22 then you need to go meta for function results ...then you have macros ...

20:22 seems like a mountain to me =P

20:22 anyways i would gladely use it of someone writes it

20:32 arohner: dysinger: it does bind everything to a list called args. You can use let's destructuring to pull arguments out of the list, or write a macro

20:32 dysinger: you meant djkthnx

20:33 arohner: yup, sorry

20:33 djkthx: yeah, that's what i was planning to do

20:33 i'm just really used to common lisp

20:33 arohner: djkthx: check out deftmpl in compojure.control

20:33 djkthx: so i periodically ask how to do things that i would normally do in CL

20:34 arohner: you can define things that are called like (foo :bar 1 :baz 2)

20:35 djkthx: ah, cool

20:52 msingh`: why doesn't clojure have erlang style pattern matching?

21:12 seems to me being able to pattern match atoms is a pretty useful thing and cl already had destructuring so what progress has clojure made in this respect?

21:20 dnolen: msingh: do multimethod not work for you?

21:22 msingh`: dnolen: haven't looked at htem yet.. i'm watching a podcast where the person mentions not being keen on patern matching except the destructuring aspect

21:23 dakrone_hb: a clojure podcast?

21:23 msingh`: yeah

21:23 cmvkk: i believe that's why, actually. rich hickey doesn't care for them that much.

21:23 msingh`: it's by the author, 'clojure for lisp programmers'

21:25 dakrone_hb: msingh`, http://pragprog.com/podcasts/show/24 this one?

21:25 msingh`: dnolen: are you suggesting that mms allow you to pattern match by value of parameters?

21:25 dakrone_hb: just curious where it was

21:26 dnolen: msingh: it can, your dispatch-fn can just return the value of the params.

21:26 cmvkk: msingh`, multimethods allow you to match by anything you want.

21:26 msingh`: dakrone_hb: nope, one sec i'll get the url for you.

21:27 oh that sounds cool!

21:28 dakrone_hb: http://blip.tv/file/1313398

21:29 dakrone_hb: msingh`, cool, thanks!

21:30 msingh`: np :) there is part 2 too, i've been watching it on the train on a shuffle.

21:31 dakrone_hb: yea, these are the ones from the clojure page right?

21:32 msingh`: yeah

21:40 hiredman: clojurebot: http://clojure-log.n01se.net/date/2009-04-14.html#12:06 remember this

21:41 clojurebot: you are here right?

21:41 clojurebot: Titim gan �ir� ort.

21:44 hiredman: clojurebot: http://clojure-log.n01se.net/date/2009-04-14.html#12:06 remember this

23:00 dysinger: What benefits do you get by having json in json contrib instead of just using a json lib in java like .org.json ?

23:00 sorry json in clojure.contrib

23:00 probably it understands clojure better

23:00 to answer my own question

23:00 danlarkin: deals in native clojure datastructures

23:06 dysinger: y

23:06 already using it.

23:06 slick

23:07 what does it mean when I get "java.lang.IllegalArgumentException: No matching ctor found for class" trying to define a simple proxy of an interface

23:07 ?

23:09 Chouser: probably passing the wrong number or wrong types of args to the base class constructor

23:25 dysinger: hmmm

23:25 bingo

23:33 tanks chouser

23:51 user> (json-str "hello")

23:51 "\"hello\""

23:51 clojurebot: BUENOS DING DONG DIDDLY DIOS, fRaUline dysinger

23:51 dysinger: user> (json-str :hello)

23:51 "\"hello\""

23:51 user> (json-str 'hello)

23:51 "hello"

23:51 ^^ broken ?

23:52 "hello" isn't a json encoded string

23:52 danlarkin: (json/encode-to-str 'hello)

23:52 ,(json/encode-to-str 'hello)

23:52 clojurebot: java.lang.Exception: No such namespace: json

23:52 danlarkin: ,(org.danlarkin.json/encode-to-str 'hello)

23:52 clojurebot: "\"hello\""

23:54 dysinger: cool

23:55 also contrib's json feels clunky

23:55 (read-json-string (json-str (str *ns*)))

23:55 "user"

23:56 (clojure.contrib.json.read/read-json-string (clojure.contrib.json.write/json-str (str *ns*)))

23:56 ,(clojure.contrib.json.read/read-json-string (clojure.contrib.json.write/json-str (str *ns*)))

23:56 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.json.read

23:58 dysinger: If I hadn't read the comments, I would think two different people wrote the read / write.

23:58 It doesn't feel unifrom

23:58 uniform

23:59 unless it's some lisp-y idiom I don't get

23:59 probably why there are 2 or 3 other json libs for clojure on github

Logging service provided by n01se.net