#clojure logs

2012-02-01

00:53aphyrOut of curiosity, how expensive is deref in clojure?
00:53aphyrSafe to call, say, 250K/sec?
00:54G0SUBaphyr, vars are getting deref-ed all the time.
00:54G0SUBaphyr, in 1.2 all vars are dynamic, for example. so I guess it should be pretty fast.
00:55ibdknoxit depends entirely on what you're derefing
00:56aphyribdknox: (ref (NonBlockingHashMap.)) in this case.
00:57aphyrI've been using it to allow an aleph server to change its underlying configuration after being started
00:57aphyrBut now I'm wondering if I should build some kind of reload functionality instead
00:57ibdknox,(time (loop [i 0] (when (< i 250000) @x (recur (inc i)))))
00:57clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)>
00:57ibdknox,(let [x (atom 1)] (time (loop [i 0] (when (< i 250000) @x (recur (inc i))))))
00:57clojurebot"Elapsed time: 75.945 msecs"
00:57ibdknox,(let [x (ref 1)] (time (loop [i 0] (when (< i 250000) @x (recur (inc i))))))
00:57clojurebot"Elapsed time: 100.592 msecs"
00:58ibdknoxit appears that will not be an issue
00:58ibdknox:)
00:58G0SUBibdknox, :-)
00:58aphyrHaha, apparently not. :)
00:59aphyr,(time (loop [i 0] (when (< i 250000) (recur (inc i)))))
00:59clojurebot"Elapsed time: 21.745 msecs"
00:59aphyr,(time (loop [i 0] (when (< i 250000) (recur (inc i)))))
00:59clojurebot"Elapsed time: 20.966 msecs"
00:59aphyrSo ~80ms for the var deref
01:00aphyrout of a 1-second timeslice, 8%... hmm. Might be worth investigating actually.
02:33pyrhi
02:33G0SUBpyr
02:34pyrdoes read-string "intern" strings on the jvm, thus making use of permgen space
02:34G0SUBpyr, literal strings are interned.
02:35pyras well as keywords
02:35pyri have a permanent process that reads of a queue
02:36pyrand does read-string on the input
02:36pyri see constant permgen space growth
02:36pyrwhich i don't understand
02:42G0SUBpyr, -XX:MaxPermSize=128m -XX:PermSize=128m might be the only option.
02:43aphyrWait, so any string created with read-string is on permgen?
02:43raekkeywords are always interned (by Clojure), but strings are not always
02:43G0SUBpyr, apparently interned strings are GCs as expected - http://stackoverflow.com/questions/1091045/is-it-good-practice-to-use-java-lang-string-intern/2012661#2012661
02:44raekstring literals in function bodies tend to be identical
02:45raekanyway, the Clojure reader does not call .intern on the strings, IIRC
02:45raek,(identical? (read-string "\"foo\"") (read-string "\"foo\""))
02:45clojurebotfalse
02:46raek,(identical? (name (read-string "foo")) (name (read-string "foo")))
02:46clojurebottrue
02:47raekthe names of keywords and symbols are, though
02:47aphyr,(.get (System/getenv) "PWD")
02:47clojurebot#<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.*)>
02:47aphyrha
02:48aphyrI actually could use some sandbox code right now... good to know
02:48pyrraek: yup, but i clearly don't have enough keyword read in
02:48pyrraek: to justify the growth i'm seeing
02:58JachyIs there a way I can do (def (symbol ...) val) outside a macro?
03:15raekJachy: not with 'def', no.
03:16raekthere is intern though
03:18Jachyraek: That looks useful, thanks.
04:04clj_newbis it possible to ahve two separate instances of clojure share the same jvm?
04:04clj_newbfor example, I have a simle digital led clock writen in clojure -- I think ti's a bit overkill to have it have its own jvm instance
04:05simonjHi all. Confused as to the non-laziness of the returned Seq from this function. https://gist.github.com/1716056
04:22pyralright, so given a huge list of strings containing pr-str'd maps
04:22pyrif i do: (let [m (doall (map read-string huge-list)] (Thread/sleep 10000) (println "saw: " (count m)))
04:23pyri see a permgen increase which doesn't get freed up
04:23pyrusing CMSClassUnloadingEnabled and UseConcMarkSweepGC
04:23pyrdoesn't change a thing
05:33yawNOi often see in clojure libs (defn ^
05:33yawNOwhat is that?
05:33yawNO*def ^
05:35ivanyawNO: are you asking about metadata?
05:35yawNOi dont know asd
05:35yawNOi've been clojuring for like
05:35yawNO3days?
05:35yawNOso im really kinda noob right now :P
05:36ivan^{:a 1} (fn) attaches {:a 1} as metadata to (fn)
05:36ivansee also with-meta and meta
05:36yawNOokay got it
05:36yawNOthx :D
05:37yawNOyeah i know with-meta and meta :D
05:37Martijn2I just installed lein and made anew project based on clojure 1.2.0 and clojure-contrib 1.2.0 When I do (require 'clojure.contrib.str-utils) I get this error:
05:37Martijn2java.lang.NoClassDefFoundError: clojure/lang/RT (NO_SOURCE_FILE:0)
05:37Martijn2what is going on?
05:39Martijn2sorry, problem solved
06:40cemericktotally OT, but: does anyone else find it totally bizarre that the 13" Macbook Pro has a lower screen resolution than the 13" Macbook Air?
06:42ordnungswidrigcemerick: yes, me. now as I know the fact.
06:46BorkdudeI installed rlwrap on my mac. how is "lein repl" supposed to use it for completion?
06:48lucianBorkdude: rlwrap lein repl
06:48lucianit literally wraps your commands
06:48Borkdudelucian: how does it do autocompletion then?
06:48jondotmy first hit at useful clojure code - a ring middleware: https://github.com/jondot/ring-ping/blob/master/src/ring/middleware/ping.clj ==> anyone care to take a look and point some aweful newbie pitfalls to me?
06:48lucianBorkdude: oh, completion? sorry
06:48lucianBorkdude: for that you'd need some machinery in lein i think
06:48cemerickBorkdude: I can't see how rlwrap would help with completion.
06:49luciancemerick: it can, actually. there was a small hack i saw for the regular clj
06:49cemerickcommand history and editing, yes.
06:49luciancemerick: rlwrap can search a file of completions when you press tab
06:49Borkdudecemerick: command history also worked without rlwrap on my mac
06:49lucianBorkdude: you could generate such a file with (find-doc) or something
06:49cemericklucian: oh; that's not really completion tho. :-)
06:50Borkdudenot very intelligent completion anyway ;)
06:50lucianhttps://github.com/technomancy/leiningen/pull/381
06:50lucianit's terrible, really
06:50luciandon't bother
06:50cemerickBorkdude: lein will be getting some baked-in completion shortly.
06:51BorkdudeI have some students who are trying out clojure, they used a console for it, so I thought it could be handy for them
06:52cemerickBorkdude: this is likely to be the new frontend for lein's repl: https://github.com/trptcolin/reply/
06:56luciancemerick: that reply thing is awesome
06:56lucianit has precisely the features i want, and nothing else
06:57Borkdude_cemerick: totally cool, autocompletion works
06:58cemericklucian: you want more, you just don't know it yet ;-)
06:58luciancemerick: heh
07:06cemerickG0SUB: you have a MBA, right?
07:18G0SUBcemerick, lol!
07:18G0SUBcemerick, not at all. I have a BS in CS, that's all.
07:18cemerickMacbook Air :-P
07:18G0SUBcemerick, haha
07:18G0SUBcemerick, yeah, 11" MBA :-)
07:19G0SUBcemerick, the same as cgrand
07:19cemerickG0SUB: I take it the SSD makes up for anything the CPU is lacking, then?
07:19Fossilol
07:19Fossibest ever
07:19Fossiyou should put that on your business card XD
07:20G0SUBFossi, ;-)
07:20G0SUBcemerick, I agree. and the CPU isn't that bad either.
07:31G0SUBcemerick, cgrand, ninjudd & I have the same MBA.
08:01shalesHi, does anyone know what version of mongodb 4clojure requires?
08:06romain_pHi everyone, what is the best way of turning {:a #{:foo :bar}, :b #{:baz}} into [[:a :foo] [:a :bar] [:b :baz]] ?
08:07lucianmaybe something like (map vec your-hash)
08:08romain_p,(map vec {:a #{:foo :bar}, :b #{:baz}}
08:08clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
08:08romain_p)
08:08romain_p,(map vec {:a #{:foo :bar}, :b #{:baz}})
08:08clojurebot([:a #{:foo :bar}] [:b #{:baz}])
08:08romain_phmmm no
08:09lucianclose, just vec again on the set
08:13lucian,(map (fn [item] [(first item) (vec (second item))]) {:a #{:foo :bar}, :b #{:baz}})
08:13clojurebot([:a [:foo :bar]] [:b [:baz]])
08:14luciannvm, i must've misread
08:23romain_plucian: thanks!
08:24romain_poops no
08:24lucianromain_p: it's not what you asked
08:24shales,(mapcat (fn [[k v]] (map vector (repeat k) v)) {:a #{:foo :bar}, :b #{:baz}})
08:24clojurebot([:a :foo] [:a :bar] [:b :baz])
08:24shalesthat work?
08:24romain_pshales: yup that does it, cheers
08:25babilenHow can I influence the sort order of records? I essentially want them sorted by field1 first, then field2, … What would be a good approach?
08:32llasrambabilen: Have the records implement Comparable?
08:32babilenllasram: Not yet - I figured that something like this would be the best approach, but wanted to ask first.
08:35llasramOk. I'm pretty sure that's the best/only way to do it
08:36babilenllasram: Can you, by chance, provide pointers to documentation on how to achieve this (easily)?
08:40llasrambabilen: Just the normal way you implement interfaces for defrecords/types. Some general examples at: http://clojuredocs.org/clojure_core/clojure.core/defrecord
08:40babilenI am not sure how to achieve this, but figure that implementing a comparator (for e.g. sorted-set-by) is another option. (which is as far as my knowledge is concerned easier)
08:42llasrambabilen: Here's a specific simple example: https://refheap.com/paste/527
08:43llasramYou can also just pass a comparator (just a function returning {-1,0,1} for any argument pair) whenever you need to sort
08:43babilenllasram: Thanks -- Is it important that I implement in a way that allows comparison between different types or is that checked earlier?
08:44llasramNormal rules apply: only if you care about inter-type sorting.
08:44babilenllasram: I don't (at least not right now)
08:46llasramAh, and the `sort' default behavior just throws an exception anyway with different types intermixed. You'll definitely need to pass in a comparator if you ever do want anything sane to happen in those cases :-)
08:50raekbabilen: one way is to implement Comparable, and one way is to implement Comparator. one thing that's convenient is that functions of two arguments implement Comparator
08:50babilenllasram: Ok, that makes sense and is good news. Thanks for your kind and great help. Have a nice day!
08:52raek,(sort #(> (.length %1) (.length %2)) ["a" "aaa" "aa"])
08:52clojurebot("aaa" "aa" "a")
08:52babilenraek: Ok, great. Well -- I have collections of records and want them sorted by field1, field2 and don't really care about additional fields. (still need to be part of the comparison as sorted-set-by would, for example, remove all elements that differ only in additional fields)
08:53raekbabilen: you can also use sort-by. it accepts a function that gives another value which is used for te comparisons
08:54raek,(sort-by (juxt length last) [[1 2 3] [1 2] [0 0 10]])
08:54clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: length in this context, compiling:(NO_SOURCE_PATH:0)>
08:54raek,(sort-by (juxt count last) [[1 2 3] [1 2] [0 0 10]])
08:54clojurebot([1 2] [1 2 3] [0 0 10])
08:54raekvectors and sequences are compared element wise
08:55babilenyeah -- I will try to implement a compare-by-field([:field1 :field2]) → comparator -- that will take additional (i.e. other not listed fields) into account, but sorts by field1 first, then field2, then the rest in no specific order. (alphabetically maybe)
08:55raekyou can use (juxt :field1 :field2) as the key-fn
08:56babilenraek: Indeed - I am just not sure how to deal with the other fields that might be present in the record (yet).
08:56raekthe ones with the same :field1 and :field2 value will be sorted next to each other in some order
09:00babilenraek: Shouldn't be hard though (use (keys rec) to get keys, remove given ones, ...) -- Thanks for your comments as well.
09:05Kototamahi, is there a way in SLIME to have slime-repl-previous-matching-input behavior more like the one from term-send-reverse-search-history (like C-r in the console) ?
09:24noidiis it not possible to implement two protocols (defined in different namespaces) with the same method name?
09:26noidiI get "Duplicate method name&signature" when I try to implement foo/Foo with foo/get-xyzzy, and bar/Bar with bar/get-xyzzy in the same reified protocol implementation
09:26noidiluckily I'm just playing around with this, so it's not a real problem that I'm facing
09:27noidithis kind of makes namespaces useless when using protocols
09:29gfredericksnoidi: I don't know the reasoning behind it, but I think each method that you implement gets added as an actual java method on the type, without the namespace, so I'm not sure how that could be resolved
09:31noidiyeah, some sort of a name mangling scheme would be needed
09:32gfrederickswhich would be gross for anybody who intended to actually use the methods
09:33noidiwell, now you need to do the name mangling manually to avoid this problem
09:34gfrederickstrue; I am not equipped to argue about the design choices.
09:34noidior to avoid causing problems for the people who have to implement your protocol, possibly along with other protocols also out of their control
09:34gfredericksbut hode up
09:34gfredericksthe exact same problem exists with java interfaces doesn't it?
09:35noidiprobably. I'm not that familiar with Java.
09:35gfredericksyeah, now that I think about it I expect this is a very general problem
09:35cemericknoidi: you can implement two protocols with the same signature, etc. without a problem *unless you're doing so inline*
09:36cemerickuse extend-type, extend-protocol, or extend to provide protocol impls.
09:36gfrederickscemerick: how does it map to method names?
09:36noidicemerick, thanks, I was hoping that it could be possible via extending!
09:36noidiI'll give that a go
09:37cemerickgfredericks: extend* doesn't map to method names.
09:37cemerickThat's why it works. :-)
09:37gfredericksIndeed!
09:51noidicemerick, brilliant, that works!
09:51cemerick:-)
09:52cemericknoidi: inline implementations are really only needed for maximum perf and Java interop.
09:55noidiI hope that the times I'll have to implement two Java interfaces with colliding method names will be few and far between
10:08noidinow if only there was a way to specify contracts directly on the protocol instead of the contract block of each method implementation...
10:09noidiit seems that trammel doesn't do that (yet)
10:19cmajor7is there a "mental rule" on where to use map/reduce/filter vs. list comprehensions?
10:20gtrakless/clearer code wins?
10:21raekcmajor7: whatever shows the intent of the code the best... :-)
10:23cmajor7gtrak, raek: but from a "problem solution" side. besides constantly mentally substituting both approaches ( map/reduce/filter & list compr ), is there certain indicators?
10:24cmajor7e.g. list comprehensions would probably make more sense when iterating over multiple seqs where each element in one seq needs to visit each element in the other…
10:24TimMccmajor7: Sure. If you want to walk through a collection one at a time and use the values to hammer on some other value, 'reduce is your friend.
10:25TimMcespecially if you are trying to maintain some invariant on that value
10:25gtrakreduce is aggregation
10:25TimMcreduce is folding
10:25TimMcYou're folding values in, one at a time.
10:26noidimy own mental rule is that when I use map with a lambda, it probably reads better as a list comprehension
10:26TimMclist comprehensions are a Swiss Army knife
10:26TimMcgtrak: Challenge: Implement 'reduce using 'for.
10:27gtrakhmm :-)
10:27TimMcMy gut says you can't.
10:27gtraki can find a way
10:29TimMccmajor7: Given a collection, 'map gives you 1-for-1 collection answer, 'filter gives you a subset, and 'reduce gives you a single value for the whole thing.
10:30TimMccmajor7: So first, ask yourself which of those results is what you want!
10:31cmajor7TimMc: thank you. interesting.. I do understand map vs reduce vs filter. I am on list comprehensions vs map/filter/reduce… is there a difference in performace? e.g. reduce only walks once over all the seqs given and grows the accumulator, where if multiple seqs are given to "for" e.g. for [s1 (range 1 10) s2 (range 1 10)], it will walk seq2 completely for each element in seq1…
10:31noidiwith my rule: (map #(* 2 %) (filter #(> % 5) (range 10))) --> (for [x (rang 10) :when (> x 5)] (* 2 x))
10:32babilennoidi++
10:32TimMccmajor7: I can't imagine the performance would be different enough to care about.
10:34cmajor7TimMc: { btw, I also find that in several cases reduce gives you a subset => similar to a filter. the true difference between "reduce" and "filter" in my understanding, is that "reduce" would have an accumulator, which allows a _new_ seq, rather than just a subset of the existing seq that "filter" does }
10:34TimMcYes, you can certainly implement filter and reverse and so forth using reduce.
10:34TimMcand map, for that matter
10:35TimMc&(reduce #(conj %1 (* 3 %2)) [] (range 10))
10:35lazybot⇒ [0 3 6 9 12 15 18 21 24 27]
10:36TimMc&(reduce #(cons %2 %1) () (range 10)) ; reverse
10:36lazybot⇒ (9 8 7 6 5 4 3 2 1 0)
10:38TimMcgtrak: I think 'for can produce a collection with at minimum the number of elements that :when and :while let through.
10:39TimMcOh, and it always produces a collection, so you *can't* do it without at least some post-processing.
10:39gtrakI think there's no reason for not being able to reduce with a for, but i can't make my code work at the moment, I'm rusty :-), my basic idea is for x in the range of the length, swap an accumulator atom
10:39TimMcUgh, that's terrible!
10:39gtrakreduce isn't lazy either
10:40TimMcYeah, that's the kicker, I think.
10:41cmajor7seems that 'list comprehensions in fact is somewhat close to a noidi's idea of "map + filter" application to seq(s). :while is an interesting one.. would 'list compr actually stop a seq walk on the first "while false"?
10:41TimMc&(for [a [(atom 0)] x (range 6)] (swap! a (partial + x))) ;; reductions
10:41lazybot⇒ (0 1 3 6 10 15)
10:43TimMccmajor7: :while will stop the current iteration only, and only at that level.
10:45shalesdoes anyone know what version of mongodb 4clojure requires?
10:45cmajor7&(dorun (for [col "ABCD" :when (not= col \B) row (range 1 4) :while (< row 3)] (println (str col row))))
10:45lazybot⇒ A1 A2 C1 C2 D1 D2 nil
10:45TimMc&(for [l0 '[a b c], l1 '[1 2 3] :while (< l1 3), l2 '[d e f]] (str l0 l1 l2))
10:45lazybot⇒ ("a1d" "a1e" "a1f" "a2d" "a2e" "a2f" "b1d" "b1e" "b1f" "b2d" "b2e" "b2f" "c1d" "c1e" "c1f" "c2d" "c2e" "c2f")
10:46cmajor7TimMc: so the iteration actually stopped when a row became 3?
10:46TimMccmajor7: Correct.
10:47cmajor7cool. so it is quite "controllable".. nice
10:47TimMcand :let makes it even better
10:49noidijust think of `for` as a fancy `map` :)
10:50cmajor7I still feel I would need to right many more maps/reduces/filters & listcomps to get the true feeling on when the one is more applicable.. but appreciate all the thoughts.. very cool.
10:51cmajor7noidi: 'map can't really iterate over multiple collection matching each element of one collection to all elements of another ( unless there is an internal map/reduce ). while 'listcomp can and does that. or am I missing something?
10:51cmajor7*over multiple collections
10:52noidiit can't. you'll need something like (map (fn [x] (map f x)) xs)
10:52TimMccmajor7: It can, the result is just a collection of collections.
10:52gtrakyou can do it with map, but it'd be really awkward?
10:52TimMcmapcat takes care of that.
10:53gfredericksyou could do X with just a bunch of lambdas also
10:53TimMccmajor7: 'for is great for unrolling nested collections, by the way.
10:53cmajor7doesn't mapcat just flatten the result of mapping?
10:53TimMcYeah, but it does the mapping too.
10:54cmajor7but not on nested collections..
10:54cmajor7e.g how would you do this
10:54cmajor7&(dorun (for [col "ABCD" :when (not= col \B) row (range 1 4) :while (< row 3)] (println (str col row))))
10:54lazybot⇒ A1 A2 C1 C2 D1 D2 nil
10:54cmajor7with a single map/mapcat?
10:54TimMcwithout the :when and :while, of course
10:56TimMc&(mapcat (fn [c] (map (fn [r] (str c r)) (range 1 3))) "ABC")
10:56lazybot⇒ ("A1" "A2" "B1" "B2" "C1" "C2")
10:56cmajor7right => 2 maps
10:56TimMcsure
10:56TimMcwhich is equivalent to a 2-level 'for
10:57cmajor7yep.. so another mental rule would be.. "think about 2> maps? try 'it' with for"
10:57cmajor7(thinking out loud)
10:57TimMcyeah, cartesian joins
10:58cmajor7is there an appealing case to use 'for vs 'map on a single seq?
10:59cmajor7( I meant 'for vs. 'map/'filter/'reduce )
10:59gfrederickscmajor7: I like map with named functions and for with inline functions
10:59TimMcSure, when the lambda is of moderate complexity and depends on a bunch of local s
10:59cmajor7besides the laziness of the result of course
10:59TimMccmajor7: 'for is lazy
11:01cmajor7TimMc: "when the lambda is of moderate complexity and depends on a bunch of local s" => this would be strictly a readability advantage, right? [not saying it is not enough of an advantage though]
11:12TimMccmajor7: A lamba of moderate to high complexity should generally be extracted as a separate named function, but if you'd have to pass it a crapload of locals, it *might* be better to keep it inline in a 'for.
11:13cmajor7TimMc: yep, makes sense. thank you.
11:13gfredericks(> (count locals) crapload)
13:04muhoothese instructions assume i have a pom.xml file. i don't. this is lein, i have a project.clj and it looks like the dependencies are there instead. http://devcenter.heroku.com/articles/local-maven-dependencies
13:05muhoohow woudl i translate those instructions from maven into lein?
13:05technomancymuhoo: I recommend using this instead: https://github.com/technomancy/s3-wagon-private
13:05technomancyshould see about getting that devcenter article to mention it
13:06TimMctechnomancy: But otherwise, you would just add a file: repo to your project.clj, right?
13:06muhootechnomancy: very cool, thanks!
13:08technomancyTimMc: yeah, but ... binaries in git; yuck.
13:08muhooi don't mind having it on s3. and yes, binaries in git makes my skin crawl
13:09muhooin fact, i don't even need credentials, i expect i could do this over http too
13:09muhoothis stuff isn't private or confidential, it's just not in anyone's maven repo
13:09technomancyoh yeah, in that case you can use http
13:18gtrakha, rich hickey calls { a curly in his vid, I'm vindicated
13:31maiowhich version of Clojure is prefered for newbies?
13:32sritchiedo you guys any recommendations on how to check equality of two regexes?
13:32sritchie,(= #"string" #"string")
13:32clojurebotfalse
13:32sritchieI guess this works:
13:32sritchie,(= (.pattern #"string") (.pattern #"string"))
13:32clojurebottrue
13:32technomancysritchie: yeah, that kills me
13:32gtrakmaio: check out https://github.com/arthuredelstein/clooj
13:34sritchietechnomancy: I wonder why implementation isn't value-based
13:34gtraki don't use it, i recommend it for people to play around with? remind me of drscheme
13:35gtrakexcept, now that I try it, it doesn't work at all :-)
13:35cemerickmaio: just grab leiningen, and you can get started in the REPL in a snap
13:36cemerickalternatively, there are plugins for all the major Java IDEs and emacs
13:36faust45what is the best way to dispatch method for empty list and not empty list?
13:36cemerickmaio: http://dev.clojure.org/display/doc/Clojure+Tools
13:37faust45so i have two cases for empty list return '() and for not empty return lazy-seq
13:37faust45but i wish to avoid (if code
13:37Raynesgtrak: I mean, clooj would be a good way to get started if it even supported syntax highlighting.
13:37gtrakRaynes: yea, I thought it was further along than it is
13:38RaynesThere are Clojure plugins for generally every popular editor/IDE and it is almost certain that any given person coming to Clojure is already familiar with one of them. I just don't know where clooj fits in.
13:38maio<- Vim guy :) I'm asking because I every now and then I end with "Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite" errors
13:38RaynesNot to dismiss the fellow's work. It is quite admirable.
13:39Raynesmaio: I use Vim too (these days, anyways). :>
13:39RaynesIt is an excellent environment for Clojure.
13:40raekmaio: try creating a new temp project, change the clojure version to "1.2.1", run lein deps, delete the temp project
13:41technomancyyou're pulling in a broken plugin that declares its own version of Clojure
13:43maioyes. (this time) It started when I installed nailgun plugin
13:43rlbfaust45: multiple function bodies, perhaps? (defn foo ([] 42) ([&x] 13))
13:44maiois there something I can do about it?
13:44faust45rlb: (defn foo []) not work for me if call (foo '())
13:47cemerickfaust45: An empty seq can be a number of different concrete types. Just use a conditional. (if (seq x) y z)
13:48faust45cemerick: LazySeq never become EmptyList
13:49faust45type
13:49faust45cemerick: so its impossible dispatch on type
13:50cemerickfaust45: of course it can. &(class (rest (lazy-seq [1])))
13:50cemerickuh, lazybot?
13:50cemerick,(class (rest (lazy-seq [1])))
13:50clojurebotclojure.lang.PersistentList$EmptyList
13:51cemerickfaust45: you can dispatch on type, it's just hardly ever a good idea. What are you actually trying to accomplish?
13:51faust45clojurebot: great )
13:51clojurebotTitim gan éirí ort.
13:51Raynescemerick: ##(class (rest (lazy-seq [1])))
13:51lazybot⇒ clojure.lang.PersistentList$EmptyList
13:51Raynescemerick: Don't blame lazybot for your inability to understand him. He is a complex being.
13:52cemerickThe beatings will continue until lazybot can read my mind.
13:52Raynescemerick: We'd just go with &&(), but that'd blow up in our face for channels where people use languages like Ruby.
13:52RaynesSame with &()
13:52faust45cemerick: thanks will try
13:53faust45Raynes: why you confused about ruby use case ?
13:53cemerickRaynes: I figured you'd set up per-channel characters.
13:54Raynescemerick: Man, we've set up so much per-channel crap that our config file is like 100 line long and it's all one big map. I'm to the point where anything that requires me to have per-channel configuration, I just disable entirely and forget exists.
13:55Raynescemerick: I originally planned for lazybot to be an end-user bot, but I don't think any non-programmer in the world could figure it out at this point.
13:59cemerickRaynes: are there end user bots?
14:06amalloylazybot ends users
14:08jsabeaudryRecommandations regarding a lein clojurescript plugin? lein-cljsbuild looks like it has a lot of features
14:11jkdufairi've been using clojure-mode and the swank-clojure lein plugin. What do i need to use my local emacs to control swank running on a remote server? an explicit slime install? will it conflict with the slime embedded in clojure-mode?
14:12technomancyjkdufair: yeah, manual slime install; you can use marmalade
14:12jkdufairsuper. thx.
14:12technomancyor if you use an emacs instance that has already jacked in, it'll already have it.
14:12technomancymight be nicer not to rely on that leftover copy though
14:12jkdufairhow does that work?
14:13technomancyhow does which work?
14:14jkdufairusing an instance that is already jacked in? in other words, where is slime in clojure-mode? didn't see it in the sources
14:14jsabeaudryemezeske, Out of curiosity, why arent hooks and :jar true the default values in lein-cljsbuild?
14:14technomancyit's a "payload" that comes from the swank-clojure jar
14:14jkdufairoh fascinating. thx.
14:15jkdufairclever idea.
14:16technomancyit's insane. =)
14:23emezeskejsabeaudry: I don't think there's any way to enable the hooks by default
14:23emezeskejsabeaudry: And the plugin began life without :jar support, so when it was added, we made it default to off for backwards compat.
14:40jsabeaudryOk I got hiccup and clojurescript but what about css?
14:42fliebeljsabeaudry: There where some DSLs, but nothing really useful afaik.
14:47jkdufairhow do i get swank-clojure to listen on an external interface?
14:49pjstadigjkdufair: according to `lein help swank` it accepts port and host arguments
14:49pjstadigso you should be able to do something like `lein swank 6666 123.123.123.123`
14:49jkdufairpjstadig: thank you. wasn't aware of lein help :-O
14:49pjstadig:)
14:56tscheibljsabeaudry: cssgen from paraseba (it's on github) is quite useful
14:57jsabeaudrytscheibl, Thanks I'll take a look
14:59tscheibljsabeaudry: i've been using it for quite some time know... for generating css on the fly in compojure routes
15:00tscheibljsabeaudry: it's better than writing css directly because it's composable and supports inline hierarchies
15:00jsabeaudrytscheibl, Is that so the users can modify the "skin" of the site?
15:01tscheibljsabeaudry: it renders to pure css ..
15:02tscheibljsabeaudry: I usually create compojure routes which set the Content-Type to "text/css" and return on the fly generated css
15:03amrohttp://hastebin.com/qihujumime.lisp I get java.lang.NullPointerException after the ex[ected pit[it
15:03amroexpected output*
15:04jsabeaudrytscheibl, Yes I was curious to know in which context you would like to generate css on the fly?
15:05tscheibljsabeaudry: you could parameterize it that way
15:05tscheibljsabeaudry: using get query paramters
15:07tscheibljsabeaudry: e.g. using hiccup: (include-css "/main.css?background=green")
15:08tscheibljsabeaudry: in that case you would probably have to add nocache headers to the response
15:10tscheibljsabeaudry: you could also use it to compile static css from clojure files and include these in your html
15:10rsenioranyone around that can talk about the build.clojure.org setup?
15:13tscheibljsabeaudry: where maybe cookies would be the best way to make the skin user configurable
15:26aphyrtw
16:30the-kennyIs there a swank server for clojurescript?
16:33technomancythe-kenny: there's one for Javascript, but I've never used it
16:35technomancythe swank-clojure codebase is extremely intertwingled with Java though
16:40the-kennyunderstandable. One would most likely have to write a "real" swank server in clojurescript.
16:40the-kennyAlso, there's the problem of compilation
16:41clj_newbis it possible to define defrecords Foo, Bar, s.t. (.open foo) -> returns a Bar, (.close bar) -> returns a Foo ?
16:44TimMcAh, a circular dependency?
16:44TimMcIf you use protocols... maybe?
16:44clj_newbyes
16:44clj_newbah, so (.open foo) returns a BarInterface object, and (.close bar) returns a Foo interface object?
16:45TimMcYes, although that might just net you a new circular dep. :-)
16:45clj_newbat the interface level ; hmm
16:46TimMcIs this part of your scheme to create TYped Clojure?
16:46clj_newbsssssh, that could get me lynched
16:46tjgillieshow do i access functions is projectname.core namespace from lein repl?
16:46clj_newbThis is part of building my WYSIWYG editor, I'm implementing functional zippers on my own
16:47tjgilliess/is/in/
16:47clj_newbso there are "closed/open" nodes
16:47gtraktjgillies: use or require
16:47the-kennyLet's track clj_newb down and lock him behind 10^100 layers of parenthesis.
16:47xianHi, just a quick question: When I create an uberjar with leiningen, how do I ensure that additional jars specified in :extra-classpath-dirs are available/included in the resulting uberjar?
16:47clj_newband they need to return each other based on open/close
16:47tjgilliesgtrak: thnx
16:47brehautclj_newb: https://github.com/frenchy64/typed-clojure
16:47technomancyxian: only dependencies go into the uberjar
16:47gtraktjgillies: and you can in-ns to switch to your desired namespace, but it won't be compiled until it's require'd i think
16:48xiantechnomancy: Okay, is there an easy way to add arbitrary jar files as dependency?
16:48clj_newbbrehaut: certain looks interesting thanks
16:48TimMcUpload them to clojars
16:48technomancyxian: yes, you can publish them to s3, either in a public or private bucket
16:48technomancyclojurebot: repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability
16:48tjgillieswhats the syntax? i keep getting errors
16:48brehautclj_newb: im pretty sure its just experiemental
16:49tjgillies(require 'project/core) ?
16:49TimMcclojurebot is pondering your request
16:49gtraksomething like that
16:49TimMctjgillies: got, not slash
16:49TimMc*dot
16:50clj_newbbrehaut: yeah; but it has interesting links to read
16:50clojurebotAck. Ack.
16:50TimMchaha
16:50tjgilliesTimMc: thnx
16:50TimMc~repeatability
16:50clojurebotrepeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability
16:50clj_newbon a complete unrelated note, is it just me; or does anyone else have an intense urge to write cocoa apps (osx, ipad) in clojure?
16:50technomancyugh; no
16:51xiantechnomancy: Hmm, I would prefer another way, actually. Uploading them to s3 requires too much work just to get some external jars included in my clojure project.
16:51technomancyxian: have you tried it? it's much easier than the alternatives.
16:51technomancyunless you're ok with "works on my machine; good enough"
16:52TimMcxian: Do you plan on having other people use your code?
16:52clj_newbah ha
16:52clj_newbI think what I need is extend-typ
16:52clj_newbe
16:53xiantechnomancy, TimMc: I just put my jars in the lib directory and building the uberjar worked fine.
16:53xianTimMc: Not directly. Other people will interact with the uberjar.
16:53TimMcclj_newb: Yep, you'll use that after the protocols and records are defined. Have you succeeded in getting both protocols defined?
16:54clj_newbTimMc: yeah; there's no circular dependency at the protocal level since there arne't return-type signatures in protocols
16:54TimMcAh, nice.
16:55clj_newbis there a book that coers all this stuff?
16:55clj_newbI don't see it in programing clojure
16:55TimMcclojurebot: private jars is <reply> To depend on private jars, use https://github.com/technomancy/s3-wagon-private
16:55technomancyxian: if you don't care about making it work on other machines you can use lein-localrepo to turn standalone jars into real dependencies
16:55TimMcclj_newb: It's new in 1.3, how old is the book?
16:55clj_newbTimMc: says copyright 2009
16:56TimMcNot recent enough.
16:56clj_newbis any book recent enough?
16:56xiantechnomancy: Ah, I see. And yes, I only want to build the uberjar on my machine. Others won't interact with the code. Thanks for your help.
16:56clojurebotIk begrijp
16:56TimMcI don't know.
16:57clj_newbah, according to amazon, there's a new edition in april 2012
16:57TimMcxian: Well, just make sure you leave sufficient breadcrumbs so that you or someone else can figure out how to build it in the future.
16:57technomancycool
16:58TimMcclj_newb: Read through the sidebar links on http://clojure.org/, you'll pick up some new stuff.
17:00tcrawleytechnomancy: in lein 2.0, are you doing away with the ability to override :library-path, :resources-path, etc? The lack of defaults in leiningen.core.project leads me to believe that
17:02technomancytcrawley: you can override :resources-path and :source-path and friends
17:02technomancy:library-path is gone altogether; classpaths are constructed directly out of ~/.m2; so there's no more need to gratuitously copy dependencies around.
17:03TimMcNo more ./lib?
17:03tcrawleytechnomancy: ah, cool - I see :resources-path now, thanks
17:04gfrederickshow will negligent coworkers accidentally and irrevokably add 30mb of jars to the git repo?
17:04technomancythe lib/ directory was more of a historical accident from the days of M-x swank-clojure-project than something actually useful
17:04technomancygfredericks: I have no doubt their ingenuity will find a way!
17:04gfredericksI guess there's still the build outputs
17:04tcrawleytechnomancy: right now, in Immutant we assume lib/, and add the contents to the module class path for the app. if lib/ no longer exists, we'll need to suss the classpath from lein, but I suspect that won't be difficult
17:05TimMctjgillies: `lein classpath`
17:05TimMctjgillies: Sorry, that was meant for tcrawley
17:05technomancyyup
17:05tcrawleyTimMc: well, it will be a bit more involved that that, but I can find it from there. thanks!
17:06technomancyit would be easy to write a copy-deps plugin, but there's just no need to have it built-in
17:06TimMcwhoa
17:06TimMcI just realized that a meter is basically a baker's yard
17:07brehautwelcome to the future TimMc
17:07TimMchigh on the metric system
17:08TimMcSorry. ANYWAY.
17:08brehautthe initial euphoria should pass fairly quickly. it'll seem very ordinary in no time
17:09gfredericksha: TIME. When are we switching from years to kilodays?
17:09TimMctechnomancy: I assume lein2 will be able to use the vast majority of project.clj files out of the box?
17:10AimHereThen it stops being fun. You're just thinking in metres, kilometres, kilogrammes, just in order to feel normal each day.
17:10TimMcgfredericks: I already say things like "I'll be back in about a metric hour" just to mess with people.
17:10clj_newbshould I prefix protocols with I or P, i.e. IFoo or PFoo?
17:11TimMcclj_newb: From the Java side, they just look like regular interfaces, right?
17:11TimMcI haven't worked with protocols yet.
17:12clj_newbI do not know enough about clojure to know.
17:17lucianclj_newb: i've seen them prefixed with P. i wouldn't prefix them with anything, though
17:19jcrossley3clj_newb: i think the context in which a protocol is used makes the prefixes superfluous. i don't even like using 'em in java, myself.
17:19hiredmanmy irc client only shows me timestamps in kiloseconds since midnight
17:20TimMcWhich midnight, O /ignore'ant one?
17:20TimMc(UTC would be best.)
17:21jsabeaudryAnyone knows how to tell cljsbuild to look into lib so it can find cljs libraries such as pinot?
17:22clj_newbhmm; I like my hungarian notation.
17:22TimMcclj_newb: As long as it's Apps Hungarian.
17:28emezeskejsabeaudry: The missing support for that is a bug (that I plan to fix this evening)
17:28jsabeaudryemezeske, Sweet! I'll use cljs-watch for the time being
17:30technomancyTimMc: yep, the main blocker will be plugins that use Leiningen functions that have moved.
17:32jcrossley3clj_newb: TimMc: i don't even think Simonyi uses hungarian notation any more. :)
17:59the-kennyemezeske: Nice to hear this. I wated to report this bug today :)
17:59the-kennys/wated/planned/
18:44emezeskejsabeaudry, the-kenny: I'm trying to decide how best to fix the lib/ problem. I wonder if everything in :dependencies should be accessible to the cljs project, or if maybe I should add a new :dependencies option to the :cljsbuild config
18:44Raynesemezeske: http://blog.raynes.me/blog/2012/02/01/i-code-with-things-and-stuff/ I gibs vim love (and link to your copy of paredit.vim).
18:46jsabeaudryemezeske, I would tend to make everything in :dependencies and :dev-dependencies available
18:46the-kennyYup, me too.
18:46the-kennycljsbuilds own :dependencies would lead to a problem with hybrid jars which contain .clj and .cljs (like cljs-uuid)
18:48emezeskeI guess my only worry is that cljsbuild depends on clojure 1.3.0
18:48emezeskeWhat would happen if the project used 1.2.x?
18:48emezeskeRight now, the plugin uses leiningen's eval-in-project to always use 1.3.0
18:49emezeskeI'm not a jar expert, but it seems like conflicts could arise (?)
18:49emezeskeRaynes: Awesome, I'll have to give that a read-through!
18:50technomancyemezeske: yeah, declaring a direct dependency on a project that requires 1.3 will cause issues. you would have to run cljsbuild code inside eval-in-project as well
18:51emezesketechnomancy: That makes sense. I'm trying to figure out how to allow the cljs code to have jar dependencies
18:52emezesketechnomancy: right now it uses eval-in-project and does not assoc in anything from the parent
18:53technomancyemezeske: wouldn't it make sense to just say that projects that have clojurescript components can't use 1.2?
18:53emezesketechnomancy: Hmm, that seems fair. I doubt anyone that uses cljs is not up to 1.3 by this point
18:54emezeskethe-kenny, jsabeaudry: Informal survey: are your projects using clojure 1.3?
18:54TimMcI'd liek to maintain import-static from old contrib. Any thoughts on how to do this?
18:55TimMc(Should I just fork and delete everything else?)
18:57the-kennyemezeske: Yup
18:59emezeskethe-kenny: Okay, thanks
19:04cmajor7what space does "loop/recur" consume? heap?
19:05TimMccmajor7: constant space
19:05TimMcOh, you mean where does it allocate locals?
19:05cmajor7yep. where does it keep the "memories"
19:05TimMc?
19:06TimMcAs I understand it, the JVM basically puts everything in the heap.
19:06cmajor7well… recursion (unless it is "tail") keeps them on the stack
19:07cmajor7ok.. so loop/recur saves the "recursion" point in heap
19:07cmajor7right?
19:08hiredmanit doesn't consume space, that is the point
19:10cmajor7hiredman: I see, so it is in a way tailed..
19:10cmajor7like:
19:10cmajor7fac( N ) ->
19:10cmajor7 fac ( N, 1 ).
19:10cmajor7fac ( 0, Holder ) ->
19:10cmajor7 Holder;
19:10cmajor7fac ( N, Holder ) ->
19:10gfrederickscmajor7: that's why loop/recur exists
19:10cmajor7 fac( N - 1, N * Holder ).
19:10cmajor7(erlang)
19:10hiredman~pastebin
19:10clojurebotExcuse me?
19:11hiredmanclojurebot: paste you jerk
19:11clojurebotNo entiendo
19:11hiredman~paste
19:11clojurebotpaste is gist
19:11gfrederickscmajor7: because the native JVM functions won't do tail recursion
19:11hiredman~gist
19:11clojurebotgist is forget paste
19:11amalloyhiredman: he can't remember "paste is gist.github.com" because the . ends the factoid
19:11gfredericksclojurebot: paste is gist,github,com
19:11clojurebot'Sea, mhuise.
19:12hiredmanamalloy: that is not true
19:12hiredman~forget paste |is| gist,github,com
19:12clojurebotI forgot that paste is gist,github,com
19:13amalloyhiredman: okay. i'd be delighted to learn the right way to teach him, then, becase at least three times i've seen someone teach him gist.github.com and he parrots back just gist
19:13cmajor7gfredericks: right. so loop/recur pair takes an existing state, creates a new [single] stack frame, passes the state to that stack frame, and leaves the past to GC?
19:13hiredmanamalloy: most likely because some taught it 'paste is gist'
19:13hiredman~gist
19:13clojurebotgist is https://refheap.com/
19:13hiredman~paste
19:13clojurebotpaste is http://gist.github.com/
19:13hiredman~paste
19:13clojurebotpaste is gist
19:13hiredman~paste
19:13clojurebotpaste is gist.github.com
19:13hiredman~paste
19:13clojurebotpaste is http://gist.github.com/
19:14hiredmanetc
19:14amroany idea why I'm getting a NullPointerException with this macro? http://hastebin.com/qihujumime.lisp
19:14hiredmanamro: to start with docstrings go before arg lists
19:15hiredmanto end with, look at the macroexpansion
19:15gfrederickscmajor7: I don't know the GC details but it certainly doesn't accumulate space like explicit recursion does
19:16amrohiredman: yes, there's an extra pair of () around it
19:16amroI don't know how to get rid of it
19:16hiredmanextra how?
19:16hiredmanyou have a for
19:16amro((print "a")) instead of (print "a") for instance
19:16hiredmanfor is list/seq comprehension, so the result is a seq
19:17cmajor7gfredericks: that I see from the documentation. I was wondering the under the hood state of things.. it seems that it only keeps a single stack frame at a time..
19:17amrohow do I flatten just the topmost seq then? and have it return (print "a") (print "b") etc
19:18weavejesterYou probably want a (do ~@(for ...))
19:18weavejesterBut using a macro to do this is pretty strange
19:18weavejesterIs it just for practise?
19:19amroweavejester: that doesn't work, I tried it. I get Var clojure.core/unquote-splicing is unbound.
19:19amalloyalso, drop the # in b#. it will just confuse people (mostly you)
19:19amroI dumbed down the macro so I can figure out what's wrong
19:19weavejesterYou probably forgot the beginning backtick
19:19weavejesterIn total it should be `(do ~@(for ...))
19:19amalloy&(let [body '(a b)] `(do ~@(for [b body] `(print ~b))))
19:19lazybot⇒ (do (clojure.core/print a) (clojure.core/print b))
19:20amrothat's it, thanks
19:20amroI wasn't sure how to combine ` with ~@
19:20weavejester~ and ~@ go inside `()
19:20clojurebotGabh mo leithscéal?
19:21weavejesterIt's like string interpolation in Ruby, Bash or Perl
19:21weavejester"hello $foo" is kinda equivalent to `(hello ~foo)
19:21amroamalloy: b# was part of the expanded macro when I first wrote it
19:21weavejesterExcept you're using data structures instead of strings
19:22amalloypersonally i slightly prefer (cons `do (for ...)) to `(do ~@(for ...)), but i don't have a compelling argument
19:23amalloyi guess it forces me to keep in mind that really macros are functions for building lists, not "magic templates"
19:23weavejesterNot just lists in Clojure ;)
19:23gfredericksthe magic rose ~@
19:25amalloyweavejester: yeah, i know. having a macro expand to just an integer or a string is pure magic
19:26weavejesteramalloy: Hiccup makes does a lot with strings :)
19:27amalloyi feel like there must be very few cases where (html ...) expands to a string, though
19:27weavejesterYeah, it only expands to a string if there are no variables in the mix
19:27weavejesterDoes anyone else find that search engines are surprisingly good nowadays?
19:27weavejesterI mean, I take them for granted
19:28amalloyi guess that's only half-true, because (html [:div foo bar]) expands recursively to something like (str "<div>" (html foo) (html bar)], and then foo and bar might be literal strings
19:28weavejesterBut even using them everyday sometimes they manage to match queries to the right page with very little info
20:05amalloytechnomancy: make is pretty good. i'd definitely prefer it to ant, for example
20:06technomancyhigh praise
20:07amalloyyeah yeah
20:07technomancyI guess in my mind make is tainted by autotools
20:07technomancyguilt by assosiation
20:07amalloyyeah, autotools are something i cannot fathom at all. maybe it's great, but it is so bewildering
20:07brehauti can only presume that once upon a time, it didnt seem like a bad idea
20:08brehautand then it metastasized
20:08technomancythe fact that people who seem otherwise intelligent put up with them makes me think that the alternative of doing that kind of stuff by hand is just too horrible to comprehend?
20:08technomancyit is beyond my feeble imagination
20:36TimMcAny tips on testing namespace-manipulating functions?
20:37TimMcI don't want to contaminate my test namespace. Currently trying to write a macro that will evaluate its contents inside a temporary namespace.
20:39technomancyTimMc: copy what slamhound does
20:39technomancyeach run generates a throwaway ns named after a gensym
20:41TimMcI think I finally have it, thanks.
20:41TimMcBut I'll look at slamhound for sure.
20:42TimMcI ran a test in my REPL that worked differently line-by-line vs. as a single 'let form.
20:59jcromartieso I'm digging the REST vibe right now
20:59jcromartieand I am getting this idea that you could actually build a perfectly RESTful API without actually setting up routes for resources
21:00jcromartiei.e. by leveraging hypermedia and continuation-style callbacks of some sort
21:01jcromartielike, in your server-side API, you return a resource where the actions called by verbs are just closures tied to unique URLs
21:01jcromartieI hope that's not too ASP.NET
21:09seancorfieldjcromartie: do you have example code somewhere? how do you map the urls to actions?
21:10jcromartieI'm working on it :P
21:10jcromartielet me whip up an example
21:10brehautjcromartie: i dont see any reason why that couldnt be restful; nothing about rest requires you to have stable URLs
21:11brehaut(stable in terms of the app configutarion)
21:11jcromartiebrehaut: yes, that's the point
21:11jcromartiewell there do need to be stable entry points
21:11brehautsure
21:11jcromartieI think I basically just came up with Seaside for APIs
21:11jcromartiebut not so fancy in the use of continuations
21:12brehautjcromartie: yeah
21:13brehautjcromartie: as long as you keep the old URL callbacks around in case the client passes you an older version of the state, then it should be fine
21:14jcromartiebut deleting the non-idempotent verbs when they are executed
21:14jcromartiethat has the added benefit of not eve being able to accidentally DELETE something twice
21:17martinklepschwhat is the reason behind "acc" as loop binding name?
21:17brehautaccumulator
21:19brehautwhich i guess is following on from the registers of the same name
21:19martinklepschok
21:22martinklepschI don't get how acc is being bound to the new value in the (recur) example here http://clojure.org/special_forms
21:22martinklepschcould anyone explain me that?
21:23gfredericksmartinklepsch: the loop contains two bindings, so in the call to recur the second argument gets bound to acc
21:24martinklepschokay so when i have 3 bindings I'd have 3 arguments to recur etc?
21:24brehautyes
21:24gfredericksexactly
21:25martinklepschmakes sense...
21:42wiseenis there a library for serializing things to clojure Data that's more flexible than (prn-str x) ... eg. I would like java.util.Date to be serialized and some other primitives (URI)
21:43gfrederickswiseen: print-dup might be what you want?
21:46wiseenclojurebot ,(doc print-dup)
21:47ibdknoxhola
21:48Raynesibdknox: stfugoaway
21:48ibdknoxRaynes: h8.
21:51TimMcwiseen: print-dup is a multimethod you extend.
21:57blakesmithCan anyone recommend a good clojure memcache library?
22:05jcromartiewhy did I just write a JSON library
22:05gfredericksthere's nothing funner
22:05jcromartiethis sort of thing happens
22:06TimMcIt really does.
22:06jcromartiehttps://gist.github.com/3872b7bfd382ef706bd9
22:07jcromartieI think it was because I didn't feel like opening project.clj
22:07jcromartieand adding the dependency
22:07ibdknoxthat's so much slower :p
22:08jcromartienerds will go to great lengths to be lazy
22:08brehautthat sums up haskell
22:11TimMcpffft
22:12TimMcI can't remember why I ended up dropping clj-json in favor of cheshire...
22:15ibdknoxTimMc: everyone's doing it :p Raynes made me change it in Noir
22:15ibdknoxsomething to do with "more features" and "just as fast"
22:21TimMcOh! clj-json gave me string keys, I wanted keyword keys
22:23TimMcNo, it was *coercions* not being marked :dynamic, that was it.
22:23TimMcLooks like that one is fixed.
22:55Raynesibdknox: The bad part is that a coworker seems to be the maintainer now.
22:55ibdknoxRaynes: of clj-json?
22:55RaynesMaking everybody switch to cheshire is probably not a good career move.
22:55ibdknoxlol
23:00seancorfieldhow many json libraries do we have? and what's wrong with clojure.data.json?
23:00TimMcseancorfield: What's wrong with it is that I didn't know it existed. :-P
23:04seancorfieldformerly clojure.contrib.json
23:05ibdknoxseancorfield: it's not very fast I thought
23:05ibdknoxat least not compared to something using jackson
23:06seancorfieldi guess it depends whether it's "fast enough"
23:07ibdknoxformat conversions are one of those things that should just be as fast as possible
23:07seancorfieldbut i'd prefer we all worked to improve the standard clojure.* whatever libraries than proliferate incompatible alternatives :)
23:07brehautibdknox: unless its xml-rpc
23:07brehautibdknox: that might encourage someone to want to use it
23:07ibdknoxlol
23:09TimMcseancorfield: Speaking of which, I'm trying to adopt import-static right now.
23:10TimMcIt currently works by making macros, so you can't do (import-static '(java.lang.Math sqrt)) (map sqrt (range 10))
23:10TimMc...but I don't know what my chances are of getting my version blessed.
23:11seancorfield:)
23:11seancorfieldwell, after that drive-by pot-stirring, i'm off to watch TV and drink wine... or whisky perhaps?
23:12TimMcheh
23:12TimMcWhat is the beverage of choice of trolls? :-P
23:14Raynesseancorfield: I see no real point in improving clojure.* if a non-contrib library is better and significantly faster. You can't clean shit.
23:15RaynesAnd that came out a lot more rude to whoever the original author of that library is than I meant it to be.
23:15brehautRaynes: but you can dunk it in varnish
23:15RaynesMy point is, if the library can't be fast, why support it in the first place?
23:15RaynesThe only reason cheshire can't be a contrib library (or clj-json for that matter) is because it relies on a fast Java library.
23:16TimMcThe official libs also have the stigma (deserved or not) of not being able to move quickly.
23:16RaynesBut really, I hate the distinction between 'contrib' libraries and libraries that people make.
23:16seancorfieldthe guys on mythbusters proved that you _can_ polish a turd, btw
23:16TimMcRaynes: The contribs are just the officially blessed libs, yeah?
23:17RaynesIt seems to me that contrib is only useful for political purposes and for people who really like XML and terrible JIRA issue managers.
23:17brehautRaynes: i dunno, i think contrib as a 'this project has proven to be great, lets promote it into a more visible tier' is valuable; eg core.logic
23:17RaynesThat's kind of my point.
23:17RaynesThe JSON lib *isn't* great. It's slower than ever other library.
23:18RaynesBut we should work on it because… it's officially sanctioned and written in pure Clojure?
23:18Raynesinb4 itisn'tpureclojurebecauseitcallsouttojava
23:19jeremyheilerIf a project is blessed, doesn't that immediately raise the barrier of entry to support it, as opposed to just being a popular project that doesn't have the same contributor rules as clojure porper?
23:19seancorfthere are discussions around using external dependences in some contrib libs... it might happen...
23:19jeremyheilerproper*
23:19seancorfand the new process is meant to be a lot more streamlined and faster to evolve code
23:20RaynesNo, because being officially blessed means you have to go through hell to actually contribute.
23:20RaynesNot that they don't have excellent reasons for the hellish procedure.
23:20seancorfbut the important distinction is a legal one: contrib libraries are protected under the same license / IP as clojure itself - which is of concerns to a lot of companies
23:20RaynesSome of them, anyways.
23:20RaynesYeah yeah yeah, I know.
23:21RaynesNot a lawyer.
23:21RaynesThankfully.
23:21seancorfand to be honest Raynes the process really isn't hellish :)
23:21RaynesIf we're talking about barrier to entry, I'd be happy to hear of a single point in the favor of non-hellish.
23:21seancorfi ended up maintaining java.jdbc without much fuss, because i needed contrib.sql running on 1.3
23:23seancorfthere are a LOT of people with signed CA's on file which means a large pool of people who can submit patches
23:24RaynesBut we were talking about barrier to entry, right?
23:24seancorfall the open source projects i know have a similar barrier to entry
23:24seancorfyou have to sign a CA and follow the patch process
23:24cmajor7"recur special form can also be used as the last call in a function to return to the beginning of that function with new arguments" => would this be a common use? or the one to avoid? ##(defn recursive ([number] (recursive number 1)) ([number factorial] (if (zero? number) factorial (recur (- number 1) (* factorial number)))))
23:24lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
23:24RaynesI sure don't know of a lot of them.
23:25RaynesBut I wasn't arguing against the CA.
23:25RaynesLike I said, I'm not a lawyer.
23:25jeremyheilerseancorf: Is a maintianer of a contrib allowed to process patches at their own pace? So, for example if a popular library with an active community is blessed, that shouldn't hurt the project in anway, right?
23:25jeremyheilerIf*
23:25jeremyheilersorry, Is*
23:25Raynesseancorf: As a lib maintainer, are you allowed to accept patches and issues on Github?
23:25jeremyheiler(sans a CA agreement form all)
23:26seancorfno pull requests allowed
23:26RaynesI consider JIRA a massive barrier to entry, dismissing all the CA stuff.
23:26jeremyheiler^agreed.
23:26TimMcseancorf: Ouch.
23:26RaynesI consider JIRA a massive barrier to *anything*.
23:26seancorfpatches via JIRA are the acceptable way
23:26seancorfit's because of legal traceability of copyright
23:26TimMcI'm not going to even bother trying to get this contrib I'm maintaining blessed.
23:26RaynesWell, at least they've got their asses covered. *shrug*
23:27RaynesReally, really well.
23:27seancorflike i say, just like all the other open source projects that corporations feel comfortable using
23:28jeremyheilerFor core, I think the CA and legal stuff works really well. That's important. But I think it really makes it undesirable to have a library blessed into contrib if it wasn't specificlly written to be there in the first place.
23:28seancorfwhen i worked at macromedia / adobe i had the "pleasure" of going thru a license audit on a large project
23:28TimMcseancorf: Ah, you're saying that this is effectively due to pressure from corp.s that want to use these projects?
23:28RaynesI'm fine with companies not using my projects if I get to maintain them in a sane was a resut.
23:28Raynesresult*
23:28seancorfyeah, without that stuff, many corporations cannot use an open source project
23:28seancorfi want clojure to be usable by such companies so i'm happy to comply with the process
23:29RaynesThe way I feel at this point is that I just hope nobody puts any libraries I like into contrib so that, if I ever have to contribute to them, I don't have to go through all the nutty crap involved. That's just me though.
23:29TimMcseancorf: I don't see why you can't get the same traceability via Github permissions.
23:29nuclearsandwichRaynes: agreed
23:29RaynesTimMc: Apparently if you delete your account, your name disappears.
23:30TimMc>_<
23:30seancorfTimMc: because you have to go back thru the entire repo history and ensure that all committers have signed CAs on file
23:30TimMcBut the commits are still there!
23:30TimMcseancorf: Not hard. There is rarely a ton of committers.
23:30RaynesIt's probably only a matter of time before they have the code in git repos hosted on their server, just in case. :p
23:31TimMcseancorf: Although I guess someone could lie and submit under someone else's name?
23:31RaynesYou could probably send in a fake CA and submit a patch under that. Not sure what would happen. Damn not-being-a-lawyerness.
23:32Tcepsacmajor7: I believe that is a common use
23:32seancorfthe CA is a legally binding document - so it protects the project
23:32jeremyheilerI don't see why accepting a pull request can't involve a core committer checking the user for a CA first. I Imagine that is done in JIRA anyway?
23:32RaynesYou can only get a Jira account if you've been sanctioned by a team member.
23:32seancorfjeremyheiler: because then the burden is on core which isn't fair to the project
23:32RaynesIt's admittedly different.
23:32jeremyheilerAh, ok.
23:32RaynesBut...
23:33seancorfhaving been thru the other side of this at a corporation, i can only say that this is necessary for corporation adoption of clojure and its set of sanctioned contrib libraries
23:33arohnerseancorf: "this" being CAs. JIRA + patches seems to be more of an implementation detail, IMO
23:34arohnerI can imagine Github having a permissions model that would make this painless
23:34RaynesLet the record stand that it is not the CA that I have a problem with.
23:34seancorfyeah, we know you don't like JIRA :)
23:34RaynesIt is the fact that we're only allowed to use a small subset of what Github offers.
23:34RaynesYou might as well host these repositories with gitweb.
23:35TimMcOh, fun with macros: actual: (not (number? (. java.lang.Math (sqrt 3.141592653589793))))
23:35cmajor7Tcepsa: thank you. you mean it is used commonly even though it can be accomplished with "loop/recur"?
23:36seancorf*you* can use the full range of github - you can fork clojure, work on it any way you want...
23:36emezeskejsabeaudry: I just released lein-cljsbuild 0.0.10, which pulls in the host project's :dependencies and :dev-dependencies. Let me know if it works for you!
23:36Raynesseancorf: I'm making sure I'm clear on this. You know I don't like Jira, right?
23:36seancorfbut if you want a patch accepted, you have to put it in a JIRA ticket as a patch :)
23:36RaynesYou can pull from a gitweb repository and work on it anyway you want.
23:36RaynesAnd it is the exact same thing.
23:36TimMcIt's not JIRA that bothers me, it's patch-formatted contributions.
23:37seancorfi agree github's "free-for-all" workflow is more convenient
23:37Raynesseancorf: All a Github fork is is a copy of a repo under your name. It isn't anything special that you need Github for. If that was the full range of Github, I'd probably just use bitbucket and hg.
23:37seancorfbut i also understand that corporate concerns mean a tighter control on IP and contributions
23:37Raynes;)
23:38RaynesYeah, we know you're worried about corporate concerns. :)
23:38seancorfi maintain clj-time and work on congomongo too and it's nice to be able to accept random pull requests but that also means those libraries can't be used by corporations that have license audits :)
23:39jeremyheilerAll I'm saying is that "the process" might just make it less desirable to want a useful lib be blessed into contrib. Wether tha tis important or not, i don't know.
23:39jeremyheiler(from a maintainer's and community perspective)
23:40RaynesThat's where I'm at right now.
23:40seancorfjeremyheiler: understood - and several folks have raised that issue on clojure and clojure-dev MLs over the last year or so (i'm sure it came up before then too but i wasn't around then :)
23:40RaynesBut like I said, that's just how I feel. I understand the justifications and I know that my bitching wont change anything. Doesn't mean I have to like it.
23:40seancorfit's ok, we don't mind being a "shoulder to cry on" about it :)
23:41RaynesYou mean you. :p
23:41seancorfand, yeah, for the record, i wish we could accept pull requests but it is what it is
23:42Tcepsacmajor7: Yes; I believe that's the intent of providing a mechanism to return to the beginning of the current function; it prevents you from having to put in a redundant loop statement if you're essentially doing a tail-call.
23:42RaynesThe important thing is that we're all free to do whatever we want because Clojure *is* open source. If we don't want to put our libraries in contrib then we certainly don't have to. Don't have to use the ones that are there either, but the contrib process wouldn't stop me from using a good contrib library. clojure.data.json doesn't seem to be one of them though.
23:42jeremyheilerI should probably cancel mine then. (I submitted a patch as well, though)
23:42TimMcjeremyheiler: Cancel which?
23:42jeremyheilerthe pull request.
23:42TimMcheh
23:43jeremyheileryeah
23:43Tcepsacmajor7: Put another way, that's how you can approximate tail-call optimization even though the JVM doesn't support it directly.
23:43jeremyheilerRaynes: compeletely agree. And it's simple to fork a contrib lib and modify it for your own needs until a patch is approved.
23:44Tcepsacmajor7: Instead of calling your function again and pass it the new arguments, you call recur and pass IT the new arguments.
23:44kilbornHi, new to clojure, I'm trying to figure out an idiomatic way to do the equivalent of mutating a closure bound variable? I have a function which recurs, and I need it's behavior to be controllable from outside it's scope. Global variables are not the right way... Suggestions?
23:44RaynesThat's generally what I've been doing.
23:44RaynesExcept the sending a patch part. I have to really care to do that.
23:45RaynesBut that's pretty selfish and a habit I intend to break.
23:45jeremyheilerhaha
23:46cmajor7Tcepsa: I see.. so the "loop/recur" actually equals "defn/recur"?
23:46Tcepsakilborn: This is a shot in the dark, but have you looked at using an "agent"?
23:48kilbornTcepsa: I thuought about it (message-passing seems to suggest itself), but I hoped there's a simpler way then going all erlang and stuff...
23:49kilbornI'm pretty close to constructing the function by passing an atom map into it, then pinning the atom symbol on the function's metadata, but that feels too complicated as well.
23:50dnolenkilborn: what you're trying to do doesn't sound all that idiomatic. but you can do it.
23:50Tcepsacmajor7: I am not certain what's actually happening under the hood (I wouldn't be at all surprised if there was some subtle-but-important difference between the two) but that understanding will probably serve you pretty well. I think of them as being two separate things, but as far as how you go about using them, they are very similar. (In other words, it looks like it but I'm not familiar enough with the details to say "Yes
23:50Tcepsaabsolutely" ~wry grin~)
23:50dnolenkilborn: (let [x (atom nil)] (defn foo [] ...))
23:51flazzi'm doing bit operations on an integer, is there a way to not have it convert to a long?
23:52kilborndnolen: hey, you're the core.logic guy! *tips hat*. But then I keep everything in outer namespace, and it *feels* like it should be encapsulated inside the function...
23:52dnolenkilborn: it's not visible, you've create a lexical scope
23:53dnolencreated
23:53Tcepsakilborn: Also, at the hazard of looking like a complete idiot, I ask "Could you use a namespaced variable?"
23:53TcepsaNevermind, you just answered
23:53kilborndnolen: well, if I do it exactly like you suggest yeah, but then how to I modify the atom from say the REPL? i need a symbol in my hand
23:53kilborns/todo/
23:54arohnercmajor7, Tcepsa : recur goes "up" to the nearest recursion point, which is either a loop, or the defn
23:54cmajor7Tcepsa: thanks. in clojure core source I see "loop/recur", hence I suspect it outperform "defn/recur"… the thinking is "loop" just creates a "point/address" of recursion, while "defn" might be a bit more expensive. especially a arrity matching. e.g. (defn fn ([n] (fn n 1)) ([n accum] (…)))
23:54Tcepsakilborn: If you have a "starter function" (no idea what it'd really be called) that creates an atom and passes it to your recurring function and also returns the atom, then you could catch the return value and modify it in your REPL.
23:56dnolenkilborn: it sounds like you're doing something strange :) probably need more context
23:56kilbornTcepsa: True, and that's where I was leaning, but then if my function has 2 lines in it, It feels like i'm balancing dolphins on my nose while simultaneously practicing my limbo skills
23:56Tcepsakilborn: (assuming that it starts the recursive function in a separate thread, but the way you've been talking about it strongly implies that it is in a separate thread from e.g. the REPL)
23:56kilbornDnolen: gladly. you've heard of overtone?
23:56dnolenkilborn: yep
23:57kilborndnolen: great. really basic use case. I have a function which takes in a list of chords, chooses one randomly, and then reschedueles itself to play the next one in say 1000 ms
23:58kilborndnolen: it's all working nicely, but now I want to change the chord choices (say I move to the chorus in a piece, whatever). with closures and set! , or objects and setters, this would be very natural, but with immutable data I can't find the idiom
23:59dnolenkilborn: not sure why an atom at the top level your ns doesn't perfectly solve the problem.
23:59Tcepsacmajor7: I'm not sure, but based on what arohner said I'm guessing that when it enters a function it also places a point/address of recursion. Arity isn't a problem--just think of functions defined with different arities as different functions. Whichever one the recur is in is the one that will be recurred to. (i.e. you can't recur from inside a function that takes two arguments to the inside of a function of the same name that
23:59Tcepsatakes one argument; you'd have to use trampoline for that)