#clojure logs

2010-01-08

00:01mebaran151heh, it's sort of sad that the Internet actually has so little commerce on it
00:01defn`i hereby ban everyone from using -> as a way of showing the return value of some function
00:01defn`use => or die
00:01mebaran151what's the difference?
00:01defn`-> is in clojure, => isn't
00:02mebaran151that's what I figured
00:02mebaran151what do you have against the arrow?
00:02defn`nothing really, it just looks kind of like it could potentially br part of the source in certain contexts
00:02defn`be
00:03mebaran151oh you mean in comments
00:03defn`like (let [var1 flat [[a [b]] c [[[d]]]] tree]) -> ("flat" "one" "two" "three" "four")
00:03mebaran151ah yeah
00:03mebaran151=> is a lot clear
00:03mebaran151*more clear
00:04defn`or maybe ~>
00:04defn`something that's not in clojure anyway
00:04mebaran151nah ~> looks like a cool dereferencing macro
00:04defn`:)
00:04somniummaybe >>--> would be better
00:04mebaran151-> brings back semi-fond memories of C
00:04defn`ooooo i like that somnium
00:04mebaran151++
00:05defn`im working on getclojure.org and am trying to standardize on some bits of the example code
00:05somniumthough it might be better to keep that for macros too :/
00:05defn`http://getclojure.org/docs/_accessor
00:05mebaran151defn, you should implement a repl like tryruby
00:05defn`mebaran151: someone did it already :)
00:06mebaran151oh
00:06mebaran151where's?
00:06defn`http://github.com/weavejester/clojure-over-ajax
00:06JonSmithhoray!
00:06mebaran151yeah it would be him
00:07defn`what do you guys think, is ;=> blah
00:07mebaran151this looks way old and way overly complex
00:07defn`a good way of representing the output
00:07defn`mebaran151: it is definitely old
00:07JonSmith; is a comment
00:07defn`i know JonSmith, see the above link
00:07mebaran151somebody should steal clojurebots code and mod that
00:07defn`is that readable to you?
00:07JonSmithoh
00:08JonSmithyeah that looks fine
00:08JonSmithlooks like a repl output
00:08mebaran151=> is far clearer
00:08mebaran151to me at least
00:08mebaran151because it's like the repl told me it
00:08JonSmithcould even make it user=> or clojure=>
00:08mebaran151that or a simple #, like in terminal tutorials
00:08defn`i need to edit the css of my code highlighter to treat comments a bit differently
00:08JonSmithor whatever the namespace is
00:08mebaran151I'd just keep it =>
00:09JonSmithyeah i think its readable
00:09defn`so it will add a bit of padding around a ;
00:09JonSmithto actually answer the question
00:09mebaran151parsing clojure is probably pretty simple, just a bunch of s-expressions
00:09defn`JonSmith: k
00:09mebaran151shouldn't you be using a straight fixed-width font
00:10mebaran151and ~ is unquote
00:10defn`mebaran151: who me?
00:11mebaran151yeah
00:11mebaran151so ~> is actually legit clojure
00:11defn`mebaran151: sort of
00:11defn`,~>
00:11clojurebotjava.lang.IllegalStateException: Var clojure.core/unquote is unbound.
00:11mebaran151it is in a defmacro
00:11mebaran151if you wanted to buid some sort of custom comparator
00:12defn`nod
00:12somnium,'~>
00:12clojurebot(clojure.core/unquote >)
00:12defn`indeed
00:13somnium,(let [+ -] (+ 2 2))
00:13clojurebot0
00:14mebaran151I'm also trying to think of a good way to wrap netty
00:14mebaran151to make it more clojure esque
00:14somniummebaran151: if you do I will be a customer
00:14mebaran151ah, you have any ideas
00:14mebaran151I want to learn to netty to implement a nice socket server
00:15mebaran151I basically get the system now
00:15mebaran151I just need to figure out a way to make it pretty
00:15mebaran151I have a basic wrapping that looks like bad Java
00:15mebaran151(ie make-handler, tie-handler, make-pipeline)
00:16somniumhmm
00:16mebaran151and I just want to wrap it something dare I say higher order
00:16mebaran151for neo4j, it was natural just to use nested maps
00:16mebaran151but I haven't found quite as clear a fit
00:17somniumive this impression that clojure maps well to low level interfaces, since its so good at building abstractions
00:17mebaran151well they're good when you have key values
00:17mebaran151I was thinking of maybe a vector representing a pipeline
00:17somniumbut it always seems more awkward to plug into a 'middle-level' java-api
00:18mebaran151oh maps well as in relates well
00:18mebaran151heh
00:18mebaran151I read that as Clojure maps work well with
00:18mebaran151(I've been programming too much today)(
00:19mebaran151yeah midlevel java-apis always have a very strong flavor of their own
00:19mebaran151but I haven't quite grok'ed java.nio yet
00:20mebaran151it's not quite like the event based io I'm used to
00:20somniumI was never a java-dev, but Ive been trying to use nio for a tcp-ip client thing
00:20somniumnettys reviews were great but the annotations and javadocs ...
00:20mebaran151netty is pretty powerful
00:21mebaran151you can just plugin a handler and make it run
00:21somniumhmm
00:21mebaran151the first thing I've done is created two gen-class to over the two annotation cases
00:21mebaran151*to cover
00:21mebaran151I haven't quite gotten everything to work yet
00:22mebaran151usually I like to develop a representation and then code to make that work
00:22somniumIll have to look at it again
00:22somniumor wait for you to make in work
00:22mebaran151but it's whole stream model and channelhandler interface is just begging for Clojure functions
00:23mebaran151what I want is a performant way to hook a the input of buffer and the output of a buffer into the input of a function and the output of a function
00:23mebaran151i think that's the most functional way
00:23somniumthat sounds cool, would make a very pleasant api
00:23mebaran151with special ops :open and :close to represent opening and closing the channel
00:24mebaran151(because there isn't any data there)
00:26mebaran151should I pass clojure people the raw buffers or should I coerce to string?
00:27somniumanyway to parameterize it? raw buffers would be nice for perf in some cases I would guess
00:29mebaran151yeah
00:29mebaran151I'll think about these sorts of things
00:29somniumIll watch for it
00:30somniumneed to sleep for now
00:30somniumcheers
00:31mebaran151thanks for your input
01:04tomojhmm
01:04tomojI forsee increased pressure to make clojure happy with dalvik
01:09chouserI thought it worked (a bit) already?
01:31defnhmm wtf error: java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream (core.clj:1)
01:31defnthis was just working on OSX at home, but not here at work
01:32defnnvm figured it out
01:59mebaran151is there any quick way to turn an inputstream into a ChannelBuffer
02:00mebaran151sorry I mean ByteBuffer
02:00mebaran151I'd like to read an InputStream into a bytebuffer
02:09PuzzlerAnyone know whether Java 1.7 will introduce the kinds of numeric features that will allow Rich to speed up Clojure's number handling?
03:41hiredmanlisppaste8: url
03:41lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
03:42praptakIs let* different than let?
03:43lisppaste8hiredman pasted "inputstream -> bytebuffer" at http://paste.lisp.org/display/93138
03:45hiredmanpraptak: let is actually a macro implemented using let*
03:47praptakhm
03:47praptakOk, I'll check the source
03:47hiredman,(macroexpand '(let [[a b] [1 2]] [a b]))
03:47clojurebot(let* [vec__6245 [1 2] a (clojure.core/nth vec__6245 0 nil) b (clojure.core/nth vec__6245 1 nil)] [a b])
03:47Chousuke~def let
03:47praptakThanks
03:47hiredman,(let [[a b] [1 2]] [a b])
03:47clojurebot[1 2]
03:48Chousukethe destructure function is quite a monster :P
03:49hiredmanI've never looked at it, but it would have to be
03:50hiredmankind of scary, it lurks beneath the most innocuous looking code
03:50Chousukeheh
03:50Chousukebut it works.
03:50Chousukeso you can forget that it exists :)
03:51hiredmanuntil you get some head holding
03:51Chousukethat shouldn't be such of a problem anymore I think
03:52hiredman*shurg*
03:52hiredmannew isn't even master yet
03:52Chousukesince Rich introduced the early locals clearing
03:53praptakOk, so let is basically let* with added support for destructuring assignments?
03:54praptak,(let* [[a b] [1 2]] (+ a b))
03:55clojurebotjava.lang.IllegalArgumentException: Bad binding form, expected symbol, got: [a b]
03:55praptak,(let [[a b] [1 2]] (+ a b))
03:55clojurebot3
03:57praptakerr, assignments->bindings
04:04Chousuke,(#'clojure.core/destructure '[[a b] [c d]])
04:04clojurebot[vec__6261 [c d] a (clojure.core/nth vec__6261 0 nil) b (clojure.core/nth vec__6261 1 nil)]
04:04Chousukebasically let just feeds that to let*
04:19defn,(doc let)
04:19clojurebot"([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."
04:26praptak,(doc let*)
04:26clojurebotIt's greek to me.
04:29Chousukeit's a secret :)
04:30hiredmanlet* has no var to hang a docstring on
04:34Chousukeyou could easily define one, though
04:35Chousukethe special form takes precedence though, but it might work for adding a docstring
04:36hiredmanor you could add some special mechanism to doc, which I think there already is
04:37hiredmanof course clojurebot has its own 'doc' so...
04:51LauJensen~source let*
04:51clojurebotI don't understand.
04:56hiredmanlet* is in java somewhere
04:57LauJensenStrange, I felt I had a memory of seeing it in core once
04:58hiredmanit's used in core, sure
04:59LauJensenI meant the definition
05:01hiredmanwell, it's not, as a special form it must be implemented in the implementation language
05:06AWizzArdthough after bootstrapping it can be written in Clojure too :)
05:07hiredmannope
05:07Chousukewhy not? :P
05:07AWizzArdWhy not?
05:07hiredmanit's almost by definition that special forms are written in the implementation language
05:07Chousukethe plan is to do that.
05:07AWizzArdYes, but the implementation language for Clojure will be Clojure.
05:07Chousukesince the implementation language will be Clojure :D
05:08hiredmansure, but it will be sort of Clojure and Clojure'
05:08AWizzArdin some sense yes
05:08hiredmanthe let* in Clojure' will be written in Clojure
05:10hiredmanthe distinction between implemented lisp and implementing lisp is fairly common
05:10hiredmansicp does it, lisp in small pieces does it, etc
05:11ChousukeClojure might just do it so that any new versions of Clojure are compiled with an earlier version, though.
05:11hiredmanthe main reason I said "nope" was most likely over a different understanding of "bootstrapping"
05:12hiredmanChousuke: sure, the ealier version of Clojure being Clojure, and the version being built would be Clojure'
05:12Chousukebootstrapping is not easy though. I tore many hairs trying to make my reader work :P
05:12hiredmanI took "after bootstrapping" to mean after the bootstrapping section of core.clj
05:15Chousukeheh
05:15hiredmanI don't think my post to the dev group about it got a single reply
05:15ChousukeI should work on mine, too.
05:15hiredman*shrug*
05:15Chousukeit's a bit hackish right now
05:16hiredmanyours would undoubtly be more interesting, as it's not just a port
05:17ChousukeI'm not sure how to incorporate all the features I want while keeping the definition of reader macros natural AND the design (somewhat) functional. hmmh.
05:17ChousukeShould do some reading about Lisp readers I guess.
05:20hiredmanI dunno, the literature doesn't seem to overflow with reader examples
05:20hiredmanwhich is odd given how much work is sort of off loaded on to them in a modern lisp implementation
05:21ChousukeI could go read some scheme implementation for inspiration.
05:22hiredmanit annoys be sometimes that I can't have a name X'
05:22Chousukeheh
05:22Chousukehaskellish :P
05:22hiredmanI need some other way to indicate the successor to X
05:22ChousukeI guess that's what the * is for.
05:22hiredman:/
05:23hiredmanshould find some unicode glyph
05:24Chousuke’ <-here's a full width apostrophe
05:24Chousukeat least I think that's supposed to be one
05:24hiredman,x’
05:24clojurebotjava.lang.Exception: Unable to resolve symbol: x’ in this context
05:24hiredman,(let [x 1 x’(inc x)] x’)
05:24clojurebot2
05:24hiredmanhow evil is that
05:25Chousukevery
05:25ChousukeI need my japanese input method to even type that character.
05:25Chousuke,(let [x 1 x’ (inc x)] x’) this is eviler though
05:25clojurebot2
05:26hiredmanI wonder if there is some key combo I can do for that
05:27Chousukewell, in emacs you could just bind a key to the needed elisp function to produce whatever you want :P
05:38hiredmanxev-1.0.3.tbz
05:38hiredmaner
05:39hiredmangah, I can use the compose key to insert it everywhere except gnome-terminal apparently
06:16ordnungswidrighum, since when exists defprotocol/deftype? in 1.1.0-alpha I cannot find it
06:17hiredmanonly in the 'new' branch
06:19ordnungswidrignot in 1.1?
06:20hiredmannope
06:20ordnungswidrigI see.
06:21ordnungswidrigIs it available on clojars?
06:22hiredmanno idea
06:42AWizzArdclojurebot: max people
06:42clojurebotmax people is 240
07:33RCampbellwhen you type a map literal into the REPL, like {:a 1}, Clojure automatically selects the concrete map impl to use, for example array-map for small maps or hash-map for larger maps. What happens when you do (def x (array-map {a: 1})) but then you add a couple million key/val pairs? will it remain an array-map, or will Clojure somehow convert it automatically to a hash-map?
07:37AWizzArdIt will become a hashmap
07:38AWizzArdclojure.lang.PersistentHashMap
07:50RCampbellSo to be clear, Clojure will monitor a map and when it grows beyond a certain level it will switch its type? that seems wild
07:51RCampbelleven when it's explicitly instantiated using (array-map
07:56AWizzArdRCampbell: yes, the functions that can grow (assoc, conj) a map will check if there are, say, more than 8 elements in the map. If so, it will be a hashmap.
07:56AWizzArdBut dissoc will not do such a check. The reason is that a "big arraymap" performs worse than hashmaps. But small hashmaps can perform a little bit worse than arraymaps.
07:57RCampbellAWizzArd: thank you for the explanation. That's pretty cool functionality
07:58AWizzArdThe developer will always work with the concept of a map, and Clojure will try to ensure under the hood that a useful implementation will be used.
07:59RCampbellAWizzArd: then why even have (array-map) and (hash-map) functions? when would you select one of the other? Clojure controls the underlying impl, so it seems a bit misleading
08:00AWizzArd,(class (array-map))
08:00clojurebotclojure.lang.PersistentArrayMap
08:00AWizzArd,(class (hash-map))
08:00clojurebotclojure.lang.PersistentArrayMap
08:01AWizzArdIf you understand your data and problem well you may want to have a bigger array-map.
08:02RCampbellyeah, but you're saying if I do (array-map ; some massive data here) it will store it as a hash map
08:03AWizzArdalso: when you type {:a 1, :b 2} into your repl, then Clojure would like to construct a array-map for you. So it is nice to have a function available for that purpose.
08:03RCampbellwhat I mean is, if Clojure is selecting the impl on its own based on the size, why both with array-map and hash-map constructors, and why not just make one (persistant-map)
08:03AWizzArdCalling array-map results in a clojure.lang.PersistentArrayMap
08:03AWizzArd,(class (apply array-map (range 2000)))
08:03clojurebotclojure.lang.PersistentArrayMap
08:04RCampbellyeah, but you just showed (hash-map) creates an array map too
08:04AWizzArd,(class (assoc (apply array-map (range 2000)) :a :b))
08:04clojurebotclojure.lang.PersistentHashMap
08:04AWizzArdRCampbell: because you sometimes know more than the compiler does
08:05AWizzArdyou can safely forget about array-map and just use hash-map to construct your maps
08:05RCampbell(class (hash-map)) -> clojure.lang.PersistentArrayMap is saying the opposite: that the compiler knows more than me. It's a lie, isn't it?
08:05RCampbelli understand that part - that I can ignore it - but then I don't see why the two constructors exist.
08:05AWizzArdhash-map does not guarantee that the returned object will be a PersistentHashMap
08:06RCampbellthen why itsn't there just (persistent-map)
08:06RCampbellsince in the end, the compiler decides
08:06AWizzArdhash-map may call array-map if only a few elements are added
08:06AWizzArdRCampbell: the compiler will not decide when you call array-map
08:06RCampbellaha
08:06AWizzArdsee my example above, where I put 2k elements into an ArrayMap
08:06RCampbellyes, i see that
08:07AWizzArd,(class clojure.lang.PersistentHashMap/EMPTY
08:07clojurebotEOF while reading
08:08AWizzArd,(class clojure.lang.PersistentHashMap/EMPTY)
08:08clojurebotclojure.lang.PersistentHashMap
08:08RCampbellokay so array-map always returns an array-map, but later additions via assoc, conj, can convert it to a hash-map
08:08AWizzArdyes
08:08RCampbellhash-map will return an array-map for small stuff or a hash-map for big stuff
08:08AWizzArdyes, where "big" is around 8-10 elements
08:08RCampbelloh that's not so big. interesting
08:08RCampbellokay
08:22chouser,(class (hash-map 1 2 3 4))
08:22clojurebotclojure.lang.PersistentHashMap
08:22chouserdoesn't look like an array-map to me
08:23chouserI think the important thing is to not rely on the concrete type.
08:33_fogus_,(class {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16})
08:33clojurebotclojure.lang.PersistentArrayMap
08:33_fogus_,(class {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18})
08:33clojurebotclojure.lang.PersistentHashMap
08:33_fogus_But, what chouser dsaid
08:33chouserright. for literals.
08:34chouserthere's no promise about the concrete type of literals or of what's returned by assoc, dissoc, etc.
08:34_fogus_nor should there be... but people get tripped up on that
08:34chouserI do think that when you use a named factory fn like hash-map or array-map, you can rely on getting an object of that type.
08:35chouser_fogus_: hey good morning. :-)
08:35_fogus_chouser: Good morning sir!
08:35chouserif we keep this up, they could rename this channel to #joyofclojure
08:36_fogus_I think there was a time when I liked snow... but I've sent lost that childhood joy. :(
08:36_fogus_That might not be a bad idea anyway. ;)
08:37RCampbellchouser: that's what I was talking about. To me it seems a bit misleading
08:37chouserRCampbell: what's misleading?
08:37RCampbellchouser: when you say (hash-map) you expect a hashmap, no?
08:37RCampbell,(class (hash-map))
08:37clojurebotclojure.lang.PersistentArrayMap
08:38chouserah
08:38chouserwell
08:38RCampbellI agree that you shouldn't depend on the concrete types, and I love that they're managed for me, but if that's the case I just think (persistant-map) would have been better than these two
08:39chouserheh, I hadn't seen that. The thing is, what's the difference between an empty array-map and an empty hash-map?
08:39RCampbellchouser: true enough
08:39chouserwhen you actually give it some parameters, each function will return the specific type you request.
08:39RCampbellbut then my question was, why do we have these two constructors?
08:40chouser,(class (apply array-map (range 2e5)))
08:40clojurebotclojure.lang.PersistentArrayMap
08:40RCampbelltrue, but then you risk losing that type whenever you pass it to a assoc, conj, etc
08:40chouserso there's an array-map with a hunderd thousand key/value pairs, guaranteed to keep the order I gave them.
08:40chouserright, yes you do.
08:40_fogus_RCampbell: Why does it matter which map class you receive after some op(s)?
08:41RCampbelli suppose it doesn't, although it would depend on how you access your map, no?
08:42RCampbellI'm sure certain algos would operate faster on one type versus another based on how the data is accessed
08:42RCampbelli suppose you could always cast from one to another though
08:44chouserRCampbell: I understand what you're saying. I think the most dangerous detail there is that key-matching semantics are slightly different between array-map and hash-map.
08:45RCampbellchouser: could you come up with a nice example? I'm going to add it to my stackoverflow answer concerning commons mistakes beginners make in clojure
08:46chouserRCampbell: hm... my attempts at an example are failing. perhaps that's been fixed.
08:47chouser_fogus_: array-maps are order-n-ouch
08:52RCampbell,(array-map (range 100))
08:52clojurebot1
08:52RCampbell,(hash-map (range 100))
08:52clojurebotjava.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@5c8e6fb3
08:52RCampbellwhy?
08:53RCampbellarray map uses the index as the key by default?
08:53_fogus_RCampbell: Thanks for filling out some of that information on SO... that thread is getting some nice answers
08:54RCampbell_fogus_: np. Mostly I'm remembering all the WTF moments I've had along the way
08:54AWizzArdDoes a lookup in an PAM traverse the full underlying tree until it finds the key?
08:55RCampbellI'm trying to compile all the bits from the three books, mailing list, stackoverflow, and this irc channel that help me get past it
08:55_fogus_RCampbell: Eventually it would be nice to gather those WTF moments and put them somewhere on the Clojure site... but that's probably just a dream
08:56RCampbellfogus: it should be easy enough; the content on StackOverflow is GLP I believe, and Jeff does a content dump every so often
08:57RCampbellAWizzArd: that's a good question
09:03chouserAWizzArd: there's no underlying tree. Underlying a array-map is an array. And yes, it's walked linearly until a match is found.
09:06chouserRCampbell: array-map and hash-map fns both expect an even number args for the key/value pairs
09:07chouserRCampbell: so (hash-map x) is an error regardless of the value of x. But array-map doesn't do many extra consistency checks, so you managed to get away with something thre.
09:07chouserthere
09:08RCampbellchouser: okay that makes sense
09:08RCampbellalthough (range 100) is even
09:08RCampbell,(count (range 100))
09:08clojurebot100
09:09chouserit's a single object
09:09chouserif you want the contents of the range to be the contents of the map, you have to use 'apply'
09:10chouser,(apply hash-map (range 100))
09:10clojurebot{0 1, 32 33, 64 65, 96 97, 2 3, 34 35, 66 67, 98 99, 4 5, 36 37, 68 69, 6 7, 38 39, 70 71, 8 9, 40 41, 72 73, 10 11, 42 43, 74 75, 12 13, 44 45, 76 77, 14 15, 46 47, 78 79, 16 17, 48 49, 80 81, 18 19, 50 51, 82 83, 20 21, 52 53, 84 85, 22 23, 54 55, 86 87, 24 25, 56 57, 88 89, 26 27, 58 59, 90 91, 28 29, 60 61, 92 93, 30 31, 62 63, 94 95}
09:11chouserI think that once upon a time there were objects that were .equal but their .hashCode was different. Has that been fixed now?
09:12RCampbelli dunno, in Java you define your own impls (unlike in clojure) so developers can still screw up
09:13RCampbellchouser: i don't know any history of that in clojure
09:14chouserwell, if that's been fixed then perhaps array-map and hash-map now have sufficiently similar matching semantics.
09:36AWizzArdchouser: okay, this is what I guessed from the names
09:44the-kennyliebke: Which "incanter" should I use in leiningen?
09:46liebkethe-kenny: the latest version isn't up on Clojars yet, so use 1.0-master-SNAPSHOT for now
09:47the-kennyliebke: "incanter-full" or "incanter"
09:47the-kennyIf I use incanter, requiring throws an exception :(
09:47liebkeeventually incanter full, but that didn't get uploaded correctly (apparently), so use incanter
09:48the-kenny"No value supplied for key: true"
09:48liebkeI've been having problems with Clojars lately. Unfortunately, I'd recommend using the github repository
09:48liebkehmmm
09:48liebketry the 1.0-SNAPSHOT version then
09:54rrc7czdo you guys use letfn a lot? it's generally agreed that keeping declarations close to where you use them is a good thing, as is lowering the scope of something when it's possible
09:54rrc7czbut I don't see it used a lot
09:56chouserI more often use let when defining local functions than letfn.
09:57rrc7czwhy?
09:57chouserwith let I can mix fn and other locals
09:57rrc7czokay that makes sense
09:57chouserI use letfn when I need mutual recursion and/or have only fns to define
10:15LauJensenWhat the general use-case for mutual recursion ?
10:16Chousukestate machines?
10:18arohnercause it's cool?
10:24rrc7czfogus: I totally didn't make the connection between your stackoverflow question and my answer
10:24rrc7czfogus: I just noticed your name now. Thats pretty funny. I guess it's a small community
10:27_fogus_rrc7cz: A small, but growing community. :-)
10:31rrc7czfogus: I like your pre/post article; I had a question about doing design by contract in clojure and I was psyched for this functionality
10:33Chousukepre and post might be a bit problematic with libraries though. they are only checked if *assert* is bound, and the decision is made during compile time
10:33Chousukeso if you AOT-compile your library for distribution, you need to decide for the users whether to enforce asserts or not :/
10:34rrc7czChousuke: so why was assert used as the underlying mechanism? why not switch it to an if or something?
10:35Chousukerrc7cz: I guess it was intended that pre- and postconditions are only checked when debugging, and compiled away for production code.
10:35rrc7czoh
10:35chouserI don't like AOT-compiling anyway.
10:36chouserif you don't AOT-compile, your users can maintain control with *assert*
10:37_fogus_rrc7cz: Actually, Devlin's follow-up to my :pre/:post uhhhh post, is much better
10:37ChousukeI guess that's the best choice for libraries
10:40rrc7czI was looking for a way of translating some of the AssertionErrors into IllegalArgumentException which makes a lot more sense when validating arguments, but I suppose if :pre/:post were meant for debugging and not prod runtime, there isn't much point
10:42Chousukeyou can always make an assert-args macro. there actually is one in core, but it's private ;/
10:45rrc7czChousuke: it seems odd to make something that useful private
10:48Chousukerrc7cz: well, it's just a trivial helper macro in core. I don't think any significant design effort was put into it.
10:51esbenaI want to apply a side-effect function to every element of a seq, what is the name of that function (not 'map') ??
10:51chouseresbena: doseq or dorun
10:52Chousukedoseq is a macro, though, and dorun just forces a seq. :)
10:52Chousukebut those will do what you want.
10:52chouserChousuke: ok then, what's you're answer? :-P
10:53Chousukebut the answer of course is (comp dorun map)
10:53ordnungswidrigIs there a way to quickly fail in clojure. Like throw new Exception("message")
10:53chouserChousuke: :-)
10:53Chousukeordnungswidrig: (throw (Exception. "message"))
10:53ordnungswidrigChousuke: *g* something more idiomatic?
10:54Chousukereturn nil?
10:54Chousukean exception is the only way to have a non-tail exit though.
10:54ordnungswidrig(defn fail [] (throw Exception. "message")
10:55Chousukesome parens missing, but yeah.
10:55Chousukeyou could also use error-kit from contrib if you want fancy errors :P
11:12defnI have a question about paths
11:13defn(System/getProperty "user.dir")
11:13mebaran151paths?
11:13defnso let's say i have a .clj file that's nested in a lein project
11:14defnIf (System/getProperty "user.dir") is called from that file, i assume it will get the path that the file is living in, yes?
11:17mebaran151I'm actually not quite sure
11:17mebaran151user.dir is tricky
11:18mebaran151sometimes it gets where the jvm is stored
11:18mebaran151I find it unreliable
11:20chouserI think user.dir is usually the cwd when the jvm was started. And you can't change it.
11:22defnchouser: that's correct, just tested it
11:22defnit's where you run the jar from
11:22defnmebaran151: what else would you use?
11:23defnI don't want to force people to use absolute paths and edit a config file just to run this
11:23mebaran151I tend to rely on user.home very heavily
11:23mebaran151and I copy lots of things there
11:24defnhmmmm, i dont like mucking with a user's home dir if it's not necessary
11:24defnand in this case im sure it's not
11:24defnit's not like im writing a utility or an application they will want to store a local config file for
11:24defnit's something which needs to just be contained by itself
11:26defnme needs a java version of pygments
11:27mebaran151oh then what do you need user.dir for?
11:27defnto get the project root
11:27defnwhich is where the jar is built
11:28mebaran151are you on unix?
11:28defnyes
11:28defnbut not everyone will be
11:28chousersurely you can be in some other directory when you launch the thing, which might mess up your user.dir
11:28defnchouser: yeah, but im okay with that as I suspect most will run it from it's build directory
11:28defnif they dont, well, too bad for them
11:29mebaran151hmmm I'm trying to consider if some env variable will help you
11:29defnin unix it might, but idk, i think this is fine for now
11:29defnit's better than the absolute path
11:30mebaran151you probably could wrap it in a small shell script
11:30defnsomeone just msg'd me on github asking why they couldnt run it, and it's because of the absolute path
11:30mebaran151that would either pass the cwd as an argument to your proram
11:30defni told them to edit it, but it seems like a stupid step to force people into
11:31defnanyway, now im on the hunt for a way to do markdown + code highlighting
11:31defnspecifically clojure code syntax highlighting
11:32defnpygments + markdown.py and the codehilite extension which is bundled with it do a wonderful job, but that means people have to get friggen python deps for a clojure project, which is lame as hell
11:32hiredmandefn: I think user.dir will be fine
11:32defnhiredman: i agree
11:33defnhiredman: any ideas for clojure syntax highlighting which outputs as HTML?
11:33defnsomething java?
11:33hiredmannone
11:33defnbummer
11:34hiredmancan't you just use some kind of javascript deal?
11:34hiredmanisn't that the latest and greatest in web syntax hilighting?
11:34LauJensendefn: htmlize :)
11:35defnLauJensen: in clojure?
11:35LauJensenoh, no thats Emacs
11:35defnyessir :)
11:35defnhiredman: nice! i think you pointed me in the right direction with your comment: http://alexgorbatchev.com/wiki/SyntaxHighlighter
11:37LauJensendefn: I think a cocktail between compojure's html function and then just doing some kind of .replaceAll with the functions in core would get you quite far
11:38defnLauJensen: could you be more specific about what you're replacing?
11:38defnLauJensen: as in writing my own markdown processor?
11:38LauJensenWith the above approach, you'd be highlighting functions and macros
11:39LauJensendefn you're writing a Clojure program which reads clojure code and emits highlighted html right ?
11:40defnLauJensen: close -- it reads markdown which contains code blocks, which need to be highlighted as clojure
11:40LauJensenYea, almost the same
11:40LauJensenGotta boot
11:41defnmarkdown.py does a slick thing wherein it let's you specify at the top of a code block: :::clojure\n (defn omg [arg1 arg2]\n (+ arg1 arg2))
11:42hiredmanyou might even be able to use scriptjure to write custom js highlighting stuff in clojure and translate it to javascript
11:42Licenseraloa
11:42defnhiredman: not a bad idea at all
11:42mebaran151that would be way meta
11:42hiredmanso I would forget about generating hilighted html
11:42mebaran151then you could highlight the scriptjure source in js
11:44defnhttp://attacklab.net/showdown/
11:44defnmaybe?
11:47hiredmanthe markdown renders to html right?
11:48hiredmanso you just have the javascript highlight the code blocks in the html
11:48defnhow do i know im highlighting a code block though?
11:49hiredmanmagic
11:49hiredmanby magic I mean <code></code>
11:49hiredmanor whatever markdown dumps the code into
11:49defnis that what markdown renders?
11:50hiredmanI don't know, you should check
11:50defnlol
11:51djorkwow, Enlive looks very nice
11:52djorkI assume cgrand-rec in here is the dev?
11:55chouserI think -rec is his bot.
12:35nuttycom1Does anyone have a good reference for how to embed a Clojure interpreter (or compiler that can be dynamically invoked and return something callable) in a Scala (or Java) app?
12:36kotaraknuttycom1: import clojure.lang.RT; import clojure.lang.Var; Var pr = RT.var("clojure.core", "println"); pr.invoke("Hello, World!");
12:38nuttycom1kotarak: thanks
12:47nuttycom1Hmmm... are there any javadocs for jvm.clojure.lang.* or do folks just consult the sources on github?
12:47chouserthere are no official docs for the .java code. So yes, the sources.
12:48chouserthey're all going away eventually anyway. ;-)
12:48nuttycom1ah, I think I heard about that - what's the timeframe on self-hosting?
12:49Chousukewill deftype/reify be the last piece needed before the actual compiler work can begin? :/
12:49nuttycom1moreover, what can I expect with respect to my goal of having an embedded interpreter (or runtime compiler) for use from within another app?
12:49Chousukeor is there still something
12:50nuttycom1I've been using Groovy for this purpose up until now, but clojure is much more appealing.
12:50Chousukenuttycom1: but the compiler *is* a runtime one? what do you mean :/
12:50chouserclojure's got a runtime compiler built right in. read-string, eval.
12:50Chousukethere is no interpreter though :)
12:51chouserChousuke: I think a way of doing volatile fields is still missing.
12:51defnChousuke: do you have the ability to add members to the assembla project
12:51ChousukeI don't think so. hmm.
12:51defni gave rich my signed agreement and am listed on the contributers page
12:51defnerr i meant chouser
12:51defnbut my account on assembla is still Watcher
12:52Chousukedid you post to the dev group asking for a bump?
12:52defnI didn't -- I thought I'd just need to get the agreement signed and he'd handle getting me added
12:52defnbut I can do that
12:52nuttycom1Chousuke: basically, I've got an app written in Scala running on Glassfish. I need to provide a small scripting language for part of that app. I can go the parser-combinator route in Scala, but that seems like a bit heavyweight for my situation - so instead I want to use clojure, where the resulting artifact can be executed in the current classloader (or a child, of course)
12:53chouserdefn: I think you need to ask. I think only rhickey can do it.
12:53defnchouser: Chousuke: thanks
12:54hiredmanI don't know much about classloaders, but my impression is clojure still has some modularity issues on that front
12:54hiredman(no direct experience, just sort of half rememebered stuff on the internet)
12:56chousernuttycom1: so you may have to play with the classloaders a bit, but the raw materials should all be there. 'read' to convert text to a tree of clojure objects, 'eval' to run it.
13:37mebaran151hey somnium, so I've got some basic proxy netty stuff working if you want to play with it
13:38somniummebaran151: cool, sure. on github?
13:38mebaran151not yet
13:38mebaran151it's just a gist so far
13:38somniumurl?
13:38mebaran151turns out the annotations in netty are simply documentation
13:39mebaran151http://gist.github.com/272271
13:39mebaran151it basically works the way I described
13:40mebaran151takes the output of a function and writes it to the buffer, either an array of ints or a good ol' fashion bytestring
13:41mebaran151I keep around the context vars in bindings in case you wanted to do something fancy with them
13:42somniummebaran151: should I use 3.15?
13:42mebaran151I was going against 3.2 alpha
13:42mebaran151but I don't do anything particularly adventurous
13:43somniumok
13:45mebaran151I was looking for good protobuffers in clojure, but the design doesn't seem to fit the clojure mentality well
13:47mebaran151it works as a basic telnet echo, but I haven't done much more with it yet
13:48the-kennymebaran151: Maybe write a nice wrapper about the java version of the protobufs?
13:48mebaran151but protobufs is so classy
13:48mebaran151like heavily classy
13:48mebaran151it's probably a bad binary fit for clojure at the moment
13:49chousergoogle protobufs, or something else?
13:49mebaran151google protobufs
13:49chouserI use them a lot at work, from Clojure and C++
13:49the-kennyIn fact, I have never really needed a binary protocol. I always use simple json
13:50chouserso I've got fns to convert back and forth between clojure nested maps and protobufs
13:50mebaran151there's a certain mechanical elegance to a good binary protocol
13:51chouserI need them to iterop with other services. The choice to use protobufs was not mine. :-)
13:54mebaran151but if clojure itself were to have a nice easy binary protocol that handled vectors, maps, strings, and numbers, I think that might be useful, actually even outside the clojure community
13:54mebaran151I wonder if a protocol with that much flexibility though would be anymore efficient than regular ol' JSON
14:00somniummebaran151: the pet project I want to use netty for is a BSON client (http://www.mongodb.org/display/DOCS/BSON), which seems to be an attempt at being more efficient than regular 'ol JSON (or maybe just a mild case of NIHS, cant be sure)
14:01mebaran151oh I was looking into BSON as well
14:01mebaran151it seemed like it would be cool to switch between JSON and BSON
14:17somniumhmm, how do you add a repository in a project.clj? (cant seem to find an example and Im maven challenged :/)
14:19knuckollsi'm just learning clojure and i'm having a real hard time conceptualizing this. I have a file with records separated into sets of three lines, then an empty line. I want to load these into memory but I can't figure out how to pull from the seq 4 lines at a time and store them in a map. any pointers to the functions i should be using?
14:20chouser,(parition 4 (range 12))
14:20clojurebotjava.lang.Exception: Unable to resolve symbol: parition in this context
14:20chouser,(partition 4 (range 12))
14:20clojurebot((0 1 2 3) (4 5 6 7) (8 9 10 11))
14:20chouserthat might help
14:20the-kennyknuckolls: (partition 4) will partition a seq in seqs of 4 items
14:20knuckollsyes. that helps quite a bit. this is the first i've seen partition
14:20knuckollswonderful.
14:21knuckollsyep that does the trick. thanks.
14:25robwolfesomnium: IIRC it's something like this: ":repositories [["rep name" "url"]]"
14:25somniumrobwolfe: ah thanks
14:27hiredmansomnium: I am pretty sure it's a map
14:28hiredman{"google" "url"}
14:28somniumhiredman: I found a gist with a map, and that worked, then just tried the vector, and that seemed to work too (though maybe it already added the repo?)
14:28hiredmanbut it must get walked via the seq functions which sees it as the same thing as [["name" "url"]]
14:29hiredman,(seq {"google" "url"})
14:29clojurebot(["google" "url"])
14:29robwolfehiredman: there is "concat" and it works for vector and map
14:31hiredmanrobwolfe: I am just hypothesizing on why a map and a nest set of vectors both work for :repos
14:31robwolfehiredman: in Leingen there is used "concat" for joining "default repos" with defined
14:32robwolfethat's why it works I guess
14:32somniumpresumably a map would work for :dependencies too? ah, maybe not?
14:32somnium*shrug* whatever works is fine with me
14:32robwolfesomnium: we can try ;)
14:34hiredmanhttp://gist.github.com/272330 <-- makes me sad
14:40arjI have a very imperative part of my program. More or less a state machine. Any hints as to code this in clojure?
14:45stuartsierraarj: loop/recur
14:48arjhmm interesting
14:48arjI'll have a look
14:48arjthanks
14:48_fogus_arj: mutual recursion might map well also, but it takes some practice to get right
15:01ynnivis there an elegant way to break a hash map apart and reconstruct it?
15:01kotarakynniv: breaking apart in which way?
15:01ynnivi'm using mongo, and my DBObject acts like a hash map, but isn't close enough to work with some of the api
15:02ynnivi'd like to convert it to a real hash-map elegantly
15:02kotarakynniv: does it support seq? (into {} your-object)
15:02ynnivhah! perfect :)
15:03ynnivi haven't used "into" yet
15:05ynnivi probably write the worst clojure code, but even that works out better for me than great code in other languages
15:09{newbie},(into {} [:foo "bar"])
15:09clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
15:10somniumynniv: if you don't mind a shameless suggestion, congomongo on github might make the mongo-java-driver somewhat more pleasant to work with
15:10ynniv,(into {} [[:foo "bar"]])
15:10clojurebot{:foo "bar"}
15:11{newbie}:\ okay :D
15:11ynnivsomnium: I considered it, but I'm doing so little interaction with mongo that I'm not ready to switch libs yet
15:11ynnivi have a couple of .find's :)
15:16somniumynniv: just a shameless suggestion :)
15:16ynnivI have considered it, and will keep it in mind ;)
15:17ynnivi'm working in a mongo - clojure - REST - SproutCore stack, and i've been spending all my recent time on the right side of that
15:17ynnivbut i'll revisit the left sometime soon
15:20somniumynniv: cool, Ive had my eye on Sproutcore, but the docs are worse that dojo's (which Im reasonably familiar with)
15:20hiredmanhttp://andialbrecht.wordpress.com/2009/05/09/when-merging-fails/ <-- hah!
15:22the-kennyhiredman: I want this for git!
15:24robwolfehiredman: I want it for missing jars on classpath ;)
15:24AlexS_I seem to be getting an java.util.concurrent.RejectedExecutionException when trying to use a very simple agent in the slime/swank repl. Everything works fine from a non-swank repl. Anyone else encountered this? Or be willing to try an reproduce?
15:26hiredmanAlexS_: most likely means you shutdown the agent threadpools
15:27AlexS_hiredman: This was a brand new session started with the lein swank command.
15:35ynnivsomnium: SC is a tough framework to get involved with. I have the benefit of a 9 month head start learning, but even so, a lot has changed in that time.
15:44I314159hi
15:44I314159I have a struct which looks like this: (defstruct book :title :author)
15:44I314159I also have a list which looks like this: (let mybook [("my title" "my author")])
15:44I314159I want to turn this into a book struct, but doing this: (struct book mybook) gets this:
15:44I314159(:title ("my title" "my author") :author nil)
15:44I314159any tips on on what I'm doing wrong?
15:45the-kenny(apply struct book (first mybook))
15:45the-kennystruct doesn't exspect a list but single arguments
15:45I314159ahh -- thanks
15:46Chousukealso you would need to quote the lists like that :P
15:46Chousukemore idiomatic in clojure is to use a vector
15:49dataangelIs there a paper or site somewhere that describes how clojure implements persistent data structures? I know from Hickey's presentations that there's some hashing going on, that somehow affects indexing into some multilayer tree, and that CAS lets you quickly swap out elements, but I haven't seen a real description of the algorithm anywhere. I'm not a Java dev so the source code has a high barrier to entry for me ;p
15:51chouserdataangel: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/
15:52chouserdataangel: but don't just into that until you're ready -- it'll just destory the magic for you. :-)
15:52chouserdon't jump
16:32leafwany fn to flatten a list of lists ?
16:32leafwI am sure there is one ...
16:32chouserone level, or recursive?
16:32kotarakleafw: flatten?
16:32leafwone level
16:32chouser(apply concat x)
16:33leafwchouser: although recursive would be nice too.
16:33kotarakc.c.seq-utils/flatten
16:33chouser,(apply concat [[1 2 3] [4 5 6] [7] [8 9]])
16:33clojurebot(1 2 3 4 5 6 7 8 9)
16:33leafwclojure.contrib, that unknown treasure pit
16:33leafwthanks
16:33chouserheh
16:33chouser"treasure pit
16:33kotarakI hope my memory doesn't play bad tricks on me, though...
16:34chouser"treasure pit" seems more accurate that "standard lib"
16:34chouserthan
16:34chousertreasures, sure. Also, a pit.
16:34ohpauleezhaha
16:35leafwit's just too hard to ever get a general idea of what is where and how did it change recently
16:35ohpauleezThat's why I hang out in #clojure
16:36ChousukeWe have contrib excavators here.
16:36ChousukeSome people also occasionally go ahead and deepen the pit, hiding more treasures.
16:37ohpauleezit's all in the name of bringing game theory to clojure development
16:37ohpauleez:)
16:37leafwxD
16:38technomancynow that clojars exists it might be worth thinking about spinning libraries back out of contrib if they aren't intended for future inclusion in core
16:38ChousukeAll is okay as long as complexity does not approach that of Go
16:38technomancyat least, that's what I would be considering if I had authored a library that had been included in contrib
16:38hiredmantechnomancy: I was just thinkging that
16:38technomancyclojure.contrib.logging would benefit from that IMHO
16:38kotarakAh! Go. :D Hmmm...
16:39kotarakWhatever happens with contrib, I'd like to see a more modular build.
16:40kotarak3.5Megs for c.c.def.... bleh.
16:40technomancyhiredman: we analyzed our codebase at work, and 60% of contrib usage was IO (duck-streams/java-utils) and 25% was logging.
16:41hiredmanis clojure.io still in motion?
16:41technomancythen a handful of shell-out and str/seq-utils invocations
16:42technomancyhiredman: stuart S seemed to think rich had some plans up his sleeve
16:42hiredman*shrug*
16:42technomancyI was waiting to hear more about that, but it sounds like that's not going to happen
16:43hiredmanthere is a lot of chum in the water
16:43chouserone of the values of contrib is the low barrier for bug fixes from people other than the original author
16:44technomancychouser: maybe, but stuff outside contrib doesn't have to go through the ticket+patch dance
16:44technomancyauthors can pull directly from others' git repos, which is much more convenient
16:44chouserneither does stuff inside contrib when the patch is written by a committer.
16:45technomancyit's true that having multiple committers solves some problems
16:45chouserdo I have to clone someone else's repo on my dev machine before doing a pull?
16:45technomancybut with clojars if you've got a bug fix you want to use, it's easy to push your own version with the fix if you can't wait for inclusion
16:45technomancychouser: not at all
16:45ordnungswidrigis there a pendant to reduce where you provide a single initial value and a list of functions f1 f2 f3 so that is returns (f3 (f2 (f1 x)))
16:46technomancychouser: just add them as a remote, fetch from them, and create a branch based on theirs. then review changes and merge if you like 'em.
16:46chousertechnomancy: ok, thanks.
16:46kotarakordnungswidrig: (reduce #(%2 %1) 0 [inc inc dec dec])
16:47ordnungswidrigkotarak: ah fine
16:47ohpauleezordnungswidrig: it sounds like you want to do monadic functions or composition (comp)
16:47technomancyyou don't even need to create a branch based on theirs actually, you can check theirs out directly if you don't think you'll need to modify it at all.
16:47chouserordnungswidrig: (-> x f1 f2 f3)
16:47ohpauleezor that, lacing is a good way too
16:48kotarak... if f1 and friends are known at compile time.
16:48ordnungswidrigohpauleez: ((reduce comp [f1 f2 f3]) x) ?
16:48chouserordnungswidrig: or what ohpauleez said. ((apply comp [inc inc inc]) 2)
16:48kotarakordnungswidrig: ((apply comp [f1 f2 f3]) x)
16:49chouseractually [f3 f2 f1]
16:50ordnungswidrigok, I see why it didn't work for me. f is not f :: A -> A but f :: A -> B -> b where B shall be passed through. I think I can throw in some currying
16:51somnium~haskell
16:51clojurebothaskell is Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you don't compute.
16:55knuckolls,((apply comp [inc inc inc]) 2)
16:55clojurebot5
16:55knuckolls,((reduce comp [inc inc inc]) 2)
16:55clojurebot5
16:55knuckollswhat is the difference?
16:55hiredmanreduce generates more functions
16:56knuckollshow so?
16:56hiredmanreduce is (comp (comp inc inc) inc)
16:56knuckollsah
16:56mebaran151_what's the best way to get clojureql
16:57mebaran151_clojars have the right version?
16:57hiredmanlein!
16:57kotarakmebaran151_: from clojars.
16:57chousercomp has some unrolling that makes up to three args a bit faster
16:57hiredmanI bet clojars has like five versions
16:57kotarakor gradle :P
16:57mebaran151_clojars actually only has 2
16:57hiredmanchouser: eh>
16:57mebaran151_one a coworker patched of an older version
16:57mebaran151_and this unofficial snuxoll package
16:58kotarakmebaran151_: http://gitorious.org/clojureql/clojureql for the adventurous
16:58hiredman(people who can be bothered installing yet another build system)
16:58ordnungswidrigpff, is there a cheap way to reverse the seq of fs?
16:58chouserordnungswidrig: 'reverse' :-)
16:59kotarakordnungswidrig: reverse ;p
16:59hiredmanhardly cheap
16:59ordnungswidrig(apply comp (reverse (map #(partial g %) fs)))
16:59kotarakOr rseq if you have a vector
16:59ordnungswidrigatm the list is rather short.
17:00ordnungswidrigso if the list of functions is long I think I'll do it with a reduce
17:00mebaran151I wish the dependencies for clojars didn't pull down the world of sql
17:00mebaran151seems as though you should get to choose which jdbc adapter you want to compile in
17:00kotarakmebaran151: I working on that.
17:00kotarakI'm
17:01kotarakThere will be finer dependencies in the future.
17:01mebaran151while I put out my wishlist, have you guys considered adding h2
17:01mebaran151it's like a nicer version of derby, with builtin lucene integration
17:02mebaran151I'd be willing to help contribute an adapter if the process were simple enough
17:02kotarakIs that HSQL? patches welcome. ;)
17:03ordnungswidrignice: (reduce #(exe %2 %1) fs) works in my case.
17:03hiredmanmebaran151: there is some kind of exclude option for lein
17:03mebaran151it's more hsql2
17:03mebaran151I'm not sure how you guys would want to integrate the fulltext search option
17:04mebaran151it's something I've always thought an SQL db shoudl have
17:05leafwa simple question: a fn to update a value in a map, without knowing f the key already exists?
17:06kotarak(update the-map [the-key] (fnil f the-default))
17:06leafwcool
17:06kotarakleafw: fnil was on the google group, posted by Rich
17:06kotarakJust a sec
17:07kotarakleafw: http://groups.google.com/group/clojure/msg/f251cfd9baab440a
17:07hiredmandepending on the implementation of fnil you might getaway with (update the-map [the-key] fnil f the-default)
17:08knuckollssay i'm loading a huge file in slime but i want to stop the load and get back to the repl, how would i do that in slime?
17:08the-kennyC-c C-c
17:08knuckollsor really, kill any currently running s-exp. like ctrl-c
17:08knuckollsaha, tricky
17:09the-kennyMaybe you can also kill a possible-existing worker-thread
18:07mebaran151how do you insert in ClojureQL?
18:08kotarakwith insert.
18:08kotarakJust a sec
18:09kotarakmebaran151: http://gitorious.org/clojureql/clojureql/blobs/master/src/clojureql/demos/common.clj
18:09kotarakmebaran151: there are some examples
18:10mebaran151okay
18:10mebaran151thanks!
18:11mebaran151what namespace does sql refer to?
18:13hiredmanhttp://github.com/hiredman/clojurebot/blob/master/hiredman/triples.clj
18:14kotarakmebaran151: clojureql
18:21mebaran151hiredman, have you looked at neo4j's triple support?
18:21mebaran151I'm planning on wrapping it when I get the chance
18:24hiredmanmebaran151: I just through a rock and hit derby, I didn't look at anything else for clojurebot
18:28KirinDaveDoes anyone here have experience with compojure?
18:28KirinDaveSpecifically, trying to get sessions to work but the docs are kinda sketchy on what they actually want here.
18:29ctdeanI used an earlier version of compojure w/ sessions, what are you trying to do?
18:32KirinDavectdean: Just save some values in a dang session
18:32ctdeanLet me see if I can paste a quick example
18:32KirinDavehttps://gist.github.com/bcac547ff8ebfde2c982
18:33ctdeanwrap the routes in with-session
18:33KirinDaveAll of them?
18:34KirinDaveThere is only 1 where I am trying to get it to work.
18:34KirinDaveAnd also
18:34KirinDaveDo you see I wrap main-app with (with-session) ?
18:34ctdeanAh, I see. I missed that
18:34mebaran151hiredman, it might be interesting to play with
18:34mebaran151what's the best way to create table if not exists in clojureql
18:35kotarakmebaran151: there are also examples for create table in the previously posted link. However create-table is currently in flux. Just a sec.
18:35ctdeanone sec
18:36kotarakmebaran151: http://gitorious.org/clojureql/pages/CreateTableSyntax
18:38ctdeanThe only thing I can see different is that I used {:type :memory :expires (* 60 5)}) instead if the default
18:38KirinDaveWhere?
18:38ctdeanSo, (with-session thing {:type :memory :expires (* 60 5)})
18:39KirinDaveHow are you supposed to set it?
18:39somniumKirinDave: I think you need to return a map with a session key so the session middleware sees it, like {:session {:user "some-guy"} :body "..."}
18:39KirinDaveAhah
18:39KirinDaveI didn't realize I had to assoc onto their session
18:40mebaran151kotarak, how do I get the if not exists behavior?
18:41mebaran151also any easy way to create index on a table?
18:41kotarakmebaran151: no indexes, yet.
18:42ctdeanAh yes there is a (session-assoc :x 1) call you need to do
18:42mebaran151but what about if not exists, or what would be the best way to check if a table existed?
18:43kotarakmebaran151: you have to do (drop-table foo :if-exists) (create-table foo)
18:43mebaran151what if I don't want to drop the table
18:43mebaran151I just want to create it if not exist
18:43mebaran151can create-table have an :if-not-exists option?
18:44kotarakmebaran151: if the backends support it... Nicolas is currently working on create-table.
18:44mebaran151ah
18:45kotarakeg. Derby does not support drop-table if-exists, so no support there.
18:45kotarakeg. Postgres does, so the support is available.
18:46LicenserI've some seriouse problems with swank clojure and os x it just refuses to connect to the projects repl :/
18:46LicenserI get 'Polling "/var/folders/b5/b5QOdd5jGfmy7oTg2xxwEU+++TI/-Tmp-/slime.2875".. (Abort with `M-x slime-abort-connection'.)' and a few thousand attempts but it kind of just keeps doing that
18:49mebaran151kotarak, do you guys supply any mechanism to query the schema?
18:59joshua-choiQuestion: What is the purpose of separating the array-map and hash-map functions? Is there a time when I should use one and not the other?
19:04mebaran151kotarak, how does one open a db transaction?
19:04technomancyjoshua-choi: I get the feeling that's an implementation detail leaking; I don't think you ever want to call array-map
19:05technomancyarray-maps have the odd property of allowing duplicate keys, which you really don't want.
19:05joshua-choitechnomancy: Well, the {...} syntax creates array maps or hash maps, depending on the number of elements inside, right?
19:06joshua-choiI'm not sure how it decides, though
19:06technomancyif it's 8+ entries, it's a hash map
19:06technomancy,{:a "A" :b "B" :a "C"}
19:06clojurebot{:a "A", :b "B", :a "C"}
19:06joshua-choi,(type {:a 3})
19:06clojurebotclojure.lang.PersistentArrayMap
19:07joshua-choi,(type {1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98 10})
19:07clojurebotclojure.lang.PersistentHashMap
19:08joshua-choiIs there any function that imitates the {...} notation?
19:08joshua-choiSomething like the vec or set functions for maps
19:08technomancy,(type (hash-map))
19:08clojurebotclojure.lang.PersistentArrayMap
19:08technomancynot sure what to think of that
19:09technomancyI guess just use hash-map and be sure not to have any duplicate values in your literals.
19:09joshua-choiThat's so weird
19:09joshua-choiOkay, thanks for the advice
19:09technomancyas long as you don't have duplicate keys in your literals, you'll never notice the difference
19:09joshua-choi,(type (array-map 1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98 10))
19:09clojurebotclojure.lang.PersistentArrayMap
19:09joshua-choiHmm
19:10technomancyassoc and friends won't allow duplicates even on array-maps
19:10technomancyit's only the constructors that do
19:10mebaran151also, I'm getting a strange error, java.sql.SQLException, Resultset not open
19:11somnium,(type (assoc (array-map 1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98
19:11somnium 10) :a :a))
19:11clojurebotEOF while reading
19:11joshua-choiAnd it seems like array-map always returns array maps, while hash-map may return either array or hash maps
19:12technomancyI don't think it's ever an issue in real life, but it's interesting to peek under the covers
19:12somniumbah, array-maps automatically get made to hash-maps as they grow
19:12technomancythe only time it bites people is when you're using transients incorrectly (bashing in place) and an array-map grows into a hash-map
19:13joshua-choiOh, can that happen? I haven't tried map transients yet
19:14technomancywhich is actually a feature! since it gives you an opportunity to learn what transients are actually all about. =)
19:23dysingerskeptomai: I come to see opscode again in jan 25-29 timeframe :) I'll have to infect opscode with some clojure
19:23dysingerwe should actually get some chef recipes going in clojure ;)
19:24skeptomaidysinger: totally
19:24skeptomaiI have it running with slime, et al, but haven't had time to do anything cool
19:40ctdeanwhat dep should I use in lein to get the compojure jars ?
19:42tomojas far as I know there isn't a good one yet
19:43tomojall the ones I saw didn't include all the deps, as far as I could tell
19:45tomojI made my own, org.clojars.tomo/compojure
19:45tomojbut I can't remember if I've gotten it working perfectly yet
19:46ctdeanok thanks
19:46tomojeventually the compojure people will provide one, I would hope
19:51erikcwM-x swank-clojure-project doesn't seem to do anything. I setup that path with a lib directory with my extra jars, but "(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))" doesn't seem to change. Am I missing something?
19:53tomojerikcw: do you use leiningen?
19:53erikcwtomoj: not yet
19:53erikcwI'm just getting started
19:54tomojoh, I think I remember having a problem where lein tricked swank-clojure-project into not finding my jars
19:54tomojbut I'm not sure
19:54erikcwis lein the recommended "method"
19:56tomojit is getting there
19:56tomojbut I still use swank-clojure project sometimes
19:56tomoj(and it still picks up my jars)
19:57tomojwhat version of swank-clojure are you using?
19:57erikcwdo I need any directories other than lib?
19:57tomojsrc/ and lib/ are all I usually use
19:58erikcwI'm 1.1.0
19:58tomojoh, mine is outdated
19:58erikcwout of package-list-packages...
19:58tomojnow my package-list-packages isn't even working
20:15tomojmebaran151: why?
20:24mebaran151getting errors like
20:25mebaran151no multimethod for integer embedconn
20:25mebaran151resultset not open
20:25mebaran151I can't get it to do anything basic
20:25JonSmithwhat is the it that is broken
20:27mebaran151query
20:28mebaran151so I think the table gets created (it returns an EmbedStatement)
20:28mebaran151#<EmbedSQLException java.sql.SQLException: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is OFF.>
20:28mebaran151that's the error
20:28mebaran151sure there should be no rows
20:28mebaran151but I have no idea how to fix it
20:30tomojmaybe if the owner comes around he will have an idea
20:38JonSmithis there a good explanation of how the 'shared structure' works in clojure
20:40mebaran151http://gist.github.com/272648 << if anybody knows clojureql, maybe I'm just doing it wrong so to speak
20:40JonSmithI'm thinking about using a vector of hash-maps to represent state changes, where each is incrementally changed version of the next
20:40JonSmithwondering if that will be hugely memory intensive
20:41mebaran151each hash-map?
20:41mebaran151that shouldn't be
20:41mebaran151only hash-map modifications are recorded
20:41mebaran151the vectors still point to the same basic structures
20:42JonSmithyeah each hash map
20:42JonSmithi was thinking it would be a good way to represent user state in a web app
20:43mebaran151hmmm
20:43mebaran151interesting
20:51JonSmithyeah i was thinking of it as a hybrid between rest and cps frameworks
20:51hiredmanmebaran151: the results from clojureql are in a lazy seq that is closed when you leave the scope of whatever form that is
20:51hiredmancql/run
20:52hiredmanor the result of the query that is used to generate the lazy-seq is closed
20:52hiredmanbasically you have to use doall everywhere
20:52hiredmanvery much a pain
21:10mebaran151hmmm?
21:10mebaran151do hiredman, is my createtable statement okay?
21:11LordMetroidhm clojure seems very tempting, why are no one adopting it?
21:12LordMetroid*why are so few adopting it?
21:12JonSmithseems like a lot are?
21:13JonSmith#clojure pop is only 100 less than #lisp pop
21:14LordMetroidmmm, but I don't see the popularization of the language on such scale as Erlang for example.
21:19JonSmithoh
21:19JonSmithidk its pretty young so we'll see
21:21LordMetroidmmm, it sure seems to have a well progressing early adopters rate
21:22mebaran151http://gist.github.com/272668
21:22mebaran151that's my create-table method
21:22hiredmanerlang has been around *forever*
21:22mebaran151is it technically correct?
21:23mebaran151erlang hails from the late 80's doesn't it
21:25hiredmanerlang also is used to address a current problem (distributed systems) while clojure is aimed at a still developing problem (leveraging multicore)
21:25hiredmanmebaran151: as far as I can tell
21:26mebaran151I should be able to run (query users *) afterwards
21:26mebaran151however when I try to run it
21:26mebaran151I get ... brokenness
21:27mebaran151Resultset has no next ('cause there are no results)
21:27hiredmanmost likely because you are try to examine the resultset after it has been closed
21:28mebaran151(doall (dosql (query users *)))
21:28mebaran151that doesn't work
21:28mebaran151I can't figure out a single construct that does
21:28hiredmanyou have to put the doall inside
21:29hiredmanthe resultset is closed after leaveing the 'run' macro
21:29mebaran151order doesn't matter
21:29hiredmanare you sure?
21:29mebaran151putting the doall inside the dosql doesn't do anything
21:30mebaran151(run *conn-info* (doall (query users *))) << this doesn't work
21:30hiredman*shrug*
21:35cark(run *conn-info* (doall (dosql (query users *)))) not working either ?
21:35ctdeanWhat are folks using for Amazon S3 access these days?
21:35hiredmandosql expands into a call to run
21:35mebaran151yeah
21:36mebaran151just embeds *conn-info*
21:40mebaran151do I have to do something special with the embedpreparedstatement the statement creator returns?
21:42LordMetroidhiredman: Erlang was constructed to solve concurrency and reliability
21:43LordMetroidhiredman: It was developed by the company Ericsson AB to run their telephone systems, which demands reliability and concurrency
21:43mebaran151cark, no matter where I put the doall I get an error
21:43mebaran151and I can't insert
21:43mebaran151I'm gonna try building from source
21:44LordMetroidhiredman: as a side effect of them solving concurrency using hyper-lightweight processes and message passing rather than shared state Erlang is well suited for multicore deployment as well
21:45LordMetroidhiredman: as of lately the Erlang VM development has been focusing on optimizing multicore executions
21:56mebaran151I'm gonna try to run the demos
22:01JonSmitherlang is a little slower distributed because of tcp connections and message passing and stuff
22:03hiredmanLordMetroid: sure, because everyone can seen it on the horizon, but clojure is targeted at it right now
22:03LordMetroidwell, it is running on the JVM so I wouldn't exactly say it is developed for multicore deployment
22:17mebaran151this ResultSet not open is beginning to annoy me to hell
22:26hiredmanLordMetroid: have you seen the specially built jvm boxes?
22:26LordMetroidhiredman: no, what do you mean?
22:26hiredmanazul
22:27hiredmanthe jvm can do multicore just fine
22:27LordMetroidI see
22:27mebaran151now I got inserts working, I just can't get queries to ... stay open
22:28LordMetroidokay time to get some sleep before the sun rises
22:28JonSmithyou have to do everything in the dosql right?
22:28JonSmithits like a transaction or something?
22:28JonSmithor am i wrong
22:29JonSmithjust kind of wondering
22:31hiredmanit's a macro he wrote
22:31JonSmithoh that isn't native to the library
22:32mebaran151I've tried it with run
22:32mebaran151and I get the same results
22:33mebaran151(doall (sql/run *conn-info* (sql/query users * (= username "mebaran"))))
22:33mebaran151this too fails
22:34mebaran151as with the doall in front for the query
22:34mebaran151this resultset refuses to stay open
22:34hiredmandid you look at the examples from clojurebot?
22:34mebaran151yep
22:34hiredmanwell, you must not have been paying attention :P
22:34JonSmith(sql/run *conn-info* (doall (sql/query users * (= username "mebaran"))))
22:34JonSmithdid you try that?
22:35mebaran151same beans
22:35hiredmanhttp://github.com/hiredman/clojurebot/blob/master/hiredman/triples.clj#L50 <-- what is different in this call to run?
22:35mebaran151{:jdbc-url "jdbc:derby:.gate/db;create=true", :username nil, :password nil} << mode string
22:35mebaran151ah ha
22:36JonSmithhiredman wrote it?
22:36mebaran151oh
22:36mebaran151I just have to bind it to something in scope
22:36mebaran151let's try this huzzah
22:36JonSmiththat's interesting
22:37JonSmithi guess its like a with-open macro
22:37mebaran151oh my
22:37mebaran151it worked
22:37mebaran151yay
22:38hiredmanit's rather distateful
22:38hiredmanit looks like a binding form, but isn't
22:38hiredmanif you just want to use the result seq you have to call doall everywhere
22:38hiredmanetc
22:39hiredmanthere was a blog post criticizing the use (abuse?) of syntax quote and unquote
22:40hiredmanbut it works, I guess, which is good...
22:40mebaran151I thought syntax quote was okay
22:40mebaran151it made me realize that it was quoting the sql
22:40mebaran151I read the post
22:43hiredmanI have a query api I was working on for the appengine datastore, which is much simpler than sql, but i think I did a nicer job of looking like clojure
22:43hiredman(qfilter (= 1 :count) (query :counter-things))
22:48mebaran151it looks almost rubyish
22:48mebaran151you have to check the result to be a seq
22:48mebaran151(defmacro dosql
22:48mebaran151 [& forms]
22:48mebaran151 `(sql/run [*conn-info* results#] ~@forms (if (seq? results#) (doall results#) results#)))
22:48mebaran151I think it should run somewhat like that
22:49mebaran151call doall for you
22:49hiredmananyway, we need scopes
22:50mebaran151I ran into this problem with my neo4j bindings (I want to close the resultset of nodes but I can't)
22:51mebaran151do scopes have to be built into clojure proper or could sufficiently advanced macro fu emulate them?
22:51hiredmanI have such a macro
22:51hiredmanhttp://github.com/hiredman/clojurebot/blob/master/hiredman/horizon.clj
22:52hiredman~scopes
22:52clojurebotI don't understand.
22:52hiredman~scope
22:52clojurebotscope is at http://paste.lisp.org/display/73838
22:54mebaran151but you'd have to stay within and explicit scoping construct
22:54mebaran151it seems like a more general with-open
22:54hiredmansure
22:54hiredmanexactly
22:55mebaran151I'd love to be able to give a lazy-seq to some caller, and then when they are done with it, have something like IDispose get called
22:55hiredmanthat is the idea behind scopes
22:56hiredmanif F produces a lazy seq one some resource that needs to be closed, it can register a thunk to do the closing
22:57hiredmanand then just return the lazy-seq and not worry about it
22:57mebaran151but you still have to act within the scope
22:57mebaran151as in the caller has to setup the scope right?
22:57hiredmansure
22:57mebaran151I would like a super finally
22:58mebaran151finally that gets called after a variable goes out of scope permanently
22:58hiredmanno variables
22:58hiredmannames bound to values
22:59hiredmanwhen a name goes out of scope
22:59mebaran151yeah
23:00mebaran151it seems like something I'd almost want a :post on functions to handle
23:00hiredmanbut the called function can't know what (or if) it's result will be bound to
23:00mebaran151yeah
23:00mebaran151I guess it's like transactions for refs: if you want to work with a construct, you have to be prepared to inform the construct where you're working with it
23:06mebaran151so I guess inside that scope you'd like say, read all the nodes you want, copy them to the outside scope space and get to close the iterator
23:35mebaran151couldn't a sufficiently smart compiler know?
23:35mebaran151when a name would no longer be applicable, and therein dispose of the resource
23:39hiredmanfor some subset of cases
23:40hiredmanit would have to be really really smart
23:43mebaran151this is true