#clojure logs

2009-08-26

00:00mebaran151it seemed to work
00:00mebaran151clojure contrib with the old version
00:45headiusmikem: clojure's using nailgun now too, eh?
00:45headiuswe need to get together and make some improvements
00:53hiredmanvimclojure comes with a nailgun server
00:57replacais anyone else getting errors building the latest contrib?
00:58replacaI'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:
01:00hiredmanyep
01:00replacaoh, just a typo in build.xml
01:00replacaone sec, i'll check in a fix
01:05replacafixed, you can pull now
01:05hiredmanneat
01:57lowlycoderhow do i search for sample code taht uses letfn
01:58LauJensenlowlycoder: Google seemed to do the trick: http://groups.google.com/group/clojure/browse_thread/thread/a7aad1d5b94db748
01:59lowlycoderwhat did you search for?
01:59LauJensen"clojure letfn"
02:00hiredman~google clojure letfn
02:00clojurebotFirst, out of 68 results is:
02:00clojurebotletfn - mutually recursive local functions - Clojure | Google Groups
02:00clojurebothttp://groups.google.com/group/clojure/browse_thread/thread/a7aad1d5b94db748
02:00hiredmanhuh
02:11lowlycoderis there anyway I can use letfn on a proxy?
02:16lowlycoderin clojure, how can you create a proxy that will remove itself?
02:25lowlycoderthis 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?
02:27hiredmanwhat are you doing?
02:27lowlycoderi'm doing something wrong (and re-engineering my solution to not need this)
02:27lowlycoderbut now, i'm curious
02:37lowlycoderhttp://paste.lisp.org/+1UEG <-- is there a way to make this shorter / more idiomatic
02:38hiredmanlooks like you are re-implementing memoize
02:38hiredman~def memoize
02:38lowlycoderwhoa, it happens only once?
02:38lowlycoderthat's an interesting wya to use memoize
02:38lowlycoderno it's not
02:38lowlycoderi'm trying to remove the listener after it execs
02:39hiredmanwhat
02:39hiredmanthis is ridiculous
02:39hiredmanremove from what?
02:40lowlycoderi remove the listener after it exeutes once
02:40lowlycoderideally i would use letfn and not have to deal with my-ref
02:40lowlycoderbut i don't know how to use letfn with proxy
02:40hiredmanhave you read the docs for proxy?
02:40lowlycoderi have
02:40hiredmanI suggest you do, there is a very simple way to do this
02:41lowlycoderit returns a class
02:41lowlycoderno mention of the function
02:41lowlycoderthe this?
02:41lowlycoderhmm
02:41hiredman
02:50JAS415~def proxy
02:51JAS415Each method fn takes an additional implicit first arg, which is bound to 'this.
02:51lowlycoderJAS415: yep; just got it working; thanks :-)
02:52JAS415cool
02:52JAS415this is very useful, i had the same type of problem until i found it
02:53lowlycoderyeah, 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
02:53lowlycoderthen I moved on to what I pasted into lisppaste
02:53lowlycoderbut this solution I like the best :-)
03:20mebaran151has anybody tried the new enclojure
03:21mebaran151REPL seems to be failing on me in Netbeans with the newest one
03:22lowlycoderdoes enclojure have vim intergration?
03:36lowlycoderi'm really starting to hate clojure's lack of continuations
03:36lowlycoderi'm seeing them everywhere
04:27LauJensenhiredman: feeling a little grumpy today ?
04:31hiredman?
04:31hiredmanevery day
04:31lowlycoderdoes clojure have a deque structure, where I append to the front and take from the end?
04:32hiredman,(doc butlast)
04:32clojurebot"([coll]); Return a seq of all but the last item in coll, in linear time"
04:32hiredmanhmm
04:33hiredman,(doc subvec)
04:33clojurebot"([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."
04:33lowlycoder?
04:33clojurebotclojure-maven-plugin is http://github.com/talios/clojure-maven-plugin
04:33lowlycoderhmm, i'll just use reverse function
04:34hiredman,(conj [1 2 3] 4)
04:34clojurebot[1 2 3 4]
04:34LauJensenlowlycoder: 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)
04:34LauJensen~(conj '(1 2 3) 4)
04:34clojurebot(conj {:a 1} (when true {:b 2}))
04:34hiredman,(subvec [1 2 3 4] 1)
04:34clojurebot[2 3 4]
04:34LauJensenw00t?
04:34LauJensenclojureb0t is b0rked
04:34hiredmanLauJensen: what?
04:34LauJensen~(conj '(1 2 3) 4)
04:34clojurebot(conj {:a 1} (when true {:b 2}))
04:35LauJensenthat should give me (4 1 2 3)
04:35Chousuke~conj
04:35clojurebot(conj {:a 1} (when true {:b 2}))
04:35hiredmanLauJensen: ,
04:35LauJensen,(conj '(1 2 3) 4)
04:35clojurebot(4 1 2 3)
04:35LauJensenOh - So I'm the noob :)
04:35LauJensenbtw, all you danish reading compojure lovin' clojure fans, check out http://www.bestinclass.dk
04:35hiredmananyway subvec and conj will let you use a vector as a deque
04:36Chousukehmm, doesn't subvec have performance issues if you stack it too much? /:
04:36hiredmanlast I heard it did not
04:37hiredman(doc subvec)
04:37clojurebot"([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."
04:37hiredmanbah
04:37hiredman~def subvec
04:38hiredman~def c.l.RT
04:40hiredman~def c.l.APersistentVector
04:41LauJensenhiredman: Dont you worry that tinyurl will consider you a spammer?
04:43hiredmannope
07:05gko,(= (java.lang.Long. "123") (java.math.BigInteger. "123"))
07:05clojurebottrue
07:06gko,(#{(java.lang.Long. "123")} (java.math.BigInteger. "123"))
07:06clojurebotnil
07:06gkowhy ???
07:14gkois that normal?
07:27liwpgko: I think set uses .equals() to find items whereas (=) uses numerical equality for numbesr
07:28liwp,(.equals (Long. "123") (java.math.BigInteger. "123"))
07:28clojurebotfalse
07:28liwp,(.equals (Integer. "123") 123)
07:28clojurebottrue
07:29liwp,(#{(Integer. "123")} 123)
07:29clojurebot123
07:30gkoliwp: so, set of number = pain ?
07:32gkoor what should I use instead?
07:32liwpyeah, I think it tends to be uncomfortable unless you can guarantee that all the numbers are e.g. ints
07:33liwpI'm not sure what the recommended way of dealing with this is
07:33liwpif 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
07:34liwp,(doc bigint)
07:34clojurebot"([x]); Coerce to BigInteger"
07:35liwp,(#{(Long. "123")} (long 123))
07:35clojurebot123
07:35liwp,(#{(java.math.BingInteger. "123")} (bigint 123))
07:35clojurebotjava.lang.ClassNotFoundException: java.math.BingInteger
07:35liwpuhh
07:35liwp,(#{(java.math.BigInteger. "123")} (bigint 123))
07:35clojurebot123
07:36liwpgko: but yeah, you need to be careful
07:37gkoyep.
07:50raphinouis there a way to avoid the repeat of (count args) in this code? (let [argsnum# (if (< 0 (count args)) (count args) "") ] some-code)
07:53matleyraphinou, only if you write a macro if-negative-let afaik
07:55raphinouok, thx matley. It's not worth it in my case
07:58gerryxiaohello
07:58gerryxiaohow to change Graphics to Graphics2D in clojure?
07:59gerryxiao(Graphics2D g) seems not work
07:59gerryxiaog is Graphics
08:00liwpI assume you're calling a method on g that is only defined for Graphics2D instances?
08:01liwptry adding a type hint to the call site, e.g. (.foo #^Garphics2D g <rest of args>)
08:01gerryxiaonope
08:02gerryxiaoi 'm use Canvas class to draw stuff
08:02gerryxiaopaint(g)
08:03gerryxiaog is Graphics
08:03gerryxiaoi want to change it to Graphics2D and use methods from Graphics2D
08:04liwptry this: (.paint canvas #^Graphics2D g)
08:04matleynewbie 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] [] ... .... )) ?
08:04arbscht,(doc cast)
08:04clojurebot"([c x]); Throws a ClassCastException if x is not a c, else returns x."
08:05gerryxiaook
08:18gerryxiaoit works, thx
08:19gerryxiaoliwp :-)
08:19liwpgood
08:20gerryxiaobut i think "#^Graphics 2D" is much ugly
08:20liwpI haven't really figured out yet what clojure's (cast) is good for
08:20liwpyeah, the type hinting does get a bit ugly
08:20gerryxiaoi have to type it much times
08:21liwpthere was some discussion about a macro that would allow something like g:Graphics2D in function definitions
08:21gerryxiao(let [g2d #^Graphics2D g]) can't work?
08:21liwpgerryxiao: if it is in the same function you can type hint a let binding and then use that
08:21liwpyep, that's it
08:23gerryxiaothat's a bit better
08:25gerryxiaowhen will newnew be merged to master?
08:29liwpdon't know
08:53LauJensen~max
08:53clojurebotmax people is 164
08:53LauJensen~clojureql
08:53clojurebotclojureql is http://gitorious.org/clojureql
09:11lpetit_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 ?
09:12cgrand,(doc file-seq)
09:12clojurebot"([dir]); A tree seq on java.io.Files"
09:13lpetit_thx, I was searching on the wrong keyword (directory, folder)
09:20gerryxiaohello
09:20gerryxiaohow to name static innerclass in clojure?
09:20gerryxiaoclassname/innerclass ?
09:20Chouserclassname$innerclass
09:21gerryxiaook
09:21carkcarefull about importing the innerclass too, or use fully qualified names
09:22gerryxiao(import (java.awt.geom Line2D))
09:22carknope you need the containing class as well
09:23cark(import (java.awt.geom Bleh$Line2D))
09:23gerryxiaooh
09:23gerryxiaothx
09:43Chousersome day I'll come up with a use for condp's :>> clause
10:00Fossihey
10:02Fossiwe want to call some java methods on an object dynamically, like (.. (Query. "foo") (addFilter "bar") (addFilter "baz"))
10:02Fossiwith bar and baz coming from a map for example.
10:03Fossiwe used reduce for a while which went ok, but it's getting more complicated as we want to call another method
10:03Fossiis 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:04liwp,(doc memfn)
10:04clojurebot"([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:04liwpdoes that help
10:05Fossiquite some :)
10:06rhickeymemfn predates #() and the latter is preferred
10:14ankouwhat'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:17opqdonutnone really
10:17rhickeyankou: 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:17opqdonutoh, okay
10:17rhickey,'[a b]
10:17clojurebot[a b]
10:18ankouokay
10:25rhickeycgrand: let me know when you've tried the tweaks I posted, after that I think we're ready for a patch?
10:27ankouit would be nice to have some sort of tabcompletion in the repl
10:28Chousukeit's possible with rlwrap
10:28Chousukeor slime :P
10:28rhickeyor enclojure
10:29ankouwhat 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:30ankouthe same problem with IDEs, I never saw a good vi-plugin
10:30eevar2enclojure is a netbeans plugin
10:31liwpankou: rlwrap is utility that uses readline to provide any std io prompt with things like history and tab-completion
10:31Chouserankou: vimclojure exists
10:31Chouserankou: I'm psyching myself up to again try enclojure + jvi in netbeans
10:32rhickeyHas anyone tried: http://jboss.org/hornetq.html ?
10:32ankouChouser, 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:33danlarkinrhickey: 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:33Chouserankou: look at vimclojure -- runs in real vim
10:33cgrandrhickey: 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:34ankouChouser: I'm currently using it
10:34Chouserankou: and it doesn't do tab completion??
10:35ankoudon't know, I was talking about the REPL.
10:36rhickeycgrand: 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:56cemerickrhickey: 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:56rhickeycemerick: cool let me know what you think if I don't get around to it first
10:56cemerickI'm suspicious of anything coming out of jboss, though. It sits next to spring et al. in my head.
10:56rhickeylibs that this are what make Clojure so useful
10:57rhickeycemerick: heh, yeah, they seem to be bending over backwards here highlighting no deps other than the JDK etc, seems small enough
10:58cemerickI 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:58rhickeycemerick: the splitting off and packaging seems a quite deliberate effort to give it an independent life
11:00cemerickwell, here's hoping. Once burned, etc...
11:02rhickeywith these MQs it all comes down to lots-of-users + lots-of-fixes so it gets fully shaken out
11:03cemerickrhickey: what others have you taken a look at so far? I'm only now starting to look.
11:04rhickeyActiveMQ, OpenMQ, Joram, mostly reading, a little twiddling
11:05cemerickah -- I'm definitely looking for something embeddable, useful for point-to-point stuff
11:05rhickeyactivemq and joram embed
11:05cemerickWe use openmq serverside, which is fine enough.
11:05cemerickHaven't pushed it any though.
11:05cemerickah, I saw openmq and assumed they were all server-side :-/
11:07rhickeyjoram 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:08ankouis there any form of destructuring for lists?
11:08Chouserankou: vector destructuring forms work on all seqables
11:09rhickey,(let [[a b c] (range 3)] [c b a])
11:09clojurebot[2 1 0]
11:09cemerickrhickey: Oh, that's sexy.
11:09cemerickhuh, JMS compliant and around since 2000.
11:09cemerickold code so much better than new code :-)
11:10rhickeycemerick: yeah, really cool design. Persistent perf is always the challenge, HornetQ is definitely teasing here
11:11cemerickThe 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:12rhickeycemerick: I that what it means? I couldn't figure it out :)
11:12cemerickwell, it means a lot of different things to different people.
11:13cemerickMany 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:16rhickeycemerick: isn't the problem/magic in the annotator rather than the annotatee?
11:17cemerickrhickey: definitely -- what I was saying was that "POJO" might mean that a lot of functionality is only available via annotations.
11:20rhickeycemerick: 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:20cgrandrhickey: https://www.assembla.com/spaces/clojure/tickets/183-leafless-PersistentHashMap
11:21cemericksure. Annotations aren't a good path AFAIC, though -- the less Java I need to continue to have around, the better.
11:22rhickeycemerick: agreed
11:22rhickeycgrand: cool, thanks
11:23cemerickI'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:24thickeywork in progress for new t-shirt: http://www.flickr.com/photos/tommyvulgar/3858634993/
11:25liwpthickey: nice!
11:25danlarkinI love the copy
11:27thickeythanks
11:27cemerickthickey: man, has that woodstock feel, even :-P
11:29thickeydefinitely inspired by rock posters
11:30rhickeycgrand: patch doesn't apply cleanly on master: Patch failed at 0017 replace copyOf with arrayCopy
11:31rhickeythickey: wild!
11:31thickey:)
11:37cgrandrhickey: try git am -3 leafless.patch
12:00bitbcktthickey: Love the shirt design.
12:01thickeythanks!
12:02bitbcktI look forward to buying one. :-)
12:02rzoomA+++ will order
12:08rhickeycgrand: patch applied - thanks!
12:23Chouser'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:23Chouserpop would then remove from the left -- is there anything handy for removing from the right?
12:26rhickeyChouser: 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:27Chouseryeah, I had thought of that too. Not sure of the drawbacks of implementing ISeq directly...
12:29Chouserright now, cons never calls a method of the existing object
12:29rhickeywriting a finger tree in new new?
12:30Chouserthat's the plan. slapping it together with non-standard functions on top of vectors right now
12:30Chouserconjl/conjr, ft-seq/ft-rseq, etc.
12:30rhickeycool
12:31rhickeyusing delays for laziness?
12:32cemerickah, compressed oops are default in jdk7 now
12:32rhickeycompressed oops?
12:33cemerickordinary object pointers
12:33rhickeythis in 64-bit?
12:33cemerickyeah. Irrelevant in 32.
12:33cemerickah: http://wikis.sun.com/display/HotSpotInternals/CompressedOops
12:34rhickeythey were all excited about that at JavaOne
12:34ChouserI 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:34cemerickthe key changeset went in on Monday: http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/82bd76d4d7f2
12:35Chouserit'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:35rhickeyChouser: I thought laziness was needed to get amortized time properties
12:36Chouserrhickey: yes, but I thought that was for the head/tail view stuff.
12:36Chouserah, no, you're probably right.
12:36rhickeyChouser: maybe, I haven't looked at it in a while
12:37Chouserthat's where they discuss it, but perhaps they're showing that the seq doesn't force the creation of the tree until needed.
12:38ChouserI'll read that again and make sure. This stuff is definitely stretching my understanding on several levels. Difficult but fun!
12:39rhickeyyou need to be careful as, for Clojure, we care about the amortized time characteristics in a *persistent* setting
12:39rhickey"The same bounds hold in a persistent setting if subtrees are suspended using lazy
12:39rhickeyevaluation. This ensures that transformations deep in the spine do not take place
12:39clojurebotlazy is hard
12:39rhickeyuntil a subsequent operation needs to go down that far. Because of the above prop-
12:39rhickeyerties of safe and dangerous digits, by that time enough cheap shallow operations
12:39rhickeywill have been performed to pay for this expensive evaluation."
12:40ankouis there a possibility to import a whole javapackage?
12:41ankoulike import javax.swing.*; in java
12:42rhickeyyou 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:43rhickeyChouser: finger trees would be an awesome addition - good luck!
12:44Chouserheh, thanks.
12:46ChouserMy current plan is to support a map of measure/reduce functions, so you can do different kinds of searches on the same tree
12:48rhickeyneat
12:49technomancyankou: no
13:15carkclojure.test is not in 1.0 ?
13:16hiredmannope
13:16carkand test-is is not in contrib anymore ><
13:17hiredmanthere is a 1.0 compat branch of contrib
13:17carkoh well that's for simple stuff, i'll do ad hoc testing
13:17carkuntil clojure 1.1 !
14:08carka generic pool library : http://github.com/cark/clj-pool
14:09krumholt_what is a good way to deliver a clojure application?
14:09carksmallish, but might be usefull to these database guys (clojureql hint hint)
14:10carkkrumholt_ : make an executable jar
14:12krumholt_cark, i tried and failed. is there a better example then on the clojure.org website for how to do this?
14:14carkit take a couple hours of suffering to make a nice ant build file, then just copy it for each project =)
14:14clojurebotbuild is working
14:14carki could send you one of my build files, but it wouldn't make sense without the projects themselves
14:15krumholt_cark, right now i am manually ordering everthing folder structure etc it is very annoying. maybe i try ant scripts
14:16cemerickkrumholt_: clojure's jar itself is executable. You should be able to follow its build process as a template in that respect.
14:16cemerickyeah, doing it manually is a little insane :-)
14:17technomancykrumholt_: here's what I was using on an earlier project: http://github.com/technomancy/mire/blob/910d02c5d616672f46430625874cf7a68ed46eb2/compile.sh
14:17hiredmanmaybe someone should make a sort of skelton executable jar that executes a function based on a property file
14:17krumholt_technomancy, thanks
14:17hiredmantechnomancy: clojurebot should work with the latest fnparse now
14:18technomancyhiredman: awesome
14:20cemerickhiredman: shouldn't people just learn how to use the massive pile of tools that are out there?
14:21cemerickI'd hate to see some 5% solution become standard practice.
14:22carkwell there's a fine line between adding another dependency and having enough functionality
14:22carkand sometimes those java libraries a heavy
14:22carkheavy to use i mean
14:23cemerickI wouldn't call ant 'heavy'. Not using some kind of build tool is like not using autoconf with a C build or something.
14:24hiredmancemerick: 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:24carkcemerick : agreed
14:24hiredmanbut everyone hates autoconf
14:25cemerickhiredman: 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:25hiredmancemerick: because you then have to copy and paste for every project
14:26cemerickhiredman: not if you use ant properly. That's what imports and macros are for.
14:30technomancyis getting nicer docstrings for namespaces targeted for 1.1?
14:30technomancy*nicer docstring syntax
14:33samldo you use emacs?
14:34technomancysaml: me? I do.
14:34technomancyhttp://technomancy.us/126
14:49Chousuketechnomancy: hmm, maybe you should add to the instructions how to specify the encoding for SLIME to use. it seems to default to latin1 :/
14:53technomancyChousuke: yeah, good point
15:11rhickeysuggestions welcome for multimap reader syntax, a la #*{k v k2 #{vs ...} ...}
15:11cschreinerLooking for the slides from the Clojure for Lispers presentation
15:12carkrhickey : huh what is it for ?
15:12cemerickrhickey: what does that do?
15:12jensliShould a multimap really have special syntax?
15:12rhickeymultimaps ar elike maps but can support more than one value per key
15:13rhickeyjensli: do you want to be able to read/print it? I do
15:13jensliShouldnt one be more conservative with special syntax, to reduce complexity?
15:13Chouserdon't want to just repeat the key?
15:13kotarakehm, what is the difference to a map of keys to sets?
15:13cemerickrhickey: isn't that just {:a #{1 2 3}}, or whatever?
15:13rhickeyChouser: will answer you in a sec
15:14rhickey,(seq {:a #{1 2 3}})
15:14clojurebot([:a #{1 2 3}])
15:14cemerick;-)
15:14kotarakhehe
15:14Chouser#*{[1 2 3] :key-1, [1 2 3] :key-2}
15:14Chousercemerick: indeed.
15:14rhickeybut for multimaps would be [:a 1] [:a 2] [:a 3]
15:15Chouseroops. #*{[1 2 3] :val-1, [1 2 3] :val-2}
15:15cemerickrhickey: and I assume assoc would add in an additional value to the pool for the given key, etc?
15:15ChouserI would have used multimaps somewhere if we had them. I foreget where that was though...
15:15rhickeythere will be assoc* and dissoc*, which add/remove from the set
15:16jensliassoc-multi?
15:16rhickeyChouser: to your question, my design distinguishes keys that support multiple values from keys that don't
15:16cemerickI guess I'd say it doesn't excite me. assoc-in and update-in are very capable
15:16Chousersome keys in a multimap would still only have one value? overwriting?
15:17rhickey(assoc* #*{:a 1} :a 42)) = error multi-assoc to single-value key
15:18rhickey(assoc #*{:a #{1}} :a 42)) = error single-assoc to multi-value key
15:18rhickeyso the literal needs to distinguish, thus {:a 1 :b #{1}} yields single-value :a, multi-value :b
15:19jensliJust be carefull to minimize the amout of code that consists of '*' and '#'...
15:19cemerickrhickey: is there a performance improvement compared to update-in on a regular map?
15:20rhickeycemerick: no
15:20Chouserseems like multi-value keys would be more common than single-value in a #*{} -- perhaps use syntax to indicate the single case instead?
15:21rhickeybut there will be a (contains-entry? mm k v)
15:21Chouser#*{:a 1 :a 2 [:b 3]}
15:21rhickeycount is a count of vals, not keys
15:21rhickeyer, count of entries
15:21rhickeya multimap is not merely a map os keys to sets
15:22cemerickrhickey: I'm surprised you're considering special reader syntax -- seems like a pretty minor structure.
15:22rhickeyChouser: but don't forget that literals often have runtime holes - #*{:a 1 :b a -set-I-already-made}
15:23rhickeycemerick: I have big plans
15:23Chousercemerick: shhh. Soon I'll be petitioning for finger tree literals #*++[:a :b :c]
15:23cemerickhah
15:24cemerickChouser: I was about to say something about bit-set literals, but nevermind :-P
15:24rhickeyChouser: good point, I want to discuss the general problem of supporting more core structures, I think you might get #[...]
15:24jensliI dont know if I dare to learn a language where people have so big plans...
15:24rhickeycemerick: bitsets, now that is uninteresting :)
15:25cemerickLOL
15:25Chouserrhickey: there are already a lot of restrictions on runtime holes for maps
15:25rhickeyjensli: you can use just lists and pretend it's an old-fashioned Lisp
15:25cemerickjensli: "In Rich Hickey We Trust" is the motto here :-)
15:25Chouserno way to do this currently, right? {:a 1 (thing-that-produces-key-and-vals)}
15:26rhickeyChouser: I don't see that as the same at all, trying to replace many things with one
15:27rhickeywhat I'm really asking about is the space before the {}, i.e. #*, ## etc?
15:27rhickeyjensli: forgot :)
15:28rhickeybut it's true, there's a limit to how much symbol overloading we can do
15:29rhickeyit could have been #set{...} and everything else in the future could have names in there
15:29rhickey#multimap{...}
15:30Chouserthat's pretty close to #=(multimap ...) territory.
15:30ChouserI guess the args are evalutated at a different stage.
15:30rhickeyChouser: except the latter won't work with read-eval turned off
15:30Chousereh. yeah.
15:30wtetzner_what does #= do?
15:31Chouserwtetzner_: read-time eval.
15:31wtetzner_oh
15:31Chouserwtetzner_: it's used by *print-dup* to generate very specific container types
15:32rhickeyit'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:32Chouser,(binding [*print-dup* false] (prn (sorted-map :a 1 :b 2)))
15:33clojurebot{:a 1, :b 2}
15:33cemericksuch valuable real-estate, though....
15:33Chouser,(binding [*print-dup* true] (prn (sorted-map :a 1 :b 2)))
15:33clojurebot#=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})
15:34Chousercemerick: trying to think up contrasts for the vs. Scala thread? :-)
15:34cemerickChouser: I've got it queued up, haven't read it yet.
15:34dmiles_afkclojure use a real live java.lang.Integer right?
15:34cemerickI've actually been keeping up on my group reading quite a bit though.
15:34Chousercemerick: don't bother
15:34cemerickut-oh
15:34dmiles_afksomething scala did was heavy boxing avoidance
15:34Chouser,(class 5)
15:34clojurebotjava.lang.Integer
15:35dmiles_afkthe way they did that was when they compiled a finction they added extra unboxed signatures
15:36cemerickrhickey: 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:36dmiles_afka java lisp i work on uses boxed types.. i think Clojure could be considered Duck Types
15:37dmiles_afkScala does heavy boxing avoidance
15:37rhickeycemerick: what happens when I want to combine your code that uses reader and someone else's?
15:37dmiles_afkso.. 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:37Chouserdmiles_afk: Clojure can use primitives for locals and method calls and returns.
15:38cemerickrhickey: 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:38dmiles_afkClojures method can leverage very fast box/unbox of the JVM since it staying inside java.lang.Number/* .. but..
15:38rhickeycemerick: but I want to use both in my files
15:38Chouserdmiles_afk: I believe limited support for primitive clojure fn args and clojure collections are planned.
15:38dmiles_afki dont know if its more or less effectient than a LispInt
15:39rhickeycemerick: nevermind the hassles of making the supporting custom reader code accessible and available in advance of use
15:39dmiles_afkChouser: yeah that is probaby needed.. but makes me wonder *how needed*
15:39cemerickrhickey: well, that sounds a little nutty :-) One reader per ns seems perfectly reasonable, and addresses anyone's domain-specific requirements.
15:39Chouserdmiles_afk: depends on your task, I suppose. I hardly ever need even the primitive locals, let alone anything larger-scope.
15:40dmiles_afkScala did that just in case .. "because they used ScalaInt"
15:40cemerickrhickey: I know, I know. I'm just looking out for the whole general-applicability angle.
15:40dmiles_afko they were avoid a worse case
15:40dmiles_afkits possible that Cljojures worsecase is not that bad
15:40wtetzner_if i do (SwingUtilities/invokeLater (fn [] (run-code "asdf"))), does run-code use the binding in the swing thread?
15:41dmiles_afk,(+ 5 1)
15:41clojurebot6
15:41wtetzner_is there a way to set a thread-local binding in the swing thread?
15:41dmiles_afkthats clojures worsecase i think
15:41dmiles_afkthe (+ 5 1)
15:41wtetzner_without having to rebind for every fn i send to it?
15:41dmiles_afkwell what would be more worsecase is (+ 2555 2551)
15:41Chouserwtetzner_: 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:42Chouserwtetzner_: in other words, "no"
15:42wtetzner_ok
15:42Chouserdmiles_afk: well, + is a clojure-inlinable fn, so it can actually be working on primitives.
15:42wtetzner_so if i want a way to access the main JFrame in my gui, i should store it in a ref or something?
15:43Chouserwtetzner_: yes, or a global var or atom, or maybe a promise if you want to get fancy.
15:43wtetzner_promise?
15:43dmiles_afkChouser: (- 2555 (+ 2555 2551)) the result fn would need to be a primitive
15:43rhickeycemerick: 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:43arbschtwtetzner_: I like to create partial functions capturing that kind of context. see for an example http://gist.github.com/164652
15:44dmiles_afk,(class (+ 2555 2551))
15:44clojurebotjava.lang.Integer
15:44Chouserrhickey: ooh, I'd take #my-fn{...} in a second, esp. if I get to read the ... myself
15:44dmiles_afkwell it will proably always say that ')
15:44dmiles_afk[12:44] <clojurebot> j
15:44dmiles_afkoops
15:44cemerickrhickey: you do if those (or whatever) are you bread and butter. What if you had to write #vector[...] every time you use one?
15:44Chouser#my-ns/my-fn{ ... } -- perfectly composable
15:45dmiles_afkwell it will proably always say that 'java.lang.Integer' on (class...) becasue class takes an Object
15:45cemerickChouser: ssshh, I'm swinging for the fences here! ;-)
15:45dmiles_afkwould for instance (class...) have 8 differnt singatures?
15:45rhickeyChouser: it's not that simple:
15:45rhickeyuser=> (def a 42)
15:45rhickey#'user/a
15:45rhickeyuser=> {:b a}
15:45rhickey{:b 42}
15:45Chousercemerick: but I don't want your uncomposable readers! :-)
15:46dmiles_afk(that what scala did.. but still)
15:46dmiles_afkactually maybe in the end scala and clojure would have 15 possibles
15:46cemerickChouser: why not both? :-)
15:47dmiles_afkthe [Z [B etc
15:47rhickeynote how the compiler can generate a data literal expression that involves evaluation
15:47cemerickI know a couple of people for whom notation is *everything*, which is why I keep bouncing on this particular nerve
15:48rhickeycemerick: wanting something and providing an answer to these critical questions are two different things
15:48Chousercemerick: 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:48rhickeyalso, there is distinguishing use in code from use in data files
15:49rhickeyin practice, reader macros are not often used in CL and when used in libraries, widely despised, due to these issues
15:49Chouserdmiles_afk: repl-utils/expression-info lets you see when the Clojure compiler would emit code that uses primitives.
15:50dmiles_afkChouser: yeah i betting sometimes the compiler can identify a all primitive situation pretty well
15:51Chouserwell, #*{} is about as intuitive a choice as you'll find, i think, for multimap
15:52carkrhickey : reader macros are maybe bad for libraries but sometimes usefull at the application level
15:52Chouserthough #{} for very value is pretty noisy and potentially misleading.
15:52rhickeyChouser: I thought so, given assoc* and dissoc*, but open to suggestions
15:53cemerickrhickey: would Chouser's #ns/fn{...} idea be potentially better in terms of library interop (regardless of the evaluation issues)?
15:53rhickeyChouser: true, in the 'all keys will support multi' it's very verbose
15:54rhickeycemerick: I don't know, I think Chouser wants more inside {} than I was talking about with #your-factory-fn{...}
15:55rhickeybut the point I raised about evaluation of subcomponents is important. Right now, e.g. #= does not eval subcomponents/args
15:55rhickeyso supports read-time constants only
15:56rhickey#your/fn[every one of these is evaluated] would be doable
15:56rhickeyor #your/fn{every one of these is evaluated}
15:58rhickeythat's different from #your/fn{gets to read this and return some arbitrary thing}
15:59rhickeybut as I said, it's not that simple
16:00rhickeywhen I read {:fred ethel :ricky lucy} you get a map of keywords to symbols
16:00rhickeybut the evaluator will in turn evaluate that map-as-code and try to resolve ethel and lucy
16:00rhickeygetting the same for your data structures would be more involved
16:02Chouseryes, I want more in #my-fn{...} than rhickey wants to give me.
16:03Chouserrhickey: 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:03rhickeyChouser: exactly
16:04rhickey(def a 42) #my-collection{a} == ?
16:04rhickeyI presume you don't want a collection with a symbol in it
16:04cemerickI 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:05rhickeycemerick: reading and evaluation are separate
16:05cemerickoh, definitely...that's what I'm getting at
16:06rhickeybut 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:07cemerickah. 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:08rhickeycemerick: it's not happening at read time, but at evaluation time, later
16:08Chousereven without user reader macros, would you have similar questions about supporting more core collections?
16:09rhickeyChouser: it would be great to focus on collection extensibility right now, userland reader macros is an exhausting topic with no answers afaict
16:11rhickeyfor 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:12rhickeyi.e. Expr support for your collection type
16:12rhickeythe latter is not nothing
16:13Chouserdoes CL not have this issue because its only literal is the list?
16:13Chouseronly literal collection
16:16rhickeyChouser: CL doesn't have any evaluation in data literals, only constants, and backquote, the latter is hardwired for lists and vectors
16:18Howardquestion about commiting changes to clojure-contrib
16:18Howarddoes Rich extend write access to the repository
16:18Howardor do we fork it, make changes, request a pull (via GitHub)?
16:18Howard(I'm on the contributor list)
16:19Chousukefor contrib, there are contributors, a handful of committers and rich
16:19ChouserHoward: http://clojure.org/patches
16:19Chousukebut most stuff is sent via patches, yes
16:19Chouserpull requests aren't used anywhere currently
16:19kotarakPull requests require a high level discipline..
16:20kotarakWhich makes them not very suitable for open contribution, I guess.
16:20HowardSorry I missed that ...
16:20Chousukeyou'll be fine if you just use git format-patch to generate the patches from your commits
16:20HowardSure, seems like a lot of trouble though
16:20ChouserHoward: the list of people with commit access is at the bottom of this page: http://github.com/richhickey/clojure-contrib/tree/master
16:20Howardit means I can't really be self sufficient
16:21ChousukeHoward: 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:21Chousukethe patch files generated contain git commit info so all important data is preserved.
16:22HowardIt's just a bit different from the Apache way, where once you are accepted as a committer, you can commit
16:22rhickeyChouser: In CL, if you want to do the equivalent of [a b c] you need `#(,a ,b ,c)
16:22Chouserright, clojure has four levels: user, contributor, committer, and Rich.
16:23Chouserrhickey: ow
16:23HowardOk, so just attach my patch to my ticket, then rich will apply it and close it
16:23Chousukerhickey: is #() really equivalent to [] though? :/
16:23HowardAnd identify the ticket number is the commit message
16:23rhickeyso Clojure is way ahead in having vectors/maps/sets with read/print/evaluation support
16:24kotarakHuge advantage! I really like the easy access to maps and vectors!
16:24rhickeyChousuke: no, that's my point CL #() is not Clojure []
16:24ChousukeHoward: you can add "fixes #nnn" to your commit message and assembla will autoclose the bug when it's committed :)
16:25kotarakChousuke: which Rich doesn't really like, he prefers "refers #nnn"...
16:25ChouserHoward: if the patch is for contrib, you'll one of the committers will commit and close the ticket.
16:25rhickeynor is Clojure [a b c] == (vector a b c), because it reads as a true vector of symbols
16:26Chousukeyeah, that's what I thought.
16:26Chouserrhickey: it's that latter point that I'd not really internalized before.
16:27ChousukeChouser: heh.
16:27rhickeyChouser: that's the key to print/read being a replacement for JSON/XML, useful when there's no eval at all
16:27ChousukeChouser: it reads a data structure, then calls (vec stuff-that-was-just-read)
16:28ChousukeChouser: 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:29Chousukea bit wasteful but easy :P
16:30Chouserright, 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:31ChouserI mean, I guess I knew that, but didn't understand all the consequences.
16:31Chousukeit has consequences with macros too.
16:31LicenserHi everyone
16:32Licenseris there any list of the keywords Clojure has?
16:32Chousukekeywords? you mean special forms?
16:32hiredmanthey are listen on a side somewhere
16:32hiredmanslide
16:32hiredmanthere are seven or so
16:32Chousukedef, fn* loop, let*, ., try, ... hmm. I forget.
16:33Licenserhmm yes the things I can put in the first argument of a () to do something, things like def and if
16:33hiredmanLicenser: well you can put any function there
16:33hiredmanor any IFn
16:33LicenserI hean the build in ones, not self defined ones
16:33Licenserso if yes but and not
16:34kotarakLicenser: (approximately) http://clojure.org/API
16:34ChouserLicenser: use the source!
16:34Chousukeah, right, if of course.
16:34hiredmanhttp://clojure.org/special_forms
16:34LicenserUse the source Luke!
16:34Licenserhiredman: thanks that is what I was looking for :d
16:35hiredmanthis is lisp, the difference between built in and built on is negligible
16:35Chousukethat page is lying anyway. some of the special forms listed are actually macros
16:35Licenseroi :/
16:35Chouserright, depends on why you want to know
16:35Howardat 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:36kotarakBut the star form is the special form, fn=>fn*, let=>let*
16:36Chousukeyeah.
16:36LicenserChouser: for highlighting source ^^
16:36ChouserLicenser: 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:36ChouserLicenser: ah. use the web page.
16:36ChousukeI wonder if newnew will cause fn* to go away.
16:36kotarakI highlight according to the web page.
16:37HowardI wonder if newnew will get a better name :-}
16:37rhickeyso, back to multimaps - any feedback other than you're all disappointed you're not getting what you really wanted? :)
16:37Chouserthe fact that fn is a macro but fn* is builtin is just an implementation detail -- may change at any moment.
16:37rhickeyHoward: its has - reify
16:37Chousukeoh, right. you decided on that then? :)
16:37cemerickah-ha, didn't know it was official :-)
16:37hiredmanneato
16:38rhickeyI could go with #mmap{...} pretending that one day #blah{} will be extensible
16:38rhickeybut Chouser's point on verbosity with all-multi-keys is valid
16:39hiredman#mmap would require some adjustment to the reader, wouldn't it?
16:39rhickeyhiredman: yes
16:39Chouserrhickey: you specicially want to support providing a set at runtime for multiple values?
16:39rhickeythis would be a new core datatype
16:40rhickeyChouser: dunno, right now in the design I am supporting any collection as the init for a multikey
16:40rhickeyi.e. you can't have a singlekey that maps to a collection
16:41Chouserah, ok ... I was just trying to phrase that point. :-)
16:41rhickeyso #*{:a 1 :b [2 3]} would work too
16:41hiredmanhmmm
16:41rhickeythis mostly for the evaluated case #*{:a 1 :b (a-seq-fn)}
16:42Chouserwhat about {:a 1 :b #*expr} ?
16:42Chousukewait, what datatype is this?
16:42hiredmanmultimap
16:42Chouserthat way {:a [1 2] :b #*[3 4]} would have :a as a single key, :b as a multi
16:42rhickeyChouser: nothing around {}? multimap triggered by #* inside?
16:43Chousersure
16:43rhickeyhow do you make an empty multimap or one initialized with only single keys?
16:43Chousukethat would make my reader design rather ineffective :-(
16:43Chouseror both, I suppose. #*{:a 1 :b #*[2]} My main point was new reader support for the mutli-values
16:44hiredmanrhickey: well assoc* on a regular map could return a multimap?
16:44rhickeyChouser: are you saying :b is a multikey or :a?
16:44Chouserthat doesn't help remove clutter, but it makes single-value collections possible.
16:44Chouserrhickey: ooh, I meant :b as multikey, but the alternative is interesting.
16:44rhickeyChouser: I don't think I care about singlekeys mapping to collections
16:45rhickeylots of complexity elsewhere if supported
16:45Chouser#*{:a #.:single :b [:multi]} bleh.
16:46wtetzner_so a multimap is a map whose keys can hold multiple values?
16:46rhickeyI am trying to address #*{:a [1] :b [2] :c [3] ...} when you want all the keys to be multi
16:46Chouseryeah, though even that is better than #{} for each value
16:47rhickeywtetzner: basically, with the twist that some keys can be non-multi, and that is enforced
16:47kotarakWhy not making multi the default? #*{:a 1 :b 2 #1 :c 3} (with c single key.)?
16:48wtetzner_rhickey: oh, i see
16:48wtetzner_rhickey: so that's why a map of vectors isn't the same thing
16:48Chousuke#*[:a :b]{:a 1 :b 2 :c [1 2 3]}? :P
16:48Chousukeiffy.
16:48rhickeykotarak: taking colls in the literal is not bad, as (#*{:a 1 :b [2 3]} :b) -> #{2 3}
16:49wtetzner_are multimaps used often enough to give it reader syntax?
16:50rhickeywtetzner_: depends upon your domain
16:51wtetzner_maybe something like this: {:a 1 :b 2 | :c [1 2 3] :d [4]}
16:51rhickeyso far today they seem not so popular :(
16:51wtetzner_where single keys and multikeys are divided by a |
16:51Chouserwhy not support both repeated keys *and* collection values to indicate multi.
16:52rhickeyChouser: repeated keys seem really painful
16:52rhickeyand would never print that way
16:53cemerickrhickey: I just don't see the big deal given update/assoc-in, sorry. :-|
16:53cemerickrhickey: you've got the vision thing, though, which trumps a lot
16:54Chouserok, 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:54rhickeycemerick: there are differences in seq/count, can test for contains-entry
16:54rhickeyChouser: pretty much
16:54rhickeycemerick: do you do anything with RDF?
16:55cemerickah-ha
16:55cemerickno, thank goodness
16:55wtetzner_rhickey: is it neccessary to have a special character at the front for it to be a reader macro?
16:55Chouserso now I'm liking wtetzner_'s suggestion
16:56rhickeyChouser: the problem with that (separator) is the asymmetry with whatever the factory fn will be
16:56wtetzner_why couldn't the factory function do something like that?
16:57wtetzner_is | a legal symbol?
16:57wtetzner_i guess it might be bound to something though
16:57rhickeywtetzner_: take | as an argument?
16:57wtetzner_rhickey: yeah, but i guess that's a bad idea
16:57rhickeyvery difficult, will mess up apply and composition in general
16:58Chouser#*[:a :b]{:c nil :d [1 2] :e 3 :b 5}
16:58kotarakrhickey: why do you need enforcement of single-keyd-ness?
16:59wtetzner_do reader macros require that the starting character is a special character?
16:59Chouserevery key is multi unless noted in the []. (multi-map single-keys map-thing)
16:59ChousukeChouser: heh, I suggested the same earlier ;P
16:59wtetzner_could you do something nicer like M{:a 1 :b 2 :c [1 2 3] :d [4]}
17:00rhickeyChouser: thinking through composition scenarios, I see needing to ask for single keys etc
17:00Chousukewtetzner_: that makes symbol parsing a lot more complicated
17:00ChouserChousuke: yeah, I saw that, but I thought you were listing the multis
17:00samldid you write a computer game in clojure? 2d or 3d with audio?
17:00wtetzner_ok
17:00ChouserChousuke: though looking at it a again, perhaps you weren't. :-)
17:00Chousukewtetzner_: it's easier to have some special character for use in reader macros
17:00wtetzner_but all of the special characters are starting to make it look too much like perl
17:01wtetzner_maybe #M{...}
17:01ChousukeWell, ^#'foo is pushing it, yes, but ....
17:01Chousukeit's nowhere near perl.
17:02Chouser$_=~/(.)$/ # perl
17:02wtetzner_haha
17:02wtetzner_i didn't say it was as bad as perl, just that i don't want it to get any closer to perl
17:03Chousukebut certainly alphanumerics are usable for reader dispatch, as long as the # remains in place :P
17:03wtetzner_ah
17:04kotarakWhen 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:04rhickeykotarak: 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:04rhickeykotarak: well, you'd say #*{:a 1 :b [1 2 3]} in that case then
17:05rhickeyonly using coll when more than one
17:05wtetzner_what if you wanted a key to have a collection as its value?
17:05wtetzner_but only one collection
17:05Chouserzero-value case is annoying too.
17:05rhickeywtetzner_: can't
17:05rhickeyChouser: ?
17:05JAS415i don't get it, what does the * mean
17:06rhickeyJAS415: placeholder for something indicating multimap
17:06kotarakrhickey: #*{: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:06JAS415oh
17:07Chouser#*{: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:08wtetzner_Chouser: if it was multi, wouldn't it be #*{:a [1 2 3] :b [4] :c 5 :d [nil]} ?
17:08rhickeyChouser: single nil, use [] for emtpy multi
17:08wtetzner_or that
17:08Chouserwtetzner_: [nil] would be a multi with currently just one nil.
17:09Chouserok, so clutterful handles zero value case ok: nil vs. []
17:09rhickeyclutterful, h? :)
17:09kotarakI don't like the "no vectors" taste... :(
17:10Chouserrhickey: can you eloborate re: thinking through composition scenarios, I see needing to ask for single keys etc
17:10kotarakThen multi-maps don't nest anymore with the rest of the collections ...
17:10rhickeyChouser: what happens when you want to make a new multimap out of others?
17:10rhickeykotarak: they nest in
17:11rhickeya key point of multimaps is the flattening that they do. As cemerick has pointed out, you can have mappings to sets right now
17:11kotarakrhickey: But I can't do #*{:a []} (single-key with empty vector value)
17:11rhickeykotarak: I understand
17:12Chouseroh, we don't even have a 'push'. sheesh.
17:13rhickeyChouser: heh, I just did (doc push) before :)
17:13wtetzner_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:14wtetzner_or #M{(:a 1 :b 2) (:c [1 2 3] :d [4])}
17:14ChouserI think that's got the same composition problem that I'm trying to grok.
17:14rhickeywtetzner_: if you're not going to get out of :d [4] there's no point to separating them
17:15rhickeyChouser: what's the zipmap equiv for multimaps?
17:15rhickeykeying off the collection-ality of the val is easy
17:15rhickeyseparate keysets is hard
17:16Chousukemetadata? :P
17:16Chouserwhat will conj do?
17:17rhickeypersonally, 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:17Chouser(conj #*{} [:a 1] [:a 2]) ; ok or not?
17:18wtetzner_how about #M{:a 1 :b 2 :c |1 2 3| :d |4|}, so you're not using the vector syntax
17:18wtetzner_although that has the constructor asymmetry problem
17:18rhickeyChouser: I think conj will do assoc*
17:19rhickeysince :a is not already there and single, will be ok, build a multikey for :a
17:20kotarakWhy 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:24krumholt__if anyone is particularly bored maybe make a patch so that bit-or accepts an arbitrary number of arguments :)
17:30JAS415im having too much fun searching for lolcats on twitter :-P
17:33ChouserJAS415: maybe make a patch so that bit-or accepts an arbitrary number of arguments :-)
17:33JAS415hahaha okay i'll look at it
17:33Chousukeshouldn't be too difficult :/
17:34JAS415yeah it should be just like + or -
17:35kotarakWhy 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:37kotarakHmm.. I tells me, it's from seq_utils.clj:24...
17:38alrex021Hi guys. Need some help please to review a snippet of code I wrote. I pretty sure it can be inmproved
17:38alrex021oops, trigger happy
17:38kotarakhttp://paste.pocoo.org/show/136443
17:38kotarak^^^ the stacktrace
17:39Chouserkotarak: doing anything unusual with classloaders?
17:40kotarakChouser: 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:41mellingtrying to get slime working. Get an error launching inferior-lisp... can't find swank.clj
17:41melling java.lang.ClassNotFoundException: swank.swank (NO_SOURCE_FILE:0)
17:41mellingwhat do I have to set in my .emacs.
17:41mellingthese files are in /opt/swank-clojure/swank
17:43mellingthought this would do it.
17:43melling(setq swank-clojure-extra-classpaths (list "/opt/lib/java/clojure-contrib.jar:/opt/swank-clojure"))
17:43kotarakChouser: 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:44kotarakArgh... DRY caught me again.
17:45alrex021I 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://gist.github.com/175860
17:47alrex021I'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:48arohnerhas anyone gotten slime to print test/is output in your slime window rather than the console when using slime-connect?
17:48clojurebotslime is icky
17:49kotarakalrex021: maybe you want sets?
17:49arohneralrex021: yeah, using vectors for this seems weird
17:50arohnerI would use a set or a map
17:50arohnerthen you can use contains?
17:50arohneror set/difference
17:50technomancyarohner: try clojure-test-mode; it shows the test output in the test buffer itself.
17:51arohnertechnomancy: I don't have a clojure-test-mode, where do you get it?
17:51JAS415ok, i've made the changes to make it take multiple args
17:51technomancyarohner: http://github.com/technomancy/clojure-mode
17:51technomancyhaven't updated it for clojure 1.1 though. =\
17:52JAS415now i have to figure out assembla
17:52mellingPut path in clj-server file: http://yusupov.com/blog/2009/basic-clojure-setup-part-2
17:52mellingI'm done!
17:53arohnertechnomancy: oh wow my clojure-mode is old. 2008/11/13
17:54technomancyarohner: you're missing out!
17:55drewrwhoa
17:59JAS415how do i add a ticket to assembla?
18:00rhickeyhttps://www.assembla.com/spaces/clojure-contrib/support/tickets
18:00rhickeyhttps://www.assembla.com/spaces/clojure/support/tickets
18:00JAS415ah thanks
18:00rhickeyif you are not a contributor
18:03hiredman~ticket #164
18:03clojurebot{:url http://tinyurl.com/kmlk4k, :summary "[PATCH] embedded constants", :status :test, :priority :low, :created-on "2009-08-02T03:20:33+00:00"}
18:04hiredmannot that that has anything to do with anything, it just caught my eye
18:05hiredman~ticket #2
18:05clojurebot{:url http://tinyurl.com/l6lcfw, :summary "Scopes", :status :new, :priority :normal, :created-on "2009-06-15T12:35:58+00:00"}
18:07alrex021kotarak: here is an improved ver that uses sets with difference and intersection http://gist.github.com/175860
18:09alrex021not to sure if its smart to to do difference and intersection and then use into to conjoin them
18:10hiredmanclojure.set operations use sequences internally anyway
18:10hiredman:/
18:14hiredman~ticket #112
18:14clojurebot{:url http://tinyurl.com/nbtghb, :summary "GC Issue 108: All Clojure interfaces should specify CharSequence instead of String when possible", :status :new, :priority :low, :created-on "2009-06-17T21:06:11+00:00"}
18:15hiredman##java seemed to think this idea was broken for some reason, bugs with handling charsequences in jvm?
18:16hiredmanhttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4838318 ooh "3-Accepted"
18:17kotarakalrex021: what you do now is only the identity, no? A = A \ B union A intersect B, which is exactly what you wrote there.
18:24bitbckt~latest
18:24clojurebotlatest is 1382
18:24Chousukehmm
18:24Chousukethat's somehow wrong.
18:24hiredmanlatest is left over from svn
18:24hiredman~commit
18:24clojurebotI don't understand.
18:25hiredmanbah
18:25bitbcktI'm just exploring.
18:25bitbckthehe
18:25hiredman~last commit
18:25clojurebotHuh?
18:25JAS415user=> (bit-xor 1 2 3 4 5 6 7 8 9 10)
18:25JAS415(bit-xor 1 2 3 4 5 6 7 8 9 10)
18:25JAS41511
18:25hiredmanhuh
18:26hiredman(doc bit-xor)
18:26clojurebot"([x y]); Bitwise exclusive or"
18:26hiredmanJAS415: that throws an IllegalArgumentException for me
18:27Chousukeyou need a CA to contribute though :/
18:28Chousukeeven for trivial patches ;(
18:29JAS415yeah i need to submit the patch
18:29JAS415hm
18:29JAS415is there any reason to do (reduce / (x y) more)
18:29JAS415instead of
18:30JAS415(/ x (reduce * y more))
18:30Chousukethe two-argument versions are inlined
18:30JAS415yeah i think i got a patch for that too
18:30Chousukeand I think the former is neater.
18:31JAS415yeah but / is a lot less efficient than *
18:31arohnertechnomancy: 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:31JAS415just wondering if there was a situation where it was mathematically different
18:31kotarakANd x is a function? (reduce / x (cons y more))
18:31JAS415like maybe with imaginary number or something
18:31ChousukeJAS415: hm, right.
18:31technomancyarohner: how about C-c C-k?
18:31Chousukedoesn't support imaginary numbers anyway
18:31JAS415(reduce / (/ x y) more)
18:31Chousukeer. /
18:31JAS415shuld be that, was a typo
18:32arohnertechnomancy: undefined
18:32JAS415okay
18:32arohnerwhat function does that map to?
18:32JAS415i'll do it with the * anyway
18:33technomancyarohner: slime-compile-and-load-file
18:33technomancyarohner: does it show "Slime[clojure]" in the modeline?
18:33arohnerno, it shows just (Clojure)
18:33arohnerbuffers that were open before the slime connect work fine
18:34technomancyarohner: try M-x slime-mode then
18:34arohnerhrm. there may be some funkiness in my .emacs screwing with clojure-install
18:34arohnerlet me retest
18:34technomancysomehow the hook to activate that automatically must not be run
19:32JAS415assembla is pretty neat
20:16arohnerIf I want to access a nested class, its (Outer$Inner/method), right?
20:16arohnerhttp://webdriver.googlecode.com/svn/javadoc/index.html?index-all.html
20:17arohner(WebDriver$Options/setSpeed Speed/SLOW) is not working for me
20:17arohneror am I missing something?
20:18rhickeysetSpeed is not a static method
20:20rhickeyarohner: what kind of driver are you using?
20:20arohnerHtmlUnitDriver
20:21krumholt__if java expects null as a parameter can i just use nil?
20:21rhickey(-> (HtmlUnitDriver.) manage (setSpeed Speed/SLOW)))
20:22rhickeysome .s in there
20:22arohnerrhickey: ah, thanks
20:24durka421krumholt__: yes
20:24krumholt__durka42, thanks
20:25Chouserrhickey: so you'd be open to 'cons' calling a method on a collection. It never does that currently.
20:26rhickey,(doc cons)
20:26clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
20:26ChouserI don't need a ruling immediately. :-)
20:26rhickeywouldthat still be true?
20:27Chouseryes
20:27rhickeythen I think it's good
20:27rhickeyfinger trees are uber-seqs
20:27Chouser,(class (cons 5 '(1 2 3)))
20:27clojurebotclojure.lang.Cons
20:28ChouserPersistentLists are also seqs, but don't get to participate in cons.
20:28rhickey,(class (cons 42 nil))
20:28clojurebotclojure.lang.PersistentList
20:28Chouserwhee!
20:30rhickeynot sure this should be:
20:30rhickey,(class (cons 12 (cons 42 nil)))
20:30clojurebotclojure.lang.Cons
20:30Chouserright
20:30rhickeybut in any case cons makes no promise about the return type other than seq
20:30Chouser,(take 4 (map class (iterate #(cons 1 %) nil)))
20:30clojurebot(nil clojure.lang.PersistentList clojure.lang.Cons clojure.lang.Cons)
20:30Chouser(doc rest)
20:30clojurebot"([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."
20:31Chouser(doc next)
20:31clojurebot"([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."
20:31ChouserI should be able to do those too.
20:31rhickeyright
20:32rhickeyotherwise you're not really a seq
20:32Chouserbut that means my .seq will have to return this, while rseq can return a cursor object
20:32rhickeyyes (identical? ft (seq ft)) -> true
20:33Chouseranother thought I had was a .reverse that actually just flipped a switch to allow conj/pop from the other side.
20:33rhickeytrickier will be wiring into concat
20:34ChouserIConcat? :-)
20:34rhickeycould be
20:35ChouserI dunno thought, that would break the current docstring. not a lazy seq
20:35Chouserback in a minute...
20:40ChouserI would tend to think ft-concat is not the same thing as concat.
20:41rhickeywhy not?
20:41rhickeythere's just nothing to be lazy about
20:42Chouserconcat works on anything seqable. ft-concat only works on ft's with the same measure/reduce functions.
20:42clojurebotfunctions are maps
20:43rhickeyChouser: you'll have to explain those to me more
20:47Chousertheir first example is a measure of size and a reduce of add
20:48Chouserso the measure is (constantly 1)
20:49Chouserand the reduce is +
20:49Chousera node of 3 elements [1 2 3] would cache it's reduced measure of 3
20:50Chouserthese operations are done when nodes are constructured, and then used for operations like split
20:50Chouserin this case, split can use these measures to ask for the nth element of the tree
20:51Chouserbut you might have application-specific functions as well, for priority queues and such.
20:54rhickeyok, so concat could concat 2 non-conforming fts
20:55rhickeydo your fts have to have measure/reduce fns?
20:55Chouserright, by walking them. but it would not produce a ft that you could split
20:56Chouserno
20:56rhickeyok, then separate ft concat
20:57Chouserbut you can't split without measure, just conj l/r
20:58rhickeydo you support multiple measure/reduce pairs at once?
20:58Chouserhuh. the paper doesn't seem to define pop/next
20:59Chouserrhickey: I plan to. the paper supports multiples by combining functions -- my current plan is to allow a set of named measure/reduce pairs
20:59rhickeyisn't pop whatthey ar ecalling deque?
21:00Chouserthey define little triangles to the left and right, which are conj l/r
21:01Chouserthen they define reduce and seq-like views
21:01ChouserI don't see an actual "deque" operation.
21:04rhickeyI think pop/next are split
21:04rhickey?
21:04Chousercould be
21:06Chouserbut split as they define it requires a measure fn, and I ought to be able to do pop/next without any measure/reduce.
22:12Chouserany reason delay is not IMeta?
22:29ChouserI can't tell if reductions must be delayed, or if that's even possible.
22:40JAS415hmm
22:41JAS415is binding as complicated as it seems to me?
22:43Chouserok, I think can't be delayed.
22:44ChouserJAS415: are you referring to the use of thread-local bindings, or something else?
22:44JAS415i guess i am just kind of wondering how I know when I am in a specific thread
22:44JAS415in a swing app for example
22:45JAS415like I do a binding to something and call (main)
22:45JAS415then it seems like it gets unbound when I use menus and stuff
22:45JAS415possibly because they're creating threads under the hood?
22:46Chouser(binding [x 5] (foo)) will only have x bound until (foo) returns
22:47JAS415ooh
22:47JAS415okay
22:47JAS415so it has to do with when it returns
22:47JAS415hmm
22:48Chouserbinding is very much a temporary kind of thing, for a particular dynamic excursion down the call stack.
22:49JAS415i was hoping i could create new threads with different bindings kind of enclosed in them
22:50Chouserif the thread stays busy in some kind of event loop, then wrapping a single binding around that will work.
22:50tomojhmm.. would (Thread. (binding [x 3] foo)) work?
22:51tomojor since you're returning a function there, the binding is ignored?
22:51Chouser(Thread. #(binding [x 3] (foo))) would work
22:51JAS415what was trying was (thread. #(binding [x 3] (foo)))
22:51JAS415problem was
22:52JAS415(foo) returns
22:52JAS415i still have the window open
22:52JAS415and nothing is bound anymore
22:52Chouserright
22:52JAS415so i just need to keep it from returning
22:53JAS415yeah so i can make it sleep
22:55JAS415hmm
22:55JAS415nope
22:55JAS415(new Thread #(let [[con prov](login xx
22:56JAS415 xx)]
22:56JAS415 (binding [tw/*consumer* con
22:56JAS415 tw/*provider* prov]
22:56JAS415 (main-window)
22:56JAS415 (loop [] (recur)))))
22:56JAS415doesn't seem to work
22:56Chouseraren't all swing events sent to a single thread?
22:56JAS415well that would explain a lot :-P
22:56wtetzneryeah swing isn't thread safe
22:56JAS415bummer
22:57wtetznerso you need to use (javax.swing.SwingUtilities/invokeLater some-function)
22:57wtetznerand it sends some-function to the swing thread
23:00wtetznerdoes anyone know how the swing thread starts?
23:01wtetzneroh
23:01wtetznernevermind
23:02wtetznerhttp://www.javapractices.com/topic/TopicAction.do?Id=153
23:06JAS415hmm
23:07JAS415maybe i'll try a different approach
23:11wtetzneri wonder if there's a way to intercept the creation of the swing event thread
23:11wtetznerto add bindings to it
23:12Chouserwhy not use lexical scope instead?
23:13wtetznerwell, i was just thinking it would be nice to be able to bind the main JFrame to a swing var
23:14wtetznersince swing isn't thread safe, it feels wrong to store it in a global reference like a ref or atom, or global var
23:16JAS415ah
23:16JAS415well what i was hoping to do was have multiple logins
23:16JAS415which is actually kind of orthogonal to whether or not swing is thread safe
23:17JAS415just 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:17wtetznerwell you can use (javax.swing.SwingUtilities/invokeLater some-function) to interact with swing
23:21JAS415reason i would rather not do lexical scope is that it seems like i'd be passing a lot of stuff directly
23:21Chousercould you close over it instead of passing it?
23:23JAS415yeah i was considering that
23:23JAS415generating all the functions when the person logs in and closing over the results
23:31JAS415what if i just created a seperate process?
23:32Chouserwow. big hammer.
23:32JAS415yeah i guess too big