#clojure log - Aug 07 2009

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

0:01 JAS415: hmm?

0:01 tdd?

0:02 i delete all my code and start over all the time

0:02 but most of the time i keep it around so i can rewrite it

0:02 tomoj: I ended up with a huge nasty nasty mess

0:02 JAS415: rewrite/cannibalize

0:02 yeah

0:02 tomoj: doing things like (first (first blah)) multiple times to deal with shitty functions I had written before

0:02 JAS415: haha yeah that's a problem

0:03 tomoj: and really long chains of crap with multiple anonymous functions and duplication all over the place :(

0:03 JAS415: are you parsing xml or something?

0:03 duplication is time for some function passing or a macro though :-)

0:04 tomoj: parsing html

0:04 nasty, nasty html

0:05 JAS415: i avoid html when i can

0:05 tomoj: I wish I could

0:05 if my university offered the course schedule in JSON I would love them

0:05 JAS415: haha yeah

0:05 JSON is beautiful by comparison

0:06 and it parses into clojure really nicely

0:06 _mst: if you're willing to delve into java land slightly, I've found htmlcleaner.sourceforge.net nice for parsing "in the wild" html

0:06 JAS415: i think there is a contrib library for xml

0:07 if is regular html (i.e. isn't missing anything) it might work

0:08 Derander: clearly clojure needs hpricot

0:08 JAS415: hpricot?

0:08 Derander: ruby library, makes html über easy

0:09 JAS415: how does it work?

0:09 tomoj: we have enlive

0:09 Derander: JAS415: not familiar w/ the internals.

0:09 tomoj: does css selectors nicely

0:09 and it's extensible

0:09 Derander: ah, spiffy.

0:10 tomoj: like, it can do more than css

2:12 hmm

2:13 to me it seems like I have to think backwards to write clojure

2:13 I mean, anticipate all the little functions I will need in the future

2:14 or write a whole lot of code without compiling, or figure out some trick to have the compiler ignore the high level method I'm working on while I'm coding the smaller ones

2:16 ...or just learn to use clojure-mode better :)

2:16 mebaran151: you could always just declare the functions

2:16 or mock them up

2:17 also #_ is your friend (it will comment out exactly one expression)

2:17 hiredman: I tend to spend a lot of time in the repl

2:17 mebaran151: so #_(defn my-giant-fuction []) will get rid of that def all in one swoop

2:17 tomoj: ah nice

2:17 I think I can just compile each smaller defun individually as well

2:17 instead of compiling the whole file

2:17 mebaran151: yep

2:17 but sometimes it's easier just to slurp the whole file

2:18 hiredman: using -> and adding stuff to the chain until I get the desired output

2:18 mebaran151: after quickly marking the fialures

2:18 hiredman: tomoj: what do you mean by "compile"?

2:18 tomoj: previously I was doing slime-compile-and-load-file after every change

2:19 which means the whole file has to compile successfully (so either comment out code that calls nonexistant code or declare the nonexistant functions)

2:19 hiredman: oh

2:19 :/

2:19 I load a function or so at a time

2:20 tomoj: clojure-mode binds lisp-eval-defun to "\e\C-x".. O_o

2:21 alinp: hi

2:21 how does clojure handle list copying ?

2:22 I mean ... (conj [1 2 3] 4)

2:22 it will not mutate the current collection (we all know that)

2:23 tomoj: intelligently

2:23 alinp: and as far as I remember, Rich said that the copying will not be expensive

2:23 tomoj: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

2:23 alinp: ok, thanks tomoj, I'll read about that

2:27 hmmm

2:27 there is also some System.arraycopy there

2:28 tomoj: it's amortized

2:30 at least, I think so..

2:42 fsm: Hello everyone.

2:42 Is there a good sample anywhere to she the best practise for reading/parsing binary files in Clojure?

2:43 see*

3:19 demas: Hi,all. I need your help. I just wanted to use partition-all. I use 'Clojure 1.1.0-alpha-SNAPSHOT'.

3:20 But when I write 'user=> (use 'clojure.contrib.seq-utils)'

3:20 I have got next error message 'java.io.FileNotFoundException: Could not locate clojure/contrib/seq_utils__init.class or clojure/contrib/seq_utils.clj on classpath: (NO_SOURCE_FILE:0)'

3:20 Is there any ideas how to fix this error ?

3:21 hoeck1: demas: adding clojure-contrib.jar to the classpath

3:22 demas: or adding the src folder of your clojure-contrib repository to the classpath

3:22 demas: How can I find clojure-contrib.jar? Is it part of clojure?

3:23 hiredman: ~google clojure contrib

3:23 clojurebot: First, out of 4800 results is:

3:23 clojure-contrib - Project Hosting on Google Code

3:23 http://code.google.com/p/clojure-contrib/

3:23 hiredman: ugh

3:23 demas: thanks

3:23 hiredman: that is not right

3:23 ~google clojure contrib github

3:23 clojurebot: First, out of 1160 results is:

3:23 richhickey's clojure-contrib at master - GitHub

3:23 http://github.com/richhickey/clojure-contrib/tree/master

3:23 hiredman:

3:24 demas: ok, thanks

3:24 hiredman: clojurebot: contrib?

3:24 clojurebot: contrib is http://code.google.com/p/clojure-contrib/

3:24 hiredman: clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

3:24 clojurebot: 'Sea, mhuise.

3:24 lpetit: clojurebot: contrib?

3:24 clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

3:25 lpetit: your bot is really really cool :)

3:25 ~contrib

3:25 clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

3:25 hiredman: ~botsnack

3:25 clojurebot: thanks; that was delicious. (nom nom nom)

3:26 lpetit: ~google eclipse clojure plugin

3:26 clojurebot: First, out of 8920 results is:

3:26 clojure-dev - Project Hosting on Google Code

3:26 http://code.google.com/p/clojure-dev/

3:26 lpetit: Yes!

3:26 :)

4:12 Jomyoot: intellij needs better support

4:19 vy: Shouldn't (let [[#^String x y & z] "abcdef"] [x y z]) supposed to throw an error since x is not a string?

4:28 lpetit: hmm

4:29 ,(let [#^String x "a"] (prn x))

4:29 clojurebot: "a"

4:29 lpetit: no sorry !

4:29 ,(let [#^String x \a] (prn x))

4:29 clojurebot: \a

4:29 hoeck1: vy: I would say it throws an exception if you call a String only method on it

4:32 lpetit: indeed, it seems it's just for optimizing code for avoiding reflection, but not complaining if the type is not correct but not used for any reflection-avoiding code optimization

4:32 ,(let [#^String x "a"] (.length x))

4:32 clojurebot: 1

4:33 lpetit: ,(let [#^String x \a] (.length x))

4:33 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String

4:33 lpetit: ,(let [x \a] (.length x))

4:33 clojurebot: java.lang.IllegalArgumentException: No matching field found: length for class java.lang.Character

4:44 lpetit: (binding [*warn-on-reflection* true] (let [x "a"] (.length x)))

4:44 ,(binding [*warn-on-reflection* true] (let [x "a"] (.length x)))

4:44 clojurebot: 1

5:19 angerman: how can I do something like (assoc obj {:k1 1 :k2 2}) ...?

5:19 basically I'd need to destruct the map in place

5:34 Chousuke: angerman: destruct? you mean you want to merge obj and the map?

5:37 lpetit: angerman : (merge obj {:k1 1 :k2 2})

5:42 angerman: Chousuke: well, no I want it to be (assoc obj :k1 1 :k2 2)

5:43 but yes I guess that's what merge does

5:43 hmm... I'm kinda stupid today I guess :)

6:32 djpowell: I'm currently using a big map to implement a sort of union-find datastructure, where key-value mappings represent edges in the tree. I guess building that might be sped up a bit by a transient hashmap?

6:37 tbh though, most of the stuff I'm doing with clojure involves processing data from database queries, so I haven't had any kind of performance problems with clojure, that aren't be dwarfed by i/o

6:43 angerman: what is an easy way to turn [:x 1 :y 2] into {:x 1 :y 2}?

6:45 jdz: ,(apply hash-map [:x 1 :y 2])

6:45 clojurebot: {:y 2, :x 1}

6:45 angerman: aye

7:46 Chousuke: hmm

7:46 syntax-quote behaviour with maps is weird.

7:46 ,`{~@(do [1 2]}

7:46 clojurebot: Unmatched delimiter: }

7:47 Chousuke: ,`{~@(do [1 2])}

7:47 clojurebot: 1

7:47 Chousuke: ,`{1 ~@(do [1 2 3])}

7:47 clojurebot: {1 1, 2 3}

7:47 Chousuke: I think I know why that is, though.

8:12 angerman: is there a short hand to create a keyword from a symbol or do I have to go the (keyword (str x)) route?

8:12 jdz: i'd use name instead of str

8:13 rhickey: ,(keyword 'foo)

8:13 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String

8:14 rhickey: works in master

8:14 angerman: ahh, ok :)

8:14 ,(keyword (name 'foo))

8:14 clojurebot: :foo

8:15 rhickey: ,(clojure.lang.Keyword/intern 'foo)

8:15 clojurebot: DENIED

8:15 rhickey: nice

8:15 angerman: ,(try (keyword 'foo) (catch ClassCastException e (keyword (name 'foo)))

8:15 clojurebot: angerman: Titim gan éirí ort.

8:15 angerman: yes.

8:20 rhickey: what is better? using defmulti and multimethod or having a map with lambdas that get called?

8:22 jdz: it is actually not the same thing

8:22 angerman: (let [dispatch-map {:a (fn [...] ...) :b (fn [...] ...)}] ((dispatch-selector dispatch-map) arg0 arg1 arg2 ...))

8:23 jdz: there's a benefit of using multimethods: you can pass around a single thing

8:23 on the other hand, you can wrap your dispatch map in a function

8:25 angerman: hmm i'll play with it a bit

8:26 rsynnott: why does clojurebot speak Irish?

8:26 rhickey: angerman: better how? defmulti automate the map/call process

8:27 angerman: rhickey: so the implementation does pretty much the same?

8:28 rhickey: angerman: multimethods use maps, they also do isa stuff and caching, why not use the most straightforward thing (multimethods)?

8:28 jdz: i'd also go the fewer-wheel-invention road

8:30 angerman: well, using dispatch-maps was something i knew already, I'm just getting used to defmulti

8:31 jdz: after thinking a bit, it appears to me that defmulti does just that, with some clever stuff mixed in

8:31 in your case, you even don't have to redefine dispatch-selector

8:32 (or so it seems to me)

8:47 cgrand: rhickey: (-> {} (assoc :a ()) (assoc :a [])) returns {:a []} but would it be ok to return {:a ()}? (no assoc when equality)

8:49 rhickey: cgrand: no, a list is not a vector

8:50 cark: ,(= [] ())

8:50 clojurebot: true

8:50 rhickey: if someone were to start conjing on the val at that key they'd get different results

8:50 cark: hum

8:51 cgrand: ok, the last assoc must win for values

8:51 AWizzArd: ,(identical? [] ())

8:51 clojurebot: false

8:52 cgrand: BUT right now (-> {} (assoc () :a) (assoc [] :a)) returns {() :a} should it return {[] :a} instead

8:52 ?

8:53 cark: hey awizard !

8:53 AWizzArd: ,(-> {} (assoc () :a) (assoc [] :a))

8:53 cark: ,(identical? [1] '(1))

8:53 clojurebot: {() :a}

8:53 false

8:53 cark: ,(identical? (list 1) (list 1))

8:53 clojurebot: false

8:53 AWizzArd: cark: = is more like equal in CL

8:54 cemerick: identical? is reference identity, nothing to do with equality

8:54 == in java, pointer comparison in C

8:54 cark: but is it ok to have a list and a vector being = ?

8:54 cemerick: cark: absolutely; it's up to the callee of = to decide what equality means

8:54 AWizzArd: = traverses them

8:55 cark: how about the conj argument from rhickey ?

8:55 AWizzArd: there is an infinit set of meanings of what equality means. The most basic one is checked with identical?.

8:55 rhickey: cgrand: keys are based on equality, the values identity test is an optimization

8:56 cemerick: AWizzArd: identical? is *not* equality. It returns true only if two objects are *exactly the same* object.

8:56 cgrand: ok, understood, thanks

8:56 cemerick: Which, in general, is hardly ever what you want.

8:57 ,(identical? "foo" "foo")

8:57 clojurebot: true

8:57 cemerick: ,(identical? "foo" (str "foo" ""))

8:57 clojurebot: false

8:58 cemerick: even better:

8:58 ,(identical? 500 500)

8:58 clojurebot: false

8:58 rhickey: cgrand: the values identity test is an optimization that should be preserved, code can depend on assoc of item already in collection => same collection

8:58 jdz: cemerick: this is why in CL there is eq and eql

8:59 rhickey: ,(let [m {:a :b}] (identical? m (assoc m :a :b)))

8:59 clojurebot: true

8:59 jdz: ,(let [m {:a 500}] (identical? m (assoc m :a 500)))

8:59 clojurebot: false

8:59 cemerick: rhickey: that's cute

9:00 jdz: I've thankfully forgotten all of the shades of equality in CL, but OK :-)

9:00 jdz: i expect many newbies to rave in agony upon finding this out

9:00 cark: actually i liked the precision of CL equality, though there is always more variations

9:00 rhickey: jdz: that's the same value, not the same object

9:00 jdz: rhickey: yes, go tell that to the newbies ;)

9:01 rhickey: jdz: newbies shouldn't be using identical

9:01 cemerick: (almost) no one should use identical, unless you're writing core data structures

9:01 rhickey: if they have that expectation they don't understand equality yet

9:01 ,(let [m {:a 500}] (= m (assoc m :a 500))

9:01 clojurebot: EOF while reading

9:02 rhickey: ,(let [m {:a 500}] (= m (assoc m :a 500)))

9:02 clojurebot: true

9:02 cemerick: I think I've used it once or twice in ~14 months of clojure-ing, and I seem to remember it causing problems.

9:02 angerman: canI filter a map?

9:06 jdz: i was actually recently a bit surprised that rest on a vector returns different objects

9:06 ,(let [s (seq [1 2 3])] (identical? (rest s) (rest s))

9:06 clojurebot: EOF while reading

9:07 jdz: ,(let [s (seq [1 2 3])] (identical? (rest s) (rest s)))

9:07 clojurebot: false

9:07 jdz: ,(let [s (seq '(1 2 3))] (identical? (rest s) (rest s)))

9:07 clojurebot: true

9:07 jdz: (was writing a tree substitution thing which would not copy a branch if there were no substitutions made)

9:08 rhickey: jdz: how could it efficiently do otherwise?

9:08 (vectors not being a linked data structure)

9:11 jdz: well, after thinking about it, it makes perfect sense

9:11 and i was not really *very* surprised, just a little bit

9:21 Chousuke: hm

9:24 isn't (binding [foo bar] ...) supposed to establish a thread-local binding?

9:38 gulagong_: hi guys

9:38 cgrand: hi gulagong_

9:38 gulagong_: what happened to a java object which brings my thread to an infinite loop when i try to print it or return it ?

9:39 when printing it prints the classname and than hangs

9:39 while it is printable

9:40 difficult to describe for me but i nailed my problem down to this

9:43 it heats up one core and and my profiler crashes...

9:45 jdz: calculating with infinities is not supported on modern hardware

9:46 gulagong_: jdz: is this an answer to me?

9:46 Chousuke: so what's wrong if I do, in a macro, (binding [*foo* {}] (macro-driver* form)) and then try to (set! *foo* (assoc *foo* :stuff :here)) within macro-driver*?

9:46 I get an error about not being able to change root bindings :/

9:46 jdz: gulagong_: kinda

9:47 gulagong_: and what do you mean by "it is printable" when apparently it enters infinite loop?

9:48 gulagong_: jdz: these objects can regulary be printed

9:48 jdz: just this one in this situation not

9:49 jdz: gulagong_:so then it's easy - just look for what's different in "this situation"

9:49 gulagong_: jdz: its a matrix from the colt library

9:50 jdz: that is my problem.... i don't find a difference

9:50 jdz: it seems to have disappeared and send my cpu for a search out...

9:51 jdz: gulagong_: what seems to have disappeared?

9:51 gulagong_: the contents of the array

9:52 jdz: it prints the classname and then hangs when trying to print the array-content

9:52 jdz: so the array-content is infinite then

9:52 gulagong_: nope

9:53 #<DenseDoubleMatrix2D

9:53 and then nothing

9:53 jdz: try printing it to a PrintStream with auto flushing

9:54 gulagong_: which would be?

9:55 Chousuke: ah, I needed to use alter-var-root instead of set!...

9:55 gulagong_: jdz: it is a list of these matrices and all but the first element work... although i treat them all the same

9:56 jdz: and in the function returning this list i still have acces to the elements of this object

9:56 jdz: gulagong_: have you tried what i suggested?

9:57 gulagong_: jdz: i don't know which printstream has auto-flushing

9:57 jdz: *the* PrintStream

9:57 gulagong_: ok

9:58 djpowell: hmm - there is no sorted-set-by, to correspond to sorted-map-by (the constructor that takes a custom comparator)

9:59 Chousuke: user> (syntax-quote (fn [foo#] (+ foo# ~x)))

9:59 (clojure.core/fn [foo__auto__26935] (clojure.core/+ foo__auto__26935 1))

9:59 \o/

10:03 gulagong_: jdz: like this? (with-out-str (prn OBJECT)) ?

10:05 jdz: i used this as return value an it hung up

10:06 jdz: gulagong_: no, like (binding [*out* (new java.lang.PrintWriter *out* true)] (prn OBJECT))

10:06 gulagong_: jdz: ok, thanks

10:06 jdz: (untested)

10:07 or you can use System/out or System/err instead of *out* when creating that stream

10:14 Chousuke: http://gist.github.com/163921 hairy stuff... still needs some tweaking for special forms at least.

10:16 gulagong_: jdz: i tried and its the same problem

10:17 jdz: gulagong_: well then, since you don't have any output you'll have to work out where the cycle in your data structures is by yourself...

10:18 gulagong_: jdz: there is no cycle....

10:18 jdz: gulagong_: how do you know?

10:18 b4taylor: Well if it's a pure data structure you can't make a cycle.

10:19 gulagong_: jdz: cause i debug- printed this object before- then i return it and its contents brake the print?

10:19 jdz: b4taylor: as mentioned before it is something from external library

10:19 gulagong_: yap, a matrix

10:19 b4taylor: jdz: Sorry, just got here :p

10:20 gulagong_: but i'm not doing any concurrent stuff

10:20 b4taylor: Ah, which one are you using? I tried out Jama.Matrix.

10:20 gulagong_: colt

10:21 and it's great :)

10:21 eccept that it dissapears ;)

10:21 b4taylor: Disappears in what way?

10:22 jdz: gulagong_: it does not disappear. clojure tries to print it, and it [as you say] enters infinite loop

10:22 b4taylor: One problem I've been having is getting back lazy-seqs and having to force them with dorun.

10:22 gulagong_: no, nothing to do with that

10:22 b4taylor: Ah.

10:22 gulagong_: i return it and after that clojure knows the classname but not the contents.... from what i can observe

10:23 but only in one case

10:23 jdz: gulagong_: i told you like 3 times that what you observe is not what really happens.

10:23 gulagong_: jdz: i know

10:24 jdz: so, maybe i should ask how to observe better

10:24 jdz: but my profiler crashes... thats why i'm here - i have no clue

10:25 jdz: gulagong_: you don't need profiler. you need debugger.

10:26 gulagong_: jdz: ok, i'll try to find one for osx

10:28 b4taylor: I'm having some trouble importing from files in my current project. Say I have the files foo/bar/a.clj and foo/bar/b.clj and appropriate (ns foo.bar.a (:import foo.bar.b)) as well as (ns foo.bar.b) lines in each file respectively, why would this fail? Should I add /pathtofoo to my CLASSPATH?

10:28 jdz: you use import for Java packages

10:28 use for clojure ones

10:28 b4taylor: Oh of coarse.

10:29 Damn, thanks.

10:33 leafw: where are the docs for the xml functions?

10:33 search "xml" failed in the website.

10:40 bstephenson: well, there is this rather sparse documentation: http://clojure.org/api#toc673

10:43 and clojure.contrib has clojure.contrib.lazy-xml, zip-filter.zml, and a bunch of other xml utility funcs

10:43 s/zml/xml

10:43 leafw: thanks

10:45 bstephenson: by the way what is the fn to visualize an xml as a JTree in a JFrame? Haven't used this in a while

10:45 bstephenson: do (find-doc "xml") in your repl, and you will find all references to xml in the docs. if you have clojure.contrib library associated with your repl, you will get its funcs too

10:46 ,(find-doc "xml)

10:46 clojurebot: EOF while reading string

10:46 bstephenson: ,(find-doc "xml")

10:46 clojurebot: ------------------------- clojure.core/xml-seq ([root]) A tree seq on the xml elements as per xml/parse ------------------------- clojure.zip/xml-zip ([root]) Returns a zipper for xml elements (as from xml/parse), given a root element ------------------------- hiredman.clojurebot.svn/summary ([tag-map]) takes output of clojure.xml/parse on svn's xml log, returns a vector of [rev-number commit-message] --------------------

10:47 bstephenson: leafw: I will talk to my java form guys here, try to get a quick answer

10:47 leafw: bstephenson: I use to knew it, that's the ugly part

10:47 bstephenson: clojure needs a function "find-old-code". I always need that one!

10:48 leafw: xD

10:51 bstephenson: I have it, it's clojure.inspector/inspect-tree

10:54 WizardofWestmarc: man after finding out what an idiot I am when it comes to transients now I wish I was set up on my work computer to build clojure from source so I could play with it here. Bah

10:55 rhickey: WizardofWestmarc: no one's an idiot on transients, they are pretty unusual

10:56 but best to write it functionally first then add transient/persistent!

10:57 WizardofWestmarc: right. Already rewrote it and pretty sure it'll work now

10:57 what's funny is I actually DID write the original version functionally. But I didn't wrap my reduce in the persistant! so it screwed up.

10:57 bstephenson: leafw: looks good, should work well for you. we are dealing with xml slightly differently here, so could not find example of us using that in our clojure code.

10:57 WizardofWestmarc: I did it some other way that made it not quite functional.

10:59 goes to show what happens when you get away from functional programming, you fall out of good habits too quick when things get tough

11:07 btw Rich, any idea when fork/join will make it back up to master?

13:05 Chousuke: hm

13:06 wonder if it'd be worthwhile to reorganise core.clj a bit.

13:07 I'm trying to implement syntax-quote as a macro, and most of the functions I need to move "up" are small java wrappers.

13:13 for now, it seems my syntax-quote works though.

13:47 LauJensen: Good evening gents

13:48 danlarkin: Lau why did you change from Lau_of_DK

13:49 rsynnott: possibly there is now another Lau in Denmark :)

13:49 cark: or moved to Jensenia

13:50 leafw: any trivial way to read a file line-by-line using line-seq? I.e. how to create a reader from a file path string ?

13:50 and I don't mean the java way, I know that one ... there must be a clojure (read-file ...) or something

13:52 and slurp is not useful: not broken into lines

13:52 cark: (with-open [stream (BufferedReader. file-name)] (do-something (line-seq stream) ...

13:52 or something like it

13:53 rsynnott: only a small amount of unsightly java :)

13:53 leafw: cark: the problem is, with that, I have to deal with imports

13:54 and I'd rather not have imports for something as trivial as creating a reader from a file.

13:54 cark: mhhh there was something in contribs duck-streams ?

13:54 LauJensen: danlarkin: Lau_of_DK was something I picked up as a temporary thing, because 'lau' was already taken. So I figured I might as well grab something a little more descriptive

13:54 leafw: the same way that regex functions hide all the ugliness of java.util.regex.Pattern and friends, so could clojure hide all the FileInputStream etc verbosity with (create-reader filename) or so.

13:55 rsynnott: leafw: well, you could always write a macro to do it

13:55 danlarkin: LauJensen: reasoning accepted :)

13:55 rsynnott: (something along the lines of the CL with-open-file macro, possibly)

13:55 leafw: rsynnott: the point is I'm trying to use clojure like I would use matlab. imports just get in the way, and fully qualified names are tedious.

13:56 and reading a file it's such an essential thing, one would think.

13:56 * rsynnott hardly ever reads in files

13:56 leafw: there is slurp. But there isn't a reader-creation function.

13:56 cark: you could fully qualify BufferedReader

13:56 so no imports

13:56 rsynnott: (I always have to look up the appropriate commands in whatever I'm using)

13:57 ESPECIALLY in CL; I doubt anyone knows those from memory :)

13:57 cark: or use clojure.contrib.duck-streams/reader

13:57 LauJensen: danlarkin: Hows Madison coming along ?

13:57 rsynnott: ':supersede_if_exists' et al :)

13:58 danlarkin: LauJensen: haven't touched it in months :-o

13:58 LauJensen: oh, not good

13:58 WizardofWestmarc: yeah I gave up on Dan and started using Compojure ;-)

13:59 though I am using your couchdb lib (haven't played with it much but it seems to work)

13:59 leafw: cark: clojure.contrib.duck-streams/reader is just as long. Why not a proper function in core clojure to create a reader? It's not a big deal, and it already has functions to deal with readers (hence it looks like an omision)

13:59 cark: it feels like library stuff to me

14:00 LauJensen: WizardofWestmarc: How are you interfacing with couchdb ?

14:00 cark: you should stick something in that "utils" file you will use with almost every project =)

14:01 leafw: cark: as much lib stuff as "slurp" is. Same thing.

14:01 WizardofWestmarc: Dan has a library on github

14:01 cark: leafw:true

14:01 LauJensen: ~couchdb

14:01 clojurebot: I don't understand.

14:01 LauJensen: ~clojureql

14:01 clojurebot: clojureql is a quite impressive piece of work

14:01 LauJensen: ~clojureql

14:01 clojurebot: clojureql is http://github.com/Lau-of-DK/clojureql/tree/master

14:01 WizardofWestmarc: http://github.com/danlarkin/clojure-couchdb/tree/master

14:02 only played with it minimally as I haven't had the time to work on my clojure/compojure/couchdb project, but the very limited testing worked.

14:02 LauJensen: Ok - Was just wondering if this was something I should assimilate into ClojureQL

14:02 WizardofWestmarc: I wouldn't

14:02 couchdb and sql are too different to keep the libraries together IMO

14:02 LauJensen: No it doesnt look like a candidate

14:03 WizardofWestmarc: document based db instead of an RDBMS

14:03 LauJensen: Yep

14:03 WizardofWestmarc: which is pretty interesting so far.

14:03 views using javascript, able to easily split up data, all kinda of neat features

14:03 rsynnott: would anyone be interested in something like this: http://common-lisp.net/project/elephant/ on clojure?

14:04 I'm messing around with trying to write an analogue of it

14:04 (it's an object database)

14:04 LauJensen: rsynnott: That makes it alot like Coachdb

14:04 rsynnott: yep, but not quite the same

14:04 LauJensen: What are the major differences?

14:07 cark: LauJensen : about clojureql, does it support runtime query building or is this all macros ?

14:08 LauJensen: You can do everything runtime

14:08 cark: cool

14:08 LauJensen: Yea :)

14:08 cark: there are some examples of this ?

14:09 LauJensen: http://lau-of-dk.github.com/clojureql/2009/07/13/query-syntax.html

14:10 I think this will give you the general idea

14:11 cark: right, but what if i want to dynamically generate the where clause, like suddenly the user decides to use one of my filter boxes

14:11 LauJensen: (query tab [x y z] (= ~user-selection ~threshhold)) , that'll evaluate the environment at runtime

14:13 cark: i see

14:20 LauJensen: cark: Yea. And I know of 2 industry systems now relying on ClojureQL, and its holding up perfectly

14:20 cark: i would be using backend.clj for total control

14:21 LauJensen: cark: the frontend is all the functions you need to worry about. They compile an sql statement to our own format (which is a hash-map basically), then that gets passed through the backend when you call execute-sql or compile-sql, which then form a sql statement fitted for your particular database.

14:21 (note, postgresql create-table is currently under review)

14:22 cark: yes, but the point is that the structure of my queries varies quite a lot in a single function

14:22 i quickly made something like your backend file, but yours is way cleaner

14:23 LauJensen: I dont quite follow

14:23 ~clojureql is http://gitorious.org/clojureql/clojureql

14:23 clojurebot: c'est bon!

14:23 cark: say one query would be : select * from calls ... and the other select * from call where a=? and b=?

14:24 and i need to programatically construct these

14:24 LauJensen: So why wouldnt you just wrap that in a cond or condp, calling query as needed?

14:25 cark: because of combinatorial explosion

14:25 LauJensen: If you like, you can Gist an example

14:25 cark: i'd never see the end of it

14:25 LauJensen: (are everybody aware that Emacs integrates Gists very nicely? Push buffer to gist? Pull gist to buffer?)

14:26 WizardofWestmarc: no but I only use GIT/github at all because clojure and several of it's useful libraries are on it :P

14:26 * WizardofWestmarc is still a Windows man.

14:26 LauJensen: Seriously? :D

14:27 rsynnott: WizardofWestmarc: is there any vcs particularly associated with windows?

14:27 (they got rid of sourcesafe, right? :) )

14:27 Chousuke: LauJensen: gist.el fails to consider clojure-mode in *scratch* though :(

14:27 LauJensen: even after I added it to the list of knonw modes

14:28 LauJensen: Chousuke: Really? I hadn't noticed

14:28 Chousuke: LauJensen: you don't get syntax highlighting if the file isn't named foo.clj :/

14:28 so I made a scratch.clj :P

14:28 LauJensen: Well, I usually just mark a region and then gist it

14:28 hehe

14:29 cark: LauJensen: i'm not sure we're talking about the same thing, a good example are the html libraries in CL ... they all are macros ... but I prefer having lists that i can tear appart and mix together at run-time instead of compile-time. html libs are easier to me in clojure for that reason

14:29 WizardofWestmarc: rsynnott I prefer mercurial

14:29 LauJensen: cark: I think we are. We use drivers for all our macros to force evaluation of all the items we need to evaluate.

14:29 WizardofWestmarc: it works on every platform easily

14:30 since it's python based.

14:30 LauJensen: WizardofWestmarc: But seriously.. Windows? :)

14:30 WizardofWestmarc: though to be fair the Github guys made a bridge between git and mercurial

14:30 Lau: a) dayjob, and b) I still game sometimes :P

14:30 and I despise apple so Mac isn't an option.

14:30 LauJensen: I have a Macbook which runs Linux perfectly well

14:30 WizardofWestmarc: though my current clojure project is on an ubuntu 9.04 server VM.

14:31 cark: LauJensen: well i'll look into it =) thanks for your time

14:31 LauJensen: np

14:31 WizardofWestmarc: again, despise apple so no macbooks ;-)

14:31 LauJensen: ok, sounds like a political thing

14:32 WizardofWestmarc: not exactly. I don't like microsoft either honestly, but Wine doesn't cut it for some stuff sadly.

14:33 and my day job is windows dev so it's hard to jump off the deep end and just go pure linux.

15:18 cddr: what's the clojure equivalent of CLOS's `call-next-method'?

15:21 hiredman: cddr: I don't think there is one, but you can use parent and get-method

15:22 ,(parent String)

15:22 clojurebot: java.lang.Exception: Unable to resolve symbol: parent in this context

15:22 hiredman: :/

15:22 ,(parents String)

15:22 clojurebot: #{java.lang.CharSequence java.lang.Object java.io.Serializable java.lang.Comparable}

15:23 hiredman: ,(get-method print-method Object)

15:23 clojurebot: #<core$fn__6175 clojure.core$fn__6175@199de59>

15:23 hiredman: ,((get-method print-method Object) "foo")

15:23 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$fn

15:23 hiredman: whoops

15:23 ,(doc print-method)

15:23 clojurebot: "; "

15:23 hiredman: clojurebot: worthless

15:23 clojurebot: Pardon?

15:25 cddr: hiredman: thanks, I think I get it ((get-method (first (parents obj))) obj)

15:26 hiredman: something like that

15:27 cemerick: cddr: there was a very interesting thread on the group talking about clos, call-next-method, and how to do similar things in clojure, which led to Rich adding get-method (which is a superset of java's super, call-next-method, etc). Can't find it now, of course.

15:29 cddr: yeah I was surprised a search of the groups archive didn't turn anything up

15:30 does it keep all the history?

15:30 cemerick: google groups search *sucks*. hard.

15:30 hiredman:

15:30 cemerick: you're actually better off querying on google.com with "site:groups.google.com clojure ....."

15:35 WizardofWestmarc: yeah, it's kinda funny how bad groups search sucks, when google's searching groups with the web engine is fine...

15:36 cemerick: well, not fine by any stretch, but not totally useless

15:38 LauJensen: ~brain-dump

15:38 clojurebot: brain dump is http://clj.thelastcitadel.com/clojurebot

15:59 LauJensen: ~forget clojureql

15:59 clojurebot: I forgot clojureql

15:59 LauJensen: ~clojureql is http://gitorious.org/clojureql

15:59 clojurebot: You don't have to tell me twice.

15:59 LauJensen: For those of you who use ClojureQL, we'd moved primarily development to Gitorious (and added a bugtracker). We will still update Github somewhat regularily

16:08 devinus: can anybody point me to a few good tutorials or free books for learning clojure? the clojure.org's few pages of introduction are too high-level for me

16:09 LauJensen: devinus: clojure.org is mostly for reference.

16:09 Google search for "clojure tutorial" yields about 44k results

16:10 djwhitt: devinus: this is a good tutorial: http://java.ociweb.com/mark/clojure/article.html

16:11 WizardofWestmarc: djwhitt's link is an excellent start

16:12 if you want a ton of useful clojure links I've got a ton that are clojure or clojure useful java stuff on my delicious feed once you get past that: http://delicious.com/wizardofwestmarch/clojure

16:13 this is a bit out of date now I believe, but also useful: http://www.youtube.com/view_play_list?p=AC43CFB134E85266

16:13 10 youtube videos about clojure

16:16 angerman: is there a (zip?

16:22 something like this: (defn zip [a b] (concat [(first a) (first b)] (if (or (= (rest a) '()) (= (rest b) '())) '() (zip (rest a) (rest b)))))

16:22 but that's quite ugly :/

16:23 Chousuke: hm

16:24 ,(map vector [1 2 3] [1 2 3]);?

16:24 clojurebot: ([1 1] [2 2] [3 3])

16:26 WizardofWestmarc: the one downside to map is if one list is longer and you want the rest of the longer list tacked on the end it won't do it.

16:32 angerman: ,(concat (map vector [1 2 3] [3 2 1]))

16:32 clojurebot: ([1 3] [2 2] [3 1])

16:32 angerman: ,(apply concat (map vector [1 2 3] [3 2 1]))

16:32 clojurebot: (1 3 2 2 3 1)

17:03 cemerick: this is worth watching out for, if you're passing values back to java:

17:03 ,(and nil)

17:03 clojurebot: nil

17:03 cemerick: ,(and false)

17:04 clojurebot: false

17:04 * cemerick has stopped thinking about concrete booleans for the most part

17:05 WizardofWestmarc: oh nice, (and nil false) gives nil back, but (and false nil) gives false back. Interesting.

17:05 wasn't sure if using them together would work that way or not.

17:07 cemerick: it short-circuits, and in that case, returns the first logically false value it encountered.

17:07 * cemerick is captain obvious

17:19 WizardofWestmarc: cemerick: right I understand it, but I wouldn't have thought of that.

17:19 good thing I rarely pass stuff to java ;-)

17:20 although at some point I'll probably try scala and mess with interop there.

18:02 fffej: I'm trying to write the "Man or Boy Test" in Clojure (just to try and understand trampoling) but it seems to be failing in bizarre ways, could someone take a look at http://clojure.pastebin.com/d25088b3 and point me in the right direction?

18:03 durka42: what are the bizarre ways?

18:04 fffej: one of the arguments (x4) becomes a function that doesn't return a number (it returns a function instead). I can't see how that can happen

18:05 Chousuke: I have no idea what's happening there.

18:05 :P

18:06 fffej: yeah, it's pretty convuluted!

18:06 durka42: is b supposed to return a function?

18:07 fffej: well, it's used with trampoline and I think that's what I'm supposed to do?

18:08 durka42: well, you return #(b)

18:08 but b in itself, from the letfn definition, returns a closure

18:08 fffej: yeah, that's the idea of the man or boy test I believe

18:09 dreish: #(b) == b more or less. Was that intentional?

18:10 durka42: so it works with values less than 4

18:10 dreish: Did you mean (fn [] b)?

18:10 fffej: durka42: yes

18:10 dreish: (fn [] b) is the same as #(b) isn't it?

18:10 dreish: No

18:10 Same as (fn [] (b))

18:11 ,'#(x)

18:11 clojurebot: (fn* [] (x))

18:12 fffej: so it's plugging into trampoline and my reading of the docs is I should wrap a closure over the tail call rather than a direct call of b. Isn't that what #(b) does?

18:14 hiredman: yes

18:14 dreish: Can't tell what you're trying to do, but in any case, you can just replace #(b) with b.

18:14 It's already a function.

18:15 fffej: I see what you mean - I should get rid of the # in the letfn and just have it on the tail call

18:16 dreish: That also seems like a good idea.

18:16 fffej: but then I get a stackoverflow, presumably because the body of b is evaluated in the letfn? (and it calls a)

18:17 dreish: #(b) is syntactically a little absurd, by itself.

18:17 fffej: yup, I see that now :)

18:17 hiredman: fffej: have you tried this yet without the trampoline?

18:17 dreish: It says, "Give me a function that is the same as calling b."

18:18 fffej: hiredman: yeah, stack trace with x=4, correct values for x=0,1,2

18:18 (stack overflow)

18:22 dreish: I think your expectations that Clojure will behave like ALGOL60 are a little ... off.

18:23 fffej: I was adapting a Common Lisp version

18:23 dreish: Where's that?

18:23 fffej: and the test is about recursion and closures, so it's not Algol 60 specific :)

18:23 http://rosettacode.org/wiki/Man_or_boy_test#Common_Lisp

18:25 dreish: "This creates a tree of B call frames that refer to each other and to the containing A call frames, each of which has its own copy of k that changes every time the associated B is called."

18:25 You don't have anything mutable, so right away it can't be right.

18:26 fffej: hiredman: yup - it overflows the stack

18:26 dreish: so k should be an atom right?

18:27 dreish: Maybe.

18:27 fffej: ok, I got it now

18:29 well, by got it I mean I have something that doesn't crash; now it just produces the wrong results :) Thanks for pointing me in the right direction!

18:40 duck11231: What's the best way to pass the name of a function, execute that function, then modify the name of the function (to refer to a different function) and then execute that one? If I pass the function un-quoted, I can't get the ns and name of the original location, and if I quote it, it's not respecting the alias in place when it was declared

18:40 I tried using keywords and converting them, but that resulted in a mess

18:40 hiredman: :(

18:41 that sounds pretty horrible

18:41 duck11231: basically, in a different namespace, I wanted to be able to do (show-html (show args))

18:41 hiredman: clear as mud

18:42 Chousuke: you could use resolve

18:42 hiredman: ,(resolve (symbol "+"))

18:42 clojurebot: #'clojure.core/+

18:42 Chousuke: ,((resolve '-) 1 2)

18:42 clojurebot: -1

18:42 hiredman: ,((resolve (symbol "+")) 1 2)

18:42 clojurebot: 3

18:45 duck11231: I was trying to use ns-resolve, because the function wasn't refered to in the executing ns, but was having problems. I was trying to be able to return something like {:action :view/show, :format :html, :args [7]} and turn that into (unaliased.ns.for.view/show-html (unaliased.ns.for.view/show 7))

18:46 but maybe I need to take a different approach

18:49 hiredman: ,((ns-resolve (create-ns 'clojure.core) (symbol "+")) 1 2)

18:49 clojurebot: 3

18:50 duck11231: hiredman: thanks, I should try using create-ns

18:51 hiredman: ,(doc create-ns)

18:51 clojurebot: "([sym]); Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name."

18:53 hiredman: I would take a moment to think about alternatives

18:54 symbol → string → string transformation → resolution to var → function call seems like a bad idea

18:55 duck11231: I agree, it sounded like a good idea when I first though of it, until I looked at what was actually involved

19:12 the end result turned out to be not that ugly, but it still seems like it's overly "clever"

19:48 alrex021: I am finding it very difficult to follow the Stack traces in Clojure, am I missing something or is there a better way to view more informative exception stack trace in clojure?

19:51 Chousuke: alrex021: I think contrib has some functions that can clean up the stack trace a bit.

19:53 alrex021: Chousuke: I see, there is a trace lib in contrib

20:35 I'm looking at the clojure.contrib online docs and I can't seem to require or use clojure.contrib.stacktrace.. Are the docs old and lib is not there or am I missing something?

20:40 I see it seems to have been moved to clojure as this now works (use 'clojure.stacktrace)

20:41 rhickey: current docs: http://richhickey.github.com/clojure-contrib/

20:43 alrex021: rhickey: thanks, I got it bookmarked now

21:11 cemerick: rhickey: do you have any ideas off the top of your head on how to exercise arbitrary code, so as to prime the JIT? We have some UI code that is plenty fast after about 15 seconds worth of use, but it's dang slow (at least w.r.t. user-perceptible responsiveness) before then.

21:12 Non-UI code is easy to optimize (just run some sample data through it in the background at app startup), but I don't see any obvious corollary for UI code.

21:13 hrm, maybe record gestures with the Robot, serialize them, and use that as sample data on an off-screen UI component...

21:16 hiredman: :(

Logging service provided by n01se.net