#clojure log - Jun 10 2010

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

0:39 _rata_: ,(doc flatten)

0:39 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

1:10 tomoj: oh shit

1:11 swank-clojure 1.2 supports slime-who-calls?!

1:14 _rata_: tomoj, what's that?

1:15 tomoj: tells you which other functions call a particular function

1:15 except it doesn't work for me

1:15 swank.util conditionally defines flatten depending on the clojure version

1:16 but for some reason I get an unbound var there :(

1:17 toast`: does clojure have much in the way of a language spec?

1:17 tomoj: hmm.. I guess it would depend on who compiled the swank-clojure snapshot, eh? this seems.. unfortunate

1:20 toast`: i guess the soon to be released book will act as one?

1:23 _rata_: tomoj, maybe that's the reason why I don't have flatten either

1:23 tomoj: on 1.2 you should have it in clojure.core

1:25 _rata_: I don't have it, don't know why... niether on 1.2 nor on 1.1

1:25 tomoj: maybe you have an old 1.2?

1:25 _rata_: yes, that could be a reason

1:25 tomoj: ,*clojure-version*

1:25 clojurebot: {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

1:25 tomoj: ,flatten

1:25 clojurebot: #<core$flatten__6406 clojure.core$flatten__6406@162477e>

1:26 _rata_: I'll try updating it

1:27 user=> *clojure-version*

1:27 {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

1:27 that's what my clojure says

1:29 tomoj: but 1.2.0 is a snapshot, so you may have an older snapshot

1:31 _rata_: yes... I got it late

1:41 si there a function like filter that works on "trees"? I mean, is there a filter that once it finds a lists it applies itself over that list?

1:49 Blackfoot: _rata_: you could have a function that does different things based on the argument it gets

1:50 _rata_: ok, I know that... the question was if that function already existed in clojure or clojure.contrib

1:51 Blackfoot: yea.. not sure about all of contrib, i haven't gone too deep in there

1:51 'walk' might help

1:52 ,(doc walk)

1:52 clojurebot: Pardon?

1:52 Blackfoot: well, http://richhickey.github.com/clojure/branch-1.1.x/clojure.walk-api.html in any case

1:52 lancepantz: _rata_: i don't know if it specifically exists, i would look at keywordize-keys which basically does that, but applying keyword

1:53 _rata_: thanks, Blackfoot :)

2:00 ,(walk identity #(filter (comp not nil?) %1) [[nil 1] [2 3]])

2:00 clojurebot: java.lang.Exception: Unable to resolve symbol: walk in this context

2:01 _rata_: ,(use 'clojure.walk)

2:01 clojurebot: nil

2:01 _rata_: ,(walk identity #(filter (comp not nil?) %1) [[nil 1] [2 3]])

2:01 clojurebot: ([nil 1] [2 3])

2:01 _rata_: mmmm ¬¬

2:01 it seems that I didn't understand what walk does

2:08 tomoj: ,(remove nil? [1 nil 2 3 false])

2:08 clojurebot: (1 2 3 false)

2:10 _rata_: yes, i need that but in nested seqs too :)

2:10 ,(remove nil? [1 [2 nil] 3])

2:10 clojurebot: (1 [2 nil] 3)

2:13 tomoj: was just commenting on (comp not nil?)

2:15 _rata_: ah ok :)

2:35 Raynes: danlarkin: Damn. Is it that bad? :\

2:37 danlarkin: yes

2:39 Raynes: danlarkin: I might have to do it just to enlighten myself. Like skydiving.

2:40 danlarkin: it's not the writing that's hard

2:41 or rather, it's the 20%

2:41 and living with your day 1 design decisions for years

2:43 Raynes: That makes sense. Nobody is ever satisfied with build tools. Like I said though, it's just an idea for a boredom project. I'll just hide it from people. :>

2:43 Blackfoot: _rata_: any luck with walk?

2:47 _rata_: Blackfoot, no, I didn't try it anymore... I found a better way to get rid of nils in nested seqs

2:49 Blackfoot: ah ok, was it basically a recursive call?

2:50 lancepantz: Raynes: danlarkin: mind if i ask what you guys are discussing?

2:50 Raynes: lancepantz: I mentioned on Twitter that I might start a build tool and dependency manager project tonight just for fun, and because I'm bored.

2:51 _rata_: no... i stopped producing them

2:51 Raynes: lancepantz: danlarkin promptly warned against doing so, telling me it would be the worst mistake of my life. :P

2:51 lancepantz: hahaha, i jumped down that hole a week ago

2:51 me and a co-worker thought it would take a few days

2:51 we've been working on it full time for about 2 weeks now

2:51 _rata_: Blackfoot, i could do a filter with another recursive call (it already has one by default), but it was easier to stop producing those nils

2:52 Blackfoot: _rata_: oh haha taken care of at the source

2:52 _rata_: yea :)

2:52 lancepantz: *err: 2.5 weeks now

3:23 hoeck: lancepantz: and do you have something to show after those 2 weeks?

3:51 _rata_: is it possible to install swank-clojure 1.2 via ELPA?

3:52 tomoj: doesn't look like it's available yet

3:52 do you not use lein or maven?

3:53 _rata_: no :(

3:54 (is it ok to say "via ELPA" in english?)

3:54 KirinDave: it is not a naughty thing to say

3:55 bozhidar: _rata_: you might have also used "from" :-)

3:56 _rata_: bozhidar, ok :) thanks

3:56 tomoj: 'via' sounds fine to my ears

3:56 bozhidar: I'm very fond of

3:56 'via' myself

3:57 not so fond of ELPA, however

3:57 tomoj: _rata_: don't want to bother with lein?

3:57 _rata_: bozhidar, hahahahaha

3:57 bozhidar: a package management system without upgrade capabilities...

3:57 tomoj: what are "upgrade capabilities"?

3:58 bozhidar: tomoj: you cannot upgrade packages automatically the way you'd do it with yum or apt

3:58 tomoj: you mean like, "upgrade all installed to the latest available"?

3:59 bozhidar: tomoj: this is one, the other is that you cannot actually upgrade anything

3:59 you have to delete the old version and install the new

3:59 which is helpful to a very limited degree IMHO

4:00 tomoj: I see

4:00 _rata_: tomoj, what's lein for?

4:00 bozhidar: I guess that when ELPA enters Emacs it will be improved a lot, but at this point

4:00 tomoj: much easier than doing it manually, I think, though?

4:00 bozhidar: _rata_: a build system

4:00 tomoj: lein also can launch swank servers for you

4:01 bozhidar: it has a target lein:swank that allows to start swank-clojure server

4:01 tomoj: and if you do it that way, you don't even need swank-clojure in emacs

4:01 bozhidar: to which you can connect from slime

4:01 Raynes: bobo_: Since when do you have to delete an old version of something to install a new version.

4:01 bozhidar: I personally prefer to use swank-clojure + clojure-project

4:01 most of the time

4:02 Raynes: bozhidar: And you're thinking of maven. All you have to do to start a swank server with Lein is add [swank-clojure "1.2.1"] to your dev-dependencies, do 'lein deps' and then 'lein swank'.

4:02 I mean, the target bit didn't make any sense in the context of Leiningen. Not saying you didn't know the last bit. Should have been separated into two messages. :p

4:03 bozhidar: Raynes: I'm pretty sure I'm not thinking of Maven and I know how to use lein :-)

4:03 Raynes: Also, didn't mean to ping bobo_. :<

4:03 bozhidar: You said, and I quote "it has a target lein:swank that allows to start swank-clojure server"

4:03 bozhidar: I imagined so

4:03 bobo_: its ok, i didnt notice :-p

4:04 Raynes: I'm not sure that makes any sense in the context of leiningen. It has a plugin for starting a swank server. lein:swank looks mavenish.

4:04 bozhidar: Raynes: ops, that's a type I'd have to acknowledge - subconscious maven :-)

4:04 Raynes: :p

4:04 bozhidar: Raynes: as for ELPA - I'm pretty certain that you'll have to delete old version of packages

4:05 otherwise the old version will remain on the emacs load path

4:05 Raynes: bozhidar: I don't think so. I installed the new clojure-mode and slime about a week ago, and they're still sitting there. Emacs automatically used the newer versions.

4:05 I mean, maybe in an other version or with other packages.

4:06 older*

4:06 bozhidar: hmm, when I updated slime it continued to use the old slime until I deleted it

4:06 tomoj: package.el does seem to somewhat often not work

4:06 but still, I like it

4:06 * Raynes should stop listening to loud music when typing, so he doesn't type things he doesn't mean.

4:07 _rata_: mmmmm... but what if I don't want to start a project, but just play a bit with swank-clojure in emacs?

4:07 Raynes: bozhidar: Are you certain? technomany alerted me to a bug where slime warns you that the swank and slime versions are mismatched, when they actually aren't. He said deleting the elc file solves it.

4:07 _rata_: is lein useful for doing that?

4:08 Raynes: _rata_: Personally, I have an "experimentation" project for that that I can hop in whenever I want.

4:08 bozhidar: Raynes: it was some time ago, so my memory is a bit flimsy. I recall only how frustrated I was with ELPA...

4:08 Raynes: bozhidar: ELPA sucks pretty bad, I agree.

4:08 _rata_: mmmmm

4:09 bozhidar: I really hope someone will sit down and improve it before including it in Emacs by default

4:09 package management is a great concept and God knows Emacs needs it, but it must be implemented right

4:10 tomoj: on osx I always run into very strange problems with package.el

4:11 for example sometimes the installation itself will hang until I move the mouse

4:11 Raynes: On OSX, you run into strange problems with * it seems.

4:11 bozhidar: my favorite problem is the byte-compilation that almost never works

4:11 Raynes: :\

4:12 bozhidar: or the dependency resolution problems - sometimes deps come in just fine, other times - I have to mark every dep manually

4:12 tomoj: yeah..

4:12 _rata_: I saw that when I installed swank-clojure 1.1 from ELPA, it installed three jar files in ~/.swank-clojure/

4:12 tomoj: and then you wind up in weird states where something isn't installed but you also can't install it

4:13 _rata_: clojure*jar, clojure-contrib*jar and swank-clojure*jar

4:13 bozhidar: _rata_: clojure, clojure-contrib and swank

4:13 that'

4:13 s totally fine

4:13 _rata_: isn't there any way to the the same manually but with 1.2?

4:13 esj: Morning Everybody.

4:14 _rata_: where can I get the swank-clojure 1.2 jar?

4:14 how can I tell emacs to use them without installing swank-clojure from ELPA?

4:14 tomoj: I thought swank-clojure would download those jars itself after installation

4:15 if so it would make sense for swank-clojure 1.2 to install its jar as well

4:15 but I don't know if that's really how it works

4:15 _rata_: but swank-clojure 1.2 is not in ELPA

4:15 in fact, is it possible to use the system-wide clojure installation with swank-clojure?

4:15 tomoj: what I am suggesting is to delete ~/.swank-clojure, install swank-clojure 1.2 manually, and then try using it

4:16 it should download the jars automatically

4:17 but swank-clojure for emacs is obsolete, I think

4:17 _rata_: I've download swank-clojure's git, but there's no installation instructions

4:17 tomoj: http://github.com/vu3rdd/swank-clojure-extra

4:17 _rata_: really?

4:18 tomoj: I don't use that stuff so don't trust me too much

4:18 see also http://groups.google.com/group/swank-clojure/browse_thread/thread/e6656cc66c5ac15f

4:19 bozhidar: tomoj: swank-clojure is obsolete?

4:19 after all slime for clojure depends on it :-)

4:20 tomoj: not swank-clojure, swank-clojure for emacs

4:20 i.e. swank-clojure.el

4:20 cschreiner: I always seem to pollute my namespace with definitions I don't want. How can I undefine a var from the repl?

4:21 * cschreiner is sure using the wrong terminology

4:21 _rata_: tomoj, ah ok... I read that in the git too

4:21 bozhidar: tomoj: this seems unlikely to me, since in some point you have to bridge slime and clojure and you have to do it in Emacs Lisp...

4:21 at some point*

4:22 _rata_: bozhidar, not necessarily when you use slime-connect (IIRC)

4:22 tomoj: I don't have swank-clojure installed in my emacs

4:23 yet I use slime for clojure

4:23 so, doesn't seem altogether unlikely to me

4:23 ,(doc ns-unmap)

4:23 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

4:23 tomoj: cschreiner: ^

4:23 bozhidar: tomoj: I read the docs, you're right

4:24 tomoj: it seems that swank-clojure.el simply provided the means to start swank-clojure from emacs

4:24 cschreiner: tomoj: yeah, suspected that one, ty

4:32 esj: bozhidar: I'm not if this helps, but what I do to get a 1.2 repl in emacs is to run >lein swank for the the project directory to get a swank server, then in emacs >silme connect to get a repl

4:34 _rata_: the syntax highlighting in emacs is swank-clojure thing or a clojure-mode thing?

4:34 tomoj: clojure-mode

4:34 _rata_: ok :)

4:43 bozhidar: esj: you probably meant to say _rata_ :-)

4:45 esj: bozhidar: apologies... that's what skim reading gets me

4:46 bozhidar: esj: np

4:57 _rata_: how can I know which swank-clojure I'm using?

4:59 esj: _rata_: why do you want to know that?

5:01 _rata_: seriously, if what you want is Clojure 1.2, connected into emacs, my previous comment will get it for you.

5:01 tomoj: only with project overhead

5:03 _rata_: because I'd suppose that emacs doesn't have enough information to know where to find swank-clojure... plus I have two swank-clojure around and I don't know which one is using

5:03 it's really not an important thing

5:03 because I now have swank-clojure 1.2 :)

5:04 and the flatten function :)

5:04 it was just out of curiosity

5:04 esj: nice, enjoy !

5:05 _rata_: but I'm amazed at the way I could finally do it

5:05 I was expecting it not to work

5:14 brehaut: hmm. enlive could do with a defmultisnippet

5:15 cgrand: brehaut: what would it do?

5:15 brehaut: mashup of defsnippet and defmulti

5:16 it maybe that im too inexperienced to see how it would fit together

5:16 but my attempts to use (snippet ...) as the rhs of a defmethod form all failed

5:16 and ive opted to define each snippet and then the method that applies them

5:18 (i have a bunch of 'fragments' in a couchdb that i pull out. each has a :type that i switch on to work out how to render them)

5:23 cgrand: btw cheers for moustach and enlive. both are working out well for me

5:24 cgrand: brehaut: http://gist.github.com/432752

5:25 brehaut: cgrand: perfect :)

5:27 cgrand: brehaut: you're welcome

5:47 _rata_: good bye guys :)

5:48 thank you all

5:51 LauJensen: Morning all

5:51 rrc7cz: good morning

5:51 lpetit: Morning Lau

6:00 esj: Hello Lau

6:14 candera: Anyone know of any libraries for creating Swing UIs declaratively in Clojure?

6:15 AWizzArd: candera: I know of a Clojure-Lib for creating Pivot applications. See http://github.com/hoeck/clj-pivot and for Pivot itself: http://pivot.apache.org/

6:17 candera: AWizzArd: thanks. I'll check that out.

6:18 Raynes: candera: Licenser has written a sort of wrapper around Swing in Clojure. http://github.com/Licenser/clj-swing I believe

6:18 kensanata: Yeah, apparently there's a form macro based on http://stuartsierra.com/2010/01/05/taming-the-gridbaglayout

6:19 Licenser_: ping

6:19 Licenser: kensanata: pong

6:20 candera: OK, cool. I remember seeing mention of that. Didn't know it had a home.

6:20 Licenser: it's incorporating it, not based on it :P

6:20 kensanata: Hehe

6:21 Licenser: and there is stuff for text fields, trees, panels, combo boxes

6:22 AWizzArd: Though swing does not support data binding, and is unfortunately more ugly to code, and some nice other features are not available.

6:23 Licenser: wait clj-swing has data bindings, the trees, foends and combo boxes are all backed by cljure STM constructs as data bindings

6:24 but I think clj-pivot might be more compleat

6:27 AWizzArd: I am not sure if we mean the same thing by data binding. In Pivot terms it means that you can just say something like: (fill-form-fields my-map), and then all 12 fields in a form are filled. So, you don't need to write (do (.setText field1 (:name my-map)) (.setText field2 (:age my-map) ... (.setText field12 (:username my-map)))

6:28 Though, it would be cool if you could add such a feature to clj-swing!

6:31 And the other direction should also be supported. If you want to send a filled out form back to the server you only need to say in Pivot something like: (get-form-data the-form) ==> map-with-all-data

6:35 Licenser: AWizzArd: Swing is not the same as piviot, this sounds very webby

6:35 swing is more interactive and less send stuff forth and back

6:36 you can certenly do something like that already just use a map of refs to represent data bindings

6:38 AWizzArd: Well, not so webby. Form data needs to be handled anyway to be useful. The target could be a text file or a database then.

6:42 Licenser: yes but the idea of sending data forth and back is kind of webby, opposite to just having it there


6:44 esj: can somebody explain the reasoning behind what appears to be an inconsistency:

6:44 ,(subseq (sorted-set 4 5 6) > 7)

6:44 clojurebot: nil

6:44 esj: ,(subseq (sorted-set 4 5 6) < 3)

6:44 clojurebot: ()

6:44 esj: why nil in one case and empty set in the other ?

6:44 AWizzArd: Licenser: Just replace in my original statement that part with writing data from a db, or read it from there and put it into the form.

6:45 ,(doc subseq)

6:45 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

6:45 cemerick: G0SUB: thanks for the happy msg on docuharvest :-)

6:46 AWizzArd: esj: the docstrings don't mention that subseq will return nil. It will always return a seq... in theory ;)

6:46 rhickey: has anyone tried the prim branch?

6:47 AWizzArd: What is special about it?

6:47 rhickey: AWizzArd: it has static linking and primitive support in fns

6:48 esj: AWizzArd: OK, so its an 'undocumented feature'

6:48 cemerick: rhickey: I think an assembla page is needed for prim so people have an idea of what it's about

6:48 AWizzArd: rhickey: oh, that sounds good

6:48 cemerick: yes, I didn't even notice that there is such a branch

6:48 cemerick: (benchmarks are a magnet for such things, too ;-))

6:48 AWizzArd: I only saw rhickey talking about :static and basically a day later he already said that he implemented it :)

6:49 rhickey: cemerick: Yes, have to make it first, then doc it. I'm wary of hype on it though

6:49 cemerick: AWizzArd: I knew about it, and looked at the code very briefly, but as much as I'm here, even I don't know the full story :-)

6:49 rhickey: because it's thoroughly experimental, liable to be dropped, or just in flux?

6:49 rhickey: some other useful things came out of the effort. I ran up against the max method size limit on the core init code, and added support for breaking up init into multiple methods

6:50 cemerick: because I don't like hype

6:51 cemerick: oh, Rich. :-)

6:51 rhickey: when I'm done here, I'll run your PR operation so you don't have to bother with it.

6:51 ;-)

6:51 rhickey: heh

6:52 anyway, once the tea kicks in here I'll consider moving it into master

6:52 then I'll get feedback :)

6:52 cemerick: really?

6:52 I assumed this was post-1.2

6:54 rhickey: cemerick: It is an important complement to what's in 1.2. Right now I find I often am using definterface in order to get helper methods that take/return primitives for deftypes, there's no way to write factory functions to construct deftypes without boxing the ctor args, there are no knobs on direct linking. This work addresses all of that

6:55 I wouldn't want to wait 6 months or more for this, and back-to-back releases is a lot of non-productive work

6:57 :static itself can be labelled experimental

6:57 cemerick: rhickey: I'm sure you're right, but there's tons of stuff that could be complimentary to stuff that's in 1.2.

6:57 rhickey: cemerick: like?

6:59 cemerick: I should have said "I'm sure there is tons of stuff...". The only thing off the top of my head is user-defined factory fns for defrecord, but by broader point is that more releases are better than fewer. I'm certain people wouldn't mind more frequent releases with fewer features / release.

6:59 A regular cadence is also good for hype. ;-)

6:59 Twey: Why is there this pattern I see in the docs of defining a bunch of arguments even when the last one ends with &rest?

6:59 ,(doc partial) ; for example

6:59 clojurebot: "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

7:00 Twey: Why isn't it just [f &args]?

7:00 rhickey: Twey: performance

7:00 Twey: The fixed ones are specialised somehow?

7:01 rhickey: there is work involved in getting things out of the & seq that need not occur for args in hand

7:01 Twey: Ah… hm, okay

7:01 Couldn't this be done behind the scenes somehow?

7:01 rhickey: no

7:02 the body of [f arg1 arg2] uses arg1 and arg2 by name. Couldn't automatically create that code from just & args

7:04 you might be able to write a macro to write such functions though. I haven't looked into that, but now that there are a few instances, one could look to automate it

7:05 cemerick: keeping useful, already implemented features-to-be in master seems like a way to keep everyone on snapshots

7:06 but we are ready to pull the trigger on 1.2, you don't want primitive args?

7:06 cemerick: rhickey: the people who are willing to be on snapshots will *always* be on snapshots. The larger population isn't willing, and will only use releases.

7:07 Oh, I think *everyone* wants primitive args. I think there's a lot to be said for dropping a release now instead of adding significant changes that would need to percolate for....a few weeks, perhaps?

7:08 rhickey: cemerick: this release will have a true 'beta' period, as it already contains much not yet percolated

7:09 cemerick: even more reason to not try to put a star on top of the already-laden tree then

7:09 rhickey: cemerick: then I should turn off current direct linking as that will not be the future, giving everyone a perf hit

7:10 Raynes: But stars are pretty.

7:10 cemerick: rhickey: pulling that out when statics go in would be a breaking change?

7:10 rhickey: the best way to help make this an informed decision is to try the prim branch

7:11 cemerick: dunno, but I could either support issues around it (dead) or statics (future)

7:11 cemerick: kheh

7:12 rhickey: plus, users can't actually use direct linking themselves, a huge loss. I know I want direct linking for my code

7:12 cemerick: fair enough, then.

7:13 oh, I was never doubting the utility

7:13 rhickey: right now we have tests for clojure and contrib, plus a suite called argos which contains several popular libs and their tests. All tests pass with prim

7:14 cemerick: good to know

7:14 where's this argos?

7:14 rhickey: http://github.com/stuarthalloway/argos

7:14 cemerick: right, I knew about that :-/

7:15 Then, ignoring primitives, I think everyone would like to see more frequent releases, as "non productive" as they are. ;-)

7:15 Just moving the contrib stuff over could have constituted a release, IMO.

7:15 (for example)

7:16 rhickey: other neat things in this work - recognition of map (and soon vector/set) literals composed of literals, and avoiding evaluation of same

7:16 cemerick: I wouldn't want to see releases of a language more frequent than every 6 months

7:17 feature releases that is

7:17 cemerick: not sure what "feature releases" are

7:17 rhickey: releases that add features vs just fix bugs

7:17 cemerick: ah

7:18 6 months is a *long* time

7:18 rhickey: to wait for new features in a language?

7:18 I disagree

7:19 cemerick: I think that might be appropriate for a "mature" language, where gotta-have-it features come up rarely

7:20 rhickey: If you gotta have it, there's git

7:23 AWizzArd: I was also thinking about this, and while a realese every 3 months does not leave too much room for improvements, it could be a target to have close to 2 releases per year.

7:34 rrc7cz: are there any inspection fns for objects? I don't mean the inspector for a clj data structure, but I have an instance and I'd like to list its members and such

7:35 AWizzArd: rrc7cz: you can use JVM reflection.

7:36 rrc7cz: AWizzArd: definitely, but I _really_ thought there was a clojure fn that did this

7:36 AWizzArd: rrc7cz: http://java.sun.com/javase/7/docs/api/java/lang/Class.html

7:36 ,(doc show)

7:36 clojurebot: "clojure.contrib.repl-utils/show;[[x] [x selector]]; With one arg prints all static and instance members of x or (class x). Each member is listed with a number which can be given as 'selector' to return the member object -- the REPL will print more details for that member. The selector also may be a string or regex, in which case only members whose names match 'selector' as a case-insensitive regex will be printed. Finally

7:36 rrc7cz: that's it!

7:36 AWizzArd: k

7:36 rrc7cz: thanks

8:00 rhickey: vector and set constants now in prim

8:01 AWizzArd: So, those are really immutable?

8:01 Or what does "constant" mean in this context?

8:12 rhickey: AWizzArd: the evaluation model of literal vectors maps and sets in code is that their contents are evaluated, and a corresponding vectors/map/set created wit hthe result. This actually happens, even when the contents are themselves literals, meaning you always get the overhead of a ctor call at least. Now, if the contents are compile-time constants (e.g. 1, "fred", :ethel), so is the collection, no runtime cost

8:15 tomoj: "java.lang.IllegalArgumentException: Unable to resolve classname: ARef (inspector.clj:184)" weird

8:15 line 184 is in the middle of a comment

8:15 rhickey: e.g. in (let [a 1 b 2] [[a b] [1 2]]), the [a b] vector needs evaluation, the [1 2] vector doesn't

8:16 AWizzArd: rhickey: damn, you are good!

8:16 I want that (:

8:16 rhickey: not really, it should have always been this way

8:16 just never got around to it

8:18 AWizzArd: No really, that's great

8:18 * AWizzArd cheers

8:19 rrc7cz: has anything changed in proxy/gen-class for allowing method overriding based on the type signature? The only method I know now is the Mark Triggs' fn name example -read-void, etc.

8:20 rhickey: rrc7cz: genclass can have separate handlers for different type sigs

8:21 -name-types

8:21 rrc7cz: rhickey: okay, that's what I found in Mark's article

8:21 tomoj: so after that last commit, with (defn foo [] [1 2 3]), (identical? (foo) (foo)) is true

8:21 nifty

8:22 rrc7cz: rhickey: is there any reason why this isn't possible: (proxy [ASTVisitor] [] (visit [#^MethodDeclaration node] ...))

8:22 I mean, using the meta type hints to specify argument type?

8:22 rhickey: proxies are name based

8:22 rrc7cz: I mean in general, like any reason this wouldn't be a better option that embedding the type name in the fn name

8:23 rhickey: so all with same name will flow to same function, but you could switch on the type there

8:23 The-Kenny: I just asked myself the question what happens when there are two methods overloaded by argument-type.

8:24 like void foo(int); foo(String)

8:24 will proxy proxy both methods?

8:24 rhickey: The-Kenny: yes, all with same arity will go to the same place

8:24 name + arity

8:24 rrc7cz: rhickey: I could, but then it requires writing a forwarding method for ASTVisitor, which has a ridiculous number of overrides :-) I'm mostly curious why you chose to embed the type name in the fn name instead of using the meta type hints

8:24 The-Kenny: rhickey: Ah, good. That's nice :)

8:26 rhickey: rrc7cz: you are going to have to deal with the ridiculous number of overrides somewhere

8:27 rrc7cz: rhickey: not when I only want to override one of them in my subclass, in this example a specific (visit [#^MethodDeclaration node]) versus forwarding on 30 others. I'm just trying to figure out why gen-class uses foo-Integer-String-Node [i s n] versus foo [#^Integer i #^String s #^Node n]

8:27 rhickey: rrc7cz: to answer your question though, proxy has a tangible dispatch map. Keys differing only in metadata are not distinguishable

8:27 rrc7cz: aha

8:28 because metadata is ignored during equality, right?

8:28 rhickey: right

8:28 rrc7cz: ok

8:44 cgrand: rhickey: I'm sorry if I hyped prim

8:45 rhickey: cgrand: you never hype

8:45 :)

8:45 cgrand: rhickey: on the "more constants" front, couldn't (long 42) and (double 3.14) be recognized as primitive constants?

8:46 rhickey: cgrand: the jit gets those calls there

8:46 they inline to static methods, always provided final arg...

8:47 what I want to get rid of is (long 42)

8:48 AWizzArd: In what way?

8:48 cgrand: ah ok! And having 42L expands to (long 42) is a no go since it would be very surprising when writing macros...

8:48 rhickey: that begs the semantic question of: should integer arithmetic auto-promote by default, or default to throw-on-overflow. The latter would unify Long and long behavior, so we could just write 42 in either context and get the same result

8:49 my preference is throw on overflow.

8:50 It's probably the biggest thing I'd like to 'fix'

8:50 but definitely a breaking change

8:51 for all those factorial demos :)

8:52 cgrand: yeah, I was going to ask if many production code relied on autopromotion

8:53 rhickey: the problem is, when you talk about this, it becomes a theoretical debate rather than a practical one. IMO, auto-promotion is impractical on current hardware, and Lisp machines haven't caught on

8:55 but a single-character reader suffix for BigInteger *would* work, as arithmetic with them would be contagious (as with doubles)

8:55 dnolen: rhickey: did you see my bug report? #^ARef causing exception on prim branch?

8:55 ?

8:55 rhickey: so just seed your factorial with 1B[ig] or whatever

8:56 dnolen: no, where?

8:56 what would the BigInteger suffix be?

8:56 dnolen: rhickey: http://groups.google.com/group/clojure/browse_thread/thread/82ca8e92b0461651

8:56 rhickey: N?

8:56 clojurebot: compilation is see compile

8:57 cgrand: ,(class 1.4M)

8:57 clojurebot: java.math.BigDecimal

8:57 rhickey: dnolen: is Aref imported?

8:57 cgrand: rhickey: there is already M

8:57 rhickey: cgrand: I suggested N

8:58 cgrand: oops I misread BigInt for BigDec

8:58 rhickey: ah

8:58 dnolen: if not, you had a user-side bug before

8:58 also, #^ is now ^

8:59 dnolen: rhickey: yes about #^. ah, ok, so that just wasn't throwing an error before. This is a swank-clojure bug that's biting me.

8:59 _fogus_: cgrand: There is an extra space in your final example --> ^{:static true :tag long : doc "docstring"}

9:00 rhickey: dnolen: hrm, swank-clojire is in argos, and tests pass there

9:00 cgrand: _fogus_: fixed, thanks

9:00 _fogus_: :)

9:02 rhickey: so, any opinions on moving numeric semantics to throw-on-overflow by default, ask for BigInteger with contagious 1N constants (as well as bigint coercion op)

9:03 my feeling is contagion is the key. As with doubles, once you are in that space you stay there, without worry about every component of the calculation

9:03 cgrand: what about ratios?

9:04 rhickey: are already ratios of bigints

9:04 would normalize to bigint I guess

9:05 42/2 = 21N

9:05 bigints would always print with N

9:09 you'd never get bad numbers, and if you get the overflow exception you forehead-slap and add an N somewhere

9:11 AWizzArd: rhickey: can we detect where the N was forgotten?

9:12 _fogus_: I think that sounds fine. It's more work WRT the book, but what can you do? ;-)

9:12 rhickey: AWizzArd: it's contagious

9:15 cgrand: I think it is more likely people will break from 42 being a Long, rather than Integer

9:16 people love switching on types

9:18 _fogus_: Maybe you could deprecate the type-based predicates (only half-joking)

9:21 dnolen: rhickey: definitely a bug in swank-clojure, just patched #^ARef -> ^clojure.lang.ARef and it works

9:21 rickey: another issue, http://gist.github.com/432975, anything obviously wrong here? getting a java.lang.VerifyError

9:21 opqdonut: oh those are the best

9:22 dnolen: rhickey: if I leave out the v binding, that fn compiles fine.

9:29 AWizzArd: rhickey: so, Long will be the new default?

9:32 The-Kenny: hm.. what's the best way to get an inputStream from a String which is either an http-url or a local file?

9:34 cemerick: The-Kenny: if you're on 1.2, clojure.java.io/input-stream

9:36 chouser: oh *there* it is. Couldn't find it.

9:37 The-Kenny: cemerick: Thank you, that's perfect :)

9:37 (I was searching in duck-streams)

9:37 rhickey: chouser: find what?

9:37 cemerick: clojure.java.io *is* duck-streams now, essentially

9:37 chouser: io in clojure.java. I was looking in clojure, clojure.core, ...

9:38 The-Kenny: cemerick: Yeah, I didn't know that it existed

9:38 Chousuke: I like that hosty stuff was put under .java :P

9:38 chouser: yeah, it's a good decision, I just forgot

9:38 Chousuke: I suppose there might be a real clojure.io someday

9:49 Twey: « Note: this is not really "duck typing" as implemented in languages

9:49 like Ruby. A better name would have been "do-what-I-mean-streams"

9:49 or "just-give-me-a-stream", but ducks are funnier. »

9:49 Hahaha.

9:52 duck1123: my type of streams

9:53 Twey: :-D

10:02 pedroteixeira: since there is an internal-reduce, are there plans for internal-map? does it even make sense to speed up map over vectors?

10:03 Chousuke: I don't think so

10:03 with reduce you know you'll be going over the entire collection but map returns a lazy sequence

10:03 pedroteixeira: Chousuke: couldn't a map over a vector return a vector? when benchmarking here, map over list is much faster.

10:04 Chousuke: vectors can't be lazy

10:04 Raynes: LazySeq, not LazyVector. :p

10:04 pedroteixeira: are there hints then to improve performance when iterating a vector?

10:04 Chousuke: though Rich has implemented a parallel map operation for vectors in a (rather old) branch

10:05 pedroteixeira: my use case is basically find the max item and its index, given a vector. trying different strategies here

10:05 rhickey: dnolen: fixed

10:05 Chousuke: manual looping is probably fastest

10:05 pedroteixeira: using a doseq with an atom to keep current max seems slow also.

10:06 Chousuke: though since you need to go over the vector in any case, you can also use reduce

10:06 atoms are definitely not needed.

10:06 pedroteixeira: Chousuke: ok, will keep trying here. thanks.

10:08 thought about using reduce, but thought would be weird to keep passing the index around.. will benchmark it :) this function needs to be ultra-fast

10:09 chouser: pedroteixeira: the simplest solution might be max-key. Not sure if loop/recur would beat that or not.

10:10 pedroteixeira: chouser: currently i'm using max-key, but I do a map before with (range (count v)) to get the item's index also. the map is slow, so trying to create a max-key-index for vectors.

10:13 chouser: ,(let [v [3 1 6 4], i (apply max-key v (range (count v)))] [i (v i)])

10:13 clojurebot: [2 6]

10:13 chouser: I was thinking something like that.

10:16 pedroteixeira: chouser: wow, that's really clever.. absorbing it still here, going to test it.

10:16 chouser: with .

10:17 I don't know why I said "with ."

10:17 eintr: is there a convenient way to make a reader that reads just a range of bytes from a file (offset, length)?

10:18 * eintr is lacking javafu.

10:40 hoeck: eintr: java.io.FileInputStream ?

10:40 aren't readers for character-data only?

10:41 dnolen: rhickey: a lot of things seem faster in the prim branch, but naive benchmarks on map/reduce seem more than 1.5X slower than master, (doall (map inc (range 1000000))), is that expected?

10:42 rhickey: dnolen: did you see your bug fixed?^^

10:42 eintr: i'm trying to get supercsv to parse a portion of a file, and it takes a Reader as argument.. so i need a Reader that will only "emit" parts of the file.

10:43 dnolen: rhickey: let me check now

10:43 AWizzArd: eintr: what class does the manual of supercsv suggest to use?

10:43 hoeck: eintr: then use the .skip method of the reader to jump to the offset

10:45 eintr: hoeck: sure, that far I got as well.. but as for stopping :)

10:47 hoeck: i need to limit the number of bytes read by the inputstream.. with a wrapper or something

10:47 hoeck: eintr:ah, now I do understand your problem, either subclass reader to only emit n characters

10:47 or read the portion of that file into a string and wrap the string into a StringReader

10:51 eintr: sth along: http://gist.github.com/433105

10:53 eintr: hoeck: thx cool.. i'll probably need a subclass though, 'cause i'm streaming large files.. thanks for the hint though :)

10:56 hoeck: eintr: then it may be worth to look into the java.nio CharBuffer, or ByteBuffer

10:59 rrc7cz: why might "lein compile" not generate a class when :aot [foo.bar] is configured, where (ns foo.bar (:gen-class :extends blah blah...). No errors, the /classes folder is created, but it's just empty

11:00 I got it to generate the class when I used (gen-class) instead of (ns foo.bar (:gen-class))

11:03 cgrand: rrc7cz: did you try :namespaces instead of :aot?

11:05 dnolen: rhickey: yes, code compiles now w/o error. thx!

11:06 rhickey: dnolen: perf degradation just some reflection that crept in, cleaning up now. Thanks for the reports!

11:06 rrc7cz: cgrand: still not working. My understanding was that namespaces was simply an alias for aot

11:08 dnolen: rhickey: yet another weird bug about not being able to find unchecked-remainder, sound plausible?

11:08 rrc7cz: the only thing I can think of is that using (gen-class) I explicitly give a :name foo.bar.Baz, whereas with (ns (:gen-class)) I simply have the namespace foo.bar.

11:10 cgrand: actually that fixed it! I had two "ss" in namespaces when I first tried it

11:10 cgrand: if namespace is simply an alias of aot according to the documentation, why does this fix it?

11:10 cgrand: rrc7cz: I don't know: I got the same problem the other day and no time to investigate

11:11 rrc7cz: cgrand: anyway, thanks for the tip

11:46 technomancy: dnolen: I can't repro the swank problem you reported with clojure master (which prim got merged to)... are you still seeing it?

11:46 oh never mind; I misread. it didn't get merged.

11:47 dnolen: technomancy: yeah, it's a simple fix really. In fact I note that it's probably an oversight, all the other type hints have the clojure.lang prefix except for ARef

11:47 in inspector.clj

11:48 technomancy: yeah, I am somewhat surprised it works without being fully-qualified. edge case of lookup rules, I guess.

11:49 dnolen: technomancy: it would also be nice to get my pretty print macroexpand patch in :)

11:50 technomancy: dnolen: it's certainly on my list. it's just that "it's broke" reports are higher priority. =)

11:51 defn: I'm looking to take a collection of integers [11 21 22 23 24 26] and return [11, 22, 24]

11:51 basically the first, third, and fifth elements in a collection will be the return

11:57 rhickey: dnolen: perf fixed

11:57 dnolen: rhickey: ^ did you see the unchecked-remainder thing I mentioned?

11:57 rhickey: dnolen: do you have a gist of the unchecked-remainder thing?

11:57 dnolen: yes one second

12:01 rhickey: http://gist.github.com/433208

12:02 rhickey: if you run the last perf test in the comment at the bottom you'll see what I'm talking about.

12:02 rhickey: dnolen: that's too much context for me to look at, I'm afraid

12:03 dnolen: rhickey: heh yeah, let me come up with something smalle based on what I'm seeing.

12:03 yacin: ,(doc key)

12:03 clojurebot: "([e]); Returns the key of the map entry."

12:03 dnolen: s/smalle/smaller

12:03 yacin: what are map entries?

12:03 i don't understand what this does or how it's used

12:04 Chousuke: yacin: running seq on a map gives you a seq of map entries

12:04 yacin: they're basically two-element vectors

12:04 yacin: got it

12:05 thanks

12:06 Twey: ,(key ['a 'b])

12:06 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

12:06 yacin: ,(map key {:a :b})

12:06 clojurebot: (:a)

12:06 yacin: ,(map val {:a :b})

12:06 clojurebot: (:b)

12:06 Twey: ,(map id {:a :b})

12:06 clojurebot: java.lang.Exception: Unable to resolve symbol: id in this context

12:06 Twey: Eh

12:06 ,(map (fn [a] a) {:a :b})

12:06 clojurebot: ([:a :b])

12:07 chouser: ,(seq {:a :b :c :d})

12:07 clojurebot: ([:a :b] [:c :d])

12:07 Twey: Ah ☺

12:07 ,((compose class first seq) {:a :b})

12:07 clojurebot: java.lang.Exception: Unable to resolve symbol: compose in this context

12:07 Twey: ,((comp class first seq) {:a :b})

12:07 clojurebot: clojure.lang.MapEntry

12:08 Twey: ,((comp meta first seq) {:a :b})

12:08 clojurebot: nil

12:08 a_strange_guy: ,(type (find :a {:a 1 :b 2}))

12:08 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map

12:08 Twey: I've never found anything for which ‘meta’ doesn't return nil

12:08 a_strange_guy: ,(type (find {:a 1 :b 2} :a))

12:08 clojurebot: clojure.lang.MapEntry

12:08 Twey: Are there any built-in values that use it?

12:08 a_strange_guy: (meta +)

12:08 Twey: ,(meta +)

12:08 clojurebot: {:ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :line 793, :arglists ([] [x] [x y] [x y & more]), :added "1.0", :inline-arities #{2}, :inline #<core$_PLUS___3866 clojure.core$_PLUS___3866@1b7713d>, :doc "Returns the sum of nums. (+) returns 0."}

12:08 Twey: Oh

12:09 Huh

12:09 I don't get that in my local REPL

12:09 a_strange_guy: all vars and fns have metadata

12:09 Twey: Just nil

12:09 a_strange_guy: ,(meta #'seq)

12:09 clojurebot: {:macro false, :ns #<Namespace clojure.core>, :name seq, :file "clojure/core.clj", :line 114, :arglists ([coll]), :doc "Returns a seq on the collection. If the collection is\n empty, returns nil. (seq nil) returns nil. seq also works on\n Strings, native Java arrays (of reference types) and any objects\n that implement Iterable.", :tag clojure.lang.ISeq, :added "1.0"}

12:09 yacin: i also get nil

12:09 Twey: Ah, I get the metadata for #'seq

12:09 yacin: yeah, #' fixes it

12:09 a_strange_guy: you use 1.1?

12:10 in 1.2 functions can have metadata

12:10 Twey: Yeah, I'm on 1.1

12:10 a_strange_guy: before that only collections, reftypes(inc. vars) and symbols could have metadata

12:11 Twey: No 1.2 in AUR yet… I'll upgrade when it comes

12:14 raek: which metadata does functions in 1.2 usually have? same as the var that contains it?

12:15 chouser: yep

12:25 dnolen: rhickey: ok, probably related, should areduce work inside of a defn ^:static?

12:29 rahulkmr: I am using emacs 23, slime and swank. Multithreaded programs don't work for me, or rather only run once. After that they throw a error: java.util.concurrent.RejectedExecutionException (par_scan.clj:0) Is it a known issue?

12:29 I am running it as C-c C-k

12:37 rhickey: dnolen: areduce should be fine

12:39 dnolen: rhickey: http://gist.github.com/433269

12:40 rhickey: both amap and adreduce seem to be affected

12:40 rhickey: dnolen: works here

12:41 dnolen: you running on a clean rebuild?

12:43 dnolen: rhickey: yes, gist updated, this seems weird now

12:44 rhickey: I added a second definition and then then I get the exception

12:45 rhickey: still works

12:45 ah, with namespace it doesn't

12:46 I'll look

12:51 dnolen: fixed, thanks for the report

13:04 dnolen: rhickey: ah, so (unchecked-remainder (int 0) (long 500)) should not work?

13:04 rhickey: dnolen: must match

13:07 The-Kenny: hm... is there a easier way to convert an InputStream to a ByteBuffer than reading from it in a loop/recur?

13:13 dnolen: rhickey: gotcha, thx

13:17 technomancy: The-Kenny: clojure.java.io/copy probably

13:18 The-Kenny: technomancy: "Output may be an OutputStream, Writer, or File." - Doesn't look so

13:21 technomancy: The-Kenny: wrap a ByteArrayOutputStream?

13:22 The-Kenny: technomancy: Huh, what a great idea (You see why I just hate java-io)

13:23 clojure should have binary-slurp as a counterpart to slurp :)

13:45 cmiles74: k

14:00 rhickey: keyword callsites now compatible with static

14:01 chouser: prim's is for post-1.2, right?

14:01 * chouser fetches prim

14:02 cemerick: rhickey: see, I'm just your canary in the coal mine ;-)

14:03 rhickey: here's the difference: http://gist.github.com/433369

14:04 note, this is not using primitives, and no change to core code other than from direct linking to statics

14:04 cemerick: still want to wait?

14:04 cemerick: damn, numbers really help with decision-making!

14:05 rhickey: note, I never said it wasn't a good change ... forward progress is still orthogonal to comprehension and such by the broader community, new users, etc.

14:05 LauJensen: What are these statistics mentioned?

14:06 rhickey: this is just the tip of the iceberg of what you can do with the prim branch, perfwise. I'm quite surprised to see this big an increase for no real change in user code

14:06 cemerick: rhickey: I promise I will not be the one to hype that gist.

14:06 :-D

14:06 rhickey: cemerick: I understand, believe me, this could have been in master already

14:09 however at this point, barring ay more bug reports (thanks dnolen!), I think it's done

14:10 * _fogus_ just fainted from gist exposure

14:10 a_strange_guy: may I ask what makes static defn's so fast

14:12 rhickey: a_strange_guy: normal fn calls go through a var, which, being variable, is volatile, and an inhibitor to inlining by hotspot. Direct linking improved that by caching the fn object. statics get rid of the fn object in some calls, replacing it with a static method that does the same job. HotSpot can inline right through those, quite easily

14:13 a_strange_guy: so it works like those fns like + etc.

14:13 inlining calls to a static method when possible, and else use the fn?

14:13 nice

14:13 rhickey: a_strange_guy: somewhat, but they required me to write a JAva static method _and_ a fn, and declare the fn inline etc. This now fall out of putting (defn ^:static foo ...)

14:14 technomancy: ah, so it's more to help out hotspot than _just_ to avoid the var lookup cost. that makes sense.

14:15 rhickey: a_strange_guy: a fn object is still in the var for use as a fn value, i.e. inc in that gist is not being called via the static

14:18 a_strange_guy: rhickey: any interest on a proposal to make deftype/record real fns, but still directly constructable, when performance is needed?

14:18 rhickey: a_strange_guy: this work is needed in part to support other options in that area, yes

14:19 a_strange_guy: http://gist.github.com/429080

14:19 rhickey: in particular, removing the 'do something else when performance needed' bit

14:20 a_strange_guy: basically its putting the classname in the metadata on the var and fn

14:21 so (Foo 1 2 3) is a Fn call through a var

14:21 and (new Foo 1 2 3) or (Foo. 1 2 3) would be a direct call of the ctor

14:25 LauJensen: rhickey: Is this going in 1.2 ?

14:26 rhickey: LauJensen: dunno - you all should try it and tell me

14:28 LauJensen: rhickey: You looking for any specific feedback, or should we just run it on recent code and see if anything breaks?

14:29 dnolen: LauJensen: probably more useful to take some of your performance examples and convert to statics.

14:29 rhickey: LauJensen: you can just try your stuff and look for breakage, and/or try the new static and primitives stuff

14:30 LauJensen: I'll drop a line if anything breaks

14:31 * dnolen is looking forward to converting all his ugly perf code to deftype+protocols+statics

14:38 raek: does this static thingy affect redefinition of functions?

14:38 dnolen: raek: no

14:38 chouser: yes

14:38 LauJensen: maybe

14:39 dnolen: chouser? really?

14:39 a_strange_guy: yes it does

14:39 dnolen: chouser: oh yeah, if you called by name in some *other* function

14:40 chouser: if fn b uses static fn a, and then you redefine a, b will continue to use the old version until you also reload b

14:40 dnolen: right

14:40 raek: ok, makes sense

14:40 rhickey: statics essentially follow rules similar to macros

14:41 but there is no reason to tag something as static until you are essentially done with it

14:42 dnolen: rhickey: I like the design. You can evolve your program to be fast.

14:42 LauJensen: aha. Isnt there a way to provide some kind of warning of you redef something, which wont take effect because its called from another fn which needs redef also? Or automate it or something like that?

14:43 bobo_: LauJensen: if you didnt know the gist you posted on twitter is deleted.

14:44 LauJensen: bobo_: ah thanks - Anybody forked it?

14:45 rhickey: Note - I haven't been able to reproduce the results in my gist, so I've deleted it. Things are faster but not by that much. My 1.2 session must have been mucked up in some way

14:45 slyphon: 1/

14:45 LauJensen: rhickey: ah ok

14:46 yacin: is there a limit to the size of the string that can be passed into sh with :in?

14:47 i'm trying to throw a 66k line string into it, and it just hangs

14:47 trying to avoid having to dump to a tempfile and input from there

14:48 chouser: yacin: sh probably needs to be multithreaded to avoid getting hung up on inputs or outputs larger than the OS's buffer

14:48 there was a message on the list. I just haven't had the time to deal with it yet.

14:49 yacin: gotcha

14:49 chouser: I don't actually use sh much. :-/

14:49 yacin: yeah, i try and avoid it if at all possible

14:49 but this particular web service i'm using makes a point of saying it only works with gnu netcat

14:51 is there anyway to do <, > or | with sh?

14:51 LauJensen: cemerick: I heard some talk about the need for a quality Clojure IDE and that some people were willing to pay 500$ per seat for it - Just wondering, why isnt something like Enclojure filling that spot?

14:51 chouser: yacin: you can use (sh "bash" "-c" "whatever < here")

15:03 rhickey: love the stack comments :-)

15:04 LauJensen: no comments on wether the redeffing could be helped along some?

15:06 a_strange_guy: LauJensen: I think this would require something like ADSF

15:06 LauJensen: ?!

15:06 a_strange_guy: giving some compiler warnings in Clojure would require the packagemanager from Common Lisp?

15:07 timcharper: LauJensen: I read that article. He said paredit mode was a requirement for that IDE

15:07 (and I would agree)

15:07 also... toggleable rainbow parens

15:07 LauJensen: oh - I think I should start selling Emacs installations for 500$/seat then :)

15:07 a_strange_guy: i don't think compiler warnings would be useful

15:07 timcharper: LauJensen: Good idea! For both fun and profit!

15:08 a_strange_guy: because every macro, static, and deftype would emit them

15:08 LauJensen: timcharper: I think seriously, if you listed all the features of Emacs and called it "Hyper Max IDE 2010" then you could probably sell quite a few licenses

15:08 (until rms found out)

15:09 chouser: to be useful, I think every user of a macro or static would have to register itself such that when the macro or static is redefined it could tell you what else might need to be reloaded

15:09 timcharper: hey... "distribution fees" are allowed with the GPL, aren't they?

15:09 It costs me $500 to burn this to a CD or let you download it.

15:09 chouser: but that would surely be a modularity problem in the general case. Maybe something an IDE could do for you?

15:10 LauJensen: chouser: perhaps - wouldnt it make sense in core?

15:10 timcharper: OK, I'm stretching it, and I'm being part of what's wrong with the world.

15:10 a_strange_guy: I personally think that such registering should be in the language

15:10 chouser: LauJensen: you want every var in core to have list all the function using it?

15:10 dnolen: Laujensen: I'd first like to see if it's really problem.

15:11 LauJensen: dnolen: Its been a problem for me in the past with macros

15:11 a_strange_guy: dnolen: it surely is a problem

15:11 dnolen: I suspect that people will only use statics only in very perf critical components of their programs. At that point you know what you're doing anyway.

15:11 LauJensen: chouser: If thats whats needed

15:11 dnolen: Laujensen: only a problem if you're doing REPL heavy stuff

15:12 LauJensen: dnolen: Which Im always doing

15:12 dnolen: around performance

15:12 which you should be doing often

15:12 shouldn't I mean

15:12 chouser: not a problem if you tend to use :reload-all to get your repl up-to-date

15:12 arohner: I use the nuclear option (require 'my-top-level-ns :reload-all). I never have problems

15:13 chouser: string's not in core yet?

15:13 arohner: yes

15:14 LauJensen: Odd, its rare that I use that work-flow

15:15 chouser: LauJensen: how often do you forget to send a form to the repl and have to go jump around in your file sending things?

15:15 LauJensen: Close to never

15:16 dakrone: LauJensen: what happened to your gist on twitter? Did you delete it?

15:16 dnolen: statics nicely solve the inner loop arithmetic performance problem that has plagued clojure, and it makes core calls zippy. What else does it buy us?

15:16 LauJensen: dakrone: Yes - It had an error, sorry

15:16 chouser: simply because you don't forget to send forms when you're done editing them, or what?

15:16 dakrone: ahh, okay

15:16 LauJensen: chouser: yes

15:16 Its also wired into my fingers to eval every time I close a parens :)

15:17 yacin: chouser: thanks, worked like a charm

15:18 a_strange_guy: you could hack such a dependency tracking system using watchers & metadata probably

15:19 chouser: a_strange_guy: ah, interesting!

15:20 a_strange_guy: if all the special forms were macros or namespaced you could redefine def to find all references to other vars and save them

15:22 arohner: a_strange_guy: def isn't a macro, but fn is

15:22 a_strange_guy: it should be hooked onto the creation of a var

15:22 arohner: someone (technomancy?) already has an fn source metadata hack that's pretty cool

15:23 a_strange_guy: or even better onto 'defn !

15:24 chouser: it'd be hard to get 100% coverage without hooking into the compiler more deeply than I know how without a patch.

15:24 even then, it would be hard to know how to re-compile all possible users.

15:25 (defn ^:static f []) (add-watcher #'g :c (fn [k r o n] (f)))

15:26 now #'g has a watcher fn that uses a static.

15:26 a_strange_guy: if you know what vars are using another var, then you could use the linenumbers to reeval the code

15:26 chouser: (defn ^:static f [] :new-f)

15:27 a_strange_guy: i think tracking other vars would cover 99% pecent of usecases

15:27 chouser: a watcher on f could now notify you that it's been updated, but did you hook add-watcher to register :c? And if you did, how do you update it -- remove the old watcher and add a new one?

15:27 a_strange_guy: yes. 99% is much easier than 100%

15:28 a_strange_guy: defn could be redefined to walk the body of its code

15:28 and to try resolve all the symbols

15:29 when it hits a var, you have a dependency

15:29 chouser: a_strange_guy: yes, you'd have to do something like that.

15:29 a_strange_guy: hackish, but possible

15:29 arohner: having watchers on namespaces would also do it. watching a namespace seems pretty cool actually

15:29 a_strange_guy: if you have compler support it would be much cleaner

15:29 chouser: of course it would have to not register things that *look* like a var-call but actually aren't.

15:31 * a_strange_guy is imagining a Lsp without special forms

15:33 LauJensen: Sounds complicated. And 99% accuracy is 100% unrealiability

15:34 a_strange_guy: not if you have compler support

15:34 * axi givse a_strange_guy an 'i' key

15:34 chouser: but with compiler support comes modularity problems

15:34 a_strange_guy: axi: thanx iiiiiiiiii

15:34 chouser: if every fn has refs to every fn that uses it, those users can never go away

15:34 LauJensen: chouser: like what?

15:35 * dnolen predicts statics will appear in 10% of libraries at most, and in those libraries they will comprise 5% of the code. Those people writing this code love rhickey for this addition and fully understand the implications of static during REPL development.

15:35 chouser: dnolen: yeah

15:36 a_strange_guy: chouser: you mean gc?

15:36 LauJensen: dnolen: Its not that I dont understand macros or statics, Im just saying Ive been forgetful with redefs in the past, and if there was a simple way to ensure no future breakages like that, I'd be happier

15:36 chouser: a_strange_guy: yeah

15:36 a_strange_guy: Java has some stuff that one could use

15:36 Referencequeues etc.

15:37 chouser: even with compiler support, how do you handle anonymous fns like my watch example above?

15:37 dnolen: Laujensen: sure. Also I wish GCC to point out magically point out memory leaks in C code :)

15:38 arohner: dnolen: have you tried valgrind? it's magical

15:38 a_strange_guy: chouser: probably not

15:38 but this would only work for sourcefiles that only have definitions

15:39 a good compromise would be to track only 'def forms

15:41 Chousuke: dnolen: we'll probably see lots of newbies using statics everywhere though :P

15:42 dnolen: Chousuke: yup and that's what we're here for :)

15:42 Chousuke: heh

15:42 humans are very good at doing the wrong thing

15:42 a_strange_guy: this is why I hate "performance first" mentality

15:42 Chousuke: fortunately they're a bit better at learning from mistakes than other animals

15:46 LauJensen: Chousuke: I'll label that: self delusion

15:50 kotarak: Yeah. ClojureCheck is back. As an extension to clojure.test. :)

15:55 lpetit: Hi

16:42 timcharper: I would like to build a lazy sequence that is processed by another thread

16:43 kotarak: (doc seque)

16:43 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

16:44 timcharper: (com.mongodb.ObjectId.)

16:44 oops, I am lame.

16:45 kotarak: thank you!

16:45 how does seque differ from fill-queue ?

16:45 kotarak: (doc fill-queue)

16:45 clojurebot: "clojure.contrib.seq-utils/fill-queue;[[filler-func & optseq]]; filler-func will be called in another thread with a single arg 'fill'. filler-func may call fill repeatedly with one arg each time which will be pushed onto a queue, blocking if needed until this is possible. fill-queue will return a lazy seq of the values filler-func has pushed onto the queue, blocking if needed until each next element becomes available. fill

16:45 kotarak: dunno

16:46 timcharper: I'm already using fill-queue to create an eagerly-processed lazy queue pipeline

16:47 It's great because the lazy seq (queue) is filled up to the queue-size in another thread, so items are ready

16:48 but I'm trying to write something where I can do a "send-off-and-forget" operation, in this case, queuing up a bunch of insert operations as if they were individual, and then bulk-inserting the whole thing every 32 or so

16:48 a_strange_guy: they both seem to do the same

16:48 timcharper: (as with congomongo, bulk-insert! can be about 5 times faster than insert! in my measurements)

16:49 hmm...

16:49 a_strange_guy: fill-queue just has an imperative interface

16:49 and seque has a functional interface

16:49 timcharper: so what I want is kind of like a flip-flopped version of fill-queue. Rather than the populator in a different thread, I want the consumer in a different thread.

16:50 a_strange_guy: you want a pipe?

16:51 chouser: hm, I think that's a weakness of fill-queue's interface rather than its design.

16:51 ~google future pipe dream

16:51 clojurebot: First, out of 266000 results is:

16:51 LTE in Consumer Devices: Technophile&#39;s Pipedream or Future Reality ...

16:51 http://www.juniperresearch.com/analyst-xpress-blog/2010/05/28/lte-in-consumer-devices-technophiles/

16:51 chouser: ~google clojure future pipe dream

16:51 clojurebot: First, out of 418 results is:

16:51 Clojure and me » Are pipe dreams made of promises?

16:51 http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/

16:51 chouser: timcharper: take a look at that last one

16:51 a_strange_guy: i actually dont like this implementation

16:52 chouser: a_strange_guy: fill-queue's you mean?

16:52 a_strange_guy: no, cgrand's pipe

16:53 chouser: oh. yeah, he's said it's more of a demonstration than something he'd recommend people use

16:53 a_strange_guy: should wrap a BlockingQueue instead

16:53 chouser: but it might be a place to start

16:53 timcharper: ok :) cool

16:53 thanks

16:54 I've had my eye on the pipe dream post for some time (http://twitter.com/timcharper/status/15282633029)

16:54 TeXnomancy: has there been any discussion of getting clj-stacktrace merged into clojure.stacktrace?

16:54 I just started using it and am kicking myself for not trying it sooner.

16:55 timcharper: I don't like that it's using futures so much

16:55 TeXnomancy: but you kinda have to monkeypatch to do anything useful with it; would be much nicer if clojure.test could be made to use it without trickery.

16:55 a_strange_guy: you mean promises?

16:56 timcharper: oh... wait... it's not creating a future for every item.

16:56 (duh)

16:56 a_strange_guy: thank you for pointing that out

16:56 are promises pretty cheap?

16:57 a_strange_guy: don't think so

16:58 they use CountDownLatches internally

16:58 which normally aren't used for that purpose

16:58 rfg: /join #erlang

16:59 Well that didn't work.

16:59 :)

17:01 garybu: I tried the prim branch to see if it improved "loading request" time on Google App Engine. The loading time went from 8 seconds to 5 seconds for my test application. This number might not be accurate because loading request times can vary for unknown reasons.

17:02 cemerick: LauJensen: enclojure gets the job done, and covers my necessities at the moment, but is by no means polished or a final solution.

17:03 LauJensen: cemerick: except paredit, whats missing?

17:03 cemerick: paredit is largely not a concern for me -- it's not like I'm used to it, though I see the utility

17:04 It's missing a variety of things, some simple, some not so simple.

17:04 When I get a few hours, I'm going to start a feature grid on that wiki page and start filling it in.

17:04 LauJensen: k cool

17:05 I gotta jet - Thursday came and went in Denmark, good night all

17:06 islon: anyone knows how can I use connection pool with clojure contrib sql?

17:07 is there any example?

17:31 pedroteixeira: anyone knows an easy way to make dotrace accept a var?

17:33 my use case is to have something like (def fns (vals (ns-publics (find-ns 'clojure.core)))) (dotrace fns ...)

17:42 powr-toc: cemerick: I'd like to see swank support in the IDE's myself

17:43 cemerick: powr-toc: I don't know enough about it to have an opinion there. I use enclojure's remote REPL library, which has been steady as a rock for me.

17:43 powr-toc: cemerick: do you have a link for that?

17:44 cemerick: obviously, some kind of remote repl capability is a requirement. It'd be nice to have a clojure-native one be the standard at some point.

17:44 powr-toc: it's poorly documented :-/

17:44 so, no

17:44 it's worth a blog post

17:44 powr-toc: cemerick: I'd just like all the IDE's to converge on a single solution for remote REPLs... that way you can use clojure-maven-plugin or lein (or anything else) for classpath management etc...

17:45 cemerick: absolutely

17:45 *all* repls should be remote repls as well. I don't know if any environments are exec'ing clojure anymore, but if they are, they should stop.

17:45 powr-toc: cemerick: And I think all the IDE's and slime-connect should be able to talk to it...

17:46 cemerick: I've overheard people complain about swank and slime from a project management point of view (e.g. breaking changes from upstream and such). I'm also wary of the CL roots insofar as it becoming a clojure-land standard.

17:46 though it's a de facto standard already :-)

17:47 powr-toc: cemerick: I agree... though there are still lots of situations where you'd want to start a JVM in another manner

17:47 kotarak: I'm happy with VimClojure: it is basically a remote repl and I use it with gradle for classpath management. gradle runNailgun and there you go... :)

17:47 cemerick: well, that's orthogonal to whether the environment *connects* to the vm over a socket vs. using exec's streams to communicate

17:48 powr-toc: cemerick: yeah... I guess that's a concern...

17:48 cemerick: gradle, huh? Brave :-)

17:48 kotarak: cemerick: gradle is quite nice, actually.

17:48 cemerick: kotarak: you certainly seem to have captured the vim market :-)

17:48 powr-toc: cemerick: my point exactly

17:48 cemerick: I'm sure it is...never used it.

17:49 kotarak: cemerick: I think, it is underrepresented in the maven vs. lein discussion. But anyway, everyone as he likes...

17:50 powr-toc: cemerick: plus the IDE's should use both mvn and lein to manage dependencies etc...

17:50 kotarak: see... ;)

17:50 cemerick: kotarak: It seems to be an obvious choice in groovy-land. What is compelling about it?

17:51 powr-toc: I'm personally very happy with Emacs/SLIME etc... but clojure definitely needs better IDE support

17:51 cemerick: powr-toc: if lein proves to have staying power, then yes

17:51 kotarak: cemerick: it is relatively declarative, but you can easily do more complex stuff. And the multiproject stuff is simply awesome.

17:52 powr-toc: cemerick: naturally... though I thought lein was becoming pretty defacto...

17:53 cemerick: powr-toc: I don't know what the numbers are like. Maven is used pretty commonly once one's project is past a certain degree of complexity AFAICT.

17:53 kotarak: cemerick: and some problems are just none with gradle. Eg. java compilation depending on the clojure side or the other way around. I don't define the order in the plugin. So you can do it yourself. Without much trouble and strange hacks.

17:54 cemerick: kotarak: surely gradle can't figure out the dependency relationship between two sets of sources on its own?

17:55 powr-toc: cemerick: yeah... I'm using maven on one project... but prefer lein if I can get away with it.

17:55 kotarak: cemerick: no. clojure depending on java is maybe possible. I don't think the other way around is possible in general.

17:55 cemerick: powr-toc: I suspect polyglot maven will be the next natural step once it's finished.

17:55 powr-toc: cemerick: yes, maybe... though I've not really looked at it too much yet

17:56 cemerick: understandably. Still pre-release.

17:56 powr-toc: I think I'm letting enough blood with bleeding edge projects as it is! ;-)

18:04 yacin: ,(bit-shift-right (expt 2 26) 31)

18:04 clojurebot: java.lang.Exception: Unable to resolve symbol: expt in this context

18:04 yacin: erm

18:04 ,(use 'clojure.contrib.math)

18:04 clojurebot: nil

18:04 yacin: ,(bit-shift-right (expt 2 26) 31)

18:04 clojurebot: 0

18:04 yacin: ,(bit-shift-right (expt 2 26) 32)

18:04 clojurebot: 67108864

18:04 yacin: is this wrap-around intended behavior?

18:04 actually

18:05 this is just weird

18:05 any ideas as to what's going on?

18:28 replaca: Q: can someone remind me how I refer to an inner class in interop? Actually I need to refer to an enum in a class (in Java it's Color.Ansi.WHITE)

18:28 lancepantz: replaca: Class$InnerClass

18:30 replaca: hmm, that's what I thought. I must have something else confused. So it would be Color$Ansi/White, right?

18:30 * Color$Ansi/WHITE

18:33 Ahh, I need to explicitly impoirt the inner class

18:34 cemerick: yeah, inner classes really are only "inner" w.r.t. java-the-language scoping

18:34 and availability of the OuterClass.this reference

18:35 hiredman: ring needs a middleware to map uris to clojure namespaces

18:36 (restify 'foo) then requests to /x/y/z call foo.x.y/z

18:56 arohner: hiredman: I wrote that awhile ago. I had problems with http methods i.e. get vs. post

18:57 replaca: In project.clj, does :jvm-opts "-D...=..." work? I'm trying to use it with lein swank and having no luck

18:57 arohner: hiredman: so I wrote defroutefn instead. http://github.com/arohner/clj-blocks/blob/master/src/clj_blocks/routes.clj

18:59 technomancy: replaca: it's a newish feature; hasn't been widely tested.

19:01 replaca: technomancy: maybe my lein is out of date then. I'll make sure I'm uptodate

19:02 technomancy: to update I get a new "lein" file and run self-install?

19:03 technomancy: replaca: no, dev builds need a bootstrap step; see "hacking" in the readme

19:03 though a stable release isn't far off

19:04 replaca: ok, for today that's too big a detour. I'll try again with stable and run by hand for now

19:04 technomancy: stable builds to respect JAVA_OPTS env var

19:05 replaca: technomancy: they will or they already do?

19:06 technomancy: sorry, they do. implemented in 1.1.0.

19:06 replaca: technomancy: thanks, that's fine for what I'm doing now

19:22 erikcw1: I have a list of several hundred URLs that I need to process in parallel. Does anyone know of an implenation of pmap that has a user-adjustable thread pool size?

19:34 tomoj: I saw something that might be almost what you want recently

19:35 timcharper: erikcw1, I have written some code to do something like what you want

19:35 erikcw1: I'm all ears! :-)

19:36 tomoj: http://s-expressions.com/2010/06/08/medusa-0-1-a-supervised-thread-pool-for-clojure-futures-2/ is what I remembered

19:36 timcharper: is it more important that you control the number of threads, or that you control how eager the list is processed ?

19:36 tomoj: not user-adjustable, but will be someday, it says

19:36 timcharper: because you can control how many are processed concurrently by controlling how far ahead you allow the list to be processed

19:37 erikcw1: timcharper: probably the number of threads. I want to list processed as quickly as possible, but I don't want to spawn so many threads that the server starts swapping to disk

19:37 tomoj: oh.. but medusa "futures" don't return values

19:37 timcharper: erikcw1: it seems that controlling how far ahead the list is processed would have the same effect, wouldn't it ?

19:37 (preventing the server from swapping to disk)

19:37 erikcw1: tomoj: I saw medusa - -but until the thread pool is user adjustable, it won't work for me

19:38 timcharper: I suppose

19:38 timcharper: anyways... here's one possible route:

19:38 ...

19:38 tomoj: it seems to me that making the thread pool size adjustable would be a trivial change

19:38 KirinDave: Someone recently did a big thing with clojure as their blogging software

19:38 who was it?

19:39 tomoj: but i suppose it's not?

19:39 KirinDave: I need to get something up and running at fayr.am soon

19:39 tomoj: lau, I bet

19:39 http://www.bestinclass.dk/index.clj/2010/05/refresh-your-cache--best-in-class-has-been-baked.html

19:39 and http://www.bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html

19:39 KirinDave: ^

19:42 timcharper: erikcw1: http://gist.github.com/433817

19:42 erikcw1: timcharper: thanks -- let me see here....

19:42 timcharper: if the overhead of futures is a concern, you can always chunk it and process chunks in parallel

19:43 at the cost of greater memory usage (more needing to be in memory at a time)

19:44 (pmap-queue odd? (range 1 10) :queue-size 5) will immediately start computing the first 5 elements in parallel

19:44 it will always stay 5 ahead from the last consumed item of the lazy sequence

19:44 (IE: it will keep 5 cores busy)

19:45 though... not very busy, using odd? :)

19:46 erikcw1: So if I'm processing a bunch of URLs (most of the time just blocking on the network), then setting the :queue-size 20 will run it on 20 threads right??

19:46 timcharper: yeah

19:46 provided you can consumer the results faster than it can produce them

19:46 ^consumer^consume

19:47 hmm... actually... there's a slight difference

19:47 if the first item takes 20 seconds, and next 19 items take 1 seconds, you would get into a state where you would be blocked by the first item

19:48 erikcw1: that's what I've been running into with the implementations I've been rolling myself

19:48 any ways around that?

19:48 timcharper: oh :)

19:49 yeah... actually...

19:50 one sec... it's on the tip of my brain

19:50 erikcw1: np

19:50 timcharper: I think you need a java.util.concurrent.LinkedBlockingQueue

19:51 fire up 20 threads that are subscribed to that queue

19:51 have them stick their results in another LinkedBlockingQueue

19:52 your results will not come back in order... but based on your requirements, you probably don't care

19:52 erikcw1: yeah -- order is not important

19:53 I assume there is a way to tell when the queue has finished processed

19:53 processing*

19:53 timcharper: I don't know if there are any clojure methods that abstract that, but LinkedBlockingQueue is pretty easy to use

19:53 yeah

19:53 you could set an atom that tells the consumers to quit

19:53 http://java.sun.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html

19:54 the poll method of LinkedBlockingQueue can receive a timeout value

19:54 you probably wouldn't want to rely on being able to write faster than they can consume... would be safer to have some control

19:56 erikcw1: and that is what LinkedBlockingQueue will give me right?

19:58 timcharper: what ?

19:58 oh... no

19:58 erikcw1: sorry -- still getting up to speed on the Java concurrency tools

19:58 timcharper: if you have 20 items consuming a queue, you're not guaranteed that the queue-filler will keep the queue full before there is no more work to do

19:59 erikcw1: but those 20 threads should just sleep if that happens right? More data comes in and they get back to work...

19:59 timcharper: yeah :)

19:59 that's why you would want to use poll

20:00 poll will sleep and wait for work if there is no work to do

20:00 then, the thread filling the queue can say "hey guys... seriously, there's nothing else... quit waiting, go home" by setting a boolean atom

20:03 (loop (let [payload (.poll q 200 java.util.concurrent.TimeUnit//MILLISECONDS)] (if payload (do (process payload) (recur)) (when @still-processing (recur)))))

20:03 something like that would be your worker

20:03 err... maybe @still-processing would be @work-pending... or something

20:04 anyways.... I'm just sketching here... I'm don't consider myself an expert at this

20:04 maybe someone has a better idea, but that's how I would approach it

20:05 erikcw1: that makes a lot of sense

20:05 thank you!

20:05 timcharper: erikcw1: sure thing! trying to pay it forward... I get tons of help in this room

20:06 oh... the (loop should be (loop []

20:07 anyways.. you get the idea :)

20:12 replaca: How do I type-hint for an array of ints? (Being lazy today!)

20:13 tomoj: ^ints I think

20:14 replaca: thanks!

20:29 danlarkin: what are situations in which a function sent to an agent wouldn't happen immediately

20:29 an idle agent

20:30 it's sent from within a transaction, so IIUC the action is only dispatch the the agent after transaction commit, but that doesn't seem to be what I'm seeing

20:42 if, instead of dispatching to an agent, I run the same code in a future, it happens right away

20:42 so I don't think it's that my code is blocking, I think somehow I'm blocking the agent from running

20:42 I just don't know how I could be doing that

20:55 bhenry: if i have a and b such that (def a [[1][1 2][1 2 3]]) (def b [2 3]) how can i replace (a 1) with b so that i get back [[1][2 3][1 2 3]]

20:58 brehaut: (assoc a 1 b)

20:58 http://clojure.org/data_structures

20:58 bhenry: brehaut thanks!

20:58 brehaut: no worries

21:57 pedroteixeira: wrote a compojure wrapper for logging trace, in case someone finds useful: http://gist.github.com/433930

Logging service provided by n01se.net