#clojure logs

2012-01-24

01:18phil_is it possible to create cyclic maps in clojure? i.e. A <-> B <-> A?
01:24G0SUBphil_: yes. using deftype.
01:25muhoowatching the clojure data structures talk on blip.tv, he does (identical? "foo" "foo") and gets false
01:25muhoo&(identical? "foo" "foo")
01:25lazybot⇒ true
01:25muhoo!
01:25manuel_hi
01:25manuel_why does contains? return false on lists?
01:25G0SUBmuhoo: literal strings are interned.
01:25amalloy~contains?
01:25clojurebotExcuse me?
01:25amalloycontains?
01:25amalloydamn it, who erased him?
01:25manuel_(contains? '(1 2 3 4) 1) => false
01:25manuel_~(contains? '(1 2 3 4) 1)
01:25clojurebotIt's greek to me.
01:26G0SUBmanuel_: contains? checks for the presence of the key. it should only be used on associative data-structures.
01:26muhooG0SUB: yes, but my point is, he does something in his talk, it gets one result. i run the exact same thing in a repl, i get a different result
01:26G0SUBmuhoo: who?
01:26muhoorich hickey
01:26manuel_got it
01:26G0SUBmuhoo: which talk?
01:26manuel_misleading name
01:27manuel_common-lisp style
01:27muhooit's the clojure data structures intro talk
01:28G0SUBmuhoo: hmm. something like contains? on a list will be O(n). you really need a set for this job.
01:28muhooG0SUB: wrong dude
01:28muhooi think manuel was asking about contains
01:29G0SUBmuhoo: right. sorry.
01:29G0SUBmanuel_: ^^
01:29manuel_so what i'm looking for would be (some #(= 1 %) '( 1 2 3 4 5))
01:29G0SUBmanuel_: or (some #{1} '(1 2 3 4 5))
01:31manuel_uh how does that work?
01:32G0SUBmanuel_: sets work as functions as well.
01:32manuel_ah got it
01:32manuel_yeah thx
01:32manuel_sorry i'm coming from CL (mostly) so getting a bit confused by the orthogonality
01:33G0SUBmanuel_: true, the names & associated semantics can be confusing if you are used to CL.
01:33muhoohashes are like functions too. clojure is trippy, especially coming from lisp
01:33manuel_but to be honest if the immutable/concurrency thing doesn't throw me off too much
01:33G0SUBmuhoo: absolutely :-)
01:33manuel_i think i'm saying goodbye to CL
01:34manuel_i had the hashes thing down
01:34G0SUBmanuel_: I said goodbye to CL in 2009 itself ;-)
01:34manuel_heh
01:34manuel_it's just too cumbersome when you need to do real life stuff with it
01:34manuel_well for me anyway
01:34G0SUBI love CL implementations, especially SBCL & Clozure CL. the language, not so much.
01:34manuel_ccl is cool yeah, thank god that one came around
01:35manuel_language i don't know, i'm just used to it
01:35manuel_not that i've been programming CL professionally a lot during for the last years
01:36G0SUBmanuel_: honestly, I still believe that CL gives the programmer an incredible amount of power. not sure if that's a good thing though.
01:36manuel_computers give the programmer an incredible amount of power
01:37kedoodek"Unix gives you just enough rope to hang yourself"
01:37manuel_i'm going to the CL meetup tonight though
01:37manuel_hehe
01:42muhooi'm ready to blow off all other languages and start using clojure for everything.
01:42muhoolet's see if i can find a way to make money doing that though :-)
01:42schleyfoxmuhoo: do it
01:42manuel_the right tool for the right job
01:43schleyfoxI just had an analysis task I was running on some of the supporting things for my company's ruby on rails application
01:44clj_newb(defn pop [] ... ) <-- creates an warning; how can I turn off the warning? I have a class (ns my.stack) ... and I really want the function to be called pop, so I can use my.stack/pop my.stack/push
01:44schleyfoxI wrote an initial version in ruby, making use of the existing internal libraries we had for it
01:44clj_newb(defn pop [] ... ) <-- creates an warning; how can I turn off the warning? I have a class (ns my.stack) ... and I really want the function to be called pop, so I can use my.stack/pop my.stack/push (I',m not actualy implementing a stack; but the point is the overriding clojure.pop is on purpose; I just want to turn off the warning for this particular function)
01:45schleyfoxIt took 50 minutes to run in moderately optimized ruby (though the underlying library was to blame). I rewrote it in basically the same amount of code and it now finishes in under a minute
01:45schleyfox*rewrote it in clojure
01:45kedoodekwhat about the libraries?
01:45kedoodekdid you rewrite them in clojure as well?
01:45schleyfoxI switched to lower level java ones
01:46schleyfoxbut the analysis code + the shims to treat it like I did in ruby were equivalent to the ruby analysis code alone
01:47muhoonice
01:47manuel_is there a way to get line numbers in error messages in clojure-swank?
01:47manuel_in slime rather
01:48manuel_i always get messages like "don't know how to create iseq from symbol" but no indication as to what iseq
02:07scottjmanuel_: C-c C-k is the best way to get line numbers in errors
02:11muhoohuh. lots of interesting surprises
02:11muhoo&(conj [ 1 2 3] 7)
02:11lazybot⇒ [1 2 3 7]
02:12muhoo (conj '(1 2 3) 7)
02:12muhoo&(conj '(1 2 3) 7)
02:12lazybot⇒ (7 1 2 3)
02:12muhoo!
02:13muhoo&(cons 7 [1 2 3])
02:13lazybot⇒ (7 1 2 3)
02:13muhoo!!
02:14muhoothe idea of consing someting onto the head of a vector and having it return a list is an intersting surprise
02:15phil_cons returns a sequence
02:16phil_conj is overloaded for all types
02:16hiredmancons is not the traditional cons
02:16hiredmanit doesn't create pairs
02:16hiredman,(cons 1 2)
02:16clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
02:16hiredmanit just adds to the head of a seq
02:16phil_so conj on a vector appends to the end, conj on a list = cons
02:17hiredmannope
02:17hiredmancons is for seqs, not lists
02:17hiredman,(list? (cons 1 '()))
02:17clojurebotfalse
02:17hiredman,(seq? (cons 1 '()))
02:17clojurebottrue
02:18phil_yea, i said so
02:19phil_but more specifically, conj's return value type is always that of its argument, while cons always returns a seq
02:19phil_correct?
02:21amalloyphil_: in general that's true, but it's stricter than is technically correct: conj can return whatever type it likes so long as it's an IPersistentCollection and it "makes sense"
02:23brehauti kinda wish i had never taken on xml-rpc implementation as a project
02:23phil_amalloy: because every collection type defines its own conj, right? but is there a concrete example in the core data structures of conj returning an alternative type?
02:24hiredmanarray maps turn into hash maps if they have more than N keys
02:24schleyfoxbut that happens when they go over N=16 regardless of operation, I thought
02:24phil_ah good to know
02:24amalloy&(let [m (into {} (map vec (partition 2 (range 16))))] [(class m), (class (conj m [18 19] [20 21]))])
02:24lazybot⇒ [clojure.lang.PersistentArrayMap clojure.lang.PersistentHashMap]
02:25amalloyschleyfox: relevance?
02:26schleyfoxI suppose none
02:26schleyfoxjust curious about any conj specific variance
02:26amalloyalso not actually true, although it could be if anyone had bothered to implement it
02:27amalloy&(let [m (apply array-map (range 100))] ((juxt class count) (dissoc m 0)))
02:27lazybot⇒ [clojure.lang.PersistentArrayMap 49]
02:28schleyfoxcurious and curiouser
02:29amalloybut the difference between hash and array maps is one that you may as well pretend doesn't exist, in which case there are no "interesting" examples of conj changing type of the entity
02:30schleyfoxwhich is probably a good thing
02:33muhoobrehaut: why? is xmlrpc painful in clojure?
02:34brehautmuhoo: the spec is crap
02:35brehautif anything clojure makes it extremely clean inspite of the problems
02:36muhooi have to guess that the spec for xmlrpc has to be better than the one for json
02:36brehauthells no
02:36replacaI used xmlrpc from clojure and it wasm't too bad
02:37brehautreplaca: via necessary-evil or a java lib?
02:37replacathe worse prob is that I was talking to bugzilla which is written in perl so if something looks like a number it makes it a number
02:37replacajava lib
02:37emezeskehow could the xmlrpc spec possibly be better than the json spec? ^_^
02:38muhooreplaca: the apache sax?
02:38brehautreplaca: right. i've written a clojure / ring implementation of it
02:38replacaapache xmlrpc client
02:38replacabrehaut: to serve it?
02:39brehautreplaca: both
02:39replacaahh, cool
02:39brehautit uses clj-http for the client
02:40brehautreplaca: https://github.com/brehaut/necessary-evil
02:40replacayeah, this was old code
02:40schleyfoxbrehaut: good name
02:40replacaand it's been woking for over a year now, so I'm sure I'll leave it alone :)
02:41replacaespecially since we'll probably ditch bugzilla anyhow this year
02:42brehautreplaca: that seems to be the best idea with xmlrpc
02:44replacathe whole low-level part of it (that pulls bugzilla data into clojure data structures set up the way I want them) is maybe 70-100 lines
02:45replacamaybe 2% of the code in the program
02:47brehautfor comparison the entire necessary evil is 475 lines
02:48brehaut(client and server)
02:48replacayeah, that sounds about right
02:49replacaa bunch of my code is weird date conversion stuff and the like
02:49brehauthah yes
02:49brehautclj-time made life easier
02:49brehautonce i worked out how to encode the craziness
02:49unlinkWhat's the closest Clojure idiom for OOP? I'm looking to do something like (defn make-my-object [] (let [closed-over-field-a (ref []) other-closed-over-field (ref {})] (fn [param1 param2] method-body...)))
02:49replacaand bugzilla has other problems with time
02:50replacaand then making sure that things that should be strings really are strings (and not numbers)
02:50brehautunlink: err. the first major idiom is to stop writing OO like code
02:50phil_whats a shorter way for (swap! x (fn [_] y))?
02:50replacathat's a perl prob, though, but xmlprc lets it happen
02:50schleyfoxunlink: the closest (in the most literal sense) would be deftype
02:50unlinkbrehaut: Fair enough, but this time I really want it.
02:51brehautphil_: (swap! x (constantly y)) but its not actually shorter
02:51phil_brehaut: but clearer, thx
02:53brehautunlink: what is it you are trying to do. we cant make any suggestions with just what youve said
02:56unlinkbrehaut: I'm building an analysis platform which hosts generic, independent analysis workers which subscribe to and process real-time data feeds. That is the abstraction I'm structuring now -- enabling those workers to run, possibly with multiple instantiations, without sharing their private state
02:57schleyfoxunlink: looked at storm
02:57schleyfox?
02:59brehautschleyfox: maybe jumping the gun a bit there
02:59schleyfoxperhaps
02:59brehautunlink: ok. so you dont actually want data hiding as much as polymorphism right?
03:01unlinkbrehaut: No, I want both. Clojure functions and maps with (static) vars would be great except I need to run multiple instances of the same worker at once, and their state must be independent
03:02brehautunlink: independant state is different to encapsulation
03:02brehautwhat im asking is, are you doing the closure to hide the data or just to hold a ref?
03:02unlinktrue, I suppose that clojure's modules provide good enough encapsulation.
03:03brehautwhatever the case, id probably unify all the refs you have into a single map in a ref or atom
03:03brehautso that the data for the whole thing can be treated atomically
03:04brehautyou can use the *-in family of fns to manage it trivially anyway
03:04brehaut(update-in, get-in)
03:06brehauteg, (let [a (ref {}) b (ref {})] …) becomes (let [state (ref {:a {} :b {}))] …)
03:06unlinkright
03:06unlinkI'm more concerned with the closure itself, though.
03:06brehautwell its fine
03:07brehauti cant really suggest any more without knowing more about how you are structuring the rest of the program
03:08AimHereI see a line with lots of colons and empty curly braces and I immediately think of a fork bomb
03:35Blktgood day everyone
04:29noidihow can I println to stderr?
04:30noidiis there something handier than (binding [*out* *err*] (println ...))?
04:41CmdrDatsnoidi: (defmacro out-to-err [& body] `(binding [*out* *err] ~@body)) ?
04:42CmdrDatshaven't tested it, just wrote from the top of my head :P but then you should be able to just (out-to-err (println …))
04:42AWizzArdYou could also (.write ^java.io.PrintWriter *err* "Hallo Welt")
04:43AWizzArd(defn prerrntln [& args] (.write ^PrintWriter err (apply str args))) or something like that.
04:57tsdhAWizzArd: prerrntln, what a beautiful name. I'll call my first-born that way. ;-)
05:01clgvtsdh: try Atomfried for your first born ;)
05:03tsdh:-)
05:17noidiCmdrDats, AWizzArd: thanks. I only need stderr in one place so I'll just go with the binding, if there's no prerrntln (!) in clojure.core.
05:17clojurebotexcusez-moi
05:21AWizzArdnoidi: that is perfectly fine, it just is less efficient than calling “.write”.
06:16Dotan_hey guys, a long shot here - is there a guide showing "scheme to clojure" or anything close that someone familiar with scheme can use to boost up learning?
06:30Kototamahi, why does all my clojure files get compiled when building a WAR file with lein ring uberwar?
06:31Kototamait creates a class per function, isn't that expensive?
07:02tsdhKototama: Why do you think so?
07:16ArafangionKototama: Some languages create an *object* per function.
07:22raekKototama: clojure will create one class per (fn ...) expresion you eval. if you ahead of time compile your code, these classes will be stored in .class files
07:23raekhrm, that was not totally accurate
07:25raekbefore code is executed it's always compiled to jvm byte code
07:25raekand each (fn ...) expression is compiled as its own class
07:26raekwhen the code is evaluated (by running the compiled code) no new classes are created
08:03samaaronquick java question: when code creates a new object and assigns it to a private variable in the scope of a class, but not in any methods - how does that differ from not initialising the variable, and assigning to it in a constructor?
08:04TimMcKototama: You can prevent the AOT generation of classes in your uberwar, but it will just happen again at JIT compilation, on the fly.
08:06raeksamaaron: it is the same as assigning it from the constructor.
08:06dnolensamaaron: well, the latter has concurrency implications
08:07dnolenmain reason why deftype/record don't support constructors
08:07raeksamaaron: on the bytecode level, all initializations happen in a constructor (<init>) or in the static initializer (<clinit>) for static fields
08:09raekI assumed you were asking about what happens when you initialize a java field outside a constructor (syntactically)
08:10raekclass and instance fields are different from local variables on the byte code level
08:14samaaronraek: yes - the code i'm reading is initialising an instance field outside of a constructor
08:15samaaronso, you're saying that on compilation, these external initilisations are moved inside of the constructor?
08:22Kototamatsdh: i just though loading so many classes would not be efficient for the JVM. Maybe i'm wrong
08:24KototamaTimMc: how can I prevent aot when building a WAR?
08:24tsdhKototama: I don't think there's much difference between loading thousands of classes with only a handful of members and loading a handful of classes with thousands of members each.
08:33TimMcKototama: I wrote something to do this fo uber*j*ars, it could be expanded or imitated: https://github.com/timmc/lein-jit
08:34TimMcKototama: You can also modify your project to do this without any plugin help.
08:40fbru02hey guys i asked this at night, but couldn't figure it out I have sth like this : {"5" {"6" {"7" {"3" {:words {"close" 1}}}}}} I want to get to the {:words ...} hash what's the best way to do it ?
08:40compjget-in ?
08:41fbru02compj: fair enough but i don't know the sequence (i.e. 5 6 7 3)
08:45raeksamaaron: yes
08:45KototamaTimMc: you mean modifying the project.clj ?
08:46samaaronraek: thanks. I just managed to find this post which appears to explain this stuff pretty well: http://www.artima.com/designtechniques/initializationP.html
08:47TimMcKototama: Replace your core.clj with a loader.clj that calls it using clojure.main.
08:47TimMcKototama: look inside src/lein-jit or whatever.
08:48raekKototama: the alternatives are loading those classes from files (aot) or compiling these classes from clojure source (in memory) and then load them (non-aot)
08:48TimMcfbru02: You don't know the sequence statically, you mean?
08:49raekthis non-aot mode is sometimes called "jit compilation" which is a bit confusing IMHO, since there is already jit compilation on another level on the jvm
08:49TimMcWe should call it OTF, On-The-Fly
08:50raekmaybe the lein-jit plugin should be called lein-dont-force-aot
08:50TimMcyeah
08:50raekor the lein jit behavior could become the default
08:51fbru02TimMc: yeah
08:53TimMcfbru02: ##(let [path ["5" "6" "7" "3"] ds {"5" {"6" {"7" {"3" {:words {"close" 1}}}}}}] (get-in ds path))
08:53lazybot⇒ {:words {"close" 1}}
08:53TimMcget-in isn't a macro, you just pass it the path
08:53fbru02TimMc: will try that :)
08:53fbru02thanks
09:15smokecfhi'd like to browse through source code of a big clojure project -- any recommendations for that?
09:19joegalloany particular kind of project or library?
09:19joegalloi mean, if you're familiar with http & java servlets, then maybe ring would be a good place to start for instance. but if that's greek to you, then maybe it wouldn't.
09:21compjan idea how I can add quaqua to a leiningen project and only add it to the jar when on a mac?
09:22smokecfhjoegallo: anything big is fine, i'm especially interested in how well clojure scales when working in a team
09:23joegallosadly, the biggest clojure project i know is closed source, but i can assure it works great on our team ;)
09:24gtrak`smokecfh: probably similarly to lisp, I imagine it depends on the team
09:36kmicusmokecfh: can you explain what do you mean by "programming language scales by team size"?
09:39phil_how can i insert (not replace) an element at a specific location in a vector?
09:39phil_conj always add to the end, assoc replaces the element at the given index
09:40smokecfhkmicu: in my experience (with java and common lisp mostly), the more restraining a language is, the easier it is to work in a team. i would like to see that this premise is incorrect.
09:40phil_adds*
09:43dnolensmokecfh: Clojure much more restrained then Java or Common Lisp
09:45kmicusmokecfh: Personally I don't see any correlation, but if you want browse some code, then 'closurescript one' source code is relatively big and has many deps.
09:45compjphil_: don't think there is something in the std lib, try a combination of split-at and concat
09:46phil_compj: really? why is that operation deemed so rare that its not even in the std lib?
09:46dnolenfor the ClojureScripters, anything thoughts on this change? https://github.com/clojure/clojurescript/compare/115-internal-set-fields
09:47dnolenallows set! on deftype/record fields declared ^:mutable
09:47compjmaybe vectors aren't made for such use cases
09:48phil_dnolen: are you storing the mutables in the metadata?
09:48phil_compj: :/ the whole point of a vector is fast access to indexed elements imo
09:49phil_but ok ill think of something
09:49dnolenphil_: there is no reified metadata in CLJS, this is just at the level of the compiler
09:49dnolenphil_: set! actually always let's you set fields, but this seems kind of nice both as documentation and a bit of sugar
09:50clgvphil_: but inserting in a persistent vector implies concatenation of two vectors which is currently not possible with sharing structure of both vectors in clojure
09:50compjphil_: yes, access to a indexed element, but that has nothing to do with inserting an element I think
09:51clgvphil_: concatenation with the current vector implementation need O(n) with n being the element count of the second vector
09:51joegallomy impression is that if you want to do something that's not very efficient, then clojure doesn't go out of its way to make that easy
09:52joegallobut that's just an idle thought
09:52phil_clgv: ah i see
09:52dnolenjoegallo: phil_: phil bagwell presented a data strucuture at the Clojure/conj that can work with persistent vectors that allows efficient insertion, but no ones taken up the enhancement
09:53phil_clgv: will have to look again at the low level implementation to see exactly why but ill take your word for it :) well then this explains things
09:53joegallodnolen: yes, good point
09:54phil_dnolen: what does set! translate into on the js side? just a regular "a.x = y;"?
09:54dnolenphil_: yes
09:54dnolenphil_: the compiler does some enforcement tho, not allowed to set locals
09:55phil_can you tell me where exactly in the code this translation takes place? i was looking at the cljs compiler recently in order to understand how assoc works on defrecords and was able to only imply what is happening by looking at the generated js code
09:56dnolenphil_: compiler doesn't do anything for assoc, that's all in CLJS
10:00phil_dnolen: well this happens in emit-defrecord in clj/cljs/core.clj, isnt that part of the compiler?
10:03dnolenphil_: yes defrecord spits out default implementations for a variety of protocols
10:05phil_dnolen: and what you did with set! works on all types?
10:05dnolenphil_: any deftype and defrecord yes
10:07phil_so you modified the compiler to support (or allow set!) but defrecord/type are just macros on the cljs side that expand and use the underlying mechanisms provided by the compiler?
10:07phil_(sorry for the dumb questions)
10:09dnolenphil_: yes. set! is allowed in Clojure if you declare mutable fields. This doesn't currently work in CLJS and this brings things more in line.
10:11phil_dnolen: cool, when is this going into master?
10:13dnolenphil_: just making sure no one is totally offended by it, probably later today.
10:15phil_dnolen: this is perfect, was contemplating on dropping to js for some heavy object manipulation, this will hopefully allow me to stay fully in cljs
10:16dnolenphil_: note that you can always (set! (.-property foo) ...), it's just unidiomatic.
10:18phil_dnolen: ok, will have to dive into things a bit more
10:20dnolenphil_: I've been thinking about the heavy object manipulation problem in CLJS as well. I want to experiment with the notion of transients in CLJS.
10:22phil_dnolen: yes, this would certainly simplify things... right now, if you want to do animations with timers or something it wont be very fast (judging by the generated js code), especially on mobile devices
10:22phil_i made a simple assoc test in a 3-way three of height 5-6 and it took almost 2secs for 1000 asoocs
10:23phil_(well, assoc-ins)
10:23dnolenphil_: true tho animations in JS is quickly becoming an anti-pattern especially on mobile devices that support CSS Transitions
10:23phil_(with simple compilation)
10:24phil_dnolen: yep, css3 is the way to go but if you want older browser support then you have to drop to timers
10:25phil_and unfortunately right now ie8 user base is big enough :/
10:25lynaghkdnolen, speaking of animation do you have any idea why doseq is so slow in cljs?
10:25dnolenlynaghk: allocation overhead
10:25lynaghkI remember chris granger throwing together a gist with some examples. I've found that it's something like 200 times slower than JS
10:26dnolenlynaghk: seqs just don't rock nearly as hard in JS as they do on the JVM
10:26lynaghkDo you have any nice tricks to get around that?
10:26dnolenlynaghk: for high perf JS code I think you'll want to write the critical bits with loop recur, dotimes, and mutable arrays/objects
10:26dnolensame as Clojure really.
10:27lynaghkokay, I'll look into that
10:27lynaghkI was under the impression that doseq is just some sugar on something like loop recur
10:27lynaghkthough that's just because I daydream a lot.
10:27vimjaI'm trying to use a defrecord in another namespace; I've use'd the relevant namespace (test.my-record) and imported the class (test.my-record.Foo) but I can't figure out how to access the record. Any suggestions?
10:28dnolenlynaghk: I'm porting the Processing flocking animation from Clojure to CLJS, a benchmark for this stuff.
10:28dnolena good benchmark I mean
10:29phil_dnolen: is the code public? would like to take a look at high perf cljs code
10:29dnolenphil_: it will be, got some work to do yet.
10:29phil_thx
10:30lynaghkdnolen: yeah, that sounds great. I'd love to take a look at that to optimize my cljs visualization library
10:30phil_lynaghk: is your code public? :)
10:31lynaghkdnolen: also, if you want to use Cassowary there is a chromium guy who is also doing a JavaScript port focused on speed
10:31lynaghkdnolen: https://github.com/slightlyoff/cassowary-js-refactor
10:31dnolencool!
10:32lynaghkyeah, apparently at the same time as I released mine. December was the dig-out-old-simplex-solvers month
10:32lynaghkphil_: it's not yet, but it will be released by March (in time for my Clojure/West talk)
10:33phil_lynaghk: allright, thx
10:33lynaghkphil_: it's basically a rewrite of D3 in ClojureScript that is more declarative and takes advantage of Clojure's semantics to do neat things. For instance, if you pass it data inside of an atom, it will update the DOM whenever the atom changes.
10:33dnolenlynaghk: slick!
10:34lynaghkAlso, not tied to the DOM, so you can run it on the server. Or teh iPadz.
10:34phil_lynaghk: sounds cool, would love to take a look when its public
10:35lynaghkyeah, speaking of it I should probably get to work. Clients need their charts & graphs = )
10:36phil_haha, dito :D
10:37pandeirolynaghk: that is very cool re: using atom watchers to update DOM... one of Clojure's very webapp-friendly features IMO
10:39lynaghkpandeiro: yeah, it's one of those things that's, "oh, I could've made this in JS with an object with getters & setters and callbacks" but you just never got around to it
10:39lynaghkA lot of ClojureScript kind of feels like that, and it really adds up to a nicer experience.
10:39lynaghkThat there are all these neat things laying around for you to use already
10:40phil_is there a more idiomatic way of doing this: https://gist.github.com/1670753 i.e. a zipper changing global state whenever it is updated
10:41phil_like using core.zip or something
10:45phil_im basically trying to have an immutable global tree with the addition that every node can update its children (and thus the global tree) without having to know where exactly it is located in the tree
11:25blcooleyIs anyone successfully using SLIME apropos with clojure-jack-in?
11:25jebberjeb#away
11:25jebberjebuh, sorry
11:26blcooleyI can use the other SLIME documentation commands (C-c C-d d) but apropos gives me an assert error on descriptor
11:34compjblcooley: apropos works here
11:35blcooleycompj:ok, thanks. probably just something in my setup I guess.
11:35compjdo you have clojure swank 1.4.0 snapshot?
11:36compji think there were some commits recently
11:37compjhere this might be the difference https://github.com/technomancy/swank-clojure/commit/8637ccfec5fbfb85bf418f9be54465edb86699e5
11:38blcooleycompj: aha, that's probably it. Thank you very much. Updating now.
11:38compjno problem :)
11:45blcooleycompj: That did the trick. Thanks again.
11:46compjlet's thank tavisrudd for the fix
11:46blcooleyIndeed!
11:51tavisblcooley: it was just fixed yesterday
11:51compjhas anyone else the buffer name *slime-repl nil* instead of *slime-repl clojure* in emacs?
11:51stuartsierracompj: yes
11:52tavisyep, also just fixed yesterday: https://github.com/technomancy/clojure-mode/pull/62
11:52tavisthe fix is in there waiting to be pulled
11:52stuartsierracool, thanks tavis
11:53compjI dived into the *slime-repl nil* problem for a while and I think I have a solution
11:53tavisanother bug fix introduced it so hopefully I haven't reintroduced it
11:53jonasenAnyone been able to use goog.dom.query with ClojureScript? It's included in the closure zip file that the bootstrap script downloads.. But I don't know how to require it
11:53blcooleytavis: Thanks! Really helpful!
11:53tavisit's jack-in calling (slime-output-buffer) before the connection is open
11:54jonasenIt's in the third_party folder
11:54compjhttps://github.com/technomancy/swank-clojure/blob/master/src/swank/payload/slime.el#L2058
11:54philjonasen: look at the samples, i thinnk they use that
11:54compjI changed this handle to be synchron and it worked
11:55compjalthough the comment says you shouldn't
11:56jonasenphil: I've only seen goog.dom used in the samples and not goog.dom.query. I'll have to take another look
11:57taviscompj: btw, were you having the nil issue prior to last summer? If so, it's not caused by what I thought.
11:57compjmh can't say, using it since september
11:59taviswell, fingers crossed. Good to know there's another way around it if my fix doesn't solve it for everyone.
11:59compjthe implementation name seems to be set too late. the buffer gets created before the result from the connection-info request are there
11:59tavisexactly
11:59tavisclojure-jack-in was doing something too early
12:48tavisdoes clojure.contrib.profile have a new 1.3 home?
13:00philare there any vids available from the last clojure/conj?
13:05TimMctavis: Is it not listed on the contrib migration page?
13:06TimMc~clojure.contrib
13:06clojurebotexcusez-moi
13:06TimMcclojurebot: Where did contrib go?
13:06clojurebotwell... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
13:07TimMctavis: Oh, looks like it's listed, but has no home in 1.3.
13:09tavisdo you know of any good simple alternatives that would work well from a repl?
13:10tavisaside from `time`
13:30jsabeaudryIs there a way to have some kind of redirect in a clojure web application that will be transparent to the client?
13:32jsabeaudryLet me take a step back
13:34jsabeaudryI am hosting a web application on limited hardware. One of my http handlers is returning a binary stream but clojure is too slow to do the work. What I thought is that I could run a C server that does the work and my clojure webapp would just be a kind of proxy for that particular handler
13:34jsabeaudryAm I dreaming or is that feasible?
13:34gtrak``jsabeaudry: what's the source of the stream?
13:35Tweyjsabeaudry: Is this binary stream static?
13:35jsabeaudrygtrak``, A FPGA but some processing is required on the stream
13:35gtrak``if it's a file, you can mmap it
13:35gtrak``fun
13:36gtrak``jsabeaudry: so, how do you get the data for the stream?
13:36TimMcjsabeaudry: Your web server itself can run a reverse proxy that delegates as necessary.
13:36muhoodepends on how the device driver is implemented, i suppose
13:37jsabeaudrygtrak``, Most probably a non-seekable character device
13:38jsabeaudryTimMc, What would be a good lib for reverse proxying in clojure?
13:38gtrak``ah, so if you can't mmap, you'll have to buffer, but I guess you already know that? is that avoidable in C?
13:39muhoothere's a java trick to turn a char device into a filestream
13:39muhooprobably would work in clojure too
13:39gtrak``if it works in java, it works in clojure
13:40jsabeaudrymuhoo, Yes but I also need to do some processing on it
13:40gtrak``what kind of processing?
13:40muhooi did this recently in java
13:40jsabeaudrymuhoo, That is what causes the problem, because clojure/jvm is too slow
13:40muhooi used a FileInputStream
13:40muhooread from that, then sent it out a FileOutputStream
13:40jsabeaudrygtrak``, signal processing,
13:41gtrak``right, i figured as much
13:41sridnon-clojure question, but I figured people here may have some idea: is redis appropriate for storing a stream of real-time events (eg: from log files on many servers; think heroku pulse)? or is there something else that is more appropriate?
13:41muhooi had to write a jni ttyserial.c to do it
13:41muhoo(this was on android platform)
13:41muhooit was a PITA
13:42gtrak``jsabeaudry: well, if you're doing some algorithmic stuff, sounds like you'll want to optimize for your processor, you could also look into JNI or JNA for a C to java bridge
13:42muhoo+1 jni
13:42muhooah
13:42clojurebotHuh?
13:43gtrak``jsabeaudry: there are ways to share data to C without copying
13:43tavisjsabeaudry: are you doing any post processing on the clojure side?
13:43jsabeaudrytavis, I don't plan too
13:43gtrak``without knowing much about your design, imo, I'd keep everything I can in java, like web stuff
13:43gtrak``by java I mean clojure
13:44tavisdo you have another webserver sitting in front of your jvm?
13:44jsabeaudryI guess I'll go with TimMc's suggesting of running a reverse proxy on the server
13:44muhooeasier
13:45jsabeaudrytavis, No
13:46gtrak``jsabeaudry: interesting to me b/c in a past life I studied DSP/compArch :-)
13:46muhooso, "slow" in the sense of latency?
13:47muhooin that case, http redirect, let the browser talk directly to the stream, less stuff in the way.
13:47jsabeaudrymuhoo, No, too slow in terms of CPU usage
13:49gtrak``jsabeaudry: in general, unless you're writing vector code with custom simd stuff, java can be faster
13:50jsabeaudrygtrak``, Basically we are doing an instrument, the UI is web-based, runs on an arm7a platform the size of a credit card, some of the DSP is done on an FPGA and some on the arm. Lot's of fun stuff if you ask me.
13:50gtrak``or trying to take advantage of mem alignment, cache stuff, etc..
13:50gtrak``ah, arm
13:50gtrak``yea, I think on arm java the tradeoffs are different
13:51gtrak``actually never looked into it deeply, what about the jazelle stuff?
13:52jsabeaudrygtrak``, I checked quickly but it seems the architecture we are running on is not supporting it
13:53jsabeaudryIn all cases, it's not a big deal to have some stuff running in C
13:53jsabeaudryAll the drivers are written in C anyways
13:53gtrak``yea, so you want avoid writing web code in C
13:53jsabeaudryExactly
13:54jsabeaudryJust that one handler will be in C and its just an application/octet-stream so no web stuff really
13:54TimMcSo you just need to proxy data from C out across a binary HTTP response?
13:55gtrak``you have choices, if JNI works, use that, or you can use some kind of IPC, pipes, streams, sockets, etc... not sure how hard http would be in C
13:55jsabeaudryTimMc, Yes pretty much
13:56TimMcthen it's probably easier to proxy from Clojure than accept a web request from C
13:56muhoonet socket is probably a LOT easier than jni
13:57gtrak``proxying a http request sounds wasteful to me, sockets would be trimmer
13:57muhooif the c thing speaks tcp, probably easier to shovel bytes to cloujre via a net socket, then from clojure out to the browser, than to go dicking around with jni and opening char devices
13:59emezeskeIs it possible to access unix domain sockets from Java? Those are always nice for efficient local proxies (and very simple from C).
13:59muhooah
13:59muhoohttp://nakkaya.com/2010/06/15/clojure-io-cookbook/
13:59tavisdo you have access to unix domain sockets? If so you could do the initial request handling on the clj side and then sendmsg to pass the client socket off to c
13:59muhooso, there's the socket way, and the file way, both in clojure :-)
14:00gtrak``awesome that you get to write clojure code on an arm, btw :-)
14:01gtrak``there's this: http://code.google.com/p/junixsocket/
14:02gtrak``apparently to use unix sockets you need native code
14:02gtrak``tcp sockets I guess you don't
14:02muhoogtrak``: jsabeaudry: http://nakkaya.com/2010/06/15/clojure-io-cookbook/
14:03gtrak``muhoo: yea, I saw that, unix sockets are different
14:07muhooooh neat, there's some clojure sugar around the ugly java file io http://richhickey.github.com/clojure/clojure.java.io-api.html
14:07lazybotNooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/clojure.java.io-api.html and try to stop linking to rich's repo.
14:07gtrak``$botsnack
14:07lazybotgtrak``: Thanks! Om nom nom!!
14:09muhoohm, google disagrees with the bot
14:11TimMcGoogle can suck my keyboard.
14:11TimMcI'm so done with them. </rant>
14:12TimMcmuhoo: What really needs to happen is that site should be replaced by redirects. I think replaca is the one who can do that.
14:14gtrak``it's been talked about a lot
14:14gtrak``every page that someone can link to needs to be replaced by a redirect?
14:15TimMcright
14:15TimMcIt can be done with a META refresh or maybe some JS.
14:20raekrefresh and js solutions do not preserve the "referer" header
14:20raekin case you want that data in google analytics, for example
14:22TimMcWell, you could still get origin information off the original repo.
14:23TimMcI'm not sure I can bring myself to care about "page stickiness ranked by origin" or other such abominations of analytics.
14:25amalloyjsabeaudry: is there a reason you can't just use nginx or some similar webserver to bypass the clojure app entirely in cases where you'd have it proxy to C?
14:27RaynesTimMc: I found that putting nude images of amalloy up on refheap took traffic away from the main content, thus not helping the cause at all.
14:27TimMcRaynes: I thought that was an iguana. :-P
14:28amalloyhahaha
14:28TimMcamalloy: That would require responding to HTTP in C.
14:30jsabeaudryamalloy, probably not, it is one of the possibility but I wonder if that might have some impact with regards to authentification
14:31muhoois this thing linux on this arm?
14:31muhoojust run lighthttpd or any of the many arm/busybox http daemons, i.e. for openwrt
14:32muhooiirc there is even an httpserver applet built into busybox
14:34bhenry&(doc if-let)
14:34lazybot⇒ "Macro ([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"
14:39jsabeaudrymuhoo, And run clojure as fastcgi?
14:41tavisjsabeaudry: the fd descriptor passing over AF_UNIX sockets approach I mentioned won't work in java: http://lifecs.likai.org/2010/05/passing-file-descriptor-over-unix.html
14:45replacaTimMc: so it turns out that github pages (which is what we use for the docs) doesn't support redirects
14:45brehautreplaca: you could use an html meta equiv
14:45brehaut(not ideal though)
14:45replacabrehaut: I looked at that a while back and decided it would be better to just edit that pages
14:46replacahaven't gotten to it yet though :(
14:46brehautreplaca: i'd probably do both :(
14:46replacayeah, I might
14:46brehautsearch engines at least will respect the header
14:46replacathat would be a bonus
14:48replacawhat I've really been waiting for is for github to support redirects, but I need to bother them more and maybe buy them some beer :)
15:02the-kennyWhat's the best way to stay updated on ClojureScript-Development? Like breaking changes etc.
15:03stuartsierraclojure-dev
15:03TimMc^ the mailing list
15:04the-kennyHm, okay
15:04the-kennyThanks :)
15:05stuartsierraalso just watch Git and read the commits
15:07Raynes$ git log
15:15amalloyRaynes: i think your shell is in another buffer
15:15TimMcSorry, Mario.
15:16Raynesamalloy: I was responding to the-kenny, but yes, it is definitely elsewhere.
15:16the-kenny:D
15:45sritchiedo you guys know how to add other repositories to leiningen's list when searching for plugins?
15:45sritchietechnomancy: this might be for you
15:46Raynessritchie: Edit your hosts file. ;P
15:46joegallohttps://github.com/technomancy/leiningen/blob/master/sample.project.clj#L106
15:46joegalloi think
15:46sritchiejoegallo: this is for plugins, so it works outside of projects
15:47sritchieRaynes: is that in ~/.m2?
15:47joegallooh, my bad
15:47joegalloprobably some magic init.clj then, but i dunno
15:47sritchieRaynes: I don't know where to look for the file that sets up central and clojars
15:47Raynessritchie: It was a bad joke. I was talking about http://en.wikipedia.org/wiki/Hosts_(file)
15:48sritchienice, I'll just redirect clojars over and call it a day
15:48RaynesHeh
15:48RaynesBut that is a good question.
15:49RaynesThe plugin system is just a bizarre way to avoid a global project, it seems.
15:49RaynesBut what do I know?
15:52technomancysritchie: that's something we'll have a better answer for in lein2
15:52sritchiethis is for an internal twitter lein plugin
15:52sritchieso for now i should just have people install it manually?
15:52rlbtechnomancy: btw, happy to see you're working on lein for debian.
15:53technomancyrlb: that's mostly bablien
15:53sritchietechnomancy: I'll have folks git clone and lein install
15:53technomancysritchie: user-level repositories are basically build-poison in most cases
15:53rlbtechnomancy: ok, still happy ;>
15:53technomancy#1 cause of works-on-my-machine
15:54sritchieI agree
15:54sritchiewhat do you think I should do here?
15:54technomancybut this is a special case
15:54sritchiefor distributing a private plugin
15:54sritchiey
15:54sritchieeah
15:54technomancyI need to head off; can you start a mailing list thread?
15:54samaaronwhat's the simplest approach to compiling a nested set of dirs with .java files in?
15:54TimMcjavac
15:55samaaronTimMc: can i just pass a root dir to javac?
15:55TimMc* poker face*
15:55RaynesTimMc: You can use Leiningen.
15:55RaynesBut you're not samaaron.
15:55RaynesAnd I need to get more sleep.
15:55samaaronRaynes: i moved from javac to lein
15:55samaaronbut lein javac just created me an empty classes dir
15:56Raynessamaaron: Could you tell me about your project setup?
15:56samaaronmy problem is that i don't know what's going on under the hood here
15:56RaynesI probably do. So start talking.
15:56samaaronRaynes: well, i have a dir with other dirs in
15:56samaaronand in some of the other dirs are java files
15:56Raynessrc/
15:56Raynes?
15:56samaaronyup
15:56samaaroni'm assuming it's standard java layout
15:56samaaronwith a dir per package
15:57RaynesSo, there is no Clojure stuff at all?
15:57samaaronnot yet ;-)
15:57RaynesIn your project.clj, set :java-source-path to "src"
15:57samaaronah, i'd set :java-source to "src"
15:57RaynesIf you end up mixing clj files and Java files in the same source path, you'll need to use the latest 1.x branch of Leiningen because I fixed some issues with that there.
15:58samaaronRaynes: ah cool, thanks for the heads up
15:59samaaronis there a simple way of adding an extra lib dir with jar deps?
16:00samaaronnot all the deps to this project are in maven...
16:07jeremyheilersamaaron: could you install the jars into a local maven repo? or do you simply want them distributed with the project?
16:08samaaronjeremyheiler: eventually they'll go in a local maven repo - but just to bootstrap things it might be easier to bundle the jars with the src
16:08technomancysamaaron: if it's not in a repository it's not a real dependency
16:08samaarontechnomancy: i don't quite understand the sentiment of that statemnt
16:09samaaronhow can you have a non-real dependency?
16:09technomancythat would be a "works by accident" situation, I guess
16:09samaaroncurrently the jars are stored in the project's repo
16:09samaaronwhich isn't ideal
16:10samaaronbut not all of those jars are available in maven - I assume they're bespoke libs
16:11samaaronso i thought it a good start to separate the maven libs from the bespoke libs until we get a local maven repo set up
16:11technomancysamaaron: have you tried the private-s3-wagon?
16:11samaarontechnomancy: no - i haven't heard of it
16:11technomancyit's pretty easy to set up a private repo now: https://github.com/technomancy/s3-wagon-private
16:11Raynestechnomancy -- makin' hard stuff easy and easy stuff avoidable.
16:12technomancy(the plugin-ness of it will be more streamlined in 1.7.0)
16:12samaaronsure, but this isn't a personal project
16:12technomancysamaaron: meaning you currently don't have a corporate aws account?
16:13samaaronmeaning i'm sure i'm not allowed to stick these jars on non-uni servers
16:13samaaronand i also know that they're working on deploying a local maven repo
16:13samaaronso i was just thinking of something that works for now
16:14samaaroni.e. have a non-maven-lib with non maven jars
16:14samaaronwhich would also be in the classpath
16:14technomancyit can be done, but it's strongly discouraged
16:14samaaronuntil those libs are available in a local maven repo
16:14technomancyyou can specify file:// URLs in :repositories
16:14technomancyas a temporary measure
16:15samaarontechnomancy: what's the motivation for strongly discouraging the practice?
16:15technomancysamaaron: git is absolutely wretched at storing binary files
16:15samaaronyeah, that's very true
16:15technomancyit's just the wrong place for artifacts
16:15weavejestertechnomancy: Is the lein-survey yours?
16:15technomancybut if you're working around bureaucratic policies then I have some sympathy =)
16:15technomancyweavejester: aye; hope to have the results summarized within a week
16:16samaarontechnomancy: well, it's only a short-term solution - I'll be rebuilding it all in Clojure anyway
16:16technomancysamaaron: just be aware you may want to rewrite that stuff out of your history down the line if you continue to use that same git repo
16:16weavejestertechnomancy: Your shell command for finding most-used subcommands has a bug
16:16weavejestertechnomancy: It strips out commands in the 100s and 10s
16:17technomancysamaaron: I saw a project using jars-in-git that had just switched to git 3 months ago and had already bloated the repo size up to 300MB
16:17samaarontechnomancy: understood
16:17technomancyweavejester: yeah, it's fairly flawed. if you have multiple shells open you can't really trust your history.
16:17technomancyweavejester: plus it doesn't work with zsh
16:17technomancytaking it with a huge grain of salt
16:17weavejestertechnomancy: It worked okay with my zsh
16:18weavejestertechnomancy: Well, except for removing the first 4 lines, but that was egrep
16:18technomancyheh
16:20TimMcI still don't understand how history interacts with multiple shells.
16:20samaaronis there a difference between Sun JDK and Open JDK libs? javac is crying about not being able to find javax.servlet.http.HttpServletRequest
16:20TimMcI think sometimes they get reused, too...
16:21jeremyheilersamaaron: HttpServlerRequest is in java ee
16:21amalloyTimMc: it's just a total mess. i don't trust it at all
16:21jeremyheilerso, not part of the std dist
16:21SomelauwWhy even have the difference between sun and open jdk? It's just confusing anyway.
16:21samaaronjeremyheiler: I thought ee was just some marketing hype
16:21geoffeg_camolly: http://stackoverflow.com/questions/8992997/initializing-elements-of-a-map-conditionally-in-clojure you put the let around the defn? does that make the fn scoped inside the let? :)
16:21samaaronis it an extension to the JDK libs?
16:21TimMcSomelauw: Sun (well, Oracle) is being a bastard about licensing right now. I'm glad to have the OpenJDK.
16:21jeremyheilersamaaron: it's a separate lib, yes.
16:22TimMcAlso, I think at v1.7, OpenJDK is the reference impl
16:22jeremyheilerwell, it's mutltipe separate libs...
16:22samaaronjeremyheiler: separate lib as in apt-get java-ee or a maven dep?
16:22jeremyheilersamaaron: you want servlet-api.jar
16:22jeremyheilermaven dep
16:22samaaronnice
16:22amalloyi don't think i understand either the question there, geoffeg_c
16:22TimMcgeoffeg_c: No, it just means the defn seems some locals no one else does.
16:22TimMc*sees
16:23samaarontechnomancy: thank you so much for lein search :-)
16:23technomancysamaaron: yeah once I wrote that I wondered why I had taken so long =)
16:23geoffeg_chmm, nice.. i guess :)
16:24samaaronhmm, so the question now is which version of the servlet-api to go for...
16:24jeremyheilerwhat servlet container are you deploying to?
16:24samaaronjeremyheiler: is tomcat a servlet container?
16:25TimMcgeoffeg_c: Do you *need* to know users' gender? At least allow an :unspecified.
16:25jeremyheilerusually you mark "servlet-api" as a compile time dep, and thenuse the servlet-api.jar bundled with tomcat (in your case) be used at runtime.
16:26samaaronjeremyheiler: sounds swanky, but i'm not sure what you mean by marking as a compile time dep
16:26cemerickjeremyheiler: you mean "provided"
16:26jeremyheilercemerick: yes, my bad
16:26samaaronperhaps i'm doing totally the wrong thing, but i'm currently attempting to compile my java code so tomcat can run it
16:26samaaronbut i'm really shooting in the pitch black darkness with all this
16:27jeremyheilersamaaron: you're on the right track. The problem is that you need servlet-api.jar to compile, but your servlet container (this case tomcat) provides one for you, so you don't need to distrubute your war with the servlet-api.
16:27cemericksamaaron: If you're using ring, you don't need to worry about it; it already depends on servlet-api transitively.
16:27samaaroncemerick: i will be using ring in the rewrite
16:27samaaronbut right now i just need to get this old java fecker working and fix some bugs
16:28samaaronjeremyheiler: so do i need to compile with the same servlet-api that ships with tomcat?
16:29mattmitchellwhat's the best way to turn a collection into a hash-map, where the key is the index of the item in the collection?
16:29jeremyheilersamaaron: the same version, es.
16:29jeremyheileryes*
16:29samaaronalso, i see no evidence of war on the server
16:29samaaronit just seems that the compiled libs are put in a tomcat-friendly dir structure where tomcat knows where to look
16:30the-kennymattmitchell: (into {} (map-indexed identity seq)) or something like that
16:30amalloymattmitchell: map-indexed vector?
16:30samaaronWAR.. HUH! What is it good for?
16:30jeremyheilerif you put a war file into the "webapps" directory, then tomcat will auto deploy it aka, unpackage it.
16:30amalloy&(into {} (map-indexed vector '[a b c d e]))
16:30lazybot⇒ {0 a, 1 b, 2 c, 3 d, 4 e}
16:30the-kenny&(into {} (map-indexed identity '[a b c d e]))
16:30lazybotclojure.lang.ArityException: Wrong number of args (2) passed to: core$identity
16:30mattmitchellahh map-indexed! thanks
16:30samaaronjeremyheiler: sounds a bit pointless - unless i want to email the whole thing or somethign
16:30the-kennyGnah :/
16:30technomancysamaaron: the only thing harder than resisting making jokes about .war files is resisting making jokes about .ear files.
16:31jeremyheilersamaaron: it makes remote deployment easier.
16:32m0smithhi all
16:32mfex&(zipmap (range) [:a :b :c :d]) mattmitchell
16:32lazybot⇒ {3 :d, 2 :c, 1 :b, 0 :a}
16:32m0smithhas anyone done any work in using Clojure within a JSP? maybe a taglib?
16:32the-kennyAh, that's nice too
16:32mattmitchellmfex oh that's nice!
16:33TimMcm0smith: I was trying that out at work, but Enlive has terrible documentation.
16:33Somelauw,(into {} (keep-indexed vector [:a :b :c :d])) ; Wait that is actually longer
16:33clojurebot{0 :a, 1 :b, 2 :c, 3 :d}
16:34TimMcI'll probably give it another shot in a month or so.
16:35RaynesI've tried to read Enlive docs/tutorials, but I mostly just get a headache and forget about it.
16:35Somelauwand has already been poste
16:35RaynesNot sure how I feel about a templating tool where it is appropriate to spend half a tutorial talking about scraping a website with it.
16:36m0smithThanks TimMC
16:37m0smithI am really more interested in having HTML with tags. or clojure scriptlets or some such
16:37m0smithNot too interested in re-inventing that wheel
16:37brehautRaynes: its definately worth pushing through the headache
16:37Raynesbrehaut: Well, I expect someone will write something about it that isn't insane at some point. I'll definitely start paying attention then.
16:38brehautRaynes: noted
16:38technomancybrehaut: yes, but that forces everyone else who might help in the future to go through the same headache =)
16:39brehauttechnomancy: sadly true
16:39technomancyevery time I start a new project I intend to try enlive, spend a few minutes looking at docs, and go back to hiccup.
16:39brehautfwiw cemerick et al's book has a brief but clear introduction to enlive
16:39technomancyI'm strongly biased towards self-evident code.
16:39cemerickI've never quite understood the grumbling about enlive. If you know CSS…
16:40cemerickbrehaut: much expanded, actually.
16:40brehautcemerick: oh, fantastic!
16:40cemerickThe whole rough cuts thing never worked out so well. What's up there is probably 6 months old.
16:40RaynesMy book will have a much better cover than his.
16:40RaynesWhich makes it a better book by far.
16:40technomancycemerick: it's not the selectors; it's the transformation macros
16:40cemerick…and less than half the content.
16:40brehautcemerick: how much XSLT had you done before enlive?
16:41brehautcemerick: oh wow, that is very stale
16:41cemericktechnomancy: it's (nearly) all function-based at this point.
16:41cemerickbrehaut: too, too much
16:41brehautoh yeah, it used to be heavily macro voodoo right?
16:42cemerickYeah
16:42technomancycemerick: in that case it's the out-of-date examples and docs I guess
16:42brehautcemerick: i think of enlive as xslt done right rather than php done better
16:42cemerickit was the migration from that to where it is today that prompted cgrand's macro talk at the first conj
16:43brehauttechnomancy: i think the biggest impedance to getting the hang of enlive at the moment is starting off with deftemplate
16:44cemerickbrehaut: what, as in, where to put the template files?
16:44brehautcemerick: partly, but also that its structured doc -> seq of strings
16:44brehautrather than structured -> structred
16:44brehautsorry about the typos
16:45cemerickwell, that's the *last* step, not the first
16:45brehautright, but if you go in thinking 'i want to template some stuff' its easy to get off on the wrong foot with it and make your life much harder than it needs to be
16:46TimMccemerick: There's still a carpload (not correcting that typo) of macros, and no docs on them indicating how they should be used.
16:46TimMcIt's all macro-source-reading.
16:48brehauttheres only 14 macros?
16:48brehautto several hundred functions
16:49brehaut13 if you dont count sniptest
16:49cemerickTimMc: I don't think that's true on either count.
16:49TimMccemerick: It was several months ago, last time I tried it.
16:50TimMc"does foo" is not sufficient doc -- "takes a fn and produces a transformer which does foo" is much better
16:50brehautTimMc: have you seen brian maricks tutorial in the wiki?
16:51brehauthttps://github.com/cgrand/enlive/wiki/Table-and-Layout-Tutorial%2C-Part-1%3A-The-Goal
16:51TimMcYeah, I couldn't get through it.
16:53brehauti presume that goes doubly for dnolans tutorial then?
16:53brehauts/ans/ens/
16:53pandeiroi found dnolen's easier to 'get into'... but then i didn't use enlive on anything afterwards and have forgotten everything already
16:54TimMcWhich is that?
16:54brehauthttps://github.com/swannodette/enlive-tutorial/
16:56TimMcThat was better, once I skipped past the scraping.
17:05ordnungswidrigis there a way to know if read encountered an eof in the middle of a form?
17:06ordnungswidrigI mean "[1 2 3]" vs. "[1 2"
17:06brehaut,(read-string "(inc 1")
17:06clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:06SomelauwThat is a very generic error to catch
17:07brehauthas a fairly boring consistent string though
17:07RaynesYou can catch it and check the message.
17:07RaynesIf the message isn't right, rethrow.
17:07Somelauw,(read-string "1/0")
17:07pjstadigor just don't catch it and see what magic happens
17:07clojurebot#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
17:07hiredmanif you get the cause it's a lispreaderexception
17:07RaynesThere ya go.
17:08Somelauw&(instanceMember (ArithmeticException. "") RuntimeException)
17:08lazybotjava.lang.RuntimeException: Unable to resolve symbol: instanceMember in this context
17:08ordnungswidrig,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a 1"))] (read r) (read r))
17:08clojurebot1
17:09ordnungswidrig(let [r (new java.io.PushbackReader (new java.io.StringReader ":a ["))] (read r) (read r))
17:09TimMcordnungswidrig: You might check to see how the REPL handles this.
17:09Somelauw&(instance? (ArithmeticException. "") RuntimeException)
17:09lazybotjava.lang.ClassCastException: java.lang.ArithmeticException cannot be cast to java.lang.Class
17:09TimMcsince it knows when a form is complete.
17:09ordnungswidrig,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a ["))] (read r) (read r))
17:09clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:09ordnungswidrig,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a"))] (read r) (read r))
17:09clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:09Somelauw&(instance? RuntimeException (ArithmeticException. "")) ; Sorry, I am not that good at writing working code
17:09lazybot⇒ true
17:10m0smith,( + 2 3 4)
17:10clojurebot9
17:10SomelauwBut I made my point
17:10m0smith&(+ 1 2 3)
17:10lazybot⇒ 6
17:10Licenserordnungswidrig use the reader eof parameter
17:10Licenser&(doc read)
17:10lazybot⇒ "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ."
17:10TimMcm0smith: You can /msg lazybot for that too,
17:11Licenser,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a"))] (read r false :eof))
17:11clojurebot:a
17:11Licenser,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a ["))] (read r false :eof))
17:11clojurebot:a
17:11Licenser,(let [r (new java.io.PushbackReader (new java.io.StringReader ":a ["))] (read r false :eof) (read r false :eof) )
17:11clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:11Licenserhrm
17:11amalloyLicenser: that's for "no forms left", not "incomplete form"
17:11LicenserI think the pushback reader was allowing unfinished forms, hence the pushback part
17:12amalloyno way
17:12amalloythe pushbackreader is just so it can parse, for example, "abc(1)" - it can't know the symbol is done until it hits (, but it has to put the ( back in the stream
17:13Licenserhrm
17:14ordnungswidrigi think i will to have to add some meta information to my files like a checksum or "number of expected forms"
17:15ordnungswidrigor I can peek using the pushbackreader if more is to come
17:16TimMcTrying to figure it out from here: https://github.com/clojure/clojure/blob/1.3.x/src/clj/clojure/main.clj
17:19TimMcOK, I think the secret is that the REPL just calls read, and since there is no EOF on stdin, it just blocks until a full form comes in.
17:19TimMcIf you give it a file or string reader, it knows right away once it reaches the end of the input.
17:19clj_newbIs there a better way to concatenate two strings than #(apply str (concat %1 %2)) ?
17:20cemerick(str a b)
17:20clj_newb,(str "thanks," " " "cemerick"))
17:20clojurebot"thanks, cemerick"
17:20TimMc&(.concat "abc" "def") ;-)
17:20lazybot⇒ "abcdef"
17:21clj_newbthis is embrassing; I even had the function in my example
17:21RaynesThat's satanic.
17:21clj_newbwhy is using the .concat part of Java.String wrong?
17:22clj_newbwhile we're taling abot strings; is there a better way to take the first 10000 chars of a string rather than (apply str (take 10000 ...)) ?
17:22TimMc&(let [ss ["abc" "def"]] (String/format (apply str (repeat (count ss) "%s")) (to-array ss)))
17:22lazybot⇒ "abcdef"
17:23cemerickclj_newb: you'd need to hint the call properly to avoid reflection; it can't be used with a HOF; it can only be used to concat two strings
17:23TimMcclj_newb: .substring, although it won't allow GC of the rest of the string while you hold it.
17:23brehaut,(subs 10 "abcdefghijklmnopqrstuv")
17:23clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String>
17:23brehaut,(subs "abcdefghijklmnopqrstuv" 10)
17:23clojurebot"klmnopqrstuv"
17:23TimMc(or is that split?)
17:23brehaut,(subs "abcdefghijklmnopqrstuv" 0 10)
17:23clojurebot"abcdefghij"
17:23clj_newbTimMc: that could be a problem; I am trimming a log this way
17:23clj_newbi.e. only keeping the most recent 10000 chars of it
17:24clj_newbif it doesn't allow the GCing of the rest of the string, I will be one unhappy clojure programmer
17:24brehautTimMc: substring does the thing you mean
17:24clj_newbdoe substring create a new string?
17:24clj_newbdoes it keep a refernece to the old string?
17:26haderachso I just tried installing emacs clojure-mode, but M-X slime connects me to sbcl. How do I point it at the right Lisp?.3
17:26SomelauwI solved it by downloading clojure-jack-in, but there might be other ways.
17:27technomancyhaderach: either M-x clojure-jack-in or M-x slime-connect; the swank-clojure readme has a pretty good (I like to think at least) overview
17:28brehautclj_newb: the docs for substring dont actually mention it. its probably an implementation detail, though i do remember readingthat sun/oracle java does just return a new string with a pointer to the same chunk of memory
17:29technomancyit doesn't create a new string; subs and subvec are both potential memory leaks if you don't keep that in mind
17:30TimMcI used a WeakReference to check; whatever I'm using for .substring allows GC.
17:30TimMc(let [s (apply str (range 10000))] (def w (WeakReference. s)) (def ss (.substring s 10 20)))
17:31TimMcThen I ran (count (take 1e6 (range))) and checked (class (.get w)), it had become nil.
17:31TimMcAnd that's (import 'java.lang.ref.WeakReference) for those following along at home.
17:37TimMc...and split, also.
17:37pyrswank-clojure is still the way to go with emacs, right ?
17:37the-kennypyr: yup.
17:38gf3awkward
17:39Somelauwwhy did they all go?
17:39TimMcOpenJDK 64-Bit Server VM 1.6.0_20
17:39hiredmanthere goes the irccloud
17:39TimMcNetsplit?
17:39gf3TimMc: nah, IRCCloud just sucks, they go down often
17:40TimMcOK. I have joins/nicks/parts/quits turned off, so I didn't see what happened.
17:40the-kennyYup, I like the idea, but there's too much downtime.
17:40amalloyTimMc: that surprises me - it's fairly clear from the source (of openjdk6, anyway) that substring shares the char[]
17:40the-kennyAnd the site gets awfully sluggish after some hours
17:40trgvhi :)
17:40TimMcamalloy: Weird.
17:40amalloyoh, i see. you were checking that the String is no longer referred to, and it isn't
17:41amalloybut the larger char[] it contained is still referred to
17:41TimMcAh!
17:41TimMcSneaky.
17:41TimMcWelp, there goes that method.
17:41TimMcamalloy: And split has the same problem? (While you're in there.)
17:42trgvi'm trying to code this algorithm http://weblog.jamisbuck.org/2010/12/29/maze-generation-eller-s-algorithm with no luck, someone could give a hint please ? =D
17:42amalloyTimMc: it looks that way
17:43amalloyString.split delegates to Pattern.split, which calls String.subSequence, which seems to do the same sharing as substring
17:44TimMcAll this structure sharing on splitting would be nicer if the GC could be told what portions of an array were still in use.
17:44TimMcLike, "give me a subarray and feel free to trim the rest as necessary".
17:53mr_rmi've built a maven uberjar with all my dependencies, including clojure and some <code>.clj files (not compiled). does anyone know the way to call a function inside one of my clj files?
17:54mr_rmi tried: java -cp uber.jar clojure.main -i /my/file.clj -e "(func)"
17:55technomancymr_rm: you can try clojure.main -m my.ns
17:55technomancybut it'll only work on the -main function
17:56mr_rmtechnomancy: ok, i'll put the entry point in "(defn -main []...)" and see what happens :) thanks
17:56technomancyalso, -m requires clojure 1.3
17:56mr_rmtechnomancy: oh... bummer. this is 1.2.1
17:57di-csuehswhat does a graph look like in clojure? What do you pass as 'g' to the clojure-contrib.graph funcitons?
17:57technomancywell I did submit the patch before 1.2 was released. =\
17:58mr_rmtechnomancy: my jar is self-executable with a java main() wrapper right now but i was just wondering if i could call individual functions from the command line
17:58technomancymr_rm: you can always use ns-resolve on the args you get.
18:00mr_rmtechnomancy: right but i'm not intending the wrapper to be a general caller. i want to distribute it always calling the main entry point. i was just wondering if there is some syntax for clojure.main that would let me call any arbitrary function inside an uncompiled clj file inside the jar
18:00technomancyyeah, it's a shame that didn't make it into 1.2 =\
18:01mr_rmtechnomancy: ok. i appreciate your response
18:03technomancyno problem
18:04mabeswhat is the correct way of using lein-multi? I'm seeing various ways: https://github.com/technomancy/doric/blob/5d996a777535f060581b350b710971187b108800/project.clj https://github.com/danlarkin/clojure-json/blob/6d7f28e58a2cd81a0e26a6c966d75b6310b638ad/project.clj
18:06clj_newbyou know what else is fricking awesome? I can have keywords not only of the form :foo but alfo of the form :foo-bar .... it's just so nice
18:06clj_newb[end rant]
18:06clj_newbsometimes I use clojure; and I just don't understand why other langauges have all these weird limiitations
18:07technomancymabes: they're both correct; what do you mean?
18:08mabestechnomancy: I guess I'm unclear what the best practice is.. from your project above it seems that you are listing 1.3 as a dep.. so if a 1.2 person includes it they will have to exclude that dep.. where as with the json example no dependency is listed but both are tested..
18:09technomancyoh, sure. I'd say it's best to list your minimum required clojure version as a :dependency and list newer ones under :multi-deps
18:10technomancyor start using lein2 where that functionality is built-in with profiles!
18:10mabesoh really... that sounds nice..
18:10technomancyit's still a bit early
18:10mabesI'm just patching clj-time so I probably won't do that in this case but for my own projects I can start trying it out
18:10technomancybut if you're feeling adventurous...
18:11technomancyreally really early, I guess I would say.
18:11mabesheh
18:11technomancymore like if you've got some time and you don't mind helping out or aborting your effort. =)
18:13mabesi.e. you like shaving yaks ;)
18:13amalloytechnomancy: perhaps your "preferred" clojure version as the actual dep, rather than minimum
18:14technomancyamalloy: you mean if you like having newer features available for convenience during dev time?
18:14technomancydunno; seems like it would be too easy to commit code that uses them by accident
18:15amalloyno, just like as a description of intent: "clojail was written for 1.3, but as you can see from lein-multi it also supports 1.2.1"
18:16amalloywhich is very different, in terms of how confidently users will use a given version, from the converse
18:16technomancyI'm still reeling from the betrayal of maven version ranges; haven't settled on The Right Thing yet.
18:17Raynesclojail actually didn't work for pre 1.3 until Alan bitched me into making it 1.2 compatible.
18:17Raynes:p
18:17technomancyseems like using the lowest by default keeps you honest
18:19amalloyi don't buy that at all: there are breaking changes in each direction. if you have 1.2 as your "canonical" version you can accidentally check in something that depends on dynamic vars, for example
18:20technomancyyeah, but 1.3 is supposedly an exception to the rule
18:20technomancyin theory all consecutive 1.x releases will be additive
18:21technomancyI guess it makes sense if your two versions are 1.2 and 1.3 though
19:04semperosway to see documentation for functions at cljs repl?
19:11RaynesWhat is 'clojure.repl/doc', Alex.
19:12amalloydoes cljs have docstrings? i thought it didn't even have vars
19:14dnolenamalloy: the data is there, somebody just needs to make it work
19:14clj_newbI need help on the right term to search for. I'm on OSX. I'm creating a GUI in Clojure via Awt/Swing (it's a JFrame). I want the Frame to "jump to the front of the screen", i.e. be on top of all other windows. What is ther right term I'm loking for? (focus is not it)
19:16RaynesOh, cljs.
19:16Raynesclj and cljs are too similar.
19:23sandbox`hello. I'm trying to test a record that implements a protocol, and i would like to stub out one of the protocol's functions. is there a way to do this? does this make any sense?
19:26sandbox`i've tried with-redefs but it doesn't seem to be doing anything in this context
19:44benares_98what's the simplest way to install clojure on mac osx?
19:45technomancyclojurebot: how do I install clojure?
19:45clojurebotGabh mo leithscéal?
19:45technomancy>=\
19:46technomancybenares_98: clojure isn't an application that you interact with as an end user; it's just a library that you include with the software you write.
19:46amalloyhttp://stackoverflow.com/questions/5983427/how-to-install-clojure-on-ubuntu-10-04-from-github-repo-with-no-clojure-jar is about ubuntu but just as relevant on macos
19:47technomancyyou mean macosecks?
19:47amalloyi like to leave you an opening to say that; you do so enjoy it
19:47technomancyI should let you know that it's appreciated.
19:49benares_98thanks, I'm looking to install several packages for my wife so she can join me for an clojure/overtone meetup tomorrow.
20:22adam_is anyone here programming clojure with monads?
20:22brehautadam_: yes
20:23brehaut~anyone
20:23clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
20:23tavisadam_: google for Konrad Hinsen or Roman Gonzalez for a start
20:23brehautalso Jim Duey
20:25tavisyeah, Jim wrote an awesome tutorial series
20:26brehautadam_: alternatively, just ask your question
20:26tavisnote the contrib module Jim talks about has been replaced by clojure/algo.monads
20:39brehauttechnomancy: theres another one?
20:39brehaut(tutorial that is)
20:39technomancyI think it was Konrad's
20:39brehautah right
20:40brehautdidnt think we needed any more
20:41technomancyif there's one thing I learned from Haskell users it's that there's always room for one more blog post about monads.
20:41brehautlol
20:42tavisnot just them: http://www.meetup.com/vancouver-scala/events/41968702/ tomorrow night
20:42taviser, Thurs
20:42brehauttomrrow night isnt thursday?
20:43brehautyou sir are living in the past
20:43tavisdamn true
20:44tavisI once flew home from NZ on xmas just after dinner and arrived home for second xmas dinner a day later
20:44brehautexcellent
20:44tavisbut second had lots of snow
20:47brehautis that a good thing?
20:47phil_is there a way to make the compiler print a warning whenever a defrecord doesnt implement all of its protocol functions?
20:48tavisbrehaut: not when your car is buried at the airport - it was
20:49brehauttavis: oh
20:49dnolenphil_: nope
20:49mattmitchellcould someone explain the reason why one of these macros works and the other doesn't? https://gist.github.com/1674116
20:49dnolenphil_: seems like something handy for the analyzer to do though
20:50mattmitchellI'm confused as to why the & arg works, but I can't pass a list in for the same result?
20:50hiredmanmattmitchell: it's not the same
20:50hiredmanyou have a quoted list and some symbols
20:50phil_dnolen: is that generally regarded as useless or is it just not high on the priority list?
20:50hiredman(a quoted list of symbols)
20:51mattmitchellhiredman: i feel like i've been down this road before, please continue :)
20:51hiredmanmattmitchell: (x (one two)) will fail in the exact same way
20:51phil_dnolen: because i think that a "record is abstract" or w/e warning would eliminate a lot of bugs
20:51hiredmanmattmitchell: well go write a lisp interpreter with quoting and macros so you know what you're doing next time
20:52mattmitchellhiredman: that's a great idea
20:52hiredmanhave fun
20:52amalloywait what, why wouldn't (x (one two)) work in the second case?
20:52amalloyit should expand to (let [one 1, two 2] (str one two)), which looks valid to me
20:53hiredmanamalloy: but look at the call to str
20:53hiredmanactually, that might fail very oddly
20:53hiredman(but it will)
20:53hiredman(str quote (one two))
20:53hiredman,quote
20:53clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: quote in this context, compiling:(NO_SOURCE_PATH:0)>
20:53amalloyhiredman: i took out the quote
20:54amalloyas did you, i think. (x (one two)) works fine with second definition
20:54amalloyagreed (x '(one two)) is rubbish, but nobody seems to be arguing about that
20:54hiredmanoh, right the let
20:54mattmitchellahh ok
20:55dnolenphil_: I don't think it's a large source of bugs. But no it doesn't look like it's a high priority. Yet another gap that the community can easily fill.
20:56hiredmanphil_: if your protocol is large enough to forget functions then maybe your protocol needs to be broken up
20:57phil_hiredman: i agree, but still, are there many use cases where it is desirable to have a half-baked defrecords lying around?
20:57phil_defrecord*
22:04thelittlelisperSo what is the most interesting Clojure project you've seen lately and why?
22:04brehautthat is such a broad question
22:06brehautavout, core.logic, counter clockwise?
22:06brehautclojurescript?
22:06clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPersistentStack>
22:07thelittlelisperCool - why are they interesting?
22:07brehautyou have google. the relevant sites are self explainatory
22:08brehautand will do a better job explaining than i will
22:09thelittlelisper:) I've seen them - I can see they're new and fresh - I was asking for personal preferences and associated reasoning
22:09thelittlelisperWhy do you find them interesting?
22:09brehautbecause they are doing cool stuff
22:20skelternetis anyone here familiar with the clojure-contrib.graph package?
22:33jkkramerskelternet: somewhat, got a specific question?
22:34skelternetI've been googling for usage and trying to understand what form the graphs should be in. I'm looking at the graph.clj source now.
22:35skelternetso, the best specific question I have at the moment is, "What is a g(raph) in clojure?"
22:38jkkramerskelternet: in general, they could be represented in many ways — a collection of edges, a map of nodes to a set of neighbor nodes, etc. c.c.graph uses a struct of :nodes and :neighbors. see https://github.com/clojure/clojure-contrib/blob/master/modules/graph/src/main/clojure/clojure/contrib/graph.clj
22:39jkkramerskelternet: you should be aware that use of clojure.contrib is discouraged. unfortunately, there's no go-to replacement for clojure.contrib.graph as far as I'm aware
22:39jkkramerskelternet: you could check out https://github.com/jkk/loom but I haven't upgraded it to 1.3 yet. maybe I should do that…
22:41skelternetThank you! I feel less disoriented. I saw the calls to (:neighbors in (get-neighbors but I didn't see anything describing what it was expecting.
22:41skelternetI've run across mention of loom.
22:41jkkrameryeah, seems to be only documented in code comments
22:42skelternetHa! was that tongue-in-cheek?
22:42skelternetif so, sorry I missed the comments
22:43jkkramernot intentionally :) they're easy to miss
22:43skelternetfound directed-graph in a defstruct
22:44skelternetyes. I'm still adjusting to the language. subtle in some ways since it eschews the ceremony.
22:45skelternetI'll take a closer look at loom
22:45skelternetthis is all recon. I'm not sure the science project will gain any traction or sponsorship in the day job.
22:48skelternetwhoa…:neighbors is not a necessarily a collection…it's a function that takes a node
22:53jkkramerclojure is cool like that. collections and functions are often interchangeable. collections can implement the function interface
22:55skelternetThank you for loom.
22:55skelternetAre you looking at Neo4j or the other graph db's in your other work?
22:56jkkramerloom was kind of an excuse for me to play with protocols & records, and get familiar with writing functional algorithms. it's relatively untested in real-world code
22:57RaynesThere is a graph DB written in Clojure: https://github.com/flatland/jiraph
22:58jkkramerwritten by some upstanding gentlemen
22:59skelternetit is a wonderful age to be a software geek. *sobs of joy*
22:59skelternetTokyo Cabinet, eh.
23:01jkkramerloom is upgraded to 1.3 now, FWIW
23:01Raynesskelternet: tokyo cabinet is just one layer -- there can be others.
23:02skelternetThanks! Now I feel a little pressure to actually use it. :) I have to ask….what did you have to change?
23:02RaynesJiraph is currently going under a semi-rewrite and amalloy is writing an in-memory STM layer.
23:02Raynesundergoing*
23:02RaynesWow, sentences are hard.
23:02amalloynah, the STM layer was done ages ago
23:03RaynesIt hasn't been *that* long since STM commits were rolling in.
23:03Raynesskelternet: Not sure I understand the question.
23:04skelternetI'll look at it on git… the upgrade to clojure 1.3 seemed really quick so I'm wondering if it was so resilient and beautiful code it just worked.
23:04jkkrameroh, that was for me
23:05jkkramerI just had to change the dependency to 1.3, and then make add a :dynamic metadata thing to a var
23:05jkkramers/make//
23:05RaynesOh.
23:06Raynesskelternet: When you're responding to a specific person, it is helpful to prefix your message with that person's nickname. Usually this is no trouble because IRC clients can typically tab-complete IRC nicks.
23:06RaynesLike I just did there.
23:07jkkramermaking code 1.3 compat isn't very hard if you're not using clojure-contrib
23:07skelternetall: I know that. I apologize. I was sloppy. Please accept my apologies.
23:07muhoo,(quote foo)
23:07clojurebotfoo
23:08Raynesskelternet: It's fine. I just got a little confused. :)
23:09skelternetsorry Raynes. I forget you can't see what direction I'm typing in. ;)
23:10skelternetI'm still reading about jiraph
23:51muhoowhat's the & operator do, as in [loc f & args] ?
23:51skelternetvargs?
23:51skelternetit's the rest of the args
23:51muhooskelternet: thanks
23:51skelternetoptional, if I recall
23:51jayunit100why is it that the 2nd expression in doseq is NOT prefixed with a # ?
23:51jayunit100(doseq [[index word] (map vector
23:51jayunit100 (iterate inc 0)
23:51jayunit100 ["one" "two" "three"])
23:52jayunit100i would think that the expression part would be an anonymous function.
23:53jayunit100(doseq [i [1 2 3 4]] (print i))
23:53skelternetis doseq a special form or a macro?
23:53jayunit100(doseq [i [1 2 3 4]] #(print i)) ;;<--- this does not run properly.... because of the #.
23:53jayunit100doseq is a macro
23:54jayunit100I guess im confused what the purpose of declaring an anoynmous function is ?
23:54jayunit100if we can just express the same thing in a Closure.
23:55amalloythose words generally mean the same thing, so you'll have to clarify
23:55jayunit100well... in clojure - i would think that
23:55jayunit100(doseq [i [1 2 3 4]] (print i))
23:55dnolenskelternet: a macro
23:55jayunit100should have the same result as
23:55jayunit100(doseq [i [1 2 3 4]] #(print i))
23:55jayunit100but it doesnt
23:56amalloyjayunit100: that would be true if (print i) were the same as #(print i), but obviously they're not
23:56jayunit100yes - one is a closure, the latter is an anoynmous function
23:56amalloyno
23:56jayunit100Ahh duh .
23:57amalloythe former is an expression causing something to be printed; the latter is an expression which evaluates to a function (closure, if you prefer)
23:57jayunit100no they are not because closures are blocks that only exist in scope of the code in which they occur.
23:58jayunit100yes @amalloy thats a good explanation
23:59skelternetHow can I use macroexpand to show what doseq is doing?
23:59dnolen,(macroexpand '(doseq [_ 10]))
23:59clojurebot(loop* [seq_33 (clojure.core/seq 10) chunk_34 nil count_35 ...] (if (clojure.core/< i_36 count_35) (clojure.core/let [_ (.nth chunk_34 i_36)] (do) (recur seq_33 chunk_34 count_35 (clojure.core/unchecked-inc i_36))) (clojure.core/when-let [seq_33 (clojure.core/seq seq_33)] (if (clojure.core/chunked-seq? seq_33) (clojure.core/let [c__3921__auto__ (clojure.core/chunk-first seq_33)] (recur (clojure.co...