0:00 mebaran151: it seemed to work
0:00 clojure contrib with the old version
0:45 headius: mikem: clojure's using nailgun now too, eh?
0:45 we need to get together and make some improvements
0:53 hiredman: vimclojure comes with a nailgun server
0:57 replaca: is anyone else getting errors building the latest contrib?
0:58 I'm getting compile_clojure: [java] java.io.FileNotFoundException: Could not locate clojure/contrib/expect/test_is_adapter__init.class or clojure/contrib/expect/test_is_adapter.clj on classpath:
1:00 hiredman: yep
1:00 replaca: oh, just a typo in build.xml
1:00 one sec, i'll check in a fix
1:05 fixed, you can pull now
1:05 hiredman: neat
1:57 lowlycoder: how do i search for sample code taht uses letfn
1:58 LauJensen: lowlycoder: Google seemed to do the trick: http://
1:59 lowlycoder: what did you search for?
1:59 LauJensen: "clojure letfn"
2:00 hiredman: ~google clojure letfn
2:00 clojurebot: First, out of 68 results is:
2:00 letfn - mutually recursive local functions - Clojure | Google Groups
2:00 http://
2:00 hiredman: huh
2:11 lowlycoder: is there anyway I can use letfn on a proxy?
2:16 in clojure, how can you create a proxy that will remove itself?
2:25 this is weird; is it possible to define a macro (run-once ...) so that even if (run-once ...) is embedded in the function of a body, it's only executed once, even if the function is called multiple times?
2:27 hiredman: what are you doing?
2:27 lowlycoder: i'm doing something wrong (and re-engineering my solution to not need this)
2:27 but now, i'm curious
2:37 http://
2:38 hiredman: looks like you are re-implementing memoize
2:38 ~def memoize
2:38 lowlycoder: whoa, it happens only once?
2:38 that's an interesting wya to use memoize
2:38 no it's not
2:38 i'm trying to remove the listener after it execs
2:39 hiredman: what
2:39 this is ridiculous
2:39 remove from what?
2:40 lowlycoder: i remove the listener after it exeutes once
2:40 ideally i would use letfn and not have to deal with my-ref
2:40 but i don't know how to use letfn with proxy
2:40 hiredman: have you read the docs for proxy?
2:40 lowlycoder: i have
2:40 hiredman: I suggest you do, there is a very simple way to do this
2:41 lowlycoder: it returns a class
2:41 no mention of the function
2:41 the this?
2:41 hmm
2:41 hiredman: …
2:50 JAS415: ~def proxy
2:51 Each method fn takes an additional implicit first arg, which is bound to 'this.
2:51 lowlycoder: JAS415: yep; just got it working; thanks :-)
2:52 JAS415: cool
2:52 this is very useful, i had the same type of problem until i found it
2:53 lowlycoder: yeah, i started out with a "solution" where I had a global ref that would change the first time i exec the handler and in future checks, it would ignore the handler
2:53 then I moved on to what I pasted into lisppaste
2:53 but this solution I like the best :-)
3:20 mebaran151: has anybody tried the new enclojure
3:21 REPL seems to be failing on me in Netbeans with the newest one
3:22 lowlycoder: does enclojure have vim intergration?
3:36 i'm really starting to hate clojure's lack of continuations
3:36 i'm seeing them everywhere
4:27 LauJensen: hiredman: feeling a little grumpy today ?
4:31 hiredman: ?
4:31 every day
4:31 lowlycoder: does clojure have a deque structure, where I append to the front and take from the end?
4:32 hiredman: ,(doc butlast)
4:32 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"
4:32 hiredman: hmm
4:33 ,(doc subvec)
4:33 clojurebot: "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."
4:33 lowlycoder: ?
4:33 clojurebot: clojure-maven-plugin is http://
4:33 lowlycoder: hmm, i'll just use reverse function
4:34 hiredman: ,(conj [1 2 3] 4)
4:34 clojurebot: [1 2 3 4]
4:34 LauJensen: lowlycoder: If not, it wouldn't be difficult to make your own, and you can always take from the rear using last and append using (conj '(1 2 3) 4)
4:34 ~(conj '(1 2 3) 4)
4:34 clojurebot: (conj {:a 1} (when true {:b 2}))
4:34 hiredman: ,(subvec [1 2 3 4] 1)
4:34 clojurebot: [2 3 4]
4:34 LauJensen: w00t?
4:34 clojureb0t is b0rked
4:34 hiredman: LauJensen: what?
4:34 LauJensen: ~(conj '(1 2 3) 4)
4:34 clojurebot: (conj {:a 1} (when true {:b 2}))
4:35 LauJensen: that should give me (4 1 2 3)
4:35 Chousuke: ~conj
4:35 clojurebot: (conj {:a 1} (when true {:b 2}))
4:35 hiredman: LauJensen: ,
4:35 LauJensen: ,(conj '(1 2 3) 4)
4:35 clojurebot: (4 1 2 3)
4:35 LauJensen: Oh - So I'm the noob :)
4:35 btw, all you danish reading compojure lovin' clojure fans, check out http://
4:35 hiredman: anyway subvec and conj will let you use a vector as a deque
4:36 Chousuke: hmm, doesn't subvec have performance issues if you stack it too much? /:
4:36 hiredman: last I heard it did not
4:37 (doc subvec)
4:37 clojurebot: "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."
4:37 hiredman: bah
4:37 ~def subvec
4:38 ~def c.l.RT
4:40 ~def c.l.APersistentVector
4:41 LauJensen: hiredman: Dont you worry that tinyurl will consider you a spammer?
4:43 hiredman: nope
7:05 gko: ,(= (java.lang.Long. "123") (java.math.BigInteger. "123"))
7:05 clojurebot: true
7:06 gko: ,(#{(java.lang.Long. "123")} (java.math.BigInteger. "123"))
7:06 clojurebot: nil
7:06 gko: why ???
7:14 is that normal?
7:27 liwp: gko: I think set uses .equals() to find items whereas (=) uses numerical equality for numbesr
7:28 ,(.equals (Long. "123") (java.math.BigInteger. "123"))
7:28 clojurebot: false
7:28 liwp: ,(.equals (Integer. "123") 123)
7:28 clojurebot: true
7:29 liwp: ,(#{(Integer. "123")} 123)
7:29 clojurebot: 123
7:30 gko: liwp: so, set of number = pain ?
7:32 or what should I use instead?
7:32 liwp: yeah, I think it tends to be uncomfortable unless you can guarantee that all the numbers are e.g. ints
7:33 I'm not sure what the recommended way of dealing with this is
7:33 if you do need to worry about BigIntegers, then you can of course make everything into a big-int before you add it to the set and look it up
7:34 ,(doc bigint)
7:34 clojurebot: "([x]); Coerce to BigInteger"
7:35 liwp: ,(#{(Long. "123")} (long 123))
7:35 clojurebot: 123
7:35 liwp: ,(#{(java.math.BingInteger. "123")} (bigint 123))
7:35 clojurebot: java.lang.ClassNotFoundException: java.math.BingInteger
7:35 liwp: uhh
7:35 ,(#{(java.math.BigInteger. "123")} (bigint 123))
7:35 clojurebot: 123
7:36 liwp: gko: but yeah, you need to be careful
7:37 gko: yep.
7:50 raphinou: is there a way to avoid the repeat of (count args) in this code? (let [argsnum# (if (< 0 (count args)) (count args) "") ] some-code)
7:53 matley: raphinou, only if you write a macro if-negative-let afaik
7:55 raphinou: ok, thx matley. It's not worth it in my case
7:58 gerryxiao: hello
7:58 how to change Graphics to Graphics2D in clojure?
7:59 (Graphics2D g) seems not work
7:59 g is Graphics
8:00 liwp: I assume you're calling a method on g that is only defined for Graphics2D instances?
8:01 try adding a type hint to the call site, e.g. (.foo #^Garphics2D g <rest of args>)
8:01 gerryxiao: nope
8:02 i 'm use Canvas class to draw stuff
8:02 paint(g)
8:03 g is Graphics
8:03 i want to change it to Graphics2D and use methods from Graphics2D
8:04 liwp: try this: (.paint canvas #^Graphics2D g)
8:04 matley: newbie question. I am trying to subclass a ListModel. In this case the subclass should have an additional state (a sorted-set). Is it right to do (let [state (ref ...)] (proxy [javax.swing.DefaultListModel] [] ... .... )) ?
8:04 arbscht: ,(doc cast)
8:04 clojurebot: "([c x]); Throws a ClassCastException if x is not a c, else returns x."
8:05 gerryxiao: ok
8:18 it works, thx
8:19 liwp :-)
8:19 liwp: good
8:20 gerryxiao: but i think "#^Graphics 2D" is much ugly
8:20 liwp: I haven't really figured out yet what clojure's (cast) is good for
8:20 yeah, the type hinting does get a bit ugly
8:20 gerryxiao: i have to type it much times
8:21 liwp: there was some discussion about a macro that would allow something like g:Graphics2D in function definitions
8:21 gerryxiao: (let [g2d #^Graphics2D g]) can't work?
8:21 liwp: gerryxiao: if it is in the same function you can type hint a let binding and then use that
8:21 yep, that's it
8:23 gerryxiao: that's a bit better
8:25 when will newnew be merged to master?
8:29 liwp: don't know
8:53 LauJensen: ~max
8:53 clojurebot: max people is 164
8:53 LauJensen: ~clojureql
8:53 clojurebot: clojureql is http://
9:11 lpetit_: Hi I can't find a pre-existing function returning a (flat or not) list of filepaths (recursive from a root directory). Neither in core or contrib ? Do I miss something or do I have to (yet again) rewrite my own ?
9:12 cgrand: ,(doc file-seq)
9:12 clojurebot: "([dir]); A tree seq on java.io.Files"
9:13 lpetit_: thx, I was searching on the wrong keyword (directory, folder)
9:20 gerryxiao: hello
9:20 how to name static innerclass in clojure?
9:20 classname/innerclass ?
9:20 Chouser: classname$innerclass
9:21 gerryxiao: ok
9:21 cark: carefull about importing the innerclass too, or use fully qualified names
9:22 gerryxiao: (import (java.awt.geom Line2D))
9:22 cark: nope you need the containing class as well
9:23 (import (java.awt.geom Bleh$Line2D))
9:23 gerryxiao: oh
9:23 thx
9:43 Chouser: some day I'll come up with a use for condp's :>> clause
10:00 Fossi: hey
10:02 we want to call some java methods on an object dynamically, like (.. (Query. "foo") (addFilter "bar") (addFilter "baz"))
10:02 with bar and baz coming from a map for example.
10:03 we used reduce for a while which went ok, but it's getting more complicated as we want to call another method
10:03 is there a simple way to do such things? can you for example somehow treat java methods as first class functions and put them into a map?
10:04 liwp: ,(doc memfn)
10:04 clojurebot: "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."
10:04 liwp: does that help
10:05 Fossi: quite some :)
10:06 rhickey: memfn predates #() and the latter is preferred
10:14 ankou: what's the difference between reader macros and vectorsyntax? As far as I can see they are not really like macros, but just other special syntax rules? what's the difference between [a b] as (vector a b) and '(a b) as (quote (a b)) ?
10:17 opqdonut: none really
10:17 rhickey: ankou: when the reader reads [a b] it reads a vector object containing 2 symbols, not (vector a b). When it reads '(a b) it reads the list (quote (a b)), where quote, a and b are symbols
10:17 opqdonut: oh, okay
10:17 rhickey: ,'[a b]
10:17 clojurebot: [a b]
10:18 ankou: okay
10:25 rhickey: cgrand: let me know when you've tried the tweaks I posted, after that I think we're ready for a patch?
10:27 ankou: it would be nice to have some sort of tabcompletion in the repl
10:28 Chousuke: it's possible with rlwrap
10:28 or slime :P
10:28 rhickey: or enclojure
10:29 ankou: what is rlwrap or enclojure? I would like to use slime but I'm soo used to vim and viper wasn't that good. Slimv wasn't very nice either
10:30 the same problem with IDEs, I never saw a good vi-plugin
10:30 eevar2: enclojure is a netbeans plugin
10:31 liwp: ankou: rlwrap is utility that uses readline to provide any std io prompt with things like history and tab-completion
10:31 Chouser: ankou: vimclojure exists
10:31 ankou: I'm psyching myself up to again try enclojure + jvi in netbeans
10:32 rhickey: Has anyone tried: http://
10:32 ankou: Chouser, with vi-plugin I meant something integrating vi in an IDE, not integrating closure in vim. I really missed splitwindows in jvi. I'm normally working with 4 codewindows and would really miss this
10:33 danlarkin: rhickey: do you have the power to invite a regular old email address to join clojure-dev? I want to join but not with a google account, which it seems is the only way google will let me
10:33 Chouser: ankou: look at vimclojure -- runs in real vim
10:33 cgrand: rhickey: gah! I didn't think of reusing the Box. I see you make room for two extra key-values pair when a bitmapnode grows. Did you try parallel arrays instead of the interleaved array?
10:34 ankou: Chouser: I'm currently using it
10:34 Chouser: ankou: and it doesn't do tab completion??
10:35 ankou: don't know, I was talking about the REPL.
10:36 rhickey: cgrand: I haven't tried 2 arrays, and think we can leave that idea for the moment. In my testing leafless is at least as fast as what we've got now, and sometimes faster, with better memory utilization. The last thing I haven't tested is seq perf
10:56 cemerick: rhickey: I just saw hornetq yesterday myself. It certainly *sounds* like a winner. I need some lightweight messaging library very shortly, so I'll probably put it through its paces.
10:56 rhickey: cemerick: cool let me know what you think if I don't get around to it first
10:56 cemerick: I'm suspicious of anything coming out of jboss, though. It sits next to spring et al. in my head.
10:56 rhickey: libs that this are what make Clojure so useful
10:57 cemerick: heh, yeah, they seem to be bending over backwards here highlighting no deps other than the JDK etc, seems small enough
10:58 cemerick: I worry about 2 months from now, I'm using hornet, and then one little piece that would be helpful as an add-on comes out, but depends upon 18 spring libs.
10:58 rhickey: cemerick: the splitting off and packaging seems a quite deliberate effort to give it an independent life
11:00 cemerick: well, here's hoping. Once burned, etc...
11:02 rhickey: with these MQs it all comes down to lots-of-users + lots-of-fixes so it gets fully shaken out
11:03 cemerick: rhickey: what others have you taken a look at so far? I'm only now starting to look.
11:04 rhickey: ActiveMQ, OpenMQ, Joram, mostly reading, a little twiddling
11:05 cemerick: ah -- I'm definitely looking for something embeddable, useful for point-to-point stuff
11:05 rhickey: activemq and joram embed
11:05 cemerick: We use openmq serverside, which is fine enough.
11:05 Haven't pushed it any though.
11:05 ah, I saw openmq and assumed they were all server-side :-/
11:07 rhickey: joram has a kind of unique multi-peer strategy when embedded. If used persistently, a client can durably 'send' a message when not connected to the network, and will get to target server when reconnected
11:08 ankou: is there any form of destructuring for lists?
11:08 Chouser: ankou: vector destructuring forms work on all seqables
11:09 rhickey: ,(let [[a b c] (range 3)] [c b a])
11:09 clojurebot: [2 1 0]
11:09 cemerick: rhickey: Oh, that's sexy.
11:09 huh, JMS compliant and around since 2000.
11:09 old code so much better than new code :-)
11:10 rhickey: cemerick: yeah, really cool design. Persistent perf is always the challenge, HornetQ is definitely teasing here
11:11 cemerick: The up-front mention of "POJO" is a warning flag. That often means "there's a lot of complexity under the covers so that setters are actually triggering messages/transactions/connections under the covers" in other libs.
11:12 rhickey: cemerick: I that what it means? I couldn't figure it out :)
11:12 cemerick: well, it means a lot of different things to different people.
11:13 Many libs are annotation-driven these days, where you add a @Whatever to your class or field, and it decorates all your "POJO" methods with whatever machinery is appropriate. Hibernate comes to mind as a significant example.
11:16 rhickey: cemerick: isn't the problem/magic in the annotator rather than the annotatee?
11:17 cemerick: rhickey: definitely -- what I was saying was that "POJO" might mean that a lot of functionality is only available via annotations.
11:20 rhickey: cemerick: well, I like that you can create a configuration thingy in code. One thing about Joram is, even when embedded, needs some XML to configure, iirc
11:20 cgrand: rhickey: https://
11:21 cemerick: sure. Annotations aren't a good path AFAIC, though -- the less Java I need to continue to have around, the better.
11:22 rhickey: cemerick: agreed
11:22 cgrand: cool, thanks
11:23 cemerick: I'm hoping someone with serious Java-fu comes along with a contrib to support annotations in clojure. That's probably the last significant interop hole left.
11:24 thickey: work in progress for new t-shirt: http://
11:25 liwp: thickey: nice!
11:25 danlarkin: I love the copy
11:27 thickey: thanks
11:27 cemerick: thickey: man, has that woodstock feel, even :-P
11:29 thickey: definitely inspired by rock posters
11:30 rhickey: cgrand: patch doesn't apply cleanly on master: Patch failed at 0017 replace copyOf with arrayCopy
11:31 thickey: wild!
11:31 thickey: :)
11:37 cgrand: rhickey: try git am -3 leafless.patch
12:00 bitbckt: thickey: Love the shirt design.
12:01 thickey: thanks!
12:02 bitbckt: I look forward to buying one. :-)
12:02 rzoom: A+++ will order
12:08 rhickey: cgrand: patch applied - thanks!
12:23 Chouser: 'into' on a finger-tree should keep the same order, so conj should add to the right, so then push could add to the left.
12:23 pop would then remove from the left -- is there anything handy for removing from the right?
12:26 rhickey: Chouser: interesting. depending on if you look at a finger tree as a seq (possible), maybe cons/next for left and conj/pop for right?
12:27 Chouser: yeah, I had thought of that too. Not sure of the drawbacks of implementing ISeq directly...
12:29 right now, cons never calls a method of the existing object
12:29 rhickey: writing a finger tree in new new?
12:30 Chouser: that's the plan. slapping it together with non-standard functions on top of vectors right now
12:30 conjl/conjr, ft-seq/ft-rseq, etc.
12:30 rhickey: cool
12:31 using delays for laziness?
12:32 cemerick: ah, compressed oops are default in jdk7 now
12:32 rhickey: compressed oops?
12:33 cemerick: ordinary object pointers
12:33 rhickey: this in 64-bit?
12:33 cemerick: yeah. Irrelevant in 32.
12:33 ah: http://
12:34 rhickey: they were all excited about that at JavaOne
12:34 Chouser: I haven't groked the paper all the way to the end. My understanding is the only place I need laziness so far for seq, and lazy-cat's giving me that for free.
12:34 cemerick: the key changeset went in on Monday: http://
12:35 Chouser: it's entirely possible I as yet misunderstand the internal requirements to deliver the complexity promises. I'll do some testing at some point to make sure I'm not claiming it's a good finger tree if it's not.
12:35 rhickey: Chouser: I thought laziness was needed to get amortized time properties
12:36 Chouser: rhickey: yes, but I thought that was for the head/tail view stuff.
12:36 ah, no, you're probably right.
12:36 rhickey: Chouser: maybe, I haven't looked at it in a while
12:37 Chouser: that's where they discuss it, but perhaps they're showing that the seq doesn't force the creation of the tree until needed.
12:38 I'll read that again and make sure. This stuff is definitely stretching my understanding on several levels. Difficult but fun!
12:39 rhickey: you need to be careful as, for Clojure, we care about the amortized time characteristics in a *persistent* setting
12:39 "The same bounds hold in a persistent setting if subtrees are suspended using lazy
12:39 evaluation. This ensures that transformations deep in the spine do not take place
12:39 clojurebot: lazy is hard
12:39 rhickey: until a subsequent operation needs to go down that far. Because of the above prop-
12:39 erties of safe and dangerous digits, by that time enough cheap shallow operations
12:39 will have been performed to pay for this expensive evaluation."
12:40 ankou: is there a possibility to import a whole javapackage?
12:41 like import javax.swing.*; in java
12:42 rhickey: you can also leverage: "In a strict language that provides a lazy evaluation primitive, we need only suspend the middle subtree of each Deep node, so only Θ(log n) suspensions are required in a tree of size n."
12:43 Chouser: finger trees would be an awesome addition - good luck!
12:44 Chouser: heh, thanks.
12:46 My current plan is to support a map of measure/reduce functions, so you can do different kinds of searches on the same tree
12:48 rhickey: neat
12:49 technomancy: ankou: no
13:15 cark: clojure.test is not in 1.0 ?
13:16 hiredman: nope
13:16 cark: and test-is is not in contrib anymore ><
13:17 hiredman: there is a 1.0 compat branch of contrib
13:17 cark: oh well that's for simple stuff, i'll do ad hoc testing
13:17 until clojure 1.1 !
14:08 a generic pool library : http://
14:09 krumholt_: what is a good way to deliver a clojure application?
14:09 cark: smallish, but might be usefull to these database guys (clojureql hint hint)
14:10 krumholt_ : make an executable jar
14:12 krumholt_: cark, i tried and failed. is there a better example then on the clojure.org website for how to do this?
14:14 cark: it take a couple hours of suffering to make a nice ant build file, then just copy it for each project =)
14:14 clojurebot: build is working
14:14 cark: i could send you one of my build files, but it wouldn't make sense without the projects themselves
14:15 krumholt_: cark, right now i am manually ordering everthing folder structure etc it is very annoying. maybe i try ant scripts
14:16 cemerick: krumholt_: clojure's jar itself is executable. You should be able to follow its build process as a template in that respect.
14:16 yeah, doing it manually is a little insane :-)
14:17 technomancy: krumholt_: here's what I was using on an earlier project: http://
14:17 hiredman: maybe someone should make a sort of skelton executable jar that executes a function based on a property file
14:17 krumholt_: technomancy, thanks
14:17 hiredman: technomancy: clojurebot should work with the latest fnparse now
14:18 technomancy: hiredman: awesome
14:20 cemerick: hiredman: shouldn't people just learn how to use the massive pile of tools that are out there?
14:21 I'd hate to see some 5% solution become standard practice.
14:22 cark: well there's a fine line between adding another dependency and having enough functionality
14:22 and sometimes those java libraries a heavy
14:22 heavy to use i mean
14:23 cemerick: I wouldn't call ant 'heavy'. Not using some kind of build tool is like not using autoconf with a C build or something.
14:24 hiredman: cemerick: it would be kind of nice just to be able to copy your clj files somewhere, edit a properties file to note the namespace and name of the function to call, run ant, and have an executable jar
14:24 cark: cemerick : agreed
14:24 hiredman: but everyone hates autoconf
14:25 cemerick: hiredman: oh, I thought the properties file thing was to avoid ant. If ant is in there anywhere, why not just copy and paste any of the dozen executable jar recipes out there?
14:25 hiredman: cemerick: because you then have to copy and paste for every project
14:26 cemerick: hiredman: not if you use ant properly. That's what imports and macros are for.
14:30 technomancy: is getting nicer docstrings for namespaces targeted for 1.1?
14:30 *nicer docstring syntax
14:33 saml: do you use emacs?
14:34 technomancy: saml: me? I do.
14:34 http://
14:49 Chousuke: technomancy: hmm, maybe you should add to the instructions how to specify the encoding for SLIME to use. it seems to default to latin1 :/
14:53 technomancy: Chousuke: yeah, good point
15:11 rhickey: suggestions welcome for multimap reader syntax, a la #*{k v k2 #{vs ...} ...}
15:11 cschreiner: Looking for the slides from the Clojure for Lispers presentation
15:12 cark: rhickey : huh what is it for ?
15:12 cemerick: rhickey: what does that do?
15:12 jensli: Should a multimap really have special syntax?
15:12 rhickey: multimaps ar elike maps but can support more than one value per key
15:13 jensli: do you want to be able to read/print it? I do
15:13 jensli: Shouldnt one be more conservative with special syntax, to reduce complexity?
15:13 Chouser: don't want to just repeat the key?
15:13 kotarak: ehm, what is the difference to a map of keys to sets?
15:13 cemerick: rhickey: isn't that just {:a #{1 2 3}}, or whatever?
15:13 rhickey: Chouser: will answer you in a sec
15:14 ,(seq {:a #{1 2 3}})
15:14 clojurebot: ([:a #{1 2 3}])
15:14 * cemerick gets the feeling we're all going to get taken to school now
15:14 cemerick: ;-)
15:14 kotarak: hehe
15:14 Chouser: #*{[1 2 3] :key-1, [1 2 3] :key-2}
15:14 cemerick: indeed.
15:14 rhickey: but for multimaps would be [:a 1] [:a 2] [:a 3]
15:15 Chouser: oops. #*{[1 2 3] :val-1, [1 2 3] :val-2}
15:15 cemerick: rhickey: and I assume assoc would add in an additional value to the pool for the given key, etc?
15:15 Chouser: I would have used multimaps somewhere if we had them. I foreget where that was though...
15:15 rhickey: there will be assoc* and dissoc*, which add/remove from the set
15:16 jensli: assoc-multi?
15:16 rhickey: Chouser: to your question, my design distinguishes keys that support multiple values from keys that don't
15:16 cemerick: I guess I'd say it doesn't excite me. assoc-in and update-in are very capable
15:16 Chouser: some keys in a multimap would still only have one value? overwriting?
15:17 rhickey: (assoc* #*{:a 1} :a 42)) = error multi-assoc to single-value key
15:18 (assoc #*{:a #{1}} :a 42)) = error single-assoc to multi-value key
15:18 so the literal needs to distinguish, thus {:a 1 :b #{1}} yields single-value :a, multi-value :b
15:19 jensli: Just be carefull to minimize the amout of code that consists of '*' and '#'...
15:19 cemerick: rhickey: is there a performance improvement compared to update-in on a regular map?
15:20 rhickey: cemerick: no
15:20 Chouser: seems like multi-value keys would be more common than single-value in a #*{} -- perhaps use syntax to indicate the single case instead?
15:21 rhickey: but there will be a (contains-entry? mm k v)
15:21 Chouser: #*{:a 1 :a 2 [:b 3]}
15:21 rhickey: count is a count of vals, not keys
15:21 er, count of entries
15:21 a multimap is not merely a map os keys to sets
15:22 cemerick: rhickey: I'm surprised you're considering special reader syntax -- seems like a pretty minor structure.
15:22 rhickey: Chouser: but don't forget that literals often have runtime holes - #*{:a 1 :b a -set-I-already-made}
15:23 cemerick: I have big plans
15:23 Chouser: cemerick: shhh. Soon I'll be petitioning for finger tree literals #*++[:a :b :c]
15:23 cemerick: hah
15:24 Chouser: I was about to say something about bit-set literals, but nevermind :-P
15:24 rhickey: Chouser: good point, I want to discuss the general problem of supporting more core structures, I think you might get #[...]
15:24 jensli: I dont know if I dare to learn a language where people have so big plans...
15:24 rhickey: cemerick: bitsets, now that is uninteresting :)
15:25 cemerick: LOL
15:25 Chouser: rhickey: there are already a lot of restrictions on runtime holes for maps
15:25 rhickey: jensli: you can use just lists and pretend it's an old-fashioned Lisp
15:25 cemerick: jensli: "In Rich Hickey We Trust" is the motto here :-)
15:25 Chouser: no way to do this currently, right? {:a 1 (thing-that-produces-key-and-vals)}
15:26 rhickey: Chouser: I don't see that as the same at all, trying to replace many things with one
15:27 what I'm really asking about is the space before the {}, i.e. #*, ## etc?
15:27 jensli: forgot :)
15:28 but it's true, there's a limit to how much symbol overloading we can do
15:29 it could have been #set{...} and everything else in the future could have names in there
15:29 #multimap{...}
15:30 Chouser: that's pretty close to #=(multimap ...) territory.
15:30 I guess the args are evalutated at a different stage.
15:30 rhickey: Chouser: except the latter won't work with read-eval turned off
15:30 Chouser: eh. yeah.
15:30 wtetzner_: what does #= do?
15:31 Chouser: wtetzner_: read-time eval.
15:31 wtetzner_: oh
15:31 Chouser: wtetzner_: it's used by *print-dup* to generate very specific container types
15:32 rhickey: it's not like there's a ton of core-ish data structures. Started with lists/maps/vectors, added sets, only looking at finger trees and multimaps at present
15:32 Chouser: ,(binding [*print-dup* false] (prn (sorted-map :a 1 :b 2)))
15:33 clojurebot: {:a 1, :b 2}
15:33 cemerick: such valuable real-estate, though....
15:33 Chouser: ,(binding [*print-dup* true] (prn (sorted-map :a 1 :b 2)))
15:33 clojurebot: #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})
15:33 * cemerick wonders what made him start thinking like a minimalist today :-P
15:34 Chouser: cemerick: trying to think up contrasts for the vs. Scala thread? :-)
15:34 cemerick: Chouser: I've got it queued up, haven't read it yet.
15:34 dmiles_afk: clojure use a real live java.lang.Integer right?
15:34 cemerick: I've actually been keeping up on my group reading quite a bit though.
15:34 Chouser: cemerick: don't bother
15:34 cemerick: ut-oh
15:34 dmiles_afk: something scala did was heavy boxing avoidance
15:34 Chouser: ,(class 5)
15:34 clojurebot: java.lang.Integer
15:35 dmiles_afk: the way they did that was when they compiled a finction they added extra unboxed signatures
15:36 cemerick: rhickey: what's the plan when some group needs to make heavy use of an entirely separate set of (for them) core data structures? bit-sets, k-d trees, and skip lists, or whatever.
15:36 * cemerick keeps angling for the userspace reader :-D
15:36 dmiles_afk: a java lisp i work on uses boxed types.. i think Clojure could be considered Duck Types
15:37 Scala does heavy boxing avoidance
15:37 rhickey: cemerick: what happens when I want to combine your code that uses reader and someone else's?
15:37 dmiles_afk: so.. where i am going is trying to decide if the java lisp i work on should adopt Clojure's Duck Types vs Scalas boxing avoidance
15:37 Chouser: dmiles_afk: Clojure can use primitives for locals and method calls and returns.
15:38 cemerick: rhickey: hey, you're the expert! ;-) I presume the reader to be used is ns-specific, and declared as such in the top-level ns form?
15:38 dmiles_afk: Clojures method can leverage very fast box/unbox of the JVM since it staying inside java.lang.Number/* .. but..
15:38 rhickey: cemerick: but I want to use both in my files
15:38 Chouser: dmiles_afk: I believe limited support for primitive clojure fn args and clojure collections are planned.
15:38 dmiles_afk: i dont know if its more or less effectient than a LispInt
15:39 rhickey: cemerick: nevermind the hassles of making the supporting custom reader code accessible and available in advance of use
15:39 dmiles_afk: Chouser: yeah that is probaby needed.. but makes me wonder *how needed*
15:39 cemerick: rhickey: well, that sounds a little nutty :-) One reader per ns seems perfectly reasonable, and addresses anyone's domain-specific requirements.
15:39 Chouser: dmiles_afk: depends on your task, I suppose. I hardly ever need even the primitive locals, let alone anything larger-scope.
15:40 dmiles_afk: Scala did that just in case .. "because they used ScalaInt"
15:40 cemerick: rhickey: I know, I know. I'm just looking out for the whole general-applicability angle.
15:40 dmiles_afk: o they were avoid a worse case
15:40 its possible that Cljojures worsecase is not that bad
15:40 wtetzner_: if i do (SwingUtilities/invokeLater (fn [] (run-code "asdf"))), does run-code use the binding in the swing thread?
15:41 dmiles_afk: ,(+ 5 1)
15:41 clojurebot: 6
15:41 wtetzner_: is there a way to set a thread-local binding in the swing thread?
15:41 dmiles_afk: thats clojures worsecase i think
15:41 the (+ 5 1)
15:41 wtetzner_: without having to rebind for every fn i send to it?
15:41 dmiles_afk: well what would be more worsecase is (+ 2555 2551)
15:41 Chouser: wtetzner_: the only way the swing thread would have a local binding in place is if you put it right there in your anonymous fn
15:42 wtetzner_: in other words, "no"
15:42 wtetzner_: ok
15:42 Chouser: dmiles_afk: well, + is a clojure-inlinable fn, so it can actually be working on primitives.
15:42 wtetzner_: so if i want a way to access the main JFrame in my gui, i should store it in a ref or something?
15:43 Chouser: wtetzner_: yes, or a global var or atom, or maybe a promise if you want to get fancy.
15:43 wtetzner_: promise?
15:43 dmiles_afk: Chouser: (- 2555 (+ 2555 2551)) the result fn would need to be a primitive
15:43 rhickey: cemerick: I don't know that you need custom reader support for data literals like bit-sets, k-d trees, and skip lists, other than #your-factory-fn{...}
15:43 arbscht: wtetzner_: I like to create partial functions capturing that kind of context. see for an example http://
15:44 dmiles_afk: ,(class (+ 2555 2551))
15:44 clojurebot: java.lang.Integer
15:44 Chouser: rhickey: ooh, I'd take #my-fn{...} in a second, esp. if I get to read the ... myself
15:44 dmiles_afk: well it will proably always say that ')
15:44 [12:44] <clojurebot> j
15:44 oops
15:44 cemerick: rhickey: you do if those (or whatever) are you bread and butter. What if you had to write #vector[...] every time you use one?
15:44 Chouser: #my-ns/my-fn{ ... } -- perfectly composable
15:45 dmiles_afk: well it will proably always say that 'java.lang.Integer' on (class...) becasue class takes an Object
15:45 cemerick: Chouser: ssshh, I'm swinging for the fences here! ;-)
15:45 dmiles_afk: would for instance (class...) have 8 differnt singatures?
15:45 rhickey: Chouser: it's not that simple:
15:45 user=> (def a 42)
15:45 #'user/a
15:45 user=> {:b a}
15:45 {:b 42}
15:45 Chouser: cemerick: but I don't want your uncomposable readers! :-)
15:46 dmiles_afk: (that what scala did.. but still)
15:46 actually maybe in the end scala and clojure would have 15 possibles
15:46 cemerick: Chouser: why not both? :-)
15:47 dmiles_afk: the [Z [B etc
15:47 rhickey: note how the compiler can generate a data literal expression that involves evaluation
15:47 cemerick: I know a couple of people for whom notation is *everything*, which is why I keep bouncing on this particular nerve
15:48 rhickey: cemerick: wanting something and providing an answer to these critical questions are two different things
15:48 Chouser: cemerick: yes, and those people would write a lib that required a notation that clashed with someone else's lib, and everyone would be stuck.
15:48 rhickey: also, there is distinguishing use in code from use in data files
15:49 in practice, reader macros are not often used in CL and when used in libraries, widely despised, due to these issues
15:49 Chouser: dmiles_afk: repl-utils/expression-info lets you see when the Clojure compiler would emit code that uses primitives.
15:50 dmiles_afk: Chouser: yeah i betting sometimes the compiler can identify a all primitive situation pretty well
15:51 Chouser: well, #*{} is about as intuitive a choice as you'll find, i think, for multimap
15:52 cark: rhickey : reader macros are maybe bad for libraries but sometimes usefull at the application level
15:52 Chouser: though #{} for very value is pretty noisy and potentially misleading.
15:52 rhickey: Chouser: I thought so, given assoc* and dissoc*, but open to suggestions
15:53 cemerick: rhickey: would Chouser's #ns/fn{...} idea be potentially better in terms of library interop (regardless of the evaluation issues)?
15:53 rhickey: Chouser: true, in the 'all keys will support multi' it's very verbose
15:53 * cemerick is working on learning something today
15:54 rhickey: cemerick: I don't know, I think Chouser wants more inside {} than I was talking about with #your-factory-fn{...}
15:55 but the point I raised about evaluation of subcomponents is important. Right now, e.g. #= does not eval subcomponents/args
15:55 so supports read-time constants only
15:56 #your/fn[every one of these is evaluated] would be doable
15:56 or #your/fn{every one of these is evaluated}
15:58 that's different from #your/fn{gets to read this and return some arbitrary thing}
15:59 but as I said, it's not that simple
16:00 when I read {:fred ethel :ricky lucy} you get a map of keywords to symbols
16:00 but the evaluator will in turn evaluate that map-as-code and try to resolve ethel and lucy
16:00 getting the same for your data structures would be more involved
16:02 Chouser: yes, I want more in #my-fn{...} than rhickey wants to give me.
16:03 rhickey: but perhaps I see your point -- the evaluator knows how to eval a map, but might not know how to eval a my-collection.
16:03 rhickey: Chouser: exactly
16:04 (def a 42) #my-collection{a} == ?
16:04 I presume you don't want a collection with a symbol in it
16:04 cemerick: I guess I keep thinking about it in terms of the clojure reader simply being a particular implementation that parses and evaluates things in a specific way...some other reader would have its own rules, but still apply them with the assistance of an evaluation mechanism that returns a value given a symbol.
16:05 rhickey: cemerick: reading and evaluation are separate
16:05 cemerick: oh, definitely...that's what I'm getting at
16:06 rhickey: but evaluation isn't just symbols, that's just my example. you could have calls, other nested data structures etc that need to be evaluated
16:07 cemerick: ah. See, I'm assuming that the userland reader would have to identify such things and hand them up to the default reader to be handled appropriately.
16:07 * rhickey thinks Chouser is reading Compiler.MapExpr right now
16:08 rhickey: cemerick: it's not happening at read time, but at evaluation time, later
16:08 Chouser: even without user reader macros, would you have similar questions about supporting more core collections?
16:09 rhickey: Chouser: it would be great to focus on collection extensibility right now, userland reader macros is an exhausting topic with no answers afaict
16:11 for truly extensible collection support you need: extensible syntax, a way to get at code for read-time data collection construction, a way to get at code for evaluation of custom collection literals
16:12 i.e. Expr support for your collection type
16:12 the latter is not nothing
16:13 Chouser: does CL not have this issue because its only literal is the list?
16:13 only literal collection
16:16 rhickey: Chouser: CL doesn't have any evaluation in data literals, only constants, and backquote, the latter is hardwired for lists and vectors
16:18 Howard: question about commiting changes to clojure-contrib
16:18 does Rich extend write access to the repository
16:18 or do we fork it, make changes, request a pull (via GitHub)?
16:18 (I'm on the contributor list)
16:19 Chousuke: for contrib, there are contributors, a handful of committers and rich
16:19 Chouser: Howard: http://
16:19 Chousuke: but most stuff is sent via patches, yes
16:19 Chouser: pull requests aren't used anywhere currently
16:19 kotarak: Pull requests require a high level discipline..
16:20 Which makes them not very suitable for open contribution, I guess.
16:20 Howard: Sorry I missed that ...
16:20 Chousuke: you'll be fine if you just use git format-patch to generate the patches from your commits
16:20 Howard: Sure, seems like a lot of trouble though
16:20 Chouser: Howard: the list of people with commit access is at the bottom of this page: http://
16:20 Howard: it means I can't really be self sufficient
16:21 Chousuke: Howard: sure you can. just commit to your own git repo as much as you want and do a git format-patch when you're ready to send in your changes.
16:21 the patch files generated contain git commit info so all important data is preserved.
16:22 Howard: It's just a bit different from the Apache way, where once you are accepted as a committer, you can commit
16:22 rhickey: Chouser: In CL, if you want to do the equivalent of [a b c] you need `#(,a ,b ,c)
16:22 Chouser: right, clojure has four levels: user, contributor, committer, and Rich.
16:23 rhickey: ow
16:23 Howard: Ok, so just attach my patch to my ticket, then rich will apply it and close it
16:23 Chousuke: rhickey: is #() really equivalent to [] though? :/
16:23 Howard: And identify the ticket number is the commit message
16:23 rhickey: so Clojure is way ahead in having vectors/maps/sets with read/print/evaluation support
16:24 kotarak: Huge advantage! I really like the easy access to maps and vectors!
16:24 rhickey: Chousuke: no, that's my point CL #() is not Clojure []
16:24 Chousuke: Howard: you can add "fixes #nnn" to your commit message and assembla will autoclose the bug when it's committed :)
16:25 kotarak: Chousuke: which Rich doesn't really like, he prefers "refers #nnn"...
16:25 Chouser: Howard: if the patch is for contrib, you'll one of the committers will commit and close the ticket.
16:25 rhickey: nor is Clojure [a b c] == (vector a b c), because it reads as a true vector of symbols
16:26 Chousuke: yeah, that's what I thought.
16:26 Chouser: rhickey: it's that latter point that I'd not really internalized before.
16:27 Chousuke: Chouser: heh.
16:27 rhickey: Chouser: that's the key to print/read being a replacement for JSON/XML, useful when there's no eval at all
16:27 Chousuke: Chouser: it reads a data structure, then calls (vec stuff-that-was-just-read)
16:28 Chouser: or in my reader, I actually always read stuff into vectors (because they expand at the end) and then do (apply hash-map...) or (set ...) on it.
16:29 a bit wasteful but easy :P
16:30 Chouser: right, but I hadn't thought through the consequences of having things other than lists in what the reader produces. That is that eval has different behavior based on the type of thing that was read.
16:31 I mean, I guess I knew that, but didn't understand all the consequences.
16:31 Chousuke: it has consequences with macros too.
16:31 Licenser: Hi everyone
16:32 is there any list of the keywords Clojure has?
16:32 Chousuke: keywords? you mean special forms?
16:32 hiredman: they are listen on a side somewhere
16:32 slide
16:32 there are seven or so
16:32 Chousuke: def, fn* loop, let*, ., try, ... hmm. I forget.
16:33 Licenser: hmm yes the things I can put in the first argument of a () to do something, things like def and if
16:33 hiredman: Licenser: well you can put any function there
16:33 or any IFn
16:33 Licenser: I hean the build in ones, not self defined ones
16:33 so if yes but and not
16:34 kotarak: Licenser: (approximately) http://
16:34 Chouser: Licenser: use the source!
16:34 Chousuke: ah, right, if of course.
16:34 hiredman: http://
16:34 Licenser: Use the source Luke!
16:34 hiredman: thanks that is what I was looking for :d
16:35 hiredman: this is lisp, the difference between built in and built on is negligible
16:35 Chousuke: that page is lying anyway. some of the special forms listed are actually macros
16:35 Licenser: oi :/
16:35 Chouser: right, depends on why you want to know
16:35 Howard: at the risk of sounding stupid; after I've attached my patch, what action do I take on the ticket (i.e., "mark ready to test") and do I reassign it?
16:36 kotarak: But the star form is the special form, fn=>fn*, let=>let*
16:36 Chousuke: yeah.
16:36 Licenser: Chouser: for highlighting source ^^
16:36 Chouser: Licenser: use the source if you want the actual list of real builtins. Use the web page if you want to know what's promised.
16:36 Licenser: ah. use the web page.
16:36 Chousuke: I wonder if newnew will cause fn* to go away.
16:36 kotarak: I highlight according to the web page.
16:37 Howard: I wonder if newnew will get a better name :-}
16:37 rhickey: so, back to multimaps - any feedback other than you're all disappointed you're not getting what you really wanted? :)
16:37 Chouser: the fact that fn is a macro but fn* is builtin is just an implementation detail -- may change at any moment.
16:37 rhickey: Howard: its has - reify
16:37 Chousuke: oh, right. you decided on that then? :)
16:37 cemerick: ah-ha, didn't know it was official :-)
16:37 hiredman: neato
16:38 rhickey: I could go with #mmap{...} pretending that one day #blah{} will be extensible
16:38 but Chouser's point on verbosity with all-multi-keys is valid
16:39 hiredman: #mmap would require some adjustment to the reader, wouldn't it?
16:39 rhickey: hiredman: yes
16:39 Chouser: rhickey: you specicially want to support providing a set at runtime for multiple values?
16:39 rhickey: this would be a new core datatype
16:40 Chouser: dunno, right now in the design I am supporting any collection as the init for a multikey
16:40 i.e. you can't have a singlekey that maps to a collection
16:41 Chouser: ah, ok ... I was just trying to phrase that point. :-)
16:41 rhickey: so #*{:a 1 :b [2 3]} would work too
16:41 hiredman: hmmm
16:41 rhickey: this mostly for the evaluated case #*{:a 1 :b (a-seq-fn)}
16:42 Chouser: what about {:a 1 :b #*expr} ?
16:42 Chousuke: wait, what datatype is this?
16:42 hiredman: multimap
16:42 Chouser: that way {:a [1 2] :b #*[3 4]} would have :a as a single key, :b as a multi
16:42 rhickey: Chouser: nothing around {}? multimap triggered by #* inside?
16:43 Chouser: sure
16:43 rhickey: how do you make an empty multimap or one initialized with only single keys?
16:43 Chousuke: that would make my reader design rather ineffective :-(
16:43 Chouser: or both, I suppose. #*{:a 1 :b #*[2]} My main point was new reader support for the mutli-values
16:44 hiredman: rhickey: well assoc* on a regular map could return a multimap?
16:44 rhickey: Chouser: are you saying :b is a multikey or :a?
16:44 Chouser: that doesn't help remove clutter, but it makes single-value collections possible.
16:44 rhickey: ooh, I meant :b as multikey, but the alternative is interesting.
16:44 rhickey: Chouser: I don't think I care about singlekeys mapping to collections
16:45 lots of complexity elsewhere if supported
16:45 Chouser: #*{:a #.:single :b [:multi]} bleh.
16:46 wtetzner_: so a multimap is a map whose keys can hold multiple values?
16:46 rhickey: I am trying to address #*{:a [1] :b [2] :c [3] ...} when you want all the keys to be multi
16:46 Chouser: yeah, though even that is better than #{} for each value
16:47 rhickey: wtetzner: basically, with the twist that some keys can be non-multi, and that is enforced
16:47 kotarak: Why not making multi the default? #*{:a 1 :b 2 #1 :c 3} (with c single key.)?
16:48 wtetzner_: rhickey: oh, i see
16:48 rhickey: so that's why a map of vectors isn't the same thing
16:48 Chousuke: #*[:a :b]{:a 1 :b 2 :c [1 2 3]}? :P
16:48 iffy.
16:48 rhickey: kotarak: taking colls in the literal is not bad, as (#*{:a 1 :b [2 3]} :b) -> #{2 3}
16:49 wtetzner_: are multimaps used often enough to give it reader syntax?
16:50 rhickey: wtetzner_: depends upon your domain
16:51 wtetzner_: maybe something like this: {:a 1 :b 2 | :c [1 2 3] :d [4]}
16:51 rhickey: so far today they seem not so popular :(
16:51 wtetzner_: where single keys and multikeys are divided by a |
16:51 Chouser: why not support both repeated keys *and* collection values to indicate multi.
16:52 rhickey: Chouser: repeated keys seem really painful
16:52 and would never print that way
16:53 cemerick: rhickey: I just don't see the big deal given update/assoc-in, sorry. :-|
16:53 rhickey: you've got the vision thing, though, which trumps a lot
16:54 Chouser: ok, so the real clutter issue is when you when you want to declare a key as multi but have zero, one, or a runtime expression value.
16:54 rhickey: cemerick: there are differences in seq/count, can test for contains-entry
16:54 Chouser: pretty much
16:54 cemerick: do you do anything with RDF?
16:55 cemerick: ah-ha
16:55 no, thank goodness
16:55 wtetzner_: rhickey: is it neccessary to have a special character at the front for it to be a reader macro?
16:55 Chouser: so now I'm liking wtetzner_'s suggestion
16:56 rhickey: Chouser: the problem with that (separator) is the asymmetry with whatever the factory fn will be
16:56 wtetzner_: why couldn't the factory function do something like that?
16:57 is | a legal symbol?
16:57 i guess it might be bound to something though
16:57 rhickey: wtetzner_: take | as an argument?
16:57 wtetzner_: rhickey: yeah, but i guess that's a bad idea
16:57 rhickey: very difficult, will mess up apply and composition in general
16:58 Chouser: #*[:a :b]{:c nil :d [1 2] :e 3 :b 5}
16:58 kotarak: rhickey: why do you need enforcement of single-keyd-ness?
16:59 wtetzner_: do reader macros require that the starting character is a special character?
16:59 Chouser: every key is multi unless noted in the []. (multi-map single-keys map-thing)
16:59 Chousuke: Chouser: heh, I suggested the same earlier ;P
16:59 wtetzner_: could you do something nicer like M{:a 1 :b 2 :c [1 2 3] :d [4]}
17:00 rhickey: Chouser: thinking through composition scenarios, I see needing to ask for single keys etc
17:00 Chousuke: wtetzner_: that makes symbol parsing a lot more complicated
17:00 Chouser: Chousuke: yeah, I saw that, but I thought you were listing the multis
17:00 saml: did you write a computer game in clojure? 2d or 3d with audio?
17:00 wtetzner_: ok
17:00 Chouser: Chousuke: though looking at it a again, perhaps you weren't. :-)
17:00 Chousuke: wtetzner_: it's easier to have some special character for use in reader macros
17:00 wtetzner_: but all of the special characters are starting to make it look too much like perl
17:01 maybe #M{...}
17:01 Chousuke: Well, ^#'foo is pushing it, yes, but ....
17:01 it's nowhere near perl.
17:02 Chouser: $_=~/(.)$/ # perl
17:02 wtetzner_: haha
17:02 i didn't say it was as bad as perl, just that i don't want it to get any closer to perl
17:03 Chousuke: but certainly alphanumerics are usable for reader dispatch, as long as the # remains in place :P
17:03 wtetzner_: ah
17:04 kotarak: When we drop the enforcement of single-keyd-ness, wouldn't then the hassle just disappear? #*{:a [1] :b [1 2 3]} ... Don't care for :a being single-key or not ....
17:04 rhickey: kotarak: It's an enhancement to the normal multimap thing, much easier to use these - without it there will always be some keys for which 'there should only be one' and manually enforcing that is tedious
17:04 kotarak: well, you'd say #*{:a 1 :b [1 2 3]} in that case then
17:05 only using coll when more than one
17:05 wtetzner_: what if you wanted a key to have a collection as its value?
17:05 but only one collection
17:05 Chouser: zero-value case is annoying too.
17:05 rhickey: wtetzner_: can't
17:05 Chouser: ?
17:05 JAS415: i don't get it, what does the * mean
17:06 rhickey: JAS415: placeholder for something indicating multimap
17:06 kotarak: rhickey: #*{:a [[1]] :b [1 2 3]} .... would allow that, again enforcing single-keyd-ness is the problem... (Just strip one set of [] to get the values...)
17:06 JAS415: oh
17:07 Chouser: #*{:a [1 2 3] :b [4] :c 5 :d nil} even if :a and :b are multis, and :c is single (ie. our clutterful option), what's :d? a single nil, or an empty multi?
17:08 wtetzner_: Chouser: if it was multi, wouldn't it be #*{:a [1 2 3] :b [4] :c 5 :d [nil]} ?
17:08 rhickey: Chouser: single nil, use [] for emtpy multi
17:08 wtetzner_: or that
17:08 Chouser: wtetzner_: [nil] would be a multi with currently just one nil.
17:09 ok, so clutterful handles zero value case ok: nil vs. []
17:09 rhickey: clutterful, h? :)
17:09 kotarak: I don't like the "no vectors" taste... :(
17:10 Chouser: rhickey: can you eloborate re: thinking through composition scenarios, I see needing to ask for single keys etc
17:10 kotarak: Then multi-maps don't nest anymore with the rest of the collections ...
17:10 rhickey: Chouser: what happens when you want to make a new multimap out of others?
17:10 kotarak: they nest in
17:11 a key point of multimaps is the flattening that they do. As cemerick has pointed out, you can have mappings to sets right now
17:11 kotarak: rhickey: But I can't do #*{:a []} (single-key with empty vector value)
17:11 rhickey: kotarak: I understand
17:12 Chouser: oh, we don't even have a 'push'. sheesh.
17:13 rhickey: Chouser: heh, I just did (doc push) before :)
17:13 wtetzner_: maybe: #M{[:a 1 :b 2] [:c [1 2 3] :d [4]]}, with a constructor function (multi-map [:a 1 :b 2] [:c [1 2 3] :d [4]])
17:14 or #M{(:a 1 :b 2) (:c [1 2 3] :d [4])}
17:14 Chouser: I think that's got the same composition problem that I'm trying to grok.
17:14 rhickey: wtetzner_: if you're not going to get out of :d [4] there's no point to separating them
17:15 Chouser: what's the zipmap equiv for multimaps?
17:15 keying off the collection-ality of the val is easy
17:15 separate keysets is hard
17:16 Chousuke: metadata? :P
17:16 Chouser: what will conj do?
17:17 rhickey: personally, most handwritten map inits are small, so I think this might be a non-problem. I'll go with collection inits for multikeys in the first pass and we'll see if it is a real problem
17:17 Chouser: (conj #*{} [:a 1] [:a 2]) ; ok or not?
17:18 wtetzner_: how about #M{:a 1 :b 2 :c |1 2 3| :d |4|}, so you're not using the vector syntax
17:18 although that has the constructor asymmetry problem
17:18 rhickey: Chouser: I think conj will do assoc*
17:19 since :a is not already there and single, will be ok, build a multikey for :a
17:20 kotarak: Why not making all keys multi per default and require a constructor for single keys? (multi-map [:a :b] :a 1 :b 2 :c [1 2 3])?
17:24 krumholt__: if anyone is particularly bored maybe make a patch so that bit-or accepts an arbitrary number of arguments :)
17:30 JAS415: im having too much fun searching for lolcats on twitter :-P
17:33 Chouser: JAS415: maybe make a patch so that bit-or accepts an arbitrary number of arguments :-)
17:33 JAS415: hahaha okay i'll look at it
17:33 Chousuke: shouldn't be too difficult :/
17:34 JAS415: yeah it should be just like + or -
17:35 kotarak: Why do I get that: "java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class;" when I try to compile c.c.lazy-xml?
17:37 Hmm.. I tells me, it's from seq_utils.clj:24...
17:38 alrex021: Hi guys. Need some help please to review a snippet of code I wrote. I pretty sure it can be inmproved
17:38 oops, trigger happy
17:38 kotarak: http://
17:38 ^^^ the stacktrace
17:39 Chouser: kotarak: doing anything unusual with classloaders?
17:40 kotarak: Chouser: not really. just setting up different compilation trees for the Ivy packages. Lazy-xml (/ seq-utils?) is the only package so far, where I see this-
17:41 melling: trying to get slime working. Get an error launching inferior-lisp... can't find swank.clj
17:41 java.lang.ClassNotFoundException: swank.swank (NO_SOURCE_FILE:0)
17:41 what do I have to set in my .emacs.
17:41 these files are in /opt/swank-clojure/swank
17:43 thought this would do it.
17:43 (setq swank-clojure-extra-classpaths (list "/opt/lib/java/clojure-contrib.jar:/opt/swank-clojure"))
17:43 kotarak: Chouser: Ok. Found the problem. For some reason, lazy-xml uses the clojure-1.0.0.jar, while the others use a more recent version.
17:44 Argh... DRY caught me again.
17:44 * kotarak has to investigate gradle to get rid of ant.
17:45 alrex021: I have two vectors of user roles. new-roles and existing-roles. I must remove old roles that are not in new-roles and add any from new-roles that re not in existing-roles. (I know I could just replace the old ones in existing-roles...but I actually want to leave those intact.) I'm sure there are better ways to do this. any comments welcome. http://
17:47 I'm trying to compare some code I had to write today at work in pure java, quite a loop headache as compare to what I even have so far in clojure.
17:48 arohner: has anyone gotten slime to print test/is output in your slime window rather than the console when using slime-connect?
17:48 clojurebot: slime is icky
17:49 kotarak: alrex021: maybe you want sets?
17:49 arohner: alrex021: yeah, using vectors for this seems weird
17:50 I would use a set or a map
17:50 then you can use contains?
17:50 or set/difference
17:50 technomancy: arohner: try clojure-test-mode; it shows the test output in the test buffer itself.
17:51 arohner: technomancy: I don't have a clojure-test-mode, where do you get it?
17:51 JAS415: ok, i've made the changes to make it take multiple args
17:51 technomancy: arohner: http://
17:51 haven't updated it for clojure 1.1 though. =\
17:52 JAS415: now i have to figure out assembla
17:52 melling: Put path in clj-server file: http://
17:52 I'm done!
17:53 arohner: technomancy: oh wow my clojure-mode is old. 2008/11/13
17:54 technomancy: arohner: you're missing out!
17:55 drewr: whoa
17:59 JAS415: how do i add a ticket to assembla?
18:00 rhickey: https://
18:00 https://
18:00 JAS415: ah thanks
18:00 rhickey: if you are not a contributor
18:03 hiredman: ~ticket #164
18:03 clojurebot: {:url http://
18:04 hiredman: not that that has anything to do with anything, it just caught my eye
18:05 ~ticket #2
18:05 clojurebot: {:url http://
18:07 alrex021: kotarak: here is an improved ver that uses sets with difference and intersection http://
18:09 not to sure if its smart to to do difference and intersection and then use into to conjoin them
18:10 hiredman: clojure.set operations use sequences internally anyway
18:10 :/
18:14 ~ticket #112
18:14 clojurebot: {:url http://
18:15 hiredman: ##java seemed to think this idea was broken for some reason, bugs with handling charsequences in jvm?
18:16 http://
18:17 kotarak: alrex021: what you do now is only the identity, no? A = A \ B union A intersect B, which is exactly what you wrote there.
18:24 bitbckt: ~latest
18:24 clojurebot: latest is 1382
18:24 Chousuke: hmm
18:24 that's somehow wrong.
18:24 hiredman: latest is left over from svn
18:24 ~commit
18:24 clojurebot: I don't understand.
18:25 hiredman: bah
18:25 bitbckt: I'm just exploring.
18:25 hehe
18:25 hiredman: ~last commit
18:25 clojurebot: Huh?
18:25 JAS415: user=> (bit-xor 1 2 3 4 5 6 7 8 9 10)
18:25 (bit-xor 1 2 3 4 5 6 7 8 9 10)
18:25 11
18:25 hiredman: huh
18:26 (doc bit-xor)
18:26 clojurebot: "([x y]); Bitwise exclusive or"
18:26 hiredman: JAS415: that throws an IllegalArgumentException for me
18:27 Chousuke: you need a CA to contribute though :/
18:28 even for trivial patches ;(
18:29 JAS415: yeah i need to submit the patch
18:29 hm
18:29 is there any reason to do (reduce / (x y) more)
18:29 instead of
18:30 (/ x (reduce * y more))
18:30 Chousuke: the two-argument versions are inlined
18:30 JAS415: yeah i think i got a patch for that too
18:30 Chousuke: and I think the former is neater.
18:31 JAS415: yeah but / is a lot less efficient than *
18:31 arohner: technomancy: when I install clojure-mode through ELPA, now C-c C-l (load file) doesn't work on new buffers created after I slime-connect
18:31 JAS415: just wondering if there was a situation where it was mathematically different
18:31 kotarak: ANd x is a function? (reduce / x (cons y more))
18:31 JAS415: like maybe with imaginary number or something
18:31 Chousuke: JAS415: hm, right.
18:31 technomancy: arohner: how about C-c C-k?
18:31 Chousuke: doesn't support imaginary numbers anyway
18:31 JAS415: (reduce / (/ x y) more)
18:31 Chousuke: er. /
18:31 JAS415: shuld be that, was a typo
18:32 arohner: technomancy: undefined
18:32 JAS415: okay
18:32 arohner: what function does that map to?
18:32 JAS415: i'll do it with the * anyway
18:33 technomancy: arohner: slime-compile-and-load-file
18:33 arohner: does it show "Slime[clojure]" in the modeline?
18:33 arohner: no, it shows just (Clojure)
18:33 buffers that were open before the slime connect work fine
18:34 technomancy: arohner: try M-x slime-mode then
18:34 arohner: hrm. there may be some funkiness in my .emacs screwing with clojure-install
18:34 let me retest
18:34 technomancy: somehow the hook to activate that automatically must not be run
19:32 JAS415: assembla is pretty neat
20:16 arohner: If I want to access a nested class, its (Outer$Inner/method), right?
20:16 http://
20:17 (WebDriver$Options/setSpeed Speed/SLOW) is not working for me
20:17 or am I missing something?
20:18 rhickey: setSpeed is not a static method
20:20 arohner: what kind of driver are you using?
20:20 arohner: HtmlUnitDriver
20:21 krumholt__: if java expects null as a parameter can i just use nil?
20:21 rhickey: (-> (HtmlUnitDriver.) manage (setSpeed Speed/SLOW)))
20:22 some .s in there
20:22 arohner: rhickey: ah, thanks
20:24 durka421: krumholt__: yes
20:24 krumholt__: durka42, thanks
20:25 Chouser: rhickey: so you'd be open to 'cons' calling a method on a collection. It never does that currently.
20:26 rhickey: ,(doc cons)
20:26 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."
20:26 Chouser: I don't need a ruling immediately. :-)
20:26 rhickey: wouldthat still be true?
20:27 Chouser: yes
20:27 rhickey: then I think it's good
20:27 finger trees are uber-seqs
20:27 Chouser: ,(class (cons 5 '(1 2 3)))
20:27 clojurebot: clojure.lang.Cons
20:28 Chouser: PersistentLists are also seqs, but don't get to participate in cons.
20:28 rhickey: ,(class (cons 42 nil))
20:28 clojurebot: clojure.lang.PersistentList
20:28 Chouser: whee!
20:30 rhickey: not sure this should be:
20:30 ,(class (cons 12 (cons 42 nil)))
20:30 clojurebot: clojure.lang.Cons
20:30 Chouser: right
20:30 rhickey: but in any case cons makes no promise about the return type other than seq
20:30 Chouser: ,(take 4 (map class (iterate #(cons 1 %) nil)))
20:30 clojurebot: (nil clojure.lang.PersistentList clojure.lang.Cons clojure.lang.Cons)
20:30 Chouser: (doc rest)
20:30 clojurebot: "([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."
20:31 Chouser: (doc next)
20:31 clojurebot: "([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."
20:31 Chouser: I should be able to do those too.
20:31 rhickey: right
20:32 otherwise you're not really a seq
20:32 Chouser: but that means my .seq will have to return this, while rseq can return a cursor object
20:32 rhickey: yes (identical? ft (seq ft)) -> true
20:33 Chouser: another thought I had was a .reverse that actually just flipped a switch to allow conj/pop from the other side.
20:33 rhickey: trickier will be wiring into concat
20:34 Chouser: IConcat? :-)
20:34 rhickey: could be
20:35 Chouser: I dunno thought, that would break the current docstring. not a lazy seq
20:35 back in a minute...
20:40 I would tend to think ft-concat is not the same thing as concat.
20:41 rhickey: why not?
20:41 there's just nothing to be lazy about
20:42 Chouser: concat works on anything seqable. ft-concat only works on ft's with the same measure/reduce functions.
20:42 clojurebot: functions are maps
20:43 rhickey: Chouser: you'll have to explain those to me more
20:47 Chouser: their first example is a measure of size and a reduce of add
20:48 so the measure is (constantly 1)
20:49 and the reduce is +
20:49 a node of 3 elements [1 2 3] would cache it's reduced measure of 3
20:50 these operations are done when nodes are constructured, and then used for operations like split
20:50 in this case, split can use these measures to ask for the nth element of the tree
20:51 but you might have application-specific functions as well, for priority queues and such.
20:54 rhickey: ok, so concat could concat 2 non-conforming fts
20:55 do your fts have to have measure/reduce fns?
20:55 Chouser: right, by walking them. but it would not produce a ft that you could split
20:56 no
20:56 rhickey: ok, then separate ft concat
20:57 Chouser: but you can't split without measure, just conj l/r
20:58 rhickey: do you support multiple measure/reduce pairs at once?
20:58 Chouser: huh. the paper doesn't seem to define pop/next
20:59 rhickey: I plan to. the paper supports multiples by combining functions -- my current plan is to allow a set of named measure/reduce pairs
20:59 rhickey: isn't pop whatthey ar ecalling deque?
21:00 Chouser: they define little triangles to the left and right, which are conj l/r
21:01 then they define reduce and seq-like views
21:01 I don't see an actual "deque" operation.
21:04 rhickey: I think pop/next are split
21:04 ?
21:04 Chouser: could be
21:06 but split as they define it requires a measure fn, and I ought to be able to do pop/next without any measure/reduce.
22:12 any reason delay is not IMeta?
22:29 I can't tell if reductions must be delayed, or if that's even possible.
22:40 JAS415: hmm
22:41 is binding as complicated as it seems to me?
22:43 Chouser: ok, I think can't be delayed.
22:44 JAS415: are you referring to the use of thread-local bindings, or something else?
22:44 JAS415: i guess i am just kind of wondering how I know when I am in a specific thread
22:44 in a swing app for example
22:45 like I do a binding to something and call (main)
22:45 then it seems like it gets unbound when I use menus and stuff
22:45 possibly because they're creating threads under the hood?
22:46 Chouser: (binding [x 5] (foo)) will only have x bound until (foo) returns
22:47 JAS415: ooh
22:47 okay
22:47 so it has to do with when it returns
22:47 hmm
22:48 Chouser: binding is very much a temporary kind of thing, for a particular dynamic excursion down the call stack.
22:49 JAS415: i was hoping i could create new threads with different bindings kind of enclosed in them
22:50 Chouser: if the thread stays busy in some kind of event loop, then wrapping a single binding around that will work.
22:50 tomoj: hmm.. would (Thread. (binding [x 3] foo)) work?
22:51 or since you're returning a function there, the binding is ignored?
22:51 Chouser: (Thread. #(binding [x 3] (foo))) would work
22:51 JAS415: what was trying was (thread. #(binding [x 3] (foo)))
22:51 problem was
22:52 (foo) returns
22:52 i still have the window open
22:52 and nothing is bound anymore
22:52 Chouser: right
22:52 JAS415: so i just need to keep it from returning
22:53 yeah so i can make it sleep
22:55 hmm
22:55 nope
22:55 (new Thread #(let [[con prov](login xx
22:56 xx)]
22:56 (binding [tw/*consumer* con
22:56 tw/*provider* prov]
22:56 (main-window)
22:56 (loop [] (recur)))))
22:56 doesn't seem to work
22:56 Chouser: aren't all swing events sent to a single thread?
22:56 JAS415: well that would explain a lot :-P
22:56 wtetzner: yeah swing isn't thread safe
22:56 JAS415: bummer
22:57 wtetzner: so you need to use (javax.swing.SwingUtilities/invokeLater some-function)
22:57 and it sends some-function to the swing thread
23:00 does anyone know how the swing thread starts?
23:01 oh
23:01 nevermind
23:02 http://
23:06 JAS415: hmm
23:07 maybe i'll try a different approach
23:11 wtetzner: i wonder if there's a way to intercept the creation of the swing event thread
23:11 to add bindings to it
23:12 Chouser: why not use lexical scope instead?
23:13 wtetzner: well, i was just thinking it would be nice to be able to bind the main JFrame to a swing var
23:14 since swing isn't thread safe, it feels wrong to store it in a global reference like a ref or atom, or global var
23:16 JAS415: ah
23:16 well what i was hoping to do was have multiple logins
23:16 which is actually kind of orthogonal to whether or not swing is thread safe
23:17 just that the things that have to activate and interact with the logins have to be in a specific thread if I want to use thread-local bindings
23:17 wtetzner: well you can use (javax.swing.SwingUtilities/invokeLater some-function) to interact with swing
23:21 JAS415: reason i would rather not do lexical scope is that it seems like i'd be passing a lot of stuff directly
23:21 Chouser: could you close over it instead of passing it?
23:23 JAS415: yeah i was considering that
23:23 generating all the functions when the person logs in and closing over the results
23:31 what if i just created a seperate process?
23:32 Chouser: wow. big hammer.
23:32 JAS415: yeah i guess too big