#clojure log - Apr 16 2009

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

0:02 monty: i see, thanks

0:16 * Raynes is doin' some hardcore Clojure advocacy on dreamincode.com

1:13 Hecktor: Any compojure aces awake?

4:03 lepassive: is clojure and NetBeans 6.7 still not fixed yet ?

4:04 Raynes: lepassive: I believe they are focusing on fixing all the problems they have with 6.5 first.

4:05 lepassive: Raynes, but it still not good to keep 2 instances of netbeans on the PC, what are the other options ? lightweight and powerful alternative ?

4:06 Raynes: Is 6.7 really that great? :|

4:07 lepassive: Raynes, yes it's i think it's one of the best versions of netbeans ever released

4:12 AWizzArd: lepassive: you could join the Enclojure team and make Enclojure work with 6.7. I think they would love to get more support!

4:13 Raynes: lepassive: They put out new releases on around a monthly basis.

4:13 lepassive: AWizzArd, that would be the case if i'm a netbeans developer

4:14 Raynes: Oh I see.

4:14 lepassive: Raynes, I hope so

4:14 Raynes: The problem is with Netbeans, not Enclojure. They are waiting to see if the NetBeans team will fix it, if not they are going to do a workaround.

4:15 lepassive: Raynes, netbeans is turning big fat :S

4:18 BTW anyone checked that ? http://www.lambdabeans.org/

4:30 eevar2: lepassive: ligthweight & powerful would be emacs+slime or vim(clojure)?

4:30 lepassive: eevar2, I'll give it a shot until Enclojure is fixed thanks alot!

4:31 eevar2: unfortunately, you get arcane & obscure along with lightweight & powerful ;)

5:48 powr-toc: What paste bin do you guys use? Is there one with clojure syntax highlighting?

5:50 Holcxjo: lisppaste8: where?

5:50 Bah

5:50 lisppaste8: where

5:51 To use the lisppaste bot, visit http://paste.lisp.org/new and enter your paste. Be sure to select the right channel!

5:57 powr-toc: Which colouriser highlights clojure code the best?

6:07 noidi: is there a function to check if a variable is a number or not?

6:07 something like num, but just returning true or false

6:08 ah, number?

6:09 num and number? but no num? or number"

6:09 that kind of sucks :P

6:10 Raynes: ,(number? 2)

6:10 clojurebot: true

6:10 noidi: ,(num 2)

6:10 clojurebot: 2

6:11 noidi: ,(num? 2)

6:11 clojurebot: java.lang.Exception: Unable to resolve symbol: num? in this context

6:11 noidi: ,(number 2)

6:11 clojurebot: java.lang.Exception: Unable to resolve symbol: number in this context

6:11 Raynes: (defn num? [x] (number? x)) :)

6:13 AWizzArd: ,(number? 15)

6:13 clojurebot: true

6:48 Raynes: Morning rhickey.

6:50 rhickey: hey

7:24 lisppaste8: powrtoc pasted "Clojure Alphabet Diamond" at http://paste.lisp.org/display/78674

7:25 powr-toc: The above is a simple programming exercise which I implemented in clojure... Does anyone have any suggestions on how to make it more idiomatic readable and terse?

7:26 I'm also still not 100% sure of the clojure/lisp formating conventions... so any suggestions would be great! :-)

7:27 antifuchs: looks good to me

7:27 (I've seen common lisp beginner programs that looked way worse (-:)

7:28 (e.g. mine) (:

7:29 ChrisF: too bad that someone' can't put a surface syntax onto clojure

7:34 powr-toc: antifuchs: thanks... clojure's my first lisp (excluding emacs lisp tinkering)... I'm not sure it's as lazy as it could be...

7:34 I'd be interested to see other solutions

7:34 ChrisF: it's probably better not even to look at CL solutions as examples

7:35 antifuchs: ChrisF: why?

7:35 ChrisF: CL is warty

7:35 antifuchs: ChrisF: let's not go ther

7:36 ChrisF: agreed

7:37 i'm amazed at the play that clojure is getting

7:37 especially from the java folks, who tend to be conservative

7:38 powr-toc: ChrisF: agreed... Though I'm perhaps more surprised more by the lisp folk... who think CL/scheme is superior to everything! clojure rocks! :-)

7:39 ChrisF: i think when the old guard at the last lisp conference gave the nod to clojure, it made a difference

7:40 antifuchs: powr-toc: I don't think anyone who has worked sufficiently long with any lisp and any one other language will find lisp winning in all cases

7:40 but oh well, there are fanatics.

7:40 ChrisF: well, you have to deal with the VM you have

7:42 for me it's not even about concurrency at this time, but sequence unification

7:43 and i need a SLIME-like repl to script with

7:43 powr-toc: Can anyone think of any ways to eliminate the flatten call in my Alpha-diamond paste?

7:44 ChrisF: so what do we have on the web front-end front? enlive and...?

7:45 antifuchs: powr-toc: what do you get without the call to flatten?

7:45 ooh, lists of char-seqs. got it.

7:45 powr-toc: you could print each of them in a loop (:

7:49 powr-toc: antifuchs: I thought about that but I'd rather keep it terse...

7:49 antifuchs: well, then that looks ok to me, I think

7:54 powr-toc: What's the best way to test for laziness in a function? I've been throwing in side-effects or Thread/sleeps at later values and then only take'ing a handful of items from the seq... surely there's a better way!

8:12 Raynes: (defn != [x y] (not= x y)) ; I am complete.

8:13 durka42: #define != not=

8:13 Raynes: durka42: I hate you :(

8:14 durka42: using the c preprocessor on clojure files would be such a bad idea

8:14 Raynes: Why would anyone even think of suck a thing. @_@

8:15 gregh: what an appropriate typo

8:16 AWizzArd: Why not (def != not=) ?

8:18 Raynes: AWizzArd: Because I like doing things the complicated way.

8:29 * cconstantine votes for !=

8:31 cemerick: I seem to remember rhickey saying that ! might be used for future syntax...

8:31 or, symbols starting with !

8:31 Raynes: in any case, not using (def != not=) will cost you an extra method invocation each time through.

8:37 rhickey: it's /= in CL

8:37 != is kind of c-derived

8:38 cemerick: There's always ? (very easily type-able on mac keyboards (option-=))

8:38 ASCII is so 20th-century ;-)

8:40 gnuvince: What's the problem with not=?

8:40 AWizzArd: Maybe we can have ? instead of fn? It is very easy to type with the NEO layout ;)

8:41 Raynes: rhickey: I know, it's fine. I just like !=.

8:42 rhickey: also, if ! is only used on side-effecty things, you can make it red or something in your editor, or search for it

8:43 cemerick: gnuvince: those three chars are *critical* ;-)

8:45 gnuvince: cemerick: I see

8:45 I have a graph for that...

8:45 or had a graph

8:45 can't find it anymore

8:46 basically, it was the first quadrant of the 1/x equation with X being the importance of a topic in computer programming (from not important at all to infinitely important) and Y being the amount of discussion it generates

8:47 Ah

8:47 got it

8:47 http://www.flickr.com/photos/gnuvince/2944227285/

8:47 antifuchs: cemerick: you could even say that one-character functions are diacritical.

8:47 cemerick: I actually hardly ever think of not= -- usually, I just use = and arrange my if clauses appropriately, or use (remove #(= ..)) instead of (filter #(not= ..))

8:48 gnuvince: very nice :-D

8:49 gnuvince: I drew that following a large debate in a programming channel about whether ++x was more efficient than x++

8:49 antifuchs: gnuvince: heh

8:49 gnuvince: 6-7 guys going at it for over an hour.

8:49 Biggest waste of time ever

8:49 antifuchs: (if it was 6-7 machines, concurrently benchmarking...)

8:50 gnuvince: antifuchs: even then, if x++ is your application's bottleneck, either you're the best programmer I've ever seen or your program does nothing.

8:50 AWizzArd: I often find myself to use if-not instead of (if (not= ..)). I like it if the very short case of if comes first, and in the else block the longer block follows.

8:51 antifuchs: gnuvince: true. still, for settling a performance argument, nothing is as effective as a benchmark

8:51 cemerick: right, yes, I <3 if-not

8:51 antifuchs: (you could plot that, too, I guess) (-:

8:52 powr-toc: Is there a clojure function to raise a single var into a sequence, unless it's already a sequence?

8:52 rhickey: I think numbers should be objects, we should add infix syntax for methods calls, and then you could say (42.=.negate x)

8:54 powr-toc: no seqify/setify yet, recently wrote the latter in some library code

8:54 cemerick: who's going to be the first one to twitter: "we should add infix syntax for methods calls" - R. Hickey

8:55 rhickey: hah

8:56 cemerick: hey, what's the point of being a public persona if you're not going to get quoted out of context? :-)

8:57 Raynes: http://xkcd.com/371/

8:59 cemerick: rhickey: BTW, +10 for me on metadata on fns (issue 90). Right now we're doing stuff like {:type :foo :source :blah :fn (fn [] ...)}

8:59 rhickey: cemerick: would all of your use cases be satisfied if there was no with-meta for fns, i.e. metadata supplied once only on creation?

9:00 powr-toc: rhickey: if I was to write such a function in the interim, what would be the best sequence type to use in the case where the argument isn't a coll? list or vector?

9:01 rhickey: powr-toc: you probably don't actually want seqify, but both listify and vecify instead

9:01 powr-toc: cool

9:01 cemerick: rhickey: I *think* so, at least right now. I can definitely see us wanting to assoc additional metadata in the future as a fn bounces along through whatever queues we have going, though.

9:01 rhickey: or generic (collify [] x)

9:02 (collify #{} y) (collify () z)

9:05 (collify set? hash-set x) (collify seq? list y) (collify vec? vec z), i.e. (collify pred ctor val)

9:34 AWizzArd: I would like to have the path of the current *file* as well as all sub-paths of it. Example: /home/wizz/hg/src/hallo.clj ==> ("/home/wizz/hg/src/", "/home/wizz/hg/", "/home/wizz/", "/home/").

9:34 Currently I am doing something like (take-while identity (reductions (fn [x _] (.getParentFile x)) (.getParentFile (File. *file*)) (cycle [0])))

9:34 Or maybe the slightly longer (loop [f (.getParentFile (File. *file*)), result ()] (if-not f result (recur (.getParentFile f) (conj result f))))

9:37 oh, in my example I forgot to include "/"

9:49 Something like a (reduce-while #(.getParentFile %) (File. *file*)) that I have overlooked so far?

9:50 kotarak: Here a lazy seq approach:

9:50 (defn path-seq

9:50 [file]

9:50 (lazy-seq

9:50 (if-let [pfile (.getParentFile file)]

9:50 (cons file (path-seq pfile))

9:50 (list (java.io.File. "/")))))

9:51 ,(let [path-seq (fn path-seq [file] (lazy-seq (if-let [pfile (.getParentFile file)] (cons file (path-seq pfile)) (list (java.io.File. "/")))))] (path-seq (java.io.File. "/home/wizz/hg/src/hallo.clj")))

9:51 clojurebot: (#<File /home/wizz/hg/src/hallo.clj> #<File /home/wizz/hg/src> #<File /home/wizz/hg> #<File /home/wizz> #<File /home> #<File />)

9:52 AWizzArd: Yes, also nice. I just hoped I overlooked something like reduce-while.

9:52 kotarak: Also shorter:

9:52 (defn path-seq

9:52 [file]

9:52 (lazy-seq

9:52 (when file

9:52 (cons file (path-seq (.getParentFile file))))))

9:52 AWizzArd: It had not shall be - Es hat nicht sollen sein.

9:53 kotarak: hehe

10:14 chessguy_work: ok, i'm trying to understand this snippet: (with-open stream (. url (openStream)) ... )

10:14 (i've left a bit out)

10:14 the result of opening the stream gets bound to 'stream'?

10:16 (i don't even get the docs for with-open at http://clojure.org/api#toc607

10:20 ,(macroexpand (with-open stream (foo) (bar)))

10:20 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: with-open requires a vector for its binding

10:20 chessguy_work: ,(macroexpand '(with-open stream (foo) (bar)))

10:20 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: with-open requires a vector for its binding

10:40 Chousuke: hm

11:04 cemerick: ~max

11:04 clojurebot: max people is 164

11:05 cemerick: I think the channel has plateued.

11:05 AWizzArd: Seems so. For now :)

11:05 cemerick: Seems to be a comfortable zone, IMO.

11:05 AWizzArd: I think when the book comes out and when there is an official 1.0 version things will change.

11:05 kotarak: Indeed it is a comfortable zone. :D

11:06 rsynnott: is this the pragprog book?

11:06 cemerick: yeah. I think the 10/1 relationship between the group and the channel is just going to break down even further, though.

11:06 bstephenson: AWizzArd: I hope you clojure experts will be ready for all of us newbies when the book and 1.0 come out.

11:06 cemerick: irc doesn't scale :-)

11:09 I don't think we've seen any real noobs yet. When the book hits, there will be a surge in people whose only experience is Java, and maybe ruby or python.

11:09 That'll be challenging. I think most people on the group and here have *some* lisp exposure prior to arriving.

11:20 kotarak: Indeed, Scheme. In particular scsh.

11:21 cemerick: hrm, a clojure shell....?

11:21 kotarak: Would be nice indeed, but I found that I don't really feel the need to script in Clojure...

11:23 cemerick: ugh, every time I do *any* scripting, I start thinking about the notion of cramming scheme into my head well enough to use scsh.

11:29 kotarak: scsh is actually very nice piece of software. And scripting can be done very well.

11:30 Also one can learn a good macro style from them.

11:30 ... and the end Scheme isn't so much different from Clojure...

11:30 cemerick: That's what always stopped me from learning scheme more than I did -- I hit the macro systems and lost the thread.

11:31 well, I worry about trying to become too proficient in two languages that have such slight differences. I can see myself writing scheme in clojure and vice versa without realizing it.

11:33 kotarak: Well it's more like pattern matching. It's not that hard when one gets his head around it. It also features automatic gensym and stuff...

11:33 Although I'm not up to date with R6RS.

11:34 What makes a big point for Clojure is the easy integration with Java and hence the good initial library situation.

11:34 That's was my main road-block with scsh.

11:34 Raynes: The hell with Scheme, we can has Clojure.

11:34 cemerick: does define-syntax and friends have any concrete benefits over clojure's macro system, given the latter's hygiene?

11:34 gnuvince: Where do you think Clojure would be if Scheme hadn't blessed us with its influence :)

11:35 Raynes: gnuvince: I'm not dissing Scheme, but Clojure is teh secks.

11:35 <3

11:36 kotarak: cemerick: I think syntax-quote and define-syntax are quite similar. The latter is also hygienic and was already so in R5RS. I haven't used it for some years now, but I remember it equally powerful to syntax-quote. I guess, the two systems just look a bit different but in the end do the same job equally well.

11:42 Chousuke: I haven't learned scheme's macro system, but looking at some examples in wikipedia, it's far from intuitive :/

11:43 cemerick: yeah. I spent a couple of days with define-syntax two summers ago. It didn't go well. :-/

11:43 or, :-(

11:44 I'm easily 4x as good as I was then though, so maybe another swing at it is warranted.

11:45 Chousuke: I like syntax-quote because it maintains the simplicity of CL macros, and is reasonably hygienic. it's pretty difficult to make a badly behaving macro

11:45 accidentally, that is. :)

11:46 kotarak: define-syntax is like some kind of pattern matching. The arguments are matched against patterns. The pattern that matches gives the expansion of the code, which is used.

11:52 And it automatically "qualifies" free parameters like `foo does, and bound parameters are automatically gensym'd to avoid clashes.

11:53 All in all very similar to syntax-quote, while that makes it easier to point the gun at yourself...

12:33 dysinger: monin'

13:02 hiredman: ,(class (seq "foo")

13:02 clojurebot: EOF while reading

13:02 hiredman: ,(class (seq "foo"))

13:02 clojurebot: clojure.lang.StringSeq

13:02 hiredman: ,(ancestors clojure.lang.StringSeq)

13:02 clojurebot: java.lang.NoClassDefFoundError: clojure/core$ancestors__4862$fn__4865

13:02 hiredman: zouch

13:15 Raynes: I'm watching an argument about why "1 + 1" doesn't logically equal 2.

13:16 Chousuke: hmm.

13:16 Raynes: It just ended with a banning.

13:17 rabidsnail: Hello all. Noob here. I was trying to run the jogl tetrahedron example (http://tinyurl.com/ck4rmw), and when it imports '(javax.media.opengl.glu GLU) I get "java.lang.NoClassDefFoundError: com/sun/gluegen/runtime/DynamicLookupHelper (NO_SOURCE_FILE:0)".

13:17 cp2: lol

13:17 rabidsnail: gluegen needs to be in the classpath

13:18 Raynes: rabidsnail: It's not in your REPL namespace.

13:18 classpath*

13:18 Fuckin' sleeplessness.

13:18 Opps I sad a bad word. :|

13:18 Chousuke: Raynes: what 1+1 equals depends on the definition of + and your numbers anyway :)

13:18 rabidsnail: Shouldn't it be in the default classpath?

13:18 cp2: *oops* :)

13:18 Raynes: Chousuke: That's what the guy was arguing. He ended up banning the other girl.

13:18 cp2: 1 + 1 is invalid syntax anyway

13:19 Raynes: rabidsnail: The JVM doesn't ship with OpenGL does it?

13:19 kotarak: And 1 + 1 is obviously 10 and not the strange other thing, I never saw before.

13:19 cp2: Raynes: no

13:19 Chousuke: Raynes: sounds like a pointless argument. 1+1 not being equal to 2 if you define it so is a truism :/

13:19 cp2: you need to grab some library that has bindings for it

13:20 rabidsnail: No, but I have it installed in /Library/Java/Extensions

13:20 libgluegen is definitely there

13:21 and it doesn't have a problem importing any of the other opengl stuff

13:21 cp2: hrm.

13:21 ;dependencies: jogl.jar, gluegen-rt.jar

13:22 obviously jogl.jar is in the classpath

13:22 rabidsnail: I have libgluten-rt.jnilib

13:22 that's what came in the zipfile from Sun's website

13:22 cp2: thats the native library

13:23 rabidsnail: isn't that what I want?

13:23 cp2: well, you do need that, but you also need gluegen-rt.jar

13:26 rabidsnail: That did it!

13:26 Now if that's required why doesn't Sun bundle it with the jogl library download?

13:27 cp2: not sure

13:28 Raynes: [12:27] <Cthulhon> i don't know how Scala's type system compares to Haskell's, but dynamic typing just leads to sloppiness.

13:29 I respect his opinion so much, but that hurt. :|

13:33 gnuvince: Bah

13:33 rabidsnail: I've also been finding that if I M-c M-e large expressions in emacs (using inferior-lisp-mode), it only loads part of the expression in the repl.

13:34 powr-toc: Is there any way to lazily wrap a lazy-sequence with a vector? e.g. the equivalent of (into [] (iterate inc 0))

13:36 Chouser: vectors aren't lazy

13:36 Chousuke: you could have a vector of delays though.

13:36 powr-toc: ,(doc delay)

13:36 clojurebot: "([& body]); Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force), and will cache the result and return it on all subsequent force calls. Any closed over locals will be cleared prior to the tail call of body, (i.e. they will not be retained)."

13:37 powr-toc: ,(doc force)

13:37 clojurebot: "([x]); If x is a Delay, returns the (possibly cached) value of its expression, else returns x"

13:39 powr-toc: interesting... though not quite what I was after... I quite like that vectors are a function of their indicies... lists and lazy-seq's aren't... that's what I was looking to replicate

13:40 Chousuke: hmm

13:41 lists aren't functions of indices because they're not associative :)

13:41 powr-toc: Chousuke: I know :-)

13:42 e.g. assuming this was possible you could do the following ((into [] (iterate inc 0) 10))

13:42 to return the 10th item

13:42 not 100% sure if it's desirable

13:43 Chousuke: you already can do that... if you fix paren placement

13:43 but it's not lazy.

13:43 oh wait

13:43 no you can't :)

13:43 powr-toc: yeah it leads to non termination because 'into' is eager

13:44 Chousuke: but I guess it might be possible to have a lazy vector that uses delays internally.

13:44 but I don't think it'd be very smart :/

13:46 kotarak's lazy-map however is quite neat.

13:46 stuhood: clojurebot: map?

13:46 clojurebot: map is *LAZY*

13:46 Chousuke: not that map

13:46 the {} map

13:47 stuhood: heh, gotcha

13:47 Chousuke: why is it not in contrib though.

13:47 powr-toc: ahhh I guess that could achieve the same result

13:48 where can it be found?

13:48 Chousuke: http://kotka.de/projects/clojure/lazy-map.html

13:48 I have no idea if it even works with the new fully lazy clojure though.

13:51 powr-toc: looks interesting...

13:51 * Raynes listens to a lecture about how Haskell is better than LISP in every way possible.

13:52 gnuvince: Raynes: link?

13:53 cemerick: well, I don't like LISP either

13:53 Raynes: gnuvince: I had the benefit of it being in an IRC conversation and directed at me.

13:55 gnuvince: Raynes: k

13:55 Chousuke: :p

13:56 Raynes: I'll paste the conversation.

13:56 Give me a second to edit.

14:00 http://paste.pocoo.org/show/112835/ A bit of talk about dynamic typing is thrown in there as well. He's given me other lectures about how Haskell is moar awesome than Lisp, but I'd rather not look those up.

14:03 gnuvince: I was expecting something more in detail.

14:04 And as for making your brain explode, Haskell does outshine Lisp in that department.

14:05 stuhood: hmm: "In a way LISP is already strongly typed... In that everything has exactly one type... That is, everything is a list."

14:05 Raynes: gnuvince: I was referring to the entire collection of articles as "How Haskell is better in every single way possible."

14:05 stuhood: was that true in common lisp?

14:05 Chousuke: no? :/

14:06 you have vectors and hash-maps and whatnot

14:06 stuhood: kinda sounds like he hasn't tried a lisp then.

14:06 Chousuke: and atoms :P

14:06 gnuvince: Chousuke: he was misinformed there, but in a sense, all data types in dynamic languages are the same type

14:07 (see PyObject for Python for example)

14:07 Chousuke: gnuvince: that's an implementation detail :)

14:07 I think it's better to say that all types share some common properties.

14:08 gnuvince: In which case he may not be wrong depending from which point of view you choose to debate.

14:08 Raynes: I don't care how awesome Haskell is Clojure rocks hard. :|

14:08 Chousuke: I think it's useful to look at dynamic languages from a property point of view.

14:08 * Raynes wraps himself tightly in parenthesis and hides under his bed.

14:09 Chousuke: two items sharing exactly the same properties can be said to have the same type

14:09 gnuvince: Raynes: it's not useful to stick your head in the sand either because you like Clojure.

14:09 Chousuke: the dynamicism comes from the fact that the properties can change during runtime.

14:09 gnuvince: Haskell has a lot of nice stuff going for it.

14:09 * Chouser descends into dependency mania. :-(

14:10 Raynes: gnuvince: What do you mean?

14:10 I never said Haskell wasn't awesome.

14:10 Chousuke: gnuvince: I wish monads weren't such a pain though :(

14:11 gnuvince: Chousuke: a pain how?

14:11 Chousuke: gnuvince: a pain to understand, create and use :P

14:12 stuhood: guido's quote about haskell pretty much summed up my feelings: "Haskell's purity reminds me of lemon juice: you need to add lots of water, sugar and ice to make refreshing lemonade."

14:12 gnuvince: the first two are rather easy, the last one I think is a result of the operations on different datatypes being visually the same while having wildly different results.

14:13 Chousuke: if the first two were easy I wouldn't have problems with the third :P

14:14 It's not like monads are the only solution, either. I think Clean's "uniqueness type" solution is much more intuitive than monads

14:15 Raynes: I think not being pure is an ever better solution.

14:15 Chousuke: I haven't looked at it in detail though, but at least it makes sense even after a cursory inspection :P

14:15 that's something Monads just fail at.

14:15 gnuvince: Chousuke: so you read that article last week on Reddit?

14:15 Chousuke: what article?

14:15 gnuvince: About Clean

14:16 Chousuke: hmm, not sure if I did.

14:16 gnuvince: Raynes: and while we're at it, why not go with mutations?

14:16 Raynes: gnuvince: It was a joke.

14:16 gnuvince: Ah

14:16 Raynes: Are you another Haskell advocate or something? :\

14:16 gnuvince: Didn't catch it.

14:17 Raynes: not an advocate, but I dislike when people diss it because they lack an understanding.

14:17 Chousuke: too bad Clean seems quite unprofessional ;(

14:17 Raynes: gnuvince: I /never/ said I didn't like the language. Ever. Not once, and I never have and I never will. I've used the language before, I like the language, which is why I didn't argue with him when he was downing Clojure.

14:18 Chousuke: it also reeks of a "closed" language, even if it is LGPL

14:20 hiredman: the road to 1.0, eh?

14:20 ye gods, "Source Control"

14:20 Chousuke: hiredman: hm?

14:20 gnuvince: hiredman: yeah, and the first reply is a plea to switch to Git

14:21 hiredman: the google group

14:21 Chousuke: ah, hah

14:21 * Chousuke would love git

14:21 Chousuke: but google code doesn't support it :(

14:21 Raynes: Git sucks on windows.

14:21 gnuvince: I'd rather we use something Rich doesn't mind using.

14:21 hiredman: so does most things

14:22 Chousuke: Raynes: does it really?

14:22 Raynes: I thought that was mostly pre 1.6.x

14:23 Raynes: Chousuke: I still haven't managed to Git it to function correctly.

14:23 But I can pull stuff and that's all I really need.

14:23 * Raynes goes to contemplate taking a nap.

14:24 stuhood: i don't know if clojure's current 'contributor' structure really requires git

14:24 since you have to get a CA to contribute anything, which I assume gets you svn access

14:25 Chouser: I think there are lots of people who have a CA on file but write access to contrib.

14:25 "but no write access"

14:26 hiredman: we should start callit the RHCA instead of CA :P

14:26 rhickey: contrib members are library progenitors

14:26 stuhood: CLJCA?

14:27 hiredman: stuhood: the form says "Rich Hickey Contributor Agreement"

14:27 RHCA

14:27 stuhood: hah, gotcha.

14:27 Chousuke: makes me think of redhat

14:28 hiredman: RHCE

14:28 yeah

14:29 rhickey: that google books link to lisp in small pieces was very helpful, thanks

14:30 (I got closures working in my toy lisp)

14:30 rhickey: hiredman: you're welcome - sorry it's out of print

14:31 hiredman: *shrug* thems the breaks

14:31 cemerick: it's completely impossible to keep up with the group entirely anymore

14:32 whoo, you'd think I had started drinking at work.

14:37 gnuvince: hiredman: link?

14:38 stuhood: http://books.google.com/books?id=iCrrcMA6TYwC&dq=lisp+in+small+pieces&printsec=frontcover&source=bl&ots=-aM6FK3qN6&sig=Pn16Sog-4BTnjBHKc8Hj4pyWzKk&hl=en&ei=G3vnSdCACY3FtgerocXRBQ&sa=X&oi=book_result&ct=result&resnum=3

14:39 hiredman: clojurebot: delicious?

14:39 clojurebot: delicious is http://delicious.com/clojurebot

14:39 stuhood: hah... that's cool

14:39 hiredman: http://delicious.com/clojurebot/rhickey

14:53 kotarak: Chousuke, powr-toc: lazy-map is compatible with current Clojure

14:54 Chousuke: it's not in contrib, because no one proposed it so far. I got only little feedback so fat, but only positive at that. :)

14:55 Chousuke: you should put it in contrib.

14:56 it doesn't get the attention it should because it's hidden on your webpage and you'll never find it unless you explicitly searched from lazy maps :P

14:57 kotarak: Well, I announce the releases on the google group

15:00 Chousuke: and they get drowned by everything else

15:00 :)

15:00 kotarak: Maybe. Lots of things got lost in the Group...

15:06 Drakeson: (?? [0 2 3] 6) -> (nil true nil true true nil)

15:07 6 is the length, and [0 2 3] is a sorted list of indexes of elements I want to be present

15:07 it could also be a set

15:07 gnuvince: Any of you guys read "Let Over Lambda"?

15:39 Chouser: Drakeson: I don't understand. elemnts you want to be present in what?

15:42 cemerick: feh, a destructuring form allowing for [ but-last > last ] or somesuch would be *great*

15:43 or [ prefix > before-before-last before-last last ] would be more general, I suppose

15:44 Chouser: hm, we don't even have a 'last' that takes a count

15:45 do we?

15:45 cemerick: drop-last?

15:45 or did you mean an nth-last?

15:46 Chouser: something that your destructing form could call internally

15:47 (drop (- (count coll) n) coll)

15:47 cemerick: yeah, that's drop-last

15:47 Chouser: no

15:47 cemerick: (essentially)

15:48 oh, crap, right, no

15:48 Chouser: (defn last* [n coll] (drop (- (count coll) n) coll))

15:48 oh

15:49 split-at

15:49 hm, nope still not quite.

15:50 (let [[xs [y z]] (split-at (- (count coll) 2) coll)] ...)

15:50 cemerick: well, that'd be a fine intermediary -- then prefix is bound to the first from split-at, and the enumerated bindings just get streamed out of the second of split last using nth

15:50 right, that :-)

15:51 Chouser: :-)

15:52 I haven't needed it, but the convolutions necessary to do it manually does suggest destructuring support might be nice

15:52 cemerick: usually, I just work around it by flipping around the order of arguments in my apis

15:52 Chouser: (let [[z y & xs] (reverse coll)] ...)

15:53 cemerick: eh -- I'd often end up having to do something more like (reverse (cons foo (concat bar first-bunch-of-stuff)))

15:54 that's why I just flip the arg order around :-)

15:54 Chouser: well, you could write a let-last macro

15:55 (let-last [[xs & y z] coll] ...) or something

15:56 Chousuke: huh

15:57 cemerick: Chouser: I aspire to a patch.

15:57 aspirations are cheap, though

15:58 bstephenson: I need a func to remove a member of a vector given its index. I looked around clojure.contrib and elswhere, but could not find specifically what I needed. I've written a single line remove-from-vector function but it is slow. Does anyone know of a lib I could have missed that would give me this type of function?

15:59 Chousuke: dissoc? :/

15:59 Chouser: vectors aren't good at sparse

16:00 rather, they're not good at removing things from the middle and updating the indexes of all the following items

16:01 Chousuke: apparently it doesn't work anyway

16:01 cemerick: bstephenson: your fn uses subvec I assume?

16:01 bstephenson: this is my func. Is it written foolishly?

16:02 (defn remove-from-vector "Takes a vector and an index, returns a vector with the member at that index removed." [vc indx] (vec (concat (subvec vc (inc indx)) (subvec vc 0 indx))))

16:02 Chousuke: As Chouser said, I think removing stuff from the middle of a vector is misuse of vectors :)

16:03 bstephenson: yeah, our clojure expert agrees, just ran into a situation that would be useful to do it. Coding is being done with different structs now because of your point.'

16:04 Chousuke: though since clojure vectors are immutable and are "partitioned", maybe they could support a reasonably quick removal from the middle :/

16:05 or hm

16:06 I guess the algorithms in the current implementation wouldn't like holes in the partitions either :(

16:06 I oversimplified the situation in my head .)

16:06 bstephenson: yeah, we are moving quickly away from vecs, to many hidden headaches

16:06 from trying to remove members

16:07 too many hidden headaches

16:08 Chouser: if you don't need the full range of indeces to be valid, a hash-map with int keys might be an option

16:08 slashus2: ,(remove #(= % 15) (range 20))

16:08 clojurebot: (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19)

16:09 slashus2: Oh, by index.

16:14 bstephenson: ,(vec (concat (subvec [0 1 2 3 4 5 6 7 8 9 10] 0 3) (subvec [0 1 2 3 4 5 6 7 8 9 10] (inc 3))))

16:14 clojurebot: [0 1 2 4 5 6 7 8 9 10]

16:15 cooldude127: isn't middle removal exactly what lists are good at?

16:17 bstephenson: so my best bet is to convert the vec to a list, remove the member, and re-vec it? Despite this one step, having a vector is most useful to this code.

16:18 Chousuke: try with a map instead.

16:18 djkthx: is it correct that suffixing a variable in a macro with # essentially generates a new symbol for it?

16:18 and makes the macro hygenic?

16:19 Chousuke: it's an auto-gensym

16:19 cooldude127: djkthx: i don't think that's all there is to hygienic macros

16:19 Chouser: bstephenson: how badly do you need fast lookup by index?

16:19 cooldude127: but it will give you a convenient gensym

16:19 bstephenson: Chousuke: thx, I see, I will try that way.....thx

16:20 lenst: It's not macros it's backquote that does the auto-gensym.

16:20 cooldude127: lenst is right

16:20 lenst: ,`(foo foo# foo# bar)

16:20 clojurebot: (sandbox/foo foo__1791__auto__ foo__1791__auto__ sandbox/bar)

16:20 lazy1: Can anyone explain http://pastebin.com/m39cd19ed to me?

16:20 bstephenson: speed of lookup is the most essential part of using a vector in this component

16:20 lazy1: I get Wrong number of args passed to: LazilyPersistentVector

16:20 Chousuke: it's quite difficult to accidentally shadow variables with the clojure system anyway.

16:20 Chouser: bstephenson: if you can find a way to working (what amounts to) uuid, or passing around the object itself, or perhaps some other options, you're likely to get more convenient code and improved performance

16:21 cooldude127: lazy1: that trips up EVERYONE

16:21 bstephenson: which is why we are trying to stay with them, but other considerations are taking over

16:21 lazy1: Gald I can join the crowd

16:21 Chousuke: clojurebot: tell lazy1 about function literals

16:21 clojurebot: Function literals are cute, but overused

16:21 kotarak: lazy1: #(vector ..) instead of #([...])

16:21 Chousuke: not that one ;(

16:21 kotarak: lazy1: #(foo) <=> (fn [] (foo)) note () around foo

16:21 lazy1: Is it in a FAQ somewhere? Couldn't find it

16:21 cooldude127: lazy1: #([blah]) is like (fn [] ([blah]))

16:22 bstephenson: Chouser: hmmm, understand your point, like the UUID idea

16:22 kotarak: clojurebot: #()

16:22 clojurebot: #() is not a replacement for fn

16:22 Chousuke: lazy1: you should use (fn [] [whatever]) in this case

16:22 kotarak: or #(vector whatever)

16:22 lazy1: This is what I did, just wondered why it didn't work

16:22 Thanks

16:22 Chousuke: kotarak: I wonder if that's equally fast though.

16:23 kotarak: *shrug* speed is overrated

16:40 pjstadig: clojurebot: speed

16:40 clojurebot: Excuse me?

16:41 pjstadig: clojurebot: speed is <reply>kotarak: speed is overrated

16:41 clojurebot: Ack. Ack.

16:41 pjstadig: clojurebot: speed

16:41 clojurebot: kotarak: speed is overrated

16:41 kotarak: clojurebot: speed is also dangerous

16:41 clojurebot: Ack. Ack.

16:42 cemerick: clojurebot: speed is also <reply>I live for speed.

16:42 clojurebot: 'Sea, mhuise.

16:43 cemerick: I wonder if hiredman flushes clojurebot out every now and then.

16:43 kotarak: cemerick: he was pissed, because someone deleted his emacs factoids...

16:44 clojurebot: speed is also <reply>Programmers should be more concerned about program correctness than speed...

16:44 clojurebot: Ik begrijp

16:44 cemerick: heh, this could go on for days

16:44 kotarak: hehe

16:47 lpetit: Hello

16:48 kotarak: do you already have source formatting in VimClojure?

16:48 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

16:49 kotarak: lpetit: yes. VC has formatting since almost a year.

16:50 I use some Vim built-in, which helps a lot.

16:50 lpetit: kotarak: if so, do you use Vim facilities, or a plain old clojure function that I could shamelessly use for clojuredev ? :-)

16:50 Our posts collided :)

16:50 kotarak: lpetit: indenting is 100% Vim.

16:52 lpetit: kotarak: How dynamic and/or specific is it ? I'm currently thinking about how to implement it in clojuredev (or reuse it from somewhere, but it seems that everybody has leveraged the facilities of one's favorite platform, so nothing can be decently be shared).

16:54 kotarak : but first, I'm thinking about the "question" : what exactly would be the behavior ? Is there somewhere something that looks like a "spec" for how to correctly format clojure code, or is this just a painful (for somebody willing to be very detailed) journey of synthetizing the way people indent their code, inferring the general case, and all the specific cases as well (e.g. for...

16:54 ...clojure "core" constructs) ...

16:54 kotarak: It is relatively static, meaning you can modify it via ftplugins for Vim. You can add the macros for you libraries. But this is not automatic. I'm planning to support a heuristic of macros which have an arglist ending in "& body".

16:55 lpetit: look at some VC code. ;P It uses some built-in Vim functions which is modelled after the "usual" Lisp style.

16:57 arohner: Most of clojure.core and clojure.contrib also follows "usual lisp style"

16:59 lpetit: kotarak: Do you make even more specific cases for some clojure core macros/special forms, or does it all come down (for call forms) to a 2 space indentation from the column of the opening paren for the first argument being part of the & body ?

17:01 arohner: yes, but alas "usual lisp style" does not speak formally about clojure general specificities, and maybe some clojure 'call symbols' even more specific cases :-(

17:01 kotarak: lpetit: it roughly comes down to this:

17:01 (some-function a b

17:01 c d)

17:01 c should align with a

17:02 (some-macro a

17:02 (body-part starts here))

17:02 For a macro with a body part.

17:02 Some exceptions I made include defmulti, -> and doto.

17:05 lpetit: kotarak: for your (some-function) example, isn't it too strict to align c with a ? Does it "scale well" if you have deep imbrication of code (does it not go too deep on the right of the screen too quickly ?)

17:06 kotarak: lpetit: not in my experience, and there is also the form:

17:06 (some-function

17:06 a b c d)

17:06 two spaces (like in the macro with body case) if a newline directly after the function/macro,

17:07 lpetit: I was wondering whether this could be a workable solution :

17:07 (some-function a b

17:07 c d) ; it's the second line, we propose 2 characters indentation by default. If the user presses tab, we indent towards a automatically

17:07 (some-function a b

17:07 c d

17:07 e f) ; e aligns with c, whatever c's column is

17:10 kotarak: lpetit: also possible

17:12 lpetit: kotarak: the advantage I see is its simplicity, and maybe also even more consistent with the (some-function\n a b c d) case (indeed, why not going one space after the end of the function name ?)

17:13 kotarak: lpetit: I'm not arguing for consistency... I just use the vim lispindent function and that's the way it works.

17:14 lpetit: kotarak: ok. Eclipse is too open in this area: it offers nothing prebuilt ! So all possibilities (and the time consuming task to elaborate on them :) ) are offered to me ! :)

17:45 hiredman: I totally just solved euler project problem #1 in the lisp I wrote

17:45 makes you appreciate lazy-seq

17:46 aperotte: hello all

17:48 stuhood: howdy

17:49 aperotte: I'm in the process of writing a matrix/n-dimensional array data type

17:49 was wondering if anyone had any suggestions or comments

17:58 stuhood: i heard mention that there was a contrib module that wanted to depend on Colt (http://acs.lbl.gov/~hoschek/colt/) for its matrix functionality

17:59 aperotte: I've looked at colt, and liked the library but it has support for data structures of only up to 3 dimensions

18:14 I also thought it would be nice to have a data structure that didn't depend on an external library

18:37 djkthx: is there a way to make macroexpand's output a little prettier?

18:37 Chousuke: use pretty-print from contrib

18:37 djkthx: with indentation and maybe syntax highlighting? (in slime)

18:39 awesome, thanks

18:45 lispbliss: Is there a more concise way of updating :b in this example: (let [m {:a {:b 1 :c 2}}] (assoc a :a (merge (:a a) {:b 2})))

18:46 Chousuke: assoc-in

18:47 lispbliss: sweet

18:47 Chousuke: ,(assoc-in {:a {:b 1 :c 2}} [:a :b] 3)

18:47 clojurebot: {:a {:b 3, :c 2}}

18:48 Chousuke: also works with nested vectors or vector-map combinations :)

18:48 lispbliss: by using an index number for the vectors?

18:48 Chousuke: yeah

18:49 ,(assoc-in [[1 2]] [0 1] 3)

18:49 clojurebot: [[1 3]]

18:50 Chousuke: can't add to vectors that way though. only "replace" an existing item

18:51 ,(assoc-in {} [:a :b :c :d :e] 4); this works with maps though

18:51 clojurebot: {:a {:b {:c {:d {:e 4}}}}}

18:51 gnuvince_: ,(update-in [[1 2]] [0] join 3)

18:51 clojurebot: java.lang.Exception: Unable to resolve symbol: join in this context

18:51 gnuvince_: ,(update-in [[1 2]] [0] conj 3)

18:51 clojurebot: [[1 2 3]]

18:51 Chousuke: ah, right, that

20:26 gnuvince_: Chousuke: http://ertes.de/articles/monads.html

20:33 scottj: Is there a function (foo {:a 1 :b 2} {:a 1 :b 3}) => {:b 2} ?

20:37 Chouser: a sort of diff?

20:38 scottj: yeah

20:38 Chouser: not that I know of: http://groups.google.com/group/clojure/browse_thread/thread/cc316de16fcba6c8/a74e652eb98693ce

20:41 Chousuke: gnuvince_: cool, some more monad stuff for me to read.

20:41 gnuvince_: Chousuke: reading it between commercial breaks

20:42 the guy seems thorough

20:42 Chousuke: I've read a lot on monads.

20:42 And still they just don't make sense.

20:43 gnuvince_: Read the ones for monads in Clojure :)

20:43 Chousuke: I mean, I already have an idea of the why and how, but there's still something missing.

20:43 yeah, I did.

20:46 cp2: ugh, anyone recommend a monospaced font with good unicode coverage?

20:49 gnuvince_: cp2: http://dejavu.sf.net

20:50 cp2: ahhh

20:50 thank you gnuvince_

20:50 this is much more pleasing to look at

20:51 gnuvince_: cp2: I use it everywhere in 16pt

20:51 Nice big mono characters

20:51 cp2: heh

22:28 chessguy: is it possible to write my own data structures in clojure that "implement" seq? so that i can use first/rest on them?

22:29 rhickey: chessguy: sure - what kind of data structure?

22:29 chessguy: rhickey i don't have one in mind, it's more of a generic question

22:30 rhickey: chessguy: you just have to implement clojure.lang.Seqable

22:31 chessguy: in java?

22:34 sorry, brand new to clojure here, and don't have a ton of lisp experience either, so i'm trying to grok what that would look like

22:34 hiredman: you could do it with proxy

22:34 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

22:35 chessguy: it sounds like i'm asking the wrong question though :)

22:35 hiredman: Seqable is just a java interface that specifies one method

22:36 chessguy: sure, i get that. i'm sure i could implement the interface in java. just not sure what that would look like in a functional language

22:37 hiredman: most likely you would have the seq method return some kind of lazy-seq over a function that iterates your datastructure

22:38 rhickey: hiredman: right, and as you said, you can implement the interface with proxy

22:38 chessguy: would it be...unusual to do that?

22:39 hiredman: normally I would just use lazy-seq

22:40 rhickey: (let [rep (create-representation)]

22:40 (proxy [clojure.lang.Seqable] []

22:40 (seq [this] (lazy-seq (cons (get-first rep)) (get-rest rep)))))

22:41 something like that

22:42 oops:

22:42 (let [rep (create-representation)]

22:42 (proxy [clojure.lang.Seqable] []

22:42 (seq [this] (lazy-seq (cons (get-first rep) (get-rest rep))))))

22:42 darn those pesky parens!

22:43 chessguy: ok, i'm way over my head now

22:43 i guess i need to just find more code to read

22:44 rhickey: chessguy: might be unusual, in that I wonder what data structure you need that isn't an aggregate of the ones in Clojure, and thus supporting seq out of the box

22:44 chessguy: fair question

22:44 rhickey: but nothing wrong with the idea

22:45 chessguy: so the more clojure-ish way would be to use some aggregate of core data structures

22:45 by writing my own constructors/selectors/etc.?

22:46 Cark: there are many data structure with different tradeoffs, it is possible that you want to build your own

22:46 i have a trie which i use for telephone prefixes

22:46 i think it makes sense to build your own data structures at times =P

22:47 chessguy: well, right this minute i'm more interested in typical usage of the language than what the language CAN do

22:48 rhickey: Cark: no doubt, I'm just interested in which ones people are needing beyond what's in core. Someone's working on a persistent heap, I'd like to see maybe treaps or finget trees

22:48 fnger

22:48 finger

22:48 Cark: chessguy : usually you'll just use what's available, you have lists lazy or not, vector, maps (sorted or not, ordered or not)

22:49 rhickey: chessguy: it's strongly advised to use the data structures rather than classes, but there are other generic data structures not included

22:49 Cark: rhickey : i'm pretty happy with what's in there already

22:49 i wouldn't expect every data structure under the sun to be available out of the box

22:50 though it would be nice to have the persitent queue available from clojure itself

22:50 rhickey: Cark: well, the implementation is there

22:50 you just want Clojure wrapper functions?

22:51 Cark: yes, someone pointed me to it, but i was a bit afraid it might disapear

22:51 you know in a version 1.0 or something =P

22:51 chessguy: so if i wanted a generic tree, for example, i would write mk-tree, map-tree, etc.?

22:52 Cark: chessguy : it depends on why you need a tree

22:52 anyways that's how i built my trie implementation

22:53 rhickey: chessguy: map-tree returns a seq or a tree?

22:53 Cark: but no map-trie .... rather a trie->seq function, which produces a lazy-seq

22:53 then i can use every map function which is already in clojure

22:53 chessguy: rhickey map-tree takes a function and a tree and returns a new tree with the function applied at each node

22:53 Cark: which includes map =)

22:53 chessguy: err, what?

22:54 Cark: ah right, it won't help building a new tree

22:54 you could add a seq->tree function though ...

22:54 chessguy: it's hard, because i'm coming from haskell, so i'm a bit lost without being able to write type signatures

22:55 hiredman: map-tree might be nice in clojure.zip

22:55 Cark: err i meant "every sequence function which includes map"

22:58 chessguy: i also am not accustomed to thinking in macros, though i get the general concept

22:59 joha1: I'm having some problems with vimclojure 2.1. My classpath is set up correctly in the shell, but when I run vim and try to execute a file that imports an external library I get a ClassNotFoundException. It seems that VimClojure sets a private CLASSPATH which is wrong. How does it work? What can I do?

23:00 hiredman: joha1: the import classpath is the classpath you pass when you start the nailgun server

23:00 important

23:03 joha1: hiredgunman: so I have to submit the complete classpath to the NGServer, not only clojure.jar and clojure-contrib.jar?

23:03 hiredman: yes

23:03 chessguy: in http://gnuvince.wordpress.com/2008/10/31/fetching-web-comics-with-clojure-part-1/ , the second snippet of code (look for with-open), why is with-open not taking a vector?

23:03 hiredman: the nailgun server is the java process

23:03 chessguy: old code

23:03 joha1: ok, makes sense. Will give it a try

23:04 chessguy: oh!

23:04 no wonder i was confused

23:07 joha1: hiredman: thanks! it works now

23:16 chessguy: does "programming clojure" work through any examples of a significant size?

23:18 djkthx: throughout the book, you write a build system similar to ant

23:18 iirc

23:18 i suppose it depends what you consider significant

23:19 chessguy: significant = non-trivial

23:19 i think that qualifies

23:23 ok, enough for one night. thanks ya'all

Logging service provided by n01se.net