#clojure log - May 06 2010

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

0:32 vIkSiT: hmm. slyphon, MadWombat - is there an equivalent of re-sub that will replace not just the first match?

0:33 slyphon: re-gsub

0:33 vIkSiT: ah

0:33 ,doc re-gsub

0:33 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/doc

0:33 vIkSiT: ,(doc re-gsub)

0:33 clojurebot: "clojure.contrib.str-utils/re-gsub;[[regex replacement string]]; Replaces all instances of 'pattern' in 'string' with 'replacement'. Like Ruby's 'String#gsub'. If (ifn? replacment) is true, the replacement is called with the match. "

0:33 vIkSiT: thx slyphon

0:33 slyphon: sure

0:33 :)

0:39 _brian2_: noob question> how true is this from stuart's book : " (exception handling )... simply is not required." ?

0:40 Like a url fetch , which crashes

0:52 Blackfoot: are there characters not allowed in (comment) forms? i'm using 1.1.0 and getting Invalid token errors in a long (comment) form

0:52 slyphon: Blackfoot: (comment) must be readable

0:53 by the compiler

0:53 not true for ;; comments

0:53 Blackfoot: ah interesting

0:53 ok, thanks

0:53 slyphon: sure

0:54 hiredman: comment is a macro

0:55 and things inside (comment ...) must be readable by the *reader*

0:55 ,(doc comment)

0:55 clojurebot: "([& body]); Ignores body, yields nil"

0:55 Blackfoot: ah i see. i thought it would just evaluate anything, haven't had much experience with the read

0:55 er

0:55 just NOT evaluate

0:56 makes sense, though, and i'll just use ;

1:18 alexyk: are things supposed to be faster when ran stand-alone vs. from repl?

1:19 chouser: nah

1:20 alexyk: good

1:21 MadWombat: seems like compojure 0.4.0 is acutally nothing more than some macros to make ring routes

1:33 defn: nothin wrong with that really

1:36 replaca: if there's less, maybe they can take the time to write some decent documentation

1:46 defn: that'd be nice

1:52 who was talkin about cupboard?

2:09 LauJensen: Morning all! :)

2:10 mabes__: need to go to bed.. it is midnight here. :)

2:19 maravillas: and a good middle of the night to you, LauJensen

2:19 LauJensen: thanks :)

2:29 slyrus: evening

2:30 i don't suppose anyone ever fixed the slime/swank-clojure problem that cropped up back in october?

2:36 tomoj: what problem was that

2:37 edge slime?

2:39 slyrus: slime changed the way it was passing some symbols around and now (then?) tries to evaluate something that isn't a valid clojure symbol

3:04 LauJensen: Raynes: You there?

5:12 * cschreiner lein lein lein, only trouble

5:14 defn: cschreiner: ?

5:15 also could someone explain a situation where you'd use nil?

5:15 err (comment)

5:15 cschreiner: defn: I get this: [INFO] Repository 'clojars' will be blacklisted when lein deps

5:16 defn: weird

5:16 what version of lein

5:16 cschreiner: 1.1.0

5:16 maybe an upgrade is due

5:16 defn: im still running 1.1.0

5:16 no issues

5:17 cschreiner: maybe my project.clj contains some odd pieces

5:17 defn: gist it and ill look if you like

5:19 cschreiner: defn: http://gist.github.com/391956

5:20 defn: first off, cool project

5:20 :)

5:20 cschreiner: well, it could be cool, if I finish it

5:20 ;-)

5:20 defn: does clojure "1.2.0

5:21 cschreiner: I guess I need some snapshot adding

5:21 defn: "1.2.0" work? I've been using 1.2.0-SNAPSHOT for clojure

5:21 and master-SNAPSHOT for clojure-contrib

5:21 sorry reverse those

5:21 1.2.0-master-SNAPSHOT for clojure, 1.2.0-SNAPSHOT for contrib

5:22 cschreiner: how about swank?

5:22 defn: lein-swank is right

5:22 swank-clojure is 1.2.0-SNAPSHOT

5:22 cschreiner: ah

5:22 cool

5:22 defn: lemme know if that helps

5:23 cschreiner: I will

5:23 fails with 1.2.0-master-SNAPSHOT on clojure

5:24 same with contrib

5:24 seems like lein just times out on those entries

5:25 _ato: strange

5:25 defn: are you behind a proxy or something?

5:25 maybe at work?

5:25 _ato: build.clojure.org is up

5:25 defn: yeah i just pulled from it

5:25 cschreiner: no proxy, but I'll try sudo again

5:25 LauJensen: cschreiner: http://www.mail-archive.com/clojure@googlegroups.com/msg22248.html

5:25 sexpbot: "Re: Renaming 1.1.0-alpha-SNAPSHOT is causing problems with projects on"

5:26 cschreiner: LauJensen: interesting...

5:26 defn: cschreiner: another thing to do just to be sure is to lein clean

5:26 cschreiner: defn: always does this

5:26 defn: you might also consider blowing away ~/.m2

5:26 cschreiner: defn: yeah, I have considered reinstalling lein

5:27 * cschreiner reading

5:28 cschreiner: LauJensen: Those error msg's are the same I get, but I'm not behind a proxy

5:28 weird

5:28 defn: cschreiner: not that you know of...

5:28 :)

5:28 LauJensen: cschreiner: They were caused by the rename, are you sure "1.2.0" is up as an artifact?

5:29 defn: LauJensen: he changed to mast-SNAPSHOT and no dice

5:29 LauJensen: oh

5:29 cschreiner: the thing is, my lib is properly populated now, but still having those error messages

5:29 LauJensen: cschreiner: rm ~/.m2 && lein self-install

5:29 cschreiner: defn: yeah, not that I know of, hehe

5:30 LauJensen: yeah, it's time for that now!

5:30 LauJensen: sometime .m2 is all thats standing between me and the bleeding edge

5:30 defn: yeah, happens often

5:30 * cschreiner die .m2!!!

5:30 defn: i wish there was a way with lein to say in project.clj "this is bleeding edge, keep pulling and replacing no matter what"

5:31 LauJensen: hehe, /me doesnt make any sense in that sentence :)

5:31 defn: shouldn't be hard to make, its easy with Gradle/Clojuresque

5:31 _ato: http://old.nabble.com/Repository-Blacklist-td15234875.html

5:31 sexpbot: "Old Nabble - Maven - Users - Repository Blacklist"

5:31 _ato: "It doesn't remember the blacklist. It does remember individual plugin download failures by virtue of writing incomplete metadata files into the local repo"

5:32 defn: bingo

5:32 _ato: so clearing ~/.m2 should fix it

5:32 stupid maven

5:32 defn: :)

5:32 _ato: any sane person downloads under a different name and atomically moves to the final name

5:32 ;-)

5:32 LauJensen: we're mostly an insane crowd

5:33 * defn doesn't have time for that kind of management

5:33 defn: 5/7 things im using in one of my projects are getting updated daily

5:33 _ato: so it could have gotten a failed download when build.clojure.org was down the other day

5:34 defn: yeah

5:34 _ato: ah yeah... by person I meant programmer (so maven should be doing that, not you doing it manually)

5:35 cschreiner: lein still use a looong time checking for updates from central, didn't do that earlier, still gives me blacklist messages, and populates the lib properly...

5:36 horseshit

5:36 LauJensen: What good would that do ?

5:37 _ato: lousy

5:37 cschreiner: something is good though, lein swank works now, for the first time in a couple of weesk

5:37 thanks for the .m2 removal hint

5:38 guess I just have to trust the system, even if I don't understand it

5:38 LauJensen: cschreiner: You could try Clojuresque instead, see if that works

5:38 defn: you /could/ understand it. there's github ;)

5:39 cschreiner: defn: need more hours for that

5:39 well, lein swank saved the day

5:39 now I can get rid of the swank-clojure-project habbit

5:40 (or whatever it's called)

5:41 defn: a habbit is what nuns wear

5:41 cschreiner: so, I am a nun?

5:41 defn: heh, i take that back

5:42 i guess it's habit

5:42 _mst: and they wear them habitually!

5:42 defn: indeed!

5:42 cschreiner: or hobbit?

5:42 ah, the polling for ever

5:42 defn: your curiosity is reminiscent of mr. baggins

5:43 cschreiner: when lein swank, it is correct to use slime-connect ?

5:44 _ato: yes

5:44 cschreiner: I get a message about: "Versions differ: 20091016 (slime) vs. nil (swank). Continue?"

5:45 when Yes, it polls forever, needs some updates I guess

5:45 not true; when Yes, I get a Java Exception about an unmatched delimiter: )

5:46 _ato: sounds like you're not having a great day. :/

5:46 are you using swank-clojure 1.1.0 in emacs?

5:47 defn: don't use swank-clojure anymore

5:47 it mangles the classpath and stuff

5:47 cschreiner: _ato: 1.2

5:47 _ato: defn: swank-clojure is the slime adapter, you need to use it

5:48 to use slime with clojure

5:48 cschreiner: defn: so I should just remove the dev-dep on swank-clojure "1.2.0-SNAPSHOT"??

5:48 _ato: maybe you mean M-x swank-clojure-project

5:48 cschreiner: nah

5:48 _ato: cschreiner: I mean swank-clojure.el -- the emacs part

5:49 cschreiner: _ato: okay, I'll remove that from my init.el

5:49 _ato: no don't remove it

5:49 just check the version

5:49 (it's listed in the comment at the top of swank-clojure.el)

5:50 or if you installed via ELPA M-x package-list-packages should tell you what version you have

5:50 cschreiner: _ato: 1.1.0

5:50 _ato: weird

5:50 I have 1.1.0 .el talking to the 1.2.0 snapshot jar fine

5:51 hmm

5:51 LauJensen: same here

5:52 cschreiner: restarting emacs does wonders :)

5:52 LauJensen: ?

5:53 restarting emacs??

5:53 cschreiner: it's okay now

5:53 _ato: ah, cool

5:53 cschreiner: LauJensen: Yeah, waht?

5:54 very cool, thanks a bunch

5:58 nurv: Morning.

6:06 cschreiner: morning

6:12 defn: yay for clojure!

6:12 cschreiner: ~max

6:12 clojurebot: maxine is http://research.sun.com/projects/maxine/

7:06 spariev: what key-val stores do you guys use with Clojure ?

7:07 I need to store byte arrays with string keys, a lot of them

7:07 tried mongodb, it uses too much memory IMO, thinking Berkeley DB JE now

7:07 AWizzArd: spariev: how much ram do you have available?

7:08 spariev: I'd like to fit in 2Gb

7:09 MongoDb uses memory mapping, and it ate about 6-7Gb with my workload

7:11 AWizzArd: spariev: you want the db to consume 2gb, but the data you will insert is more like +/- 5gb?

7:11 GeoffSK: newbie - why does this fail to print - (map println '(1 2))

7:11 AWizzArd: ,(map println '(1 2))

7:11 clojurebot: (nil nil)

7:11 AWizzArd: didn't fail

7:12 GeoffSK: ..when its in a one line file

7:12 AWizzArd: ,(let [x (println "hello")] x)

7:12 clojurebot: hello

7:12 AWizzArd: ok, the clojurebot does not show the return value here

7:12 but: println returns nil

7:13 spariev: AWizzArd: yep, but data does not have to be in memory

7:13 GeoffSK: it works at the REPL, but not in a file..what am i missing?

7:13 AWizzArd: GeoffSK: in what way does it fail?

7:13 What is the error message

7:13 spariev: yes, I understood, just wanted to have more details

7:13 GeoffSK: no printed output

7:13 AWizzArd: GeoffSK: and how did you run this file?

7:14 GeoffSK: rlwrap java -cp /home/geoffrey/projects/clojure/clojure.jar:/home/geoffrey/projects/clojure/clojure-contrib.jar test.clj

7:15 oops that was the wrong line..i have clojure.main in there to.

7:15 AWizzArd: hmm, I would more expect a "class not found" exception

7:15 could you show that one please?

7:16 GeoffSK: rlwrap java -cp /home/geoffrey/projects/clojure/clojure.jar:/home/geoffrey/projects/clojure/clojure-contrib.jar clojure.main test.clj

7:16 hoeck: GeoffSK: (map println '(1 2)) is a lazy sequence, just loading the file will not cause the sequence to be evaluated

7:16 AWizzArd: yes, that is expected to output nothing

7:16 shifty3: spariev: bdb should work for that, I have used it to store much more data than that. you can tune the in-memory buffer size to cap its memory usage

7:16 GeoffSK: i wondered about it being lazy. printing doesn't force eval?

7:16 AWizzArd: print yes

7:17 hoeck: GeoffSK: on the repl it works, because it is eager to evaluate the result of that (map println ...), so you see 1nil or so

7:17 GeoffSK: but you are not printing the result

7:17 AWizzArd: exactly

7:17 zmila: ,(- 999999999999999999 (bit-shift-left 999999999999999999 0))

7:17 clojurebot: java.lang.ExceptionInInitializerError

7:17 AWizzArd: GeoffSK: put a second line (println "hi") into the file

7:17 zmila: pff

7:17 spariev: shifty3: thanks, I'll try. Did you use any Clojure APIs for bdb ?

7:18 hoeck: GeoffSK: you are printing each element at each step of the lazy-seq evaluation

7:18 GeoffSK: the "hi" is printed nothing else

7:18 shifty3: no, didn't use it with clojure, actually, just java

7:18 AWizzArd: GeoffSK: good, then your Clojure installation is working correctly :)

7:18 hoeck: GeoffSK: (doall (map println '(1 2))) will force the lazy-seq

7:18 or (println (map ...)) will print it additionally

7:18 AWizzArd: or (count (map ..))

7:19 GeoffSK: as u expected it prints. but i dont understand

7:19 spariev: shifty3: oh, ok. just having difficulties with cupboard dbd api, looking for alternatives

7:19 shifty3: bdb also has jmx mbeans that allow you to change the buffer size while the program is running (using jconsole or visualvm). can be a lifesaver in long-running processes ;)

7:20 spariev: bdb looks much more mature than stuff like mongo and tokyo cabinet

7:21 GeoffSK: hoeck: is it because the (map ) is never evaluated and thus nor is the print?

7:21 hoeck: GeoffSK: exactly

7:21 GeoffSK: nicely functional. Thanks AWizzArd, hoeck

7:22 shifty3: yes, it is pretty stable. you may have to tune the default parameters, though. depending on your workload, the log cleaner may have trouble keeping up

7:26 AWizzArd: GeoffSK: technically speaking the map is evaluated, but the object that it returns isn't.

7:26 cemerick: replaca: that set pprint issue was resolved with a full cleanse of the snapshots

7:27 GeoffSK: AWizzArd: that makes sense.

7:42 * defn finds it very annoying when library maintainers use flatten

7:43 defn: not the c.contrib version, but their own

9:52 replaca: cemerick: makes sense. I wasn't able to reproduce it here

9:53 cemerick: yeah, sorry for the goose chase

9:53 replaca: cemerick: no worries, I only spent about 5 minutes :-)

10:22 lpetit: is my idea (posted on the ml) of getting rid of refer-clojure flawed ?

10:22 rhickey: ^^

10:22 chouser: lpetit: I failed to find the thread where refer-clojure was originally proposed

10:23 rhickey: lpetit: all proposals to change Clojure are best left to post 1.2

10:23 chouser: I seem to recall that idea coming up. If it did, it'd be interesting to see why it wasn't chosen.

10:24 lpetit: rhickey: ok, but that could be made backward compatible, that's why I talked about it before feature freeze

10:24 chouser: sure

10:25 stuartsierra: Does anyone have a link to rhickey's "or-nil" function?

10:26 rhickey: http://groups.google.com/group/clojure/msg/f251cfd9baab440a

10:26 stuartsierra: rhickey: thanks

10:27 rhickey: that never made ii into contrib eh?

10:30 stuartsierra: rhickey: dunno, I'd forgotten the name

10:30 lpetit: stuartsierra: implement your protocol on nil :-p

10:31 stuartsierra: I actually wanted something simpler: (defn or-nil [pred value] (or (nil? x) (pred value))

10:31 I mean (defn or-nil [f x] (or (nil? x) (f x))

10:31 clojurebot: executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master

10:34 lpetit: stuartsierra: that's -?> , no ?

10:34 chouser: well, here's the conversation that led to :refer-clojure http://clojure-log.n01se.net/date/2008-09-03.html#10:56

10:34 sexpbot: "#clojure log - Sep 03 2008"

10:37 lpetit: chouser: so I don't see a strong point against my proposed simplification, or did I overlook smth ?

10:37 chouser: no, I don't see it either

10:38 stuartsierra: lpetit: I guess -?> would have the same effect

10:40 lpetit: stuartsierra: (or-nil f x) vs (-?> x f) :)

10:41 stuartsierra: lpetit: I prefer or-nil in this particular case (argument checking)

10:41 chouser: lpetit: ah, here it's actually suggested here, but nobody on this thread seems to take it up (pro or con): http://groups.google.com/group/clojure/browse_thread/thread/1c5cddb04a2e6c1d/d1f3c2a842896b6e?#d1f3c2a842896b6e

10:46 lpetit: chouser: I don't understand everything, that would take more time I can devote to. I am unable to see whether what I proposed is in contradiction with one of the points raised in this ^^^ thread :-(

10:56 stuartsierra: Where do :pre/:post go in a multiple-arity function?

10:57 never mind, found it on http://clojure.org/special_forms

10:59 * dnolen is amazed that pre/post conditions can be turned off by binding *assert* to false

11:07 Raynes: LauJensen: ohai

11:07 LauJensen: hey

11:07 Raynes: I'm 8 hours late, but I'm here.

11:07 $mail

11:09 LauJensen: I couldn't do it exactly that way, but I could just include ping with sexpbot or something.

11:09 The problem is cross-platformness.

11:10 LauJensen: oh

11:10 You described a security issue that sounded specific to *nix

11:10 jfields: is there a better way to do this? (swap! an-atom-with-a-map #(merge-with + a-map %))

11:11 Raynes: It is *nix specific, but it doesn't work on Windows regardless. On windows, it always falls back to opening port 7.

11:11 But shelling out would kill it completely.

11:11 $ping localhost

11:11 sexpbot: Raynes: Ping completed in 0 seconds.

11:11 Raynes: It at least works for some things. :p

11:12 nurv: Hi.

11:12 Raynes: Hello.

11:13 chouser: jfields: I can't think of anything substantially better.

11:13 jfields: chouser: thanks.

11:14 I'm getting by with what I know, but the occasional tip on idiomatic syntax has been very helpful :)

11:15 chouser: jfields: many uses of swap! don't require #() like that because many collection functions take the collection first.

11:16 (swap! an-atom merge a-map)

11:16 jfields: chouser: yep, I've been doing that for sure. I just wanted to make sure I knew the idiomatic way when the first arg isn't a coll.

11:16 chouser: but since merge-with takes another function first, this convenient simplicity breaks down and you have to do something to get the args in the right order. #() or partial

11:18 (swap! an-atom (partial merge-with + a-map)) should work, but isn't necessarily better than what you have.

11:22 Raynes: LauJensen: $ping actually works for a lot of sites, it appears.

11:27 dnolen: matchure + pre/post is pretty slick.

11:36 gilescb: hi all, newbie question: is there a way to supply the args to a function when I have the args as a list but the function requires varargs; eg. Python's *args?

11:36 puredanger: in our drunken wanderings around the clojure design space we have hit on this pattern of using s-expressions as the data structure and creating macros that evaluate an s-expression to itself so that you don't have to worry about eager/delayed evaluation

11:36 my belief is that this is surely a well-explored pattern in clojure/lisp world

11:37 and there are probably explored pros/cons to it

11:37 please point me in the direction of that information, oh great interwebs of clojure love

11:37 Raynes: $(apply + [1 2 3 4 5])

11:37 sexpbot: result: 15

11:37 gilescb: they've failed me for about the last hour and a half :(

11:37 Raynes: gilescb: ^

11:38 dnolen: ,(str "a" "b" "c")

11:38 clojurebot: "abc"

11:38 dnolen: ,(apply str ["a" "b" "c"])

11:38 clojurebot: "abc"

11:38 Raynes: dnolen: I win. You're late. ;)

11:38 gilescb: ah... many thanks

11:39 dnolen: Raynes: an extra example never hurt anyone ;)

11:39 Raynes: ;p

11:39 chouser: puredanger: I'm not quite sure what you mean, but it sounds interesting.

11:39 puredanger: I hope you don't actually mean calling eval inside a defmacro

11:39 puredanger: so to give a specific use case, we (by which I mean people sitting in the same room as me) are building a performance testing framework in clj

11:39 Raynes: gilescb: Anyway, apply applies the function to everything in the sequence as if they were individual arguments. It's magics.

11:39 puredanger: (no not eval)

11:40 we could build a representation of a test definition as a data structure, say with vectors

11:40 or records, etc

11:40 and then write code to read that data structure, persist it to a db, evaluate it, etc

11:40 OR we could just say that an s-expr IS the data structure

11:41 but then you have to worry about it being evaluated at the point of definition

11:41 so we are using a macro like: (defmacro test-def

11:41 "Expand into a list which is itself"

11:41 [label fixture fixture-map & test-points]

11:41 `(list 'test-def ~label '~fixture ~fixture-map ~@(map test-point-as-list test-points)))

11:42 and a test like: (test-def "demo-test" sample-fixture {:x 2}

11:42 (sample-test-fcn {:x 1 :y 2 :z 3})

11:42 (throw (RuntimeException.))

11:42 (sample-test-fcn {:x 10 :y 20 :z 30}))

11:43 chouser: puredanger: well, I'm no lisp veteran, but that seems like a perfectly natural thing to do.

11:43 puredanger: we then have functions that know how to take an s-expr in this form and import, persist, evaluate it, etc

11:43 chouser: It's only a slight specilization of syntax-quote itself, in a way.

11:44 puredanger: yeah

11:44 surely there is prior art on this as an idea though, right????

11:46 chouser: btw, nice article in infoq http://www.infoq.com/articles/in-depth-look-clojure-collections

11:46 sexpbot: "InfoQ: An In-Depth Look at Clojure Collections"

11:47 chouser: puredanger: thanks!

11:47 fogus thanks you too. :-)

11:47 puredanger: yes, him too

11:48 fogus: puredanger: Indeed. Thank you

12:01 bsteuber: is there some default directory java applications should use to store their data?

12:01 AWizzArd: bsteuber: no.

12:02 bsteuber: best thing to use are command line args or environment vars or data coming from a config file.

12:02 bsteuber: yeah, but then I have to decide where to store my config file :)

12:02 so same problem

12:03 AWizzArd: bsteuber: (System/getProperty "user.home")

12:04 bsteuber: hm, but e.g. on windows I guess it's expected to use "Application Data"?

12:04 AWizzArd: Your application must have requirements. It can ask the user to provide command line args, set env vars or put something into his home.

12:05 bsteuber: on my Windows: "C:\\Dokumente und Einstellungen\\bsteuber"

12:05 * fogus thought everything on Windows went into the registry

12:06 AWizzArd: fogus: that would be another option, yes

12:06 bsteuber: I'm just looking for a reasonable default per OS that users don't complain about

12:06 AWizzArd: The installer with which bsteuber ships his app can setup the right entries in the Registry.

12:07 bsteuber: home then. And the manual can reflect this.

12:07 bsteuber: but maybe user.home/.my-app is not that bad for a start

12:07 AWizzArd: And you can offer a command line arg/env var which can override this

12:07 bsteuber: ok, thx

12:29 tufflax: What does the number 1M mean in Clojure?

12:29 stuartsierra: (type 1M)

12:29 ,(type 1M)

12:29 clojurebot: java.math.BigDecimal

12:29 tufflax: ah ok, thanks

12:38 slyphon: so, i ran into an interesting problem trying out 1.2 last night, i have a piece of code that does (bindings [c.c.sql.internal/transaction* (fn [f] (f))] ...) and under that doesn't "stick"

12:39 "under 1.2"

12:40 chouser: hm. I can't think of a reason why it shouldn't...

12:40 slyphon: yeah, it's very confusing

12:41 the sql.clj code doesn't see the binding i established

12:53 stuartsierra: Does the &env special argument make any guarantees about the order of its keys?

12:54 LauJensen: $ping www.bestinclass.dk

12:54 sexpbot: LauJensen: Ping completed in 0 seconds.

12:54 stuartsierra: E.g., will (keys &env) return locals in the order in which they were bound?

13:00 chouser: stuartsierra: no, pretty sure not.

13:01 stuartsierra: ok

13:01 chouser: stuartsierra: the current implementation probably calls 'assoc' in order, so as long as it's short it probably is an arraymap in the expected order, but as soon as it is long enough to become a hash-map the order would no longer be useful.

13:01 stuartsierra: right

13:01 so, in other words, an implementation detail that I cannot depend on

13:01 chouser: right

13:05 fogus: OH on the Intertweets: Q: "What's hot in Groovy these days?" A: "Clojure"

13:05 chouser: heh. nice.

13:06 slyphon: hah!

13:06 ataggart: lol

13:07 slyphon: whole buncha languages came along and just ate Groovy's lunch

13:16 mabes: slyphon, fogus: yeah, I remember seeing a quote from groovy's creator saying that he would have not created it if something like scala existed at the time

13:16 slyphon: yeah

13:16 i saw that too

13:16 fogus: mabes: That speaks volumes

13:17 chouser: groovy's still more dynamic than scala, isn't it?

13:17 slyphon: yeah, it's just not that "cool"

13:17 mabes: it is slower though

13:17 slyphon: compared to JRuby even, i mean, why would you mess w/ it?

13:18 LauJensen: chouser: define 'more' ?

13:18 mabes: yeah, I wonder if he would have created it if jruby was mature back then.. my guess is not

13:18 headius: groovy was originally intended to be a ruby-like language on the jvm

13:18 LauJensen: mabes: I think it was the maker of Groovy who said, that had Scala existed he wouldn't have bothered

13:18 headius: it's been altered drastically since then

13:19 mabes: LauJensen: heh, yeah, just said that :)

13:19 LauJensen: haha

13:19 mabes: headius: are does it compare speedwise with JRuby these days?

13:19 LauJensen: right you are, sorry

13:19 mabes: er.. s/are/how/

13:27 fogus: LauJensen: Scala's pretty good at dynamic

13:27 LauJensen: fogus: Yea, my understanding was that Groovy was up to par

13:28 fogus: LauJensen: I know next to nothing about Groovy unfortunately

13:28 slyphon: fogus: eh? it's a statically typed language through and through?

13:29 LauJensen: fogus: its great for build scripts :)

13:29 fogus: slyphon: I guess I should caveat that buy saying, Scala's pretty good at appearing dynamic, in certain ways

13:29 slyphon: hah, agreed

13:29 fogus: s/buy/by

13:29 Raynes: He said he "probably" never would have bothered creating Groovy.

13:29 probably

13:30 And that is what Groovyists hang their hat on. :p

13:30 slyphon: hahaha

13:30 LauJensen: Thats funny

13:30 Didn't Martin Odersky say that he wouldn't have invented Scala if C++ had been on the JVM already?

13:31 (j/k)

13:31 * slyphon tries to wrap his mind around the absurdity of that thought

13:31 Licenser: da da da

13:33 thearthur: how do i write the type of an array of bytes in a defmethod?

13:34 that dispatches on type

13:35 jfields: what's the name of the ->> operator?

13:35 slyphon: double arrow?

13:35 chouser: thearthur: I'd recommend (class (byte-array []))

13:35 LauJensen: jfields: often referred to as the threading operator

13:35 and -> is thrush I think

13:35 jfields: isn't -> the threading?

13:35 ah, ok, thanks.

13:35 slyphon: LauJensen: ah, yeah that sounds right

13:36 kwertii: Has anyone done (or looked into doing) an Eclipse Rich Client Platform app in Clojure? Googled, nothing obvious.

13:36 LauJensen: hmm

13:36 chouser: -> is threading, ->> is piping. But I don't really like those names.

13:36 LauJensen: No wait, I think its the other way around

13:36 fogus: I like arrows

13:36 LauJensen: $google thrush in clojure

13:36 sexpbot: First out of 141 results is: Ruminations of a Programmer: Thrush in Clojure

13:36 http://debasishg.blogspot.com/2010/04/thrush-in-clojure.html

13:36 Raynes: I like arrows.

13:36 LauJensen: Go check that out :)

13:36 Raynes: ->>>>>>>>> <-- We need this.

13:37 wlangstroth: "threading" is an unusual term in a language focused on concurrency

13:37 slyphon: hahahaha

13:37 chouser: wlangstroth: yeah, unfortunate

13:37 LauJensen: Something I often need, is a threading operator which creates anonymous functions and deferences their results (which are objects) and then finally constructs the return, its calld -@#()>.

13:37 wlangstroth: LauJensen: hahaha!

13:37 slyphon: "threading" makes snese in a lexical context though

13:37 hahaha

13:38 wlangstroth: doesn't -> chain functions?

13:38 cgrand: Laujensen, the name for -@#()> is" brochette"

13:38 fogus: I don't like threading as a name. It implies a connection to Thread

13:39 I'd rather say the stich operator, or arrows

13:39 LauJensen: cgrand: oh yea, its already in contrib I see :)

13:39 slyphon: fogus: eh, i always thought of it as "needle and.."

13:39 wlangstroth: (it /looks/ like it does)

13:39 slyphon: for hash key lookup you're supposed to put the keyword first?

13:39 (:key map) ?

13:39 * slyphon has a feeling he's had this backwards for a month or two

13:40 cgrand: kwertii: I think lpetit or Gaetan Morice may have tried Eclipse RCP+Clojure

13:41 LauJensen: slyphon: There was mixed oppinion about that on the ML, but you can do both ofc

13:41 headius: mabes: jruby should be faster for ruby code or I'll eat my hat...groovy is probably still faster for calling java from groovy because we have to wrap incoming objects in an IRubyObject wrapper

13:41 slyphon: hm, yeah i read the style guide, and i was a little confused as to why a distinction was made

13:41 headius: I mean jruby running ruby code should be faster than groovy running groovy code

13:42 largely because we don't have multimethod dispatch in ruby

13:42 SynrG: headius: did i mention that little issue with jline is solved by a patch provided by the debian maintainer? and in any event, i find rlwrap is nicer :)

13:42 slyphon: headius: *sigh*

13:42 headius: SynrG: oh really? since I'm supposedle jline admin I should probably know that

13:42 kwertii: cgrand: Thanks, I'll look for them

13:43 SynrG: headius: i *hope* he sent it upstream ...

13:43 headius: I don't think I saw it on jline ML, but maybe in issues

13:43 SynrG: shame on him if he didn't

13:43 headius: somehow I got added as an admin on that project

13:43 SynrG: or maybe he was waiting for me for feedback that it works?

13:43 hmm

13:44 or maybe peter isn't one of the maintainers ...

13:44 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=576814

13:44 sexpbot: "#576814 - libjline-java: left-arrow, up-arrow adds null to retrieved history line - Debian Bug report logs"

13:49 LauJensen: slyphon: I think some people felt that (fn :word) was safer than (:word fn) IIRC

13:50 slyphon: interesting

13:52 LauJensen: $google clojure group coding standards

13:52 sexpbot: First out of 1350 results is: clojure.lib coding standards: initial draft brain dump - Clojure ...

13:52 http://groups.google.com/group/clojure-dev/browse_thread/thread/d090b5599909497c

13:54 LauJensen: Great work sexpbot, slyphon check out Chas Emericks first reply

13:54 slyphon: ah, willdo

14:00 jfields: is there a function that will return {:a 1} from {:a 1 :b 2}?

14:01 ipostelnik: jfields, select-keys

14:01 slyphon: select-keys

14:01 jfields: ipostelnik, slyphon: thanks

14:01 * slyphon looks at this async code and keeps thinking o/` A is for Agent, that's good enough for me o/`

14:01 dermatthias: I want to use the (normal mu sigma) function from contrib.probabilities.monte-carlo, but I have no idea what to do with the result of, for example, (normal 0 1). As far as i can tell, it's a function and has something to do with monads....but that's where I get lost....

14:01 slyphon: (anyone not familiar with Sesame Street will not get that, but what the heck...)

14:04 dermatthias: yeah, weird

14:10 * slyphon reads through http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/ and decides to lie down for a little while

14:15 dermatthias: :)

14:15 SynrG: slyphon: good article, but yes, taxing :)

14:15 dermatthias: self-made solution: (defn normal [mu sigma]

14:15 (let [r (Random.)]

14:15 (+ mu (* sigma (.nextGaussian r)))))

14:29 Moominpapa: This may sound like a stupid question (possibly because it is) but how do you run the tests for circumspec?

14:30 lein test definitely doesn't work. Running it in the repl gets the wrong version of clojure.

14:31 technomancy: Moominpapa: the repl task works in lein 1.2 (dev build); could try that.

14:31 Moominpapa: Thanks, I will.

15:02 DeusExPikachu: w00t! figured out custom classloading

15:11 ataggart: DeusExPikachu: Don't forget to account for permgen space

15:14 wlangstroth: DeusExPikachu: what did you end up doing?

15:18 arkahn: Are there any queue-like data structures besides clojure.lang.PersistentQueue and seque? I'm looking for a FIFO

15:19 chouser: PersistentQueue is FIFO

15:19 hiredman: those are called "stacks"

15:19 arkahn: hiredman: ; ) yes

15:19 chouser: stacks are FILO

15:19 hiredman: right

15:19 <-- reversed

15:19 chouser: :-)

15:19 arkahn: chouser: do you know why PersistentQueue isn't more 'public'?

15:20 hiredman: ,(first (conj '() 1 2))

15:20 clojurebot: 2

15:20 hiredman: ,(first (conj clojure.lang.PersistentQueue/EMPTY 1 2))

15:20 clojurebot: 1

15:35 dakrone: when extending a protocol with a record, is there a way to mark some of the methods "private" so nothing other than the record can call them?

15:51 fogus_: Whoops... clojure.lang.PersistentQueue/EMPTY no longer prints as () in v1.2

15:51 That is, PersistentQueues no longer print with parens

15:52 Intentional?

15:52 AWizzArd: fogus_: how do they now print?

15:52 fogus_: AWizzard: #<PersistentQueue clojure.lang.PersistentQueue@0>

15:53 AWizzArd: oh hmm

15:53 fogus_: Not that it matters, just curious if this was by design

15:54 I always wished they printed out a queue fish: <-(1 2 3)-< :p

15:54 AWizzArd: yes, exactly what i thought

15:58 hiredman: fogus_: print-method …

15:58 fogus_: hiredman: understood. Just came across it while writing some code and wondered out loud.

15:59 hiredman: I'm just saying, if we want fish, we can have fish

15:59 it does kind of make sense, because a queue isn't a list

15:59 (or a seq)

16:00 fogus_: hiredman: Ah yes. Maybe I'll add my fish-method to my user file. ;-)

16:00 sbt: is there a standard way of picking a random element from a set?

16:02 hiredman: ,(defmethod print-method clojure.lang.PersistentQueue [q, w] (print-method "#Q" w) (print-method (seq q) w))

16:02 clojurebot: DENIED

16:02 hiredman: clojurebot: your mother wears army boots

16:02 clojurebot: My mother? I'll tell you about my mother

16:03 hiredman: ,(conj clojure.lang.PersistentQueue/EMPTY 1 2)

16:03 clojurebot: "#Q"(1 2)

16:03 hiredman: gah

16:03 fogus_: whoa!

16:03 I didn't think that would work

16:04 hiredman: ,(conj clojure.lang.PersistentQueue/EMPTY 1 2)

16:04 clojurebot: Wrong number of args passed to: core$fn

16:04 hiredman: ,(conj clojure.lang.PersistentQueue/EMPTY 1 2)

16:04 clojurebot: <-(1 2)-<

16:05 hiredman: ,(pop (conj clojure.lang.PersistentQueue/EMPTY 1 2))

16:05 clojurebot: <-(2)-<

16:06 fogus_: Much better. :-)

16:09 MadWombat: where can you get docs on clojure.lang.PersistentQueue?

16:13 chouser: sbt: (rand-nth [:a :b :c :d])

16:18 hiredman: ,Q

16:18 clojurebot: <-nil-<

16:18 hiredman: :D

16:18 nil fish

16:18 chouser: heh

16:18 ,(conj Q 1 2 3)

16:18 clojurebot: <-(1 2 3)-<

16:18 chouser: see, what's wrong with that? nothing!

16:18 stuartsierra: ,(conj Q (list) (list) (list))

16:18 clojurebot: <-(() () ())-<

16:18 stuartsierra: fish skeleton

16:19 chouser: ,(read-string (pr-str (conj Q 1 2 3)))

16:19 clojurebot: <-

16:19 stuartsierra: ,(conj Q (list (list (list))))

16:19 clojurebot: <-(((())))-<

16:19 stuartsierra: that's better

16:19 chouser: ,(conj Q Q Q)

16:19 clojurebot: <-(<-nil-< <-nil-<)-<

16:19 chouser: no-longer-hungry fish

16:19 hiredman: haha

16:20 MadWombat: ,(conj 'CLOJURE)

16:20 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$conj

16:21 MadWombat: (conj Q ('CLOJURE))

16:21 ,(conj Q ('CLOJURE))

16:21 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: Symbol

16:21 MadWombat: heh

16:22 chouser: so close.

16:22 ,(conj Q 'CLOJURE)

16:22 clojurebot: <-(CLOJURE)-<

16:25 chouser: ,(-> (partial conj Q) (iterate 0) (nth 3))

16:25 clojurebot: <-(<-(<-(0)-<)-<)-<

16:27 lpetit: any ccw user here ?

16:28 fogus_: ,(conj Q Q Q) ;; empty calories

16:28 clojurebot: <-(<-nil-< <-nil-<)-<

16:28 lpetit: any emacs user here ? :)

16:30 chouser: PeristentQueue stopped printing as () with 1b8d5001ba094053b24c55829994785be422cfbf

16:30 so I'd guess it was unintentional.

16:32 lpetit: chouser: congrats, you were the first to write something on #clojure. You won the right to review the feature list of keyboard shortcuts of the ccw editor: http://code.google.com/p/counterclockwise/wiki/EditorKeyBindingsFeatures ;)

16:32 sexpbot: "EditorKeyBindingsFeatures - counterclockwise - This page details keybindings and other feature of the editor - Project Hosting on Google Code"

16:32 lpetit: what is sexpbot ? what did trigger it ?

16:32 chouser: lpetit: the url triggered it

16:32 http://google.com/

16:32 sexpbot: "Google"

16:33 lpetit: chouser: isn't that a little bit too invasive ?

16:33 ,http://google.com would be less invasive, wouldn't it ?

16:33 clojurebot: java.lang.Exception: No such namespace: http:/

16:33 sexpbot: "Google"

16:33 chouser: I haven't formed an opinion

16:33 lpetit: :)

16:34 chouser: If by chance you really look at the page I provided, notice that the "split" between "basic edition mode" and "structural edition mode" is not done yet (that is you are in ccw either in paredit, either not)

16:35 chouser et al: I'm currently working on "polishing" the documentation of the port of paredit to ccw, and also "easing the use of newbies" by providing a basic mode and an "advanced" mode

16:35 chouser: what's <Suppr .>

16:36 dnolen: so how long before Code Quarterly interviews rhickey ? :)

16:36 lpetit: Oh, maybe it's some french : it's the "forward delete". How do you write that in french ?

16:36 s/in french/in english/

16:36 sexpbot: Oh, maybe it's some french : it's the "forward delete". How do you write that in english ?

16:36 lpetit: wow

16:36 chouser: meh

16:37 lpetit: who wrote sexpbot ?

16:37 chouser: Raynes, I believe.

16:37 lpetit: sexpbot: identity please

16:37 chouser: lpetit: maybe Delete or Del instead of Suppr? I'm not sure.

16:38 lpetit: chouser: Let's go with <Delete> ?

16:38 chouser: lpetit: it's not a modifier, right? you don't usually press it along with something else?

16:38 lpetit: chouser: right. why asking ?

16:39 chouser: just making sure we're communicating successfully. :-)

16:39 lpetit: chouser: is there a convention of *only* placing modifier keys between <> ?

16:39 chouser: no

16:40 lpetit: chouser: done for <Delete>. Other remarks ?

16:41 chouser: I want to use it! But I don't want to use Eclipse.

16:44 lpetit: chouser: When I think ccw is ready to *globally* impress emacs users, I'll say it on the clojure ml :). Anyway, thanks for the kind words.

16:44 chouser: Maybe if I were an emacs user I'd be content with paredit there.

16:44 lpetit: chouser: note that the underlying features for the basic and structural edition modes is pure clojure, depending only on clojure and clojure.contrib, and is available in an independent (from ccw) github repo

16:45 chouser: you're a user of ... which editor ?

16:45 chouser: yeah, I've heard you say that. If I ever pick up textjure again, I'll be certain to look into using your code there.

16:45 lpetit: vim

16:46 lpetit: chouser: I'm not proud of the way I've written the code, but it's guarded by a bunch of unit tests, so at least it works :)

16:46 chouser: :-)

16:46 lpetit: chouser: oh vim, ok, so you're in Meikel's team :-)

16:46 Must go to bed, thanks for the chat, cu

16:46 * riddochc has begun using git submodules to refer to clojure and clojure-contrib in my project, and the build system checks out and builds both before moving on.

16:46 chouser: g'night

16:47 Licenser: bed is a good idea, night people!

16:49 riddochc: I've also broke down and started using 'rake' for dealing with building stuff...

16:50 chouser: anything that helps you write clojure code is a good thing. :-)

16:52 riddochc: chouser: Pretty much, yeah. I've been working on implementing a wiki that uses git as its storage backend in clojure + compojure.

16:53 Just playing around, really.

16:54 chouser: excellent. That's the one thing I'm sure wave got wrong -- not building on something with complete revision semantics.

16:55 riddochc: Wave? How so?

16:55 chouser: waves have linear history. no forking, branching, merging...

16:55 your wiki will not be so constrained. :-)

16:56 riddochc: Waves as in Google Waves?

16:56 chouser: yeah

16:57 riddochc: Ahh, I see. Well, you also can commit more energy to your project... Have no fear of serious competition from me. :)

16:57 rfg: As opposed to linear wave theory.

16:59 riddochc: liner wave. Not an oxymoron?

17:00 rfg: Not in this context, no.

17:01 riddochc: Okay.

17:04 tufflax: Hm, how can I remove a specific element from a collection? I would like something that works like this: (delete 1 '(9 6 1 3 1)) -> (9 6 3 1) but after some looking I can't find anything like that.

17:06 chouser: ,(remove #{1} '(9 6 1 3 1))

17:06 clojurebot: (9 6 3)

17:06 chouser: but that got rid of both. is that not what you wanted?

17:06 tufflax: no hehe

17:08 DuneMan: You want to remove the first item?

17:08 first occurance of an item?

17:08 tufflax: I was trying to fix the all-permutations example found at the bottom here http://kyle-burton.livejournal.com/14970.html

17:08 sexpbot: "kyle_burton: List Comprehensions in Clojure"

17:08 tufflax: yes duncanm

17:08 oh, DuneMan

17:08 DuneMan: (next (take-while #(not (= % 1)) s)) ; ??

17:08 riddochc: Well, I might start with (take-while (comp pred) list) to get everything up to the 1...

17:09 DuneMan: er, yeah, mine is broken, riddoch is right ":-)

17:09 you can use ... split-at or whatever

17:09 riddochc: Ah, yeah.

17:10 tufflax: Hm, any particular reason that there isn't a simple functionfor this? :P

17:10 DuneMan: because you haven't written it!

17:10 :-)

17:10 tufflax: hehe

17:10 riddochc: Because usually people seem to want to remove *all* instances of something from a collection?

17:11 Which is what filter is for.

17:11 tufflax: hm ok

17:12 DuneMan: so yeah

17:12 use (split-with

17:12 tufflax: ok, thanks

17:13 riddochc: (let [[a b] (split-with #(not (= 1 %)) '(9 6 1 3 1))] ...)

17:13 Almost there...

17:13 DuneMan: (let [[before after] (split-with #(= % 1) col) rest (next after)....

17:14 riddochc: Then we want a new sequence...

17:14 DuneMan: (flatten [before res]))

17:14 or chain

17:14 (I'm still learning the clojure lib)

17:14 riddochc: Me too.

17:15 MadWombat: (concat (take-while #(not= 3 %) (list 1 2 3 1 2 3)) (rest (drop-while #(not= 3 %) (list 1 2 3 1 2 3))))

17:15 but yes, the version with let is a bit more concise

17:15 DuneMan: concat is the way to go. and yes, that does exactly the same thing without the let

17:16 riddochc: Ah, concat.

17:16 DuneMan: Of course, this is problematic if you're collection is potentially very large because you'll be holding onto the head

17:17 your*

17:17 MadWombat: (defn split [e col] (let [[x y] (split-with #(not= e %) col)] (concat x (rest y))))

17:18 should call it something else

17:18 or better yet

17:18 DuneMan: filter-first

17:18 riddochc: Concat doesn't return a lazy seq? I don't see where we're holding on to the head yet...

17:18 kotarak: concat is lazy

17:19 DuneMan: ah yes, indeed.

17:20 MadWombat: (defn filter-first [pred col] (let [[x y] (split-with pred col)] (concat x (rest y))))

17:21 kotarak: This holds onto col until you start consuming y in the concat.

17:22 MadWombat: probably a good usability idea is to negate the pred value, so you have to pass #(= x %1) not #(not= x %1)

17:22 riddochc: So...

17:22 ,(defn filter-first [pred s] (let [[a b] (split-with pred s)] (concat a (next b))))

17:22 clojurebot: DENIED

17:22 DuneMan: indeed kotarak

17:22 MadWombat: kotarak: hmm... yes, that is what you get with lazy sequences... lemme think

17:23 DuneMan: you need to consume the "drop-while" sequence in step with the "take-while" sequence

17:23 riddochc: Okay, fine...

17:23 ;(let [filter-first (fn [pred s] (let [[a b] (split-with pred s)] (concat a (next b))))] (filter-first #(= 1 %) '(9 6 1 3 1)))

17:23 ,(let [filter-first (fn [pred s] (let [[a b] (split-with pred s)] (concat a (next b))))] (filter-first #(= 1 %) '(9 6 1 3 1)))

17:23 clojurebot: (6 1 3 1)

17:23 riddochc: There we go.

17:23 Um...

17:23 Oops.

17:24 MadWombat: riddochc: #(not= 1 %)

17:24 riddochc: this is not a bug, this is a feature :)

17:24 DuneMan: ,(let [filter-first (fn [pred s] (let [[a b] (split-with (comp not pred) s)] (concat a (rest b))))] (filter-first #(= 1 %) '(9 6 1 3 1)))

17:24 clojurebot: (9 6 3 1)

17:25 MadWombat: DuneMan: Ah! I was looking for a way to negate the pred

17:25 DuneMan: "compose"

17:25 riddochc: Or, it could take the thing you want to filter at, instead of a predicate.

17:25 ,(let [filter-first (fn [at s] (let [[a b] (split-with #(not (= at %)) s)] (concat a (next b))))] (filter-first 1 '(9 6 1 3 1)))

17:25 clojurebot: (9 6 3 1)

17:26 tomoj: shouldn't that be called remove-first ?

17:26 riddochc: tomoj: Even better.

17:26 DuneMan: tomoj: much better name

17:26 Honestly, in all my years of programming, one of the hardest things for me to do has always been naming thing

17:26 s

17:26 kotarak: ,(let [filter-first (fn filter-first [pred coll] (lazy-seq (when-let [s (seq coll)] (let [fst (first s)] (if (pred fst) (next s) (cons fst (filter-first pred (rest s))))))))] (filter-first #(= 1 %) [9 6 1 3 1]))

17:26 clojurebot: (9 6 3 1)

17:27 kotarak: This does not hold unto the head.

17:27 DuneMan: hell, yesterday I needed to write a clojure function to turn a unix-timestamp-containing-string into a java Calendar.... I just stole CL's "decode-universal-time" :-P

17:27 kotarak: nice.

17:28 I've been worrying about head-holding a lot recently, because my app takes an infinite stream of data as the input......

17:28 badness if you accidentally pass that to a function that takes [& more]

17:28 slyphon: what's that emacs feature that lets you project specific settings in a dotfile ?

17:28 in emacs-23

17:29 tomoj: ,((fn [[& more]] (take 3 more)) (iterate inc 0))

17:29 clojurebot: (0 1 2)

17:30 riddochc: kotarak: lazy-seq + cons to the rescue, it seems.

17:30 kotarak: riddochc: low-level but flexible. Trying to press everything in higher order stuff is similar wrong as throwing lazy-seq at everything. :)

17:31 tomoj: what's the badness?

17:31 kotarak: tomoj: (apply (fn [& more] ...) ..) holds the head.

17:31 riddochc: kotarak: A good lesson for me, as I read 'real world haskell' last year before deciding I preferred clojure.

17:32 tomoj: ah

17:32 DuneMan: which is the case I ended up with

17:32 technomancy: slyphon: .dir-locals.el

17:32 slyphon: technomancy: thank you!

17:32 DuneMan: because I used "partial"

17:32 which does (apply ....)

17:32 technomancy: np

17:32 DuneMan: and thus I ate up many gigs of memory in short order and was very confused for a long time where my leak was

17:33 but in the process tuned the garbage collector for my data profile! so... it was sorta worth it...

17:33 riddochc: Is there a good way to tell when the head's being held? 'apply' holding the head really doesn't seem an obvious thing.

17:34 tomoj: I think the head is held there simply because you've got a handle to more?

17:34 DuneMan: I noticed it because my data was big enough, and my call chain structured in such a way, that no memory was getting freed

17:34 tomoj: since you can say (first more), the head is held

17:34 DuneMan: so I watched the memory with jconsole...

17:35 tomoj: yes. I also ran into problems with the clojure runtime not getting rid of references and thus creating leaks

17:35 but upgrading to 1.2 fixed that

17:35 and created this REALLY annoying problem that (hash-map ....) now throws DuplicateKeyException

17:35 whcih makes me want to kill someone.

17:35 tomoj: anyone else happen to have played with clojure+solr yet?

17:36 DuneMan: no, but I might soon... we have a project that we'd like to try with it.

17:36 kotarak: DuneMan: well, people always complained, that it is possible to create maps with duplicate keys

17:37 * riddochc learns of jconsole from DuneMan, and finds: http://formpluslogic.blogspot.com/2009/12/clojure-and-jmx.html

17:37 DuneMan: jconsole is nice.

17:39 kotarak: I ended up writing my own function that does the (apply merge (map (partial apply hash-map) (take-nth 2 s)))

17:40 kotarak: DuneMan: you probably mean partition instead of take-nth

17:40 DuneMan: yes, I do mean partition

17:42 but yeah, I suppose it's better to have the more restrictive behavior built in

17:42 'cause its easy enough to write the function

17:42 but it annoyed me int he moment :-D

17:42 kotarak: ,(-> [:a 1 :a 2 :a 3] (partition 2) (map vec) (into {}))

17:42 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$vec__4296

17:42 kotarak: ,(->> [:a 1 :a 2 :a 3] (partition 2) (map vec) (into {}))

17:42 clojurebot: {:a 3}

17:43 alexyk: hey guys -- I have a let [x blah] where blah needs to be measured; in repl with (time blah). How can I assign x and still print the time it took to blah?

17:43 DuneMan: Oh that's much simpler...

17:44 kotarak: ,(let [s [:a 1 :a 2 :a 3]] (zipmap (take-nth 2 s) (take-nth 2 (next s)))

17:44 clojurebot: EOF while reading

17:44 kotarak: ,(let [s [:a 1 :a 2 :a 3]] (zipmap (take-nth 2 s) (take-nth 2 (next s))))

17:44 clojurebot: {:a 3}

17:44 kotarak: ,(time 5)

17:44 clojurebot: 5

17:45 "Elapsed time: 0.067 msecs"

17:45 kotarak: ,(let [x (time 5)] x)

17:45 clojurebot: 5

17:45 "Elapsed time: 0.066 msecs"

17:46 hoeck: kotarak: (apply assoc {} [:a 1 :a 2 :a 3])

17:46 hircus: alexyk: as kotarak shows, the time macro prints but then return the result of the expression it measures. a more interesting challenge will be if you want to capture both the time taken and the expression result; you'd have to capture the start and end time manually in that case

17:46 tomoj: the source of time shows how

17:46 kotarak: hoeck: viele wege führen nach Rom (und wieder zurück)

17:47 tomoj: ,(System/currentTimeMillis)

17:47 clojurebot: 1273182679109

17:47 DuneMan: hoeck: but if the sequence is infinite... you will hold onto the head with the apply

17:47 well, nevermind

17:47 doesn't matter in this case

17:47 that looks simplest.

17:47 kotarak: DuneMan: (reduce #(apply assoc %&) {} s)

17:48 alexyk: kotarak: hircus: thx!

17:48 tomoj: whoa

17:48 hoeck: a creating a map from an infinite seq isnt a good idea either

17:48 tomoj: I never knew about %&

17:48 alexyk: tomoj: thx too!

17:48 DuneMan: hoeck: indeed :-)

17:48 kotarak: DuneMan: a quark. nevermind

17:48 partition is missing

17:48 alexyk: what's %&?

17:48 hoeck: kotarak: just wanted to be shure you are not missing a nice way (to rome) :)

17:49 tomoj: I assumed it's just like & more in a function

17:49 ,(#(seq %&) 1 2 3 4 5)

17:49 clojurebot: (1 2 3 4 5)

17:49 hoeck: DuneMan: although it would be possible with lazy maps :)

17:49 kotarak: tomoj: alexyk right. like %1 %2 but for & more.

17:50 DuneMan: is there any reason why just (apply assoc {} s) isn't good?

17:50 Borkdude: But what if Rome is Java?

17:50 tomoj: cool

17:50 ,(#(vector %1 %2 %3 %&) 1 2 3 4 5 6)

17:50 clojurebot: [1 2 3 (4 5 6)]

17:51 alexyk: cool

17:52 kotarak: DuneMan: since s is better finite, I think it's ok.

17:54 tufflax: MadWombat: (complement pred) also works.

17:57 riddochc: Hmm. Looks like clojure-contrib's .pom isn't making maven very happy: [WARNING] The expression ${artifactId} is deprecated. Please use ${project.artifactId} instead. @ org.clojure:clojure-contrib:1.2.0-SNAPSHOT, /home/socket/src/clojure/clojure-contrib/pom.xml

18:04 DeusExPikachu: wlangstroth, I found out clojure has like 5 classloaders up, it was a matter of picking the right one, and the right one seems to change, so far, using the one given by clojure.lang.RT/baseLoader seems to work, add URLs to that and everything should just work

18:05 DuneMan: .... grrr why isn't (apply assoc {} mySequence) worrrrrking.... "wrong number of arguments passed to assoc"

18:06 I also hate that exception. Why doesn't it tell me how many parameters were passed and how many were expected?

18:06 *smacks java*

18:07 DeusExPikachu: DuneMan, (doc assoc)?

18:07 DuneMan: (apply assoc {} [:a 1 :b 2 : a 3 :c 1}) works aight

18:07 Borkdude: DuneMan: what does mySequence look like?

18:08 DuneMan: (flatten <sequence returning [key value]>)

18:09 Borkdude: And when evaluated?

18:10 DuneMan: I'm having trouble at the moment because leiningen is v 1.1 and clojure is v1.2

18:10 alexyk: I need to pmap a big list with expensive fn. When I do pmap, I see CPU load gradually raising from 100% to 800% on my 8-core box, then dropping to 100%. Manually launching 8 agents for another job keeps it at 800% steady. Is there a way to tell pmap to just split it 8-ways and run on 8-agents? Why dips?

18:11 DuneMan: so my repl and the code are at different versions

18:11 *wonders how to make leiningen use 1.2*

18:11 alexyk: DuneMan: checl out from git

18:11 check

18:11 that uses 1.2

18:12 see Hacking on leiningen

18:12 DuneMan: Bork: Ostensibly it must be something different, but I don't see how. the whole s-exp is (apply assoc {} (flatten (map (fn [[_ k v]] [(keyword (urldecode k)) (urldecode v)] s)))))...

18:12 tomoj: anyone happen to know the right <scope> to use for swank-clojure when using clojure-maven-plugin

18:13 DuneMan: where "s" is the result of a re-seq with 3 capture groups

18:13 frodwith: ,(apply assoc (seq {:foo "bar", :baz "qux"}))

18:13 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$assoc

18:13 frodwith: ,(into {} (seq {:foo "bar", :baz "qux"}))

18:13 clojurebot: {:foo "bar", :baz "qux"}

18:14 kotarak: seq is not necessary

18:14 alexyk: is "qux" the lisp thing?

18:14 frodwith: no, it isn't

18:14 kotarak: ,(into {} {:foo :bar :baz :bob})

18:14 clojurebot: {:foo :bar, :baz :bob}

18:14 frodwith: he just has a seqence

18:14 technomancy: tomoj: you need it to be compile-scoped, which is the default

18:14 tomoj: darn

18:14 alexyk: frodwith: isn't it from "great quux"?

18:14 technomancy: tomoj: yeah, it's a very-long-standing clojure-maven-plugin bug

18:15 one of many. =\

18:15 frodwith: alexyk: I have no idea. I picked it from The Art of Unix Programming.

18:15 technomancy: tomoj: but swank isn't GPL'd anymore, so at least now compile-scoping it is legal.

18:15 alexyk: ~ google great quux

18:15 clojurebot: First, out of 1560 results is:

18:15 tomoj: I wonder what java developers working on one of these maven projects with clojure and java intertwined would think about adding the deps for clojure-maven-plugin to the poms

18:15 clojurebot: Guy L. Steele, Jr. - Wikipedia, the free encyclopedia

18:15 http://en.wikipedia.org/wiki/Guy_L._Steele,_Jr.

18:16 frodwith: so anyway, DuneMan: try using into instead of applying assoc.

18:16 tomoj: maybe I can add them in an extra file which is gitignored somehow.. hmm

18:16 technomancy: tomoj: speaking of jclouds?

18:16 tomoj: yeah

18:16 technomancy: tomoj: yeah, that struck me as weird. not going to complain though. =)

18:16 DuneMan: (into {} [:a 1 :b 2]) -->> Cannot create ISeq from keyword

18:16 kotarak: bingo

18:17 DuneMan: so then you'd need the partition

18:17 kotarak: ,(into {} [[:a 1] [:b 2]])

18:17 clojurebot: {:a 1, :b 2}

18:17 kotarak: DuneMan: and a map vec, IIRC

18:17 DuneMan: or use into for the case where I'm getting pairs

18:17 kotarak: ,(into {} (partition 2 [:a 1 :b 2]))

18:17 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

18:17 DuneMan: and apply assoc when I just have a seq

18:17 tomoj: oh, I found the deps in project/pom.xml

18:18 kotarak: DuneMan: into only works with map entries or vectors. partition is not enough

18:18 DuneMan: I actually have vectors coming out, so it works

18:19 tomoj: but swank-clojure only gets test scope

18:19 DuneMan: because I'm basically mapping a vector of 3 elements to a vector of 2 elements with transformations

18:19 and then I can just use into {}

18:19 which is quite readable.... and I didn't know about until today

18:19 clojurebot: everyday is Rich Hickey Appreciation Day

18:19 DuneMan: so thanks!

18:19 frodwith: :)

18:21 tomoj: but the classpath is all fucked up there, hmm

18:21 DuneMan: This is a wonderful place

18:23 works like a charm

18:23 awesome

18:24 tomoj: hugod: ping

18:24 hugod: tomoj: hi

18:24 tomoj: hey, do you happen to be the one who stuck swank-clojure in one of the jclouds poms?

18:25 hugod: could well be

18:25 tomoj: someone's apparently done something to try to set up a clojure dev env, but I can't see how it's supposed to work

18:25 hugod: mvn clojure:swank

18:25 tomoj: yeah, in project/?

18:26 hugod: except there's a bug in clojure-maven-plugin

18:26 tomoj: aha

18:26 hugod: http://github.com/talios/clojure-maven-plugin/issues#issue/11

18:26 tomoj: switching it to compile-scoped didn't seem to help

18:26 well, it got me to different problems at least

18:27 swank started but now the classpath isn't right for the clojure sources, so you have to go and load them manually in the right order, and eventually I hit a missing dep

18:27 wonder how the clojure code already here was written

18:31 hugod: tomoj: which sub-project?

18:31 tomoj: trying to work in the clojure stuff in aws/core

18:32 hugod: cemerick wrote that

18:32 tomoj: which requires some clj file from compute to be loaded, which requires a file from core to be loaded, which dies because of some missing google dep

18:33 ah, thanks

18:46 MadWombat: seems like there are at least a few clojure projects running out there using google app engine, but all the directions are either outdated or cryptic.

18:47 DuneMan: here

18:47 How the heck can I use the "catch" special form in a macro?

18:48 if I have `( ..... (catch Exception e)) it complains "can't bind qualified form user/e"

18:49 AWizzArd: ,(try (+ "a" 2) (catch Exception e (println e)))

18:49 clojurebot: AWizzArd: excusez-moi

18:49 MadWombat: AWizzArd: I think that is WTF in french :)

18:50 AWizzArd: yes yes, something like that.. don't know, was supposed to print something about a casting exception

18:52 DuneMan: the macroexpand gives me: (try (+ "2" 1) (catch Exception user/e nil))

18:52 so, yeah, 'e' becomes user/e... which is wrong

18:55 Ah, since I don't reference 'e' in my expression.... if I use _ it works

18:56 wait no, I'm wrong

18:59 Why isn't catch mirroring a let form?

18:59 (catch [e Exception] ....)

19:01 arohner: DuneMan: macros try to resolve symbols, unless quoted

19:01 DuneMan: doing 'e generates a macro with (quote e) in it.

19:02 er, (quote user/e)

19:02 So it resolves it...... then quotes that.

19:03 arohner: that 'e' should either be 'e#', which will generate a random name for the variable, or '~'e', which will use the literal symbol e, stomping on another symbol in the environment (if present)

19:03 you probably want to use e#

19:03 DuneMan: oh you have to quote the ~

19:04 Thanks again!

19:04 arohner: DuneMan: np

19:06 MadWombat: what is the clojure equivalent of wildcard import? If I have several files in a directory, how do I require or use all of them?

19:06 arohner: MadWombat: there's nothing built in to do that

19:07 MadWombat: you could (doseq [..] (require ...))

19:07 tomoj: did you mean for clojure files or java classes?

19:07 MadWombat: clojure files

19:07 tomoj: oh, it doesn't matter anyway

19:08 MadWombat: hmm... this is somewhat inconvenient :(

19:10 arohner: MadWombat: if you know their names, you can (doseq [file ['dir.foo 'dir.bar' 'dir.baz]] (require file))

19:10 oops, extra '

19:11 MadWombat: yes, the point was to import without knowing names

19:11 technomancy: aka "timebomb use"

19:12 arohner: MadWombat: as technomancy implies, it's unlikely to ever be a part of clojure proper

19:12 MadWombat: but writing it isn't bad

19:12 just slurp* the directory, and filter by "*.clj"

19:15 MadWombat: "timebomb use"?

19:15 ah! breaks when someone creates a file in that directory that clobbers namespace?

19:16 dired

19:17 wrong window :)

19:18 AWizzArd: arohner: why not file-seq ?

19:18 arohner: AWizzArd: I forgot about it :-)

19:19 AWizzArd: file-seq is a better solution

19:19 AWizzArd: k

19:35 * Raynes chuckles at lpetit's freaking out about sexpbot.

19:36 Raynes: chouser: You should totally form an opinion on the URL title scraper. :P I've put a lot of work into making it suitable (useful) for a channel like #clojure. Pretty sophisticated blacklisting going on.

19:36 (:

19:38 MadWombat: is there a way in emacs to open the file containing the namespace under point?

19:39 like point to (:use com.wombat.something) and open the file containing the something namespace

19:39 or switch to the buffer

19:39 technomancy: MadWombat: there's not one that knows about clojure :use clauses, but find-file-at-point will do it for regular filenames

19:40 you could probably teach it about clojure, but M-. works just as well for that

19:41 MadWombat: hmm M-. gives me ClassNotFound exception

19:41 technomancy: oh, you need to do it with a var from the desired namespace, not on :use itself

19:48 alexyk: lancepantz: ping

19:50 lancepantz: hey alexyk

19:50 sup?

19:51 alexyk: lancepantz: what happens if you do db-add with tokyocabinet without a transaction? Does it roll any write in its own transaction?

19:52 ninjudd: alexyk: yes, if i understand your question correctly

19:53 alexyk: ninjudd: hey man! so you guys won't believe the comparison results vs BDB JE cupboard

19:54 I had 5 min write and 20 min read with JE

19:55 now I have 1.5 hrs write and 3 min read with TC

19:55 ninjudd: nice!

19:55 alexyk: with the adjacency list done as protobufs

19:55 ninjudd: 1.5 hours?

19:55 alexyk: but, I didn't do transactions for TC write

19:55 MadWombat: ,(contains? (keys (ns-publics 'clojure.core)) 'apply)

19:55 clojurebot: false

19:55 MadWombat: wtf?

19:55 alexyk: yep, 6400 secs

19:55 ninjudd: that doesn't sound right

19:56 alexyk: out of which, if I pmap my graph with protobufs, 900 secs are spent protobuffing

19:56 MadWombat: (contains? (map str (keys (ns-publics 'clojure.core))) "apply")

19:56 alexyk: I'm not using jiraph, only jiraph.tc

19:56 MadWombat: ,(contains? (map str (keys (ns-publics 'clojure.core))) "apply")

19:56 clojurebot: false

19:56 alexyk: I put node, protobuf adjacency list -- those Repliers I emailed earlier

19:57 so 900 secs are spent just serializing the adjacency lists, before any writing to TC

19:57 while reading is superfast

19:57 lancepantz: alexyk: do you know the size of the adjacency list?

19:58 MadWombat: ah!

19:58 ,(contains? (ns-publics 'clojure.core) 'apply)

19:58 clojurebot: true

19:58 ninjudd: there may be room for improvement in protobuf, but still, that is 5600 secs to write

19:58 alexyk: but my lists are ranging from 1 to 10000 in each adjacency iist, much bigger than yours

19:58 so the beauty is, TC read is superfast

19:58 even at 100% CPU; vs. JE at 800%

19:58 ninjudd: oh, do you add each edge one at a time?

20:00 alexyk: ninjudd: no, I write a node and all its adges in value protobuffed

20:00 3 million nodes and protobufs

20:00 but, without transaction surrounding the whole write; need to test with that

20:01 ninjudd: hmm, can you send me some sample code so i can try it on my machine?

20:02 alexyk: ninjudd: sure, will github it soon

20:02 ninjudd: in my experience, it is slower to write than read, but the difference seems much larger than i would expect

20:03 alexyk: during TC write CPU is at abysmal 14%, I guess due to lack of transactions; the default db-init and db-open don't any bzip2, do they?

20:04 ninjudd: no

20:05 based on this, i would think writes should be fast too: http://1978th.net/tokyocabinet/benchmark.pdf

20:06 alexyk: ninjudd: so when you write a protobuf, you just (ad-add key (protobuf Foo fields)), it emits the bytestring as is, correct?

20:06 db-add

20:08 ninjudd: yeah, are you still using defgraph to create the layer?

20:08 and then using the layer directly in your benchmark?

20:10 alexyk: ninjudd: no, I don't use any of jiraph except jiraph.tc, and: db-init, db-open, (doseq [[k v] ...] db-add key (protobuf ... v ...))

20:10 and db-close

20:10 now am gonna add (db-transaction (doseq ... db-add))

20:10 is db-add slower than db-set?

20:11 ninjudd: alexyk: are you passing :load and :dump to db-init

20:11 alexyk: ninjudd: umm, not... should I? :)

20:12 sounds like I should, right

20:12 ninjudd: that is what causes it to auto-load/dump protobufs

20:12 take a look at the code for defgraph

20:13 alexyk: ninjudd: hmm; perhaps they're automerged by default?

20:13 because they "just work"

20:13 ninjudd: or just call defgraph and then use the layer

20:13 alexyk: protobufs I mean

20:13 are there any options to db-init affecting speed?

20:13 ninjudd: yes, but it uses pr-str and read-string for serialization still

20:14 alexyk: ninjudd: ah! so that slows things down?

20:14 ninjudd: yes

20:15 alexyk: kk, will stick :load and :dump to db-init... it just takes a map, so I'd just do (db-init {:path ... :load :dump}) right?

20:15 ninjudd: yes

20:16 alexyk: in defgraph, it also sets :proto proto?

20:17 ninjudd: :dump protobuf-dump :load (partial protobuf-load Foo)

20:17 or you can use defgraph and pass :proto to a layer and it will do that for you

20:18 alexyk: do I need :proto-fields as well?

20:19 ninjudd: no

20:20 MadWombat: http://blog.mitechki.net/2010/05/06/namespace-trickery-in-clojure/

20:20 sexpbot: "Namespace trickery in Clojure « Angry UNIXoid’s Humble Abode"

20:28 alexyk: sexpbot: and who are you?

20:29 clojurebot: who the heck is sexpbot?

20:29 clojurebot: that's cool

20:30 MadWombat: :)

20:40 Raynes: alexyk: Clojurebot speaks the truth.

20:46 slyphon: wow, java's Formatter is retarded

20:48 DuneMan: s/Formatter/*/

20:48 sexpbot: wow, java's * is retarded

20:48 slyphon: heh

20:49 replaca: slyphon: why do you say that?

20:49 slyphon: because it's frustrating me and i don't want to blame my own stupidity

20:49 replaca: what are you formatting?

20:49 slyphon: oh, gah

20:50 ,(format "%0.2f" 3.142)

20:50 clojurebot: java.util.MissingFormatWidthException: 0.2f

20:50 slyphon: ,(format "%.2f" 3.142)

20:50 clojurebot: "3.14"

20:50 slyphon: in ruby the 0.2 is acceptable

20:50 replaca: ahh.

20:51 slyphon: so you see, it's totally java's fault for not being ruby

20:51 replaca: I did a version of common lisp format, but if you're used to printf-style formatting, it's probably not what you want either

20:51 slyphon: hah

20:51 yeah, i don't need to display this stuff in roman numerals, fortunately

20:51 ;)

20:52 replaca: never know when latin will be back!

20:52 slyphon: :D

20:52 replaca: good to be ready

20:55 slyphon: it would be really funny if we got bought out an all of our timestamps were in roman numerals, come to think of it

20:56 everyone on the team just acting like it's totally normal

20:56 ninjudd: is there a way to write a custom constructor with deftype?

20:57 Raynes: ninjudd: You can write a make-<type> function.

21:00 ninjudd: Raynes: so make-Store if my type is called Store?

21:18 slyphon: jeez, when you hook mysql connector/j up to log4j, the name of its logger is "MYSQL"

21:19 there's something very "TIMMAH!" about that

21:25 powr-toc: if I want to extend a class that requires some state manipulation/constructor overloading, what's the best way to do it in 1.2? It seems reify is out, can I use extend or extend-type, or do I need to use gen-class?

21:26 tbh it looks like proxy is the best bet, but that's slower than other options, right?

21:27 maravillas: and incidentally, i'm wondering just how to define constructor overloads with gen-class, in 1.1 :)

21:28 coincidentally, that is

21:30 powr-toc: yeah, gen-class gets a little hairy, I want to be sure I need it before biting the bullet and requiring an AOT compile step

21:32 slyphon: man

21:32 thank god for clojars

21:32 life would truly suck that much more if i had to set up a maven repo

22:16 thearthur: how many times will a transaction retry?

22:17 slyphon: thearthur: what do you mean?

22:20 thearthur: im asking about dosync transactions on refs

22:21 _ato: ,clojure.lang.LockingTransaction/RETRY_LIMIT

22:21 clojurebot: 10000

22:21 _ato: thearthur: ^

22:21 thearthur: thanks: )

22:22 slyphon: i guess the question then is, what happens when it reaches the retry limit?

22:23 _ato: it throws an exception

22:24 http://github.com/richhickey/clojure/blob/1.1.0/src/jvm/clojure/lang/LockingTransaction.java#L381

22:26 slyphon: ah, figures

22:26 :)

22:39 livingston: I like using emacs/swank with clojure, but I need to setup some java developers to work with me, and they like eclispe, is counterclockwise the best route for them?

22:42 cemerick: that's the eclipse plugin

22:42 or, that is, I don't know of any others

22:43 I really need to take it and intellij out for a spin and see how they do.

22:43 livingston: ok, so I'll take that as a yes then ;) do you know if it does or will support 1.2 I'm poking around but haven't figured that out yet

22:43 cemerick: no idea

22:43 there's a list for it I think....

22:46 livingston: also, anyone have any suggestions on books, tutorials, class material type stuff for bringing java developers up to speed on clojure (/ functional programming) ?

22:47 cemerick: livingston: "Programming Clojure" is good. The Joy of Clojure MEAP is stellar so far.

22:47 livingston: what's a MEAP ?

22:48 cemerick: hrm

22:48 Raynes: Manning Early Access Preview

22:48 cemerick: yeah, that's it

22:48 pre-release ebook

22:48 mikem: livingston: I found "Practical Common Lisp" good reading for LISP background: http://gigamonkeys.com/book/

22:48 sexpbot: "Practical Common Lisp"

22:48 livingston: I have Programming Clojure, and like it pretty well, but that's good I hadn't heard of the other one yet.

22:48 Raynes: The first 6 chapters of Joy have been written, and if you buy the ebook, you get those chapters and all subsequent updates (with more chapters) until the book is released, and then you get the final book.

22:49 livingston: Yeah, I've been thinking about working them though the exercises in Paul Graham's book, but just do them in Clojure

22:49 cemerick: mikem: really? CL is very different from clojure philosophically.

22:49 Licenser: only thing about programming clojure might be that with 1.2 it gets a bit outdated

22:49 livingston: Licenser: I was thinking about that, but for the basics its all mostly there

22:50 Licenser: it still is (no question) a good book but exspecially for newcomers 'why isn't this working' might be a frustrating experience

22:50 mikem: cemerick: sure, but it helps to understand some of those differences. it was interesting to see how one would solve problems in a functional language

22:50 Raynes: We have books now: people can stop recommending Common Lisp books for Clojure.

22:50 :p

22:50 * mikem shrugs

22:50 mikem: i found it helpful :)

22:51 livingston: I do think Graham's exercises are more oriented toward learning an FP approach (even if it's in common lisp)

22:51 cemerick: In hindsight, I don't really like PCL. It has a very narrow perspective.

22:52 On Lisp is my bar for judging lisp books, which might not be fair.

22:53 livingston: Yes I like Graham's On Lisp and have tought out of it before

22:54 Raynes: yes there is Halloway's book, but it doesn't have exercises and it's oriented around teaching FP, per-say.

22:54 Raynes: There is The Joy of Clojure.

22:54 Which is more of what I was aiming for.

22:56 livingston: maybe that is good for people coming from the java side, but one particular thing I found annoying aobut Programming Clojure is it would say you can do it this way, and my face would cringe, then it would say this way is better, and I'd still be annoyed, and then it would say, but if you want a more FP way do this - and I would say, "why didn't you tell me that in the first place" (but I know common lisp very well so...)

22:56 I'll take a look at Joy..

22:56 mikem: there's another MEAP, "Clojure in Action"

22:56 haven't heard nearly as much about it, though, as "Joy"

22:56 cemerick: livingston: PC is definitely meant to be a step-by-baby-step approach

22:57 mikem: Seems pretty stalled, really.

22:57 compared to JoC, anyway

23:00 livingston: these are some good suggestions - thanks.

23:01 Licenser: well work time for me, take care people

23:01 livingston: I just wish one of them had exercises

23:08 wow Ch1 of Joy of Clojure kinda runs the gamut - kinda sticks you right in front of the fire hydrant

23:09 cemerick: it's definitely for grownups :-)

23:10 ninjudd: i asked about how to define a custom constructor for deftype earlier, but didn't have time to stick around and understand the answer

23:10 Raynes, you said add a method called make-<type>

23:10 Raynes: Function.

23:10 You can just write your own constructor function that wraps creating the type the way you want.

23:11 livingston: cemerick: yeah, although I don't know that that's the best way to ease some java programmers in? don't want to waste time, but don't want to make it hard either

23:11 Raynes: As far as I know, there is no way to define special constructor functions in the type.

23:11 ninjudd: oh, i see

23:11 so that's just a convention

23:12 cemerick: livingston: depends on the caliber of the programmers. If they've not looked outside of the box they're in for years, then it'll probably lead to shell-shock.

23:13 livingston: Clojure is formally and demonstrably simpler than Java, so it shouldn't be too rough for anyone who doesn't get hung up on cosmetics.

23:14 The persistent data structure thing takes a shift in perspective, but...well, that's just the way it is. Certainly no harder than grokking the nightmare that is DI or something.

23:14 livingston: I agree, they want to look at it and take it seriously, but at the same time I'd like to guide them into it, and by-in-large FP will be new too

23:15 what's DI ?

23:15 cemerick: dependency injection

23:15 livingston: oh right

23:17 yeah I find Stuart's book a little slow, but Joy seems way to fast, where's the one that's "just right" ;) we have copies of Stuart's book though, so we might just start there

23:18 cemerick: I clearly don't get around much. The notion of using a book as the primary source for learning a language is so foreign to me at this point.

23:19 livingston: I kinda just started "doing it", but I'm looking to help at least 3 people learn at once, so it's good to have something to focus on and foster discussion for regular meetings

23:19 cemerick: yeah

23:20 joshua-choi: clojurebot: What do you think of Clojure?

23:20 clojurebot: clojurebot is not a benchmarking platform

23:21 livingston: I also programmed in java a long time ago in a galaxy far far away, and spent the last 5 years writing some serious common lisp, so I'm pretty cool with clojure - I have my hangups, and miss some functions and expect some lisp stuff, but I'm embracing it

23:22 cemerick: I used CL for ~8 months some years ago. It just seems baroque at this point.

23:23 Java has changed so much since I started using clojure exclusively. I hardly recognize modern java code anymore.

23:23 livingston: nah it's great (CL), concurrency is an issue though, depending on your compiler but I loved it

23:24 that's something I miss, I'd like to be able to make a reader macro, for example

23:24 cemerick: it's a remarkable thing that Rich has pushed back on that so consistently. Gives me great hope for the future.

23:25 livingston: the STM is what got me looking seriously at Clojure though, I think one needs to embrace concurrency wholesale moving into the future

23:25 pushed back on what?

23:26 cemerick: reader macros. It's been lobbied for pretty hard from some corners, but no one's been able to propose an approach that would cleanly integrate with namespaces, etc.

23:26 It would have been a lot easier for him to just cut an implementation and not hear about it anymore.

23:27 livingston: I don't necessary want them for everyday code, but for building DSLs they can make a world of difference.

23:28 I'll have to look more at that debate sometime... but that'll have to be for another day

23:29 replaca: livingston: what do you miss from CL?

23:29 cemerick: the mailing list archive is chock-full of the discussions :-)

23:29 replaca: I missed clos for a long time, but I'm over it now

23:29 livingston: replaca: keyword parameters is one (although I hear we are getting that now)

23:30 I understand the reasons it's needed but two nils and two falses are a pain.

23:30 cemerick: yup, in the bag

23:30 replaca: livingston: well, you've always been able to do it, you just had to use a different defining form or do it yourself with destructuring

23:31 cemerick: two nils?

23:31 livingston: replaca: no you needed to have all these squigglies crud up your code

23:31 cemerick: nil and the empty list being different

23:31 replaca: ?? what do you mean

23:32 cemerick: livingston: right, well, the latter isn't nil :-) That's necessary in order to make properly lazy sequences FYI.

23:32 livingston: cemerick: I know, i get why it just makes the code uglier

23:33 replaca: yeah but you can't just con's the stuff together and then call apply, your keywords need to be separate in a map from non-optional args at the front

23:34 replaca: oh, yeah, a little bit simpler version, but with c.c.def/defnk it was pretty close

23:34 no {}

23:34 cemerick: livingston: that's also a necessary tradeoff *shrug*

23:35 it also simplifies things significantly -- the same set of destructuring operations regardless of context.

23:36 livingston: cemerick: yes, but I could write some really pretty stuff in CL, I'm not saying there aren't clear advantages to the affordance of Clojure that would have been a pain in CL, but until I get up to speed I'll naturally miss what I had

23:37 cemerick: sure

23:37 livingston: hey, I gotta roll,.. (promised a coworker a ride home) thanks for all the ideas everyone...

Logging service provided by n01se.net