#clojure logs

2011-03-03

00:31ossarehtechnomancy: have you any thoughts / experiences about how hard / easy it would be to get a git revision value in a hooke?
00:41ossarehhm, seems jgit can be wrapped reasonably easily.
00:41technomancyossareh: those seem pretty orthogonal to me
00:41ossarehwell... I want to be able to load a version number into my output html and I figured git version would be the most helpful
00:42ossarehzz my english is sucking right now :/
00:42ossarehi guess my question was more like - have you done this / know of a project doing this.
00:44technomancythe pom.xml that comes with every lein-generated jar has git revision info in it
00:45ossarehOK - that is good. So accessing that from the runtime is just a case of read/parse the pom.xml?
00:48technomancyyeah, should work with clojure.java.io/resource
00:49tomojmine doesn't appear to have git revision info
00:50tomojmaybe I misunderstood
00:51ossarehtechnomancy: ah, and there is the magic - I've realised that through my learning curve with clojure I learn about a new set of language features every 6 weeks or so - I then spend 6 weeks crow baring them into a solution that is usually already handled somewhere in the stdlibs...
01:03technomancytomoj: lein pom has no git info?
01:04tomoj`lein pom && grep git pom.xml` gives only " https://github.com/technomancy/leiningen -->"
01:05technomancyit's actually able to read files straight out of .git/; you don't even need git installed to do it
01:05technomancycrazy
01:05technomancytomoj: is the project OSS?
01:05tomojoh, is it only supposed to work when the project root is the git root?
01:05tomojnaturally, I suppose
01:05technomancyyeah, I guess it might not work for a project that's nested
01:05tomojnope
01:06tomojI tried to argue for multiple repos but wound up with one mega-repo into which all my various projects go :(
01:06technomancyah, bummer
01:07tomojof course in this case it doesn't matter anyway, I'm not publishing the pom and would want to strip any git information that did make it in..
03:28bairespace_,(defn <- [& args] (reduce #(%1 %2) args))
03:28clojurebotDENIED
03:29bairespace_,(+ 2 2 2 2)
03:29clojurebot8
03:40bairespace_,(source core/->)
03:40clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
03:41bairespace_,(doc ->)
03:42clojurebot"([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts ...
03:47bairespace_,[0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b)
03:47clojurebot[0 1 2 #{3 4 5}]
03:53bairespace_,(([0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b) 4)
03:53clojurebotEOF while reading
03:55bairespace_,([0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b))
03:55clojurebot#{3 4 5}
04:03bairespace_,[]
04:04clojurebot[]
04:04bairespace_,{}
04:04clojurebot{}
04:04bairespace_,#{}
04:04clojurebot#{}
07:08clgv&(macroexpand-1 '(when-let [bla blubb] haha hoho))
07:08sexpbot⟹ (clojure.core/let [temp__3589__auto__ blubb] (clojure.core/when temp__3589__auto__ (clojure.core/let [bla temp__3589__auto__] haha hoho)))
07:09clgvwhy are there two let expressions involved? wouldn't one be sufficient?
07:42raek&(macroexpand-1 '(when-let [[foo bar] blubb] haha hoho))
07:42sexpbot⟹ (clojure.core/let [temp__3589__auto__ blubb] (clojure.core/when temp__3589__auto__ (clojure.core/let [[foo bar] temp__3589__auto__] haha hoho)))
07:44raekclgv: I think it is done this way make sure that the expression is only evaluated once, even when combined with desctructuring
07:44clgvraek: thx. hoeck already gave me a similar hint :)
07:57fogus`Whoa! Clojure's juxt is FP's []! That is all
07:58__name__FP?
07:59__name__$source juxt
07:59sexpbotjuxt is http://is.gd/8fgyhN
08:01fogus`http://en.wikipedia.org/wiki/FP_(programming_language)
08:14clgvwhat's that supposed to mean? java.lang.IllegalArgumentException: recur arg for primitive local: sum must be matching primitive
08:15clgvI get it in this line: (loop [complist (second group-complist), cdf (transient []), sum (double 0.0)]
08:17raekclgv: what does the recur form lool like?
08:17mduerksenclgv: is the third argument in in your recur form a double?
08:18clgvit should be. it is like: new-sum (+ sum (f x)) and new-sum is in the recur
08:19AWizzArdhttp://www.classnamer.com/
08:20clgvAWizzArd: "SecureGirlfriendStream" roflmao.
08:24mduerksenclgv: if (f x) doesn't return a double, then + won't return a double as well afaik
08:25clgvmduerksen: ok, but (f x) is a method specified in a protocol. can I type hint its return type?
08:25mduerkseni'm not sure about that. i guess it also depends on the clojure version
08:25clgv1.2
08:26clgvwell otherwise I surround it with (double ...)
08:26mduerksenyou could find out with (class (f x))
08:27clgvI know that it should return a double since I wrote it myself
08:27clgvbut I don't know how to tell the compiler that this protocol method will return a double
08:27raekhrm, I thought this primitive stuff was new for 1.3...
08:28clgvraek: not everything
08:30Chousukefunctions can't return primitives in 1.2 IIRC :/
08:31clgvbut there is the fibonacci example that is said to be valid in 1.2
08:31Chousukehttp://dev.clojure.org/display/doc/Enhanced+Primitive+Support this describes 1.3
08:32clgvoh ok. damn :(
08:32clgvhmm I thought I read something related to 1.2 in a blog entry on ^:static
08:32clgvis ^:static also 1.3?
08:34cemerickIIRC, ^:static became a no-op with the recent var changes
08:34cemericka no-op and unnecessary, that is
08:40clgvok. probably (double ...) will work then
09:00clgv&(doc empty?)
09:00sexpbot⟹ "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"
09:01clgv&(empty? nil)
09:01sexpbot⟹ true
10:36flattshould I be using eval here: (defn [x] (eval (doto (SomeClass.) (.doStuff x))))? can I (or should I) pull it off with defmacro instead?
10:38raekflatt: you very rarely need to use eval.
10:38raekflatt: why not (defn [x] (doto (SomeClass.) (.doStuff x)))
10:38flattoh, wait, that was over-simplified.
10:40flatt(defn [& args] (eval `(doto (SomeClass.) ~(list '.doStuff ~args))))
10:40Chousukeflatt: why would you do that with a function?
10:40Chousukeone big problem with eval is that it can't access locals
10:41Chousukeso all you can pass to your function are symbols that name globals.
10:41Chousukeor literals
10:41raekflatt: ah, so you want something like apply, but for methods?
10:41flattoh, then then eval doesn't help there.
10:42flattimagine variable number of forms in the body of doto, depending on what args are supplied
10:44bennyluhow to use ns-publics? (ns-publics 'some-ns)
10:44bennylu=> #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.IObj>
10:44bennylui want to retrive all the functions in the namespace with a certin type ..
10:44raek,(ns-publics 'clojure.core)
10:44clojurebot{sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, val #'clojure.core/val, chunked-seq? #'clojure.core/...
10:46bennylu, (ns-publics 'clojure.xml)
10:46clojurebot{content-handler #'clojure.xml/content-handler, *stack* #'clojure.xml/*stack*, attrs #'clojure.xml/attrs, element #'clojure.xml/element, tag #'clojure.xml/tag, startparse-sax #'clojure.xml/startparse...
10:46raekbennylu: it looks like the exception is from the code that uses the value of your (ns-publics 'some-ns) call
10:48raekflatt: it is certainly possible to do that with a macro, but dependending on what you know about the methods (e.g. arity) you could possibly implement it as an ordinary function (which is preferred if possible)
10:48bennylui am calling it directly from the repl..
10:49flattraek: I see, thanks.
10:51TimMcbennylu: Are you bennylut?
10:51raekbennylu: what does the stack trace look like?
10:52raekbennylu: also, does this happen for all namespaces? for instance, does (ns-publics 'clojure.core) work for you?
11:03perkinsc,(clojure-version)
11:03clojurebot"1.2.0"
11:09sattvikflatt: If you know the number of arities you will be working with, you can do something like:
11:09sattvik,(let [invoker (fn ([a] (. Integer valueOf a)) ([a b] (. Integer valueOf a b)))] (apply invoker ["100" 2]))
11:09clojurebot4
11:09pyrhi
11:10sattvikThe only other non-macro approach I can think of is using Java's reflection APIs.
11:10pyrit's not clear to me if there's a way to kill agents forcibly
11:10pyri'm using agents with await-for
11:10pyrif an agent returns false from await-for
11:11pyrdo I need to kill it or will the thread be available for a new agent ?
11:11TimMc$findfn [1 2 3] 3 4 [1 2 4]
11:11sexpbot[]
11:12chouserpyr: I don't think there's any good way to forcibly kill an agent.
11:13pyrok
11:15clgvwhere do I get clojure-contrib 1.3.0 alpha 4?
11:49gtrakhow do you guys do a find-usages?
11:53sattvikfind-usages?
11:54gtrakyea
11:55TimMcLike, all references to a var in a project?
11:55TimMcI generally grep. -.-
11:56gtrakI guess that's pretty simple :-)
11:57dakroneb
11:58amalloygtrak: slime has a feature like that, but i don't know if the clojure swank server supports it
11:58gtrakah
11:58amalloyheh, indeed. "Wrong type argument: listp, :not-implemented"
11:59amalloyif it did work, though, it would be C-c C-w C-r
11:59amalloyfor "who references"
12:00bennyluTimMc, yes i am bennylut
12:00gtrakamalloy, i can confirm "error in process filter: who-references is not implemente yet on clojure"
12:00TimMcbennylu: OK, so you were confused some days back about why ^foo didn't give you the metadata on foo. It turns out this was a change from CLojure 1.1. to 1.2.
12:01TimMcI was reading Programming Clojure and ran into the same problem.
12:01bennyluraek, i just checked and to clojure.core and it not throwing exception..
12:01sattvikgtrak: If you wanted to do it within clojure, you could probably abuse the source macro.
12:02bennyluTimMc, Thanks! i was reading the book programming clojure and there it was explained that that sould work, i guess that it changed after the book came of
12:02amalloy$source ->
12:03sexpbot-> is http://is.gd/yfj1XP
12:03__name__good morning
12:04gtrakanyone ever had lein marg throw an exception that it can't find the project.clj?
12:05amalloyTimMc: the findfn you were looking for a bit ago is probably replace
12:05amalloy&(replace {3 4} [1 2 3])
12:05sexpbot⟹ [1 2 4]
12:06TimMcOh, right!
12:06TimMcAnd replace has the wrong semantics for me.
12:06TimMcbehavior, rather
12:07amalloyoh?
12:08TimMcI need identical? instead of =.
12:10TimMcI ended up writing replace-1: https://gist.github.com/853113
12:10amalloyTimMc: you could use an identity map
12:11TimMcWhat's this now?
12:11amalloyhttp://download.oracle.com/javase/1.4.2/docs/api/java/util/IdentityHashMap.html in java - i think there's something similar in clojure
12:12TimMcOh yeah, I just came across that the other day.
12:15TimMcHaha, it works!
12:16TimMc(replace (IdentityHashMap. {d0 d1}) [3 4 d0 5])
12:16amalloyTimMc: or (into (sorted-map-by identical?) mymap)
12:17amalloyexcept rewritten so that it actually works :P
12:25TimMcThat's even longer.
12:25naeuis there anyone about that can help me understand how I may avoid inserting a race condition by using the STM and refs?
12:25TimMcnaeu: Do you just want to make sure that a read-update-write is consistent?
12:26naeuTimMc: I'm not sure what you mean. In my head I want to make sure that if while I read a given ref, it can't be updated elsewhere
12:27naeuperhaps I just want basic locking
12:27naeubut that doesn't feel right
12:27TimMcYou don't want locking. Nobody does, even if they think they do.
12:27naeu:-)
12:27naeuso I have a ref of keywords
12:28naeuand I want one thread to be able to look at that ref, and if a particular keyword doesn't exist in there, to register a fn to be called when it does
12:28TimMcA ref of a collection of keywords?
12:28naeuand on another thread I want to be able to update the ref and add a keyword to the collection
12:29naeuand call all the registered fns associated with that keyword
12:29naeuyup, I'm just currently using a vector
12:29TimMcYou might find a set more appropriate than a vector, depending on your app.
12:30naeuTimMc: oh sure
12:30sattvikDoes ensure solve your problem?
12:30TimMcBut anyway, there are a couple of ways to do this, and I'm still learning about concurrency in Clojure.
12:31TimMcnaeu: You're familiar with dosync, yes?
12:31naeuTimMc: by familiarity, I've used it
12:31naeuand I understand that it stops modification from multiple places by re-running
12:31TimMcSo you know that inside a dosync you have a consistent view of the world.
12:31naeusattvik: so you just call (ensure my-ref) in the dosync?
12:32naeuTimMc: sure, but is that just a consistent view of the refs you modify or also the refs you deref?
12:33TimMcAll of them.
12:33naeuTimMc: perhaps not, it doesn't explain the existence of ensure
12:33naeusattvik: I think that this is exactly what I need
12:34naeuTimMc: I believe that in a dosync the state of a ref you deref may change during the rest of the execution of the transaction
12:35naeuwithout requiring the transaction to re-run
12:35sattviknaeu: Your welcome.
12:35naeuwhereas a ref you modify may not change elsewhere during the rest of the execution of the transaction
12:35naeusattvik: is what I'm saying making any sense?
12:35naeuI might be totally wrong :-)
12:35TimMchuh
12:36sattvikFrom http://clojure.org/refs : No changes will have been made by any other transactions to any Refs that have been ref-set/altered/ensured by this transaction
12:37amalloyyes, that's what ensure is for
12:37chousernaeu: I don't think that's right. Once you're in a transaction, every deref of a ref will return the same value.
12:37naeuchouser: yeah, but it will return the first value
12:38naeueven if the ref has been modified elsewhere since the first deref
12:38naeuat least that's what I understand
12:38chouseroh, maybe I misunderstood you
12:38joshua__Alright, I'm confused. I have two programs running congomongo. If I use one of the programs to upload items via the swank repl it does fine. If I use it to upload items via normal running it fails, despite the upload being accomplished through the same method calls. The other program doesn't have this problem. What am I not understanding?
12:38naeuso it provides a consistent view in the transaction
12:38naeubut not necessarily across transactions
12:39naeuwhereas if you change the ref, the transaction will ensure a consistent view across transactions
12:39naeuby forcing other transactions to repeat if necessary
12:40naeuwhich brings me to my next question - how do I have a side-effect fn get executed immediately*after* a transaction has completed
12:41naeuobviously I can't put it in the transaction
12:41naeudo i use an agent for that?
12:41Chousukedunno about immediately, but agent sends are queued until the transaction finishes
12:43naeucool, i think a combo of dosync, ensure and agents will do what I want
12:43sattviknaeu: I may be misunderstanding your question, but can't you just call the function after the transaction? (do (dosync ...) (my-fn ...))?
12:46sattvikOr you can even use the result of a transaction as an argument to a function.
12:46naeusattvik: I'm not sure I can as the arg to my-fn will be the dereffed ref
12:47naeusattvik: that might work
12:47amalloysattvik: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/registry.clj#L96 is an example of doing this
12:47sattvik,(conj [1 2] (dosync 3))
12:47clojurebot[1 2 3]
12:47amalloyer
12:47amalloynaeu: ^ was for you
12:51mattmitchellis there a way to extract values from a hash in a ordered way?
12:54naeuamalloy: so that works because bot is altered within the transaction
12:54naeubut if there was no alter on bot, then @bot might be different at time t+1 on another thread than the value of @bot at time t within the transaction
12:57amalloynaeu: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/ping.clj#L10-17 maybe? captures the return value of the dosync. still uses alter so maybe this doesn't address your concern but i guess i don't understand your concern :P
12:57naeuamalloy: I probably don't understand my concern either!
12:58naeubut i think capturing the result of a dosync will be enough
12:59TimMcnaeu: "All reads of Refs will see a consistent snapshot of the 'Ref world' as of the starting point of the transaction (its 'read point'). The transaction will see any changes it has made. This is called the in-transaction-value."
12:59TimMchttp://clojure.org/refs
12:59amalloymattmitchell: you can use a sorted-map
13:00amalloyotherwise, no, hashes are not ordered
13:00mattmitchellamalloy: ok excellent thanks!
13:00naeuTimMc: so reads don't affect a transaction then?
13:00naeuTimMc: I don't grok this snippet " The transaction will see any changes it has made."
13:01amalloy&(let [x (ref 0)] (dosync (println @x) (alter x inc) (println @x)))
13:01sexpbot⟹ 0 1 nil
13:01naeuI'm assuming it means the transaction will see any changes to the ref within it, but care of changes outside of it if the ref is only read
13:01TimMcIf I (dosync @foo (ref-set foo ...) @foo) the two reads will be different.
13:01TimMcamalloy: Holy shit you're fast.
13:01naeuTimMc: sure, but that's setting the ref from within the same transaction
13:02naeuTimMc: but if you did a ref-set in a different transaction on a different thread, @foo would always be the same
13:03amalloynaeu: that's the point. it's a transaction. you don't want to see changes others have made: if you did, it would be unrestrained global mutability, no?
13:03naeuexactly, but I want to retry my transaction if others have made changes to the ref I'm reading
13:03TimMcamalloy: Then what does ensure do?
13:03naeuwhich is why I believe I need ensure
13:03naeuwhich does exactly that
13:04amalloyright
13:04amalloyi belive you do too. we could both be wrong, but it seems like you'll find out faster if you just try
13:04naeuthe docs say it's similar (but more efficient) to doing (ref-set myref @my-ref)
13:05naeuthe problem is that it's not so easy to try out things that might have a race condition
13:05raekensure is for when you want to ensure that a ref that you don't need to read or write from stays unmodified during the transaction
13:06TimMcraek: Ah! It is a way of pulling other refs into the transaction?
13:06naeuthanks everyone for your help, it's much appreciated
13:07mattmitchellamalloy: is there a way to take a hash-map, and convert it into a sorted-map?
13:07raekI think it's like saying "this ref must be unchanged during the transaction"
13:07amalloymattmitchell: yes, but if you aren't building a sorted map to begin with it will be slow and you might as well just do (sort (keys m))
13:08naeuraek: that's my understanding too
13:08devnre-reading WhyFP is a good idea
13:08mattmitchellamalloy: ok makes sense. thanks.
13:08devnit's like re-reading the agile manifesto, it should be done every now and then
13:08bennyluhi, a little quiestion about managing clojure project -
13:08devnbennylu: go ahead
13:09amalloy&(let [m {"test" 1 "egr" 2 "wer`1" 3}] (print m) (print (into (sorted-map) m)))
13:09sexpbot⟹ {test 1, egr 2, wer`1 3}{egr 2, test 1, wer`1 3}nil
13:09amalloymattmitchell: ^
13:09bennyluif i have a reletivly big project do you split it to several namespaces in a hirarchy similar to java?
13:10devnbennylu: yes and no
13:11devnbennylu: im trying to think of how to expand on that... heh
13:11devnclojure is not java so the hierarchies look a bit different
13:12bennylui try - but it look like namespaces are "larger" in scope than classes and so there is too few name spaces and too much code in each ...
13:13devnbennylu: My opinion is that what you want to do is Separation of Concerns, and modularize where appropriate
13:13bennyluim finding myself scrolling reletivly large text in order to find the function that i want to modify / read
13:13devnive found that it is helpful to write one gigantic file where everything lives in the same namespace
13:13devnand then split it out from there
13:13devnbut i havent done anything that's like 800k lines of code
13:13devnso perhaps that would not work for you
13:14devnbennylu: clojure.core, the source, is mostly in one place
13:14devnover-namespacing can be equally annoying
13:15bennylui not talking about 800k too :) but even on 900 lines of code it gets preety heavy to find stuff..
13:15bennyluyes, i know what you means .. i guess i just have to learn to use the find function more :)
13:16amalloybennylu: are you using slime/swank?
13:16devnbennylu: i mean, this is not so much a clojure problem as it is how you decide to separate the modules
13:16devn"modules"
13:16TimMc,[(identical? 3 3) (identical? 300 300)]
13:16clojurebot[true false]
13:16TimMcIs this an instance of interning in Integer?
13:16TimMcor rather, in the compiler's handling of int literal?
13:16amalloyTimMc: yes
13:16amalloythe first 32 ints (or 256?) are interned
13:16bennylui started with it but i hear about counterclockwise and give it a shot - its preety good ..
13:17bennyluso i now use cw
13:17amalloybennylu: well, find ccw's "find" feature, then :P
13:17TimMcWHOA
13:17amalloyinstead of looking around by hand
13:17devnCCW is pretty awesome if you want to stay in IDE land. learning a little bit of slime isn't a bad idea, though. it's awesome.
13:17mattmitchellamalloy: cool thanks again :)
13:17bennylulol :)
13:17devnlpetit is a champ.
13:17bennylulpetit?
13:17TimMcI just got the last screenful of text within a couple seconds. latency weirdness
13:17devnbennylu: he did most of CCW
13:18amalloy&(identical? 1 (inc 0))
13:18sexpbot⟹ true
13:18devnhe put a ton of thought into the structural editing
13:18bennyluhe did relly good job
13:18devnyeah it's pretty great
13:19amalloyfunny how from where i'm sitting, your latency issues are indistinguishable from illegal drugs
13:19devnim an emacs guy until the day i die, but CCW is fantastic
13:19bennylui tried enclojure to but it was awfull - crashing all the time and slow...
13:19devnamalloy: who me?
13:19amalloyno, tim
13:19devnah
13:19amalloyhis sudden WHOA just reminded me of stoners
13:19devn:)
13:19devnWHOA DUDE THIS FUNCTION IS LIKE, WHOA
13:20TimMcamalloy: Same here, actually.
13:20TimMcIT'S LIKE EACH SEXPR IS ITS OWN UNIVERSE
13:21devnhahaha
13:21amalloy*chuckle*
13:21devnthat sounds like something id say after a beer or two
13:21devnim not proud of that
13:21devnit's just true
13:23devnthis is your chance to make fun of me
13:24pyr(str :foo) yields ":foo"
13:24amalloy&(name :foo)
13:24sexpbot⟹ "foo"
13:24amalloyi think stoner TimMc makes an excellent observation about the ramifications of immutability
13:24devnamalloy: say more
13:24pyramalloy: :)
13:24pyramalloy: thx!
13:25cemerickdevn: it's going to keep getting better. I'm hoping to take a day for it next week.
13:25devncemerick: yeah i didn't mean to assign all of CCW's development only to lpetit
13:25devnthanks for your work as well. :)
13:25cemerickoh, wasn't trying to grab credit
13:26cemerickHe's absolutely the driving force -- I only pitch in here and there. :-)
13:26devncemerick: nono i wasn't trying to suggest you were im just interested in giving it where it's due
13:26cemerick:-)
13:26devn:)
13:26cemerickdevn: how's things, BTW
13:27devngreat, started a clojure meetup in Madison, WI -- have our 2nd meeting next monday, still pretty small but im slowly making the rounds to local meetup groups and attracting some interest
13:27devni've slowly convinced a few ruby guys to pair program with me on some clojure
13:27devnthey scoffed and hemmed and hawed at first, but i think i beat them into submission by showing them ruby came out of dylan, scheme, and the CLOS :)
13:30devncemerick: how about you?
13:30cemerickdevn: sorry, pulled in different directions :-)
13:31cemerickabsurdly busy
13:31cemerickusually in a good way, sometimes not
13:31cemerickit's been an odd year so far
13:31devn:) sine waves or square waves?
13:31cemerickBeen working on a bunch of Clojure open source stuff in the past couple of weeks, which is a nice change of pace
13:31cemericksquare, definitely :-/
13:32devnyeah, that can be exhilirating though! when people walk in the door, hit the whiteboard and the room explodes with action that's a great feeling
13:33devncemerick: going to make it to the next conj?
13:33cemerickdevn: can't imagine not :-)
13:34devn:) good to hear it
13:34devncemerick: what open source projects have you been cracking at? (btw if you're busy feel free to table this discussion -- i had a doctor's appointment today so I'm slacking a bit)
13:36cemerickdevn: there's https://github.com/cemerick/bandalore, some nREPL fixes, and a refurbishing of a simpledb client library based on Rich's original implementation.
13:36devncemerick: wanna give me an elevator pitch? :)
13:37cemerickon simpledb?
13:37devn*nod*
13:37devnalso, i didn't know rich wrote a simpledb implementation
13:38cemerickdevn: it's a zero-admin couchdb with "proper" indexes and ad-hoc query capabilities
13:39cemerickhosted by a known-good vendor, etc
13:39cemerickright next to the EC2 instances I'm using already, etc
13:39cemerickEssentially, I'm going all-in on AWS.
13:39devnyeah absolutely -- ive been pretty much doing everything on S3 and EC2 lately along with a bit of heroku here and there
13:39cemerickThus the SQS client impl.
13:40devnRedis is really cool. Play with that at all?
13:40cemerickNo, never looked at it.
13:41cemerickI've been trying to simplify everything as much as possible of late -- and anything with a whiff of administration overhead is getting tossed overboard.
13:41devnRedis in a lot of ways reminds me of the clojure STM -- do you can wrap multiple commands in a pipeline etc
13:41cemerickdevn: FYI, the most recent maintained fork of Rich's SDB client is here: https://github.com/bapehbe/sdb
13:41devnO(1) for pretty much everything except on lists, and so on
13:42cemerickI'm mostly rebuilding it though: https://docs.google.com/document/d/1K5p2RRVtvYxBNLEJuWGNf1iZak2ri8cI73joWu9K1W0/edit?hl=en&amp;authkey=CMDR_6AF
13:42devncemerick: im definitely going to look into that
13:42devnwe've been using mongo quite a bit lately
13:42devn(where appropriate of course)
13:42cemerickit sounds like redis has a lot going for it, especially since they managed to work out larger-than-memory datasets
13:43cemerickThat was the limitation that kept me away initially
13:43devncemerick: the coolest part of redis that i have yet to toy with is the pub/sub system
13:43devnhttp://redis.io/commands#pubsub
13:46devnit gives you what is essentially a broadcast server to transmit messages over channels to many subscribers in real time
13:47devnlots of cool ideas come to mind
13:50edw```Are there Clojure-native string->number procedures? I wind up doing #(Integer. %) a lot, which is rather tedious.
13:50cemerickedw```: if you're certain the string only contains a number literal, use read-string
13:50edwThat sort of seems like using an atomic bomb when a firecracker is called for. How efficient is that?
13:50edwIn practive, I have STRING-TO-INT and STRING-TO-FLOAT defined in a million files, which is what makes me think having a built-in would be wise. (I do a lot of reading from text files and URLs.)
13:54cemerickah, so an ad-hoc mq
14:07devncemerick: yeah good way of thinking about it
14:07devncemerick: i think about using it for things like...you have data being funneled from one big EC2 instance to many smaller instances that handle specific subsets of the total dataset
14:08devnthis is probably a cliche by now, but also, if you wanted to do a Twitter clone, that's your ticket
14:09devnredis 2.3 is i believe going to introduce a more complete distributed system, it will be interesting to see how pub/sub works in that context
14:09NanarpussAnyone work with slime? I'm getting an error everytime I hit return on the REPL... It says "Error in process filter: Wrong number of arguments: nil, 1"
14:10devnNanarpuss: ah yeah i was getting that... i think it's your version of SLIME
14:10devnare you running slime from source?
14:10Nanarpussyeah
14:10devnyeah, use the ELPA package
14:10mattmitchelli'm using the contrib.sql lib and attempting to insert a date to mysql. How does it handle dates? Just as strings? Do I have to format the value myself?
14:10NanarpussI've tried ELPA too
14:10devnthat will get rid of it
14:10devnNanarpuss: hm, weird. that fixed it for me
14:11Nanarpussso ELPA slime and swank-clojure worked for you?
14:11devnNanarpuss: are you sure you don't have slime loading from source still?
14:11devnNanarpuss: yes. with 1.3.0-SNAPSHOT
14:11Nanarpussohh I'm on 1.2
14:11Nanarpusslet me try 1.3 and see what happens
14:11devnNanarpuss: im not sure how much of a difference it makes, but that's my setup and it seems to be working
14:12raekI don't think the clojure version should make any difference here
14:12devnraek: is 1.3.0-SNAPSHOT just for clojure 1.2 then? and swank-clojure is just 1.2?
14:12devnerr and swank-clojure 1.2 is just for 1.1.0?
14:13technomancyany version of swank-clojure should work with all clojure versions
14:13raekah, thought you were refering to clojure versions...
14:13technomancymodulo a few times where I apply patches I get without thinking them through =(
14:13devntechnomancy: i saw your post on the Wrong number of arguments: nil, 1 i think
14:13devnIIRC you suggested to just use the ELPA packages, and so I did, and then never received the error again
14:13technomancythe slime version is what you have to watch out for
14:14devni was compiling from source
14:14devntechnomancy: why no marmalade in the starter-kit, btw?
14:14technomancyI wish that were simpler, but I don't really have the patience to work it out with the CL guys.
14:14technomancydevn: no reason; just haven't gotten around to it
14:15technomancytarball packages are slightly more complicated; I guess that's the excuse
14:15devn*nod* -- ill submit a pull req.
14:16TimMcWhat is a use-case of ensure?
14:17TimMcThat is, why protect a ref from modification if you never read or write it in that transaction?
14:19devnTimMc: ive seen several opinions on that
14:20devnwhat ive concluded is that it's a read with an annotation
14:20devnit increases parallelism w/r/t a dummy read/write like ref-set
14:20TimMcSurely there's no behavioral difference within one transaction between @foo and (ensure foo)?
14:21devni think it basically means that you're going to be changing foo later and so others should stay away from it
14:21devnmaybe to ease contention?
14:21Nanarpusshmm still no luck
14:21Nanarpussjust tried 1.3
14:22TimMcdevn: Like a way to say early on in a long transaction, "back off, I'll be using this"?
14:22devnTimMc: i THINK so
14:22devnit increases isolation
14:22bennyluwhat is the difference between into and concat?? (besides the order of the result)
14:23TimMcI don't see any usage inside the clojure source.
14:23amalloybennylu: concat is lazy
14:23bennyluamalloy, thanks!
14:23amalloy&(take 1 (into () (range)))
14:23devnTimMc: i think it is ref-set's half-brother
14:23amalloy&(take 1 (concat () (range)))
14:23sexpbot⟹ (0)
14:23raekbennylu: into is conj'ing on some element to any data structure, concat concatenates two sequences
14:23sexpbotExecution Timed Out!
14:24TimMcbennylu: I believe into gives you back a collection of the type you asked for.
14:24devnTimMc: i think i found an answer for you
14:24amalloyTimMc: into is just (partial reduce conj), more or less
14:25amalloy&((partial reduce conj) [1 2] (range 5))
14:25sexpbot⟹ [1 2 0 1 2 3 4]
14:25amalloy&(into [1 2] (range 5))
14:25sexpbot⟹ [1 2 0 1 2 3 4]
14:25raek,[(into [1 2] [3 4]) (into (list 1 2) [3 4]) (concat [1 2] [3 4]) (concat (list 1 2) [3 4]]
14:25clojurebotUnmatched delimiter: ]
14:25raek,[(into [1 2] [3 4]) (into (list 1 2) [3 4]) (concat [1 2] [3 4]) (concat (list 1 2) [3 4])]
14:25clojurebot[[1 2 3 4] (4 3 1 2) (1 2 3 4) (1 2 3 4)]
14:25devnTimMc: The scenario you describe cannot happen in Clojure's STM. Clojure's STM uses MVCC and provides snapshot isolation to transactions - a transaction will never see inconsistent state. Being MVCC-based, it is subject to write skew, and provides an ensure construct that allows one to tag dependent reads, with more concurrency than the dummy writes usually used to address write skew. Livelock is a theoretical scenario, but it is not a non-blocking ...
14:25devn... design, thus mitigating churn. Actual livelock is avoided via retry limits and timeouts. There is, as you mention, as-yet-unrealized potential for configurable contention resolution policy.
14:26devn-rich hickey, 2009
14:27TimMcI don't know what livelock is (though I could guess) and I don't know what write skew is.
14:27TimMcSo... ensure is probably there if you need super concurrency performance.
14:27TimMc...but is never strictly necessary from a results point of view.
14:27devnTimMc: there's a lot of literature out there, but most of it is specific to an implementation
14:29devnTimMc: i wish i could be of more help, but i can't really give you anything more than i already have without speculation
14:29TimMcAs long as I don't need to know about ensure, I'll probably hold off on trying to figure it out. :-)
14:30devnTimMc: yeah I'm hunting for some code that uses it, but then you need to be sure that they're not just using it for the sake of using it
14:30TimMcIt's not present in contrib either, I think.
14:31devnTimMc: http://www.cs.rochester.edu/research/synchronization/rstm/primer.shtml
14:31devnthat's interesting and somewhat relevant to this discussion
14:31TimMc(I've only beenlooking on the .clj side of things.)
14:31devnTimMc: http://www.cs.rochester.edu/research/synchronization/rstm/libraries.shtml
14:31devnthat's good as well
14:33gfrlog,(format #"this won't work %s cuz it's a regex" "oh well")
14:33clojurebotjava.lang.ClassCastException: java.util.regex.Pattern cannot be cast to java.lang.String
14:33gfrlogso is there any function for regexly escaping a string?
14:33gfrlogand did I state that question in an understandable way?
14:33devnIIRC there is
14:34gfrlogI just looked on java.util.regex.Pattern and don't see anything
14:34TimMc$findfn "." "\\."
14:34sexpbot[]
14:34gfrlogTimMc: brilliant, if unsucessful
14:35devni used to have a thingamajig that let me build up a regex from strings
14:35brehaut(str #".")
14:35brehaut,(str #".")
14:35gfrlog,(str #".")
14:35clojurebot"."
14:35clojurebot"."
14:35TimMcooh
14:35TimMc,(java.util.regex.Pattern/quote ".")
14:35clojurebot"\\Q.\\E"
14:35gfrlogwtf is \Q and \E?
14:35TimMcOh, uh, I guess that works too.
14:36jweissquote, end quote?
14:36gfrlogman I looked right at that function in the javadocs and didn't see it cause it wasn't called "escape"
14:36TimMc,"\\"
14:36clojurebot"\\"
14:36gfrlog,(java.util.regex.Pattern/quote "\\E")
14:36clojurebot"\\Q\\E\\\\E\\Q\\E"
14:36gfrlogholy cow
14:37TimMchaha
14:37gfrlogman testing to make sure that does what I think it does sounds like a headache
14:37TimMc,(java.util.regex.Pattern/quote "\\$")
14:37clojurebot"\\Q\\$\\E"
14:37devnthis seems like the wrong way to go about doing this...
14:38gfrlogdevn: it sounds perfect, what could be wrong with it?
14:38TimMc,(java.util.regex.Pattern/quote "$")
14:38clojurebot"\\Q$\\E"
14:38gfrlog,(re-pattern (java.util.regex.Pattern/quote "\\E"))
14:38clojurebot#"\Q\E\\E\Q\E"
14:38devnmaybe i misunderstand your original problem, but you wanted to call format on a regex
14:38devni dont see how this solves your problem
14:38TimMcOK, so it doesn't attempt to quote its own sentinals via nesting or anything.
14:38gfrlogdevn: no, I actually just needed an escape
14:38gfrlog,(re-pattern (java.util.regex.Pattern/quote "\\E\\Q\\E"))
14:39clojurebot#"\Q\E\\E\Q\Q\E\\E\Q\E"
14:39gfrloghow the heck does that work?
14:39devnlol
14:39gfrlogdevn: I can do format manually with (str)
14:39gfrlogdevn: then pass to re-pattern
14:39devnokay now we're on the same page gfrlog
14:39gfrlogI'm seriously dumbfounded by the escaping strategy here
14:40devnthat's what my suggests was
14:40devnsuggestion*
14:40gfrlogI'm sure it works but I'm not sure why
14:40TimMcAfter a \Q, go into raw mode until \E.
14:41TimMc,(java.util.regex.Pattern/quote "\\")
14:41clojurebot"\\Q\\\\E"
14:41Null-A,```foo
14:41clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote sandbox/foo))))
14:41TimMcSee, that string is \Q\\E, but the \\ isn't an escape.
14:42TimMcFor a literal \E, drop out of raw mode, emit an escaped \E (\\E) and then go back into raw mode.
14:42TimMcIt's a bit silly that it puts empty raw clauses in when the beginning or end of a string is \E
14:43devn"patches welcome" ;)
14:43gfrlogTimMc: okay, I think that makes sense
14:43gfrlogthanks
14:43smnirvengot a question about clojure.contrib.sql with-query-results
14:43gfrlogsmnirven: ask that question
14:44smnirvenim trying to write a query by datetime, so I'm building a prepared statement - its not clear what I have to pass in
14:44smnirvenhere's my code:
14:44smnirven(sql/with-connection db/conn
14:44smnirven (sql/with-query-results rs [(str "select * FROM users WHERE updated_at >= ?" [start-dt-str])]
14:44smnirven (doseq [res rs]
14:44smnirven (prn res)))))
14:45gfrlogyou're right. that is not clear. Have you tried anything?
14:45smnirvenyeah, tried running that code - got this error
14:45gfrlogI know with sql you can use some kind of time literal in single-quotes. Maybe c.c.sql will take a string?
14:45smnirvenjava.sql.SQLException: No value specified for parameter 1 (NO_SOURCE_FILE:0)
14:46gfrlogsmnirven: I don't think you want the argument to be in a vector
14:46gfrlogi.e., use start-dt-str instead of [start-dt
14:46smnirvenyeah, in that code, start-dt-str is a string
14:46gfrlog-str]
14:46smnirvenjust get rid of the vector
14:46gfrlogright
14:46smnirvencool, i'll try that quick
14:46TimMcsmnirven: Is start-dt supposed to be inside (str ...)?
14:46gfrlogthe error message still looks weird, but maybe that's why anydow
14:46gfrloganyhow*
14:47smnirvennope, it gets passed into a function as a string
14:47TimMcsmnirven: ##(str "f" 5)
14:47sexpbot⟹ "f5"
14:47TimMcDo you want concatenation?
14:47gfrlogmaybe you forgot to include the (:fix-bugs) clause within the namespace declaration
14:47gfrlogTimMc: I think he was just using the c.c.sql api wrong
14:48smnirvenhere's a more direct example:
14:48smnirven(sql/with-query-results rs [(str "select * FROM raw_leads WHERE sdb_updated_at >= ?" "2011-03-03 12:00:00")]
14:49TimMcsmnirven: Right, you don't want the date inside str.
14:49smnirvenohh i think i see what i did
14:49smnirvenyeah
14:49smnirvenoy - thanks
14:49TimMcJust kill str, actually.
14:49TimMcnp
14:50smnirvenexcellent
14:50smnirventhat worked
14:50smnirventy
14:51gfrlogoh weird I didn't even see he did that in the original code
15:49chouseris this old news here? http://doc.akka.io/stm-java
15:49mattmitchelli have a lazy seq. i'd like to use map, to transform all of the values. i seriously, can't figure out how to do this, but i'm thinking doall might help me out here?
15:50chousermattmitchell: why do you want to force the lazy seq instead of letting it remain lazy?
15:51mattmitchellhmm, let me try something
15:51mattmitchellchouser: is it possible to use map on a lazy seq?
15:52chousermattmitchell: absolutely. and map returns a lazy seq in turn.
15:52mattmitchellchouser: interesting. ok.
15:55TimMcWait wait wait... http://lambda-the-ultimate.org/node/3700#comment-52647 indicates that transactions do not provide consistency, if I'm understanding write skew correctly.
15:59chouserwithin the transaction, you always see a consistent state.
16:00TimMcThat's isolation, I think.
16:00chouserAs I understand it, most relational databases that claim ACID are also subject to write skew unless you do dummy writes.
16:01TimMc...which is what ensure is a replacement for.
16:01chouserright
16:02chouserin practice, it's an unusual bit of code that is susceptible to write skew, but of course it's worth knowing about so that you can use ensure when needed.
16:02amalloymattmitchell: ##(take 10 (map inc (range)))
16:02sexpbot⟹ (1 2 3 4 5 6 7 8 9 10)
16:02TimMcchouser: How do I know if I need it?
16:03TimMcRather, do you know of an example of Clojure code that is susceptible?
16:12TimMcOK, so it looks like I need to ensure any refs whose state I only read but whose final value must be consistent with refs I am writing.
16:12chouserthat's a better description than I was in the middle of writing. :-)
16:14TimMcOK, I'll put this on the clojuredocs site.
16:16TimMcLook good? http://clojuredocs.org/clojure_core/clojure.core/ensure
16:17TimMcdevn: ^ found out about ensure
16:18TimMcAnd now if you'll excuse me, I'm off to make sure all my dosyncs are safe from write skew.
16:29TimMcHere's a question: If inside a writing dosync I call a bunch of methods that read from various global refs, how am I supposed to know what I might need to ensure?
16:31TimMcamalloy: How does that help?
16:32amalloyTimMc: it doesn't really
16:32TimMcheh
16:32chouserTimMc: you really want to keep your transactions as small and contained as possible
16:32amalloybut i find it easier to think about having a single mutable object enclosing the N things i might need to change
16:33amalloyif i had lots and lots of threads hammering on it at once that might be bad for performance, but this way i don't have to worry about other reds
16:33amalloyrefs
16:35mattmitchelltrying to get contrib.sql do-prepared to work with a collection of records. Anyone know if this actually works with a collection?
16:36TimMcMy app is a Swing graphics program where everything runs off the event loop, so it is essentially a single-threaded program. I don't *really* need to worry about concurrency. But the moment I add another thread, it'll matter.
16:38TimMcchouser: When the user drags something on the canvas, I have to use a snapshot of the current view rotation, translation, and scale along with the program's tool mode and the list of objects on the canvas. I do some computation, and then I need to update the objects on the canvas and maybe the tool state.
16:39TimMcI do try to keep the transactions small and contained, but in this case one atomic unit of work involves about 3 different refs of maps, minimum.
16:40amalloyTimMc: wtf, no it doesn't. minimum, it involves one atom enclusing three maps :P
16:41TimMcamalloy: If I merge all my global state into one reference, my program can no longer make use of concurrency when I add threads for animation, etc.
16:43amalloyanimation threads can just get a @snapshot and not worry if it's a little out of date, no?
16:43amalloyi mean, i'm not asserting that your app would be better with atoms
16:43amalloybut to claim that it is impossible with atoms is patently false
16:46TimMcI suppose that animation just needs a snapshot, yeah. It wouldn't be writing anything back to references.
16:46TimMcamalloy: Only one transaction could run on the atom at a time, right?
16:47amalloyyes
16:47amalloyor at any rate only one could succeed
16:47TimMcright
16:48TimMcI guess I'll stop complaining until I actually need concurrency. :-P
17:10solar_seaWhen I try to start "lein repl" in a new project, I'm getting this - http://pastebin.com/sxJdqYNk What host / port does lein's repl command require ?
17:11solar_seahttp://pastebin.com/9zmSKe4R - nothing weird in netstat either
17:12dmiles_afkdoes clojure's "," syntax preclude it from ever being read by the lispreader?
17:13technomancysolar_sea: it uses localhost and a random port above 1024, but you can override it with LEIN_REPL_HOST LEIN_REPL_PORT
17:13technomancysolar_sea: is it repeatable?
17:13solar_seayes, everytime
17:14dmiles_afki suppose a reader macro of #J could make the lisp reader tollerate clojure's ","
17:14dmiles_afk"," is alwaswy whitespace right?
17:15hiredmanyes
17:15technomancysolar_sea: can you open a ticket with copious details so I can check it later?
17:15solar_seasure, where's the tracker for it ?
17:15dmiles_afkteh [ and ] might i guess get tricky
17:16technomancysolar_sea: http://github.com/technomancy/leiningen/issues
17:16TimMcdmiles_afk: And {}
17:20NielsEhi, I have created a new clojure project in eclipse but it does not recognise things from contrib like 'sqrt' and 'primes', but clojure-contrib is in the classpath under libraries in eclipse, how come?
17:21TimMcchouser: I would *really* like to see some mention of write skew on the clojure.org/refs page. Should I bug Rich about that?
17:22TimMcNielsE: Have you used :require or :use in your namespace declaration to pull in contrib?
17:23NielsETimMc: somehow I was not aware that I had to use or include the contrib library explicitely, I'll look into it, thanks :)
17:24raektechnomancy: what does it mean for a project to be installed in leiningen? (I'm thinking about two-param "lein install")
17:24technomancyraek: it places shell scripts in ~/.lein/bin
17:24raekalso, I just discovered "lein repl" outside a project and the swank-clojure shell wrapper. this will aid my introductory talk on clojure very much. :)
17:24technomancyraek: I think swank is the only thing that uses it so far
17:25technomancybut I want more people to try it out; clojure's command-line story right now sucks =\
17:25technomancycools!
17:27solar_seatechnomancy, I found it, it turned out that my "lo" iface somehow was down
17:27TimMcNielsE: (:require [clojure.contrib.math :as math]) in your (ns ...) will let you do math/sqrt
17:27solar_seathere's nothing wrong with lein :)
17:27technomancysolar_sea: whoa; I didn't even know you could do that. =)
17:28solar_seame neither ... I guess the wicd network manager that I use for wifi settings is to blame, I'll dig it up further some day :)
17:28TimMcsolar_sea: How did you discover that?
17:29solar_seanetstat showed nothing wrong. LEIN_REPL_PORT/HOST didn't work either. Then I disabled ipv6, again to no avail. And I glanced again that "lo" was actually missing from ifconfig's output.
17:30TimMcEntirely missing? I would not have noticed that ever.
17:46TimMcIs the rational for class-per-fn that this allows selective code reloading?
17:54mattmitchellif i have a function, that accepts a series of optional arguments, how can i pass in a list of args without knowing the length?
17:55brehaut(apply + [1 2 3 4 5])
17:55brehaut,(apply + [1 2 3 4 5])
17:55clojurebot15
17:55mattmitchellbrehaut: ok cool. so the function i'm actually working with is clojure.contrib.sql do-prepared
17:55mattmitchellbrehaut: i have a collection of row values
17:56mattmitchelllooks something like this: (sql/with-connection db/conn
17:56mattmitchell (sql/do-prepared insert values))
17:56brehaut(apply clojure.contrib.sql/do-prepared foo bar seq-of-values)
17:56mattmitchellbrehaut: ahh ok :)
18:01mattmitchellbrehaut: thank you
18:02brehautno worries
18:02raekTimMc: what would be the alternative to class-pre-fn? you need to have separate classes for separate functions if one function should behave differently from another when called with the same method
18:05TimMcOh right, there are different methods for different arities.
18:06amalloyTimMc: i don't think that's relevant
18:06amalloythe point is that functions have to have a general "call me" button, which has to be wrapped up in a method for java
18:06amalloyif function a is to behave differently from function b, they must be different classes implementing IFn
18:06TimMcAnd they all have to be instances of different classes, right.
18:45amalloyTimMc: plus, have you ever thought about how closures are implemented? it's a neat trick
18:45TimMcHmm, fair point/
19:10bennyluwhat the equivalance of substring in clojure?
19:11bennyluanyone?
19:12clojurebotPlease do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.
19:12Apage43,(.susbtring "doghouse" 3)
19:12clojurebotjava.lang.IllegalArgumentException: No matching method found: susbtring for class java.lang.String
19:12bennylugetit! thanks..
19:12Apage43yeah, that should work outside the bot xD
19:14amalloysubs
19:14amalloywhich i think is in clojure.string
19:14amalloy&(use 'clojure.string)
19:14sexpbot⟹ nil
19:14amalloy&(subs "test" 1)
19:14sexpbotjava.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox6385
19:15amalloy&(use 'clojure.string)
19:15sexpbotjava.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox6385
19:15amalloylol wtf
19:15amalloyoh i guess it's in core anyway
19:15amalloy&(subs "test" 1)
19:15sexpbot⟹ "est"
19:15amalloybennylu: ^
19:16bennyluamalloy, Thanks!
19:34bennyluwhat the convention for constants in clojure? (for example - in jave its uppercase splitted by '_')
19:35technomancybennylu: lowercase dash-separated
19:37bennylutechnomancy, but this is the convention for normal variables - because clojure dont have a final/constant keyword i wanted to show the readers of my code that some variable is constant - i guess i will have to add somthing like c-varname
19:38Apage43bennylu: shouldn't the preponderance of your variables in clojure be constant..
19:39Apage43if you
19:39technomancyyou can tell when things are mutable by the presence of deref/atom/agent/ref
19:39Apage43if you're going around re'def'ing things that's probably wrong
19:40bennyluApage43, i guess you right.. :)
19:40bennylui still thinking in java :)
19:43pdkbennylu it's a given that they're constant
19:43amalloyhow do i specify a "source dependency" with cake/lein? it looks like with maven you add a <classifier> element
19:43pdkthey're all immutable :p
19:43pdkif you're naming a global symbol though
19:43pdkthe convetion is *like-this*
19:43amalloypdk: that's overgeneralizing
19:44amalloyyou define global symbols all the time; only the ones that you intend to be rebound are usually given *earmuffs*
19:44pdkbarring java objs/reference types
19:44amalloyooo i see there's a :classifier entry in the dependency thingy
19:44bennylupdk, amalloy, thanks
19:50TimMcamalloy: I was using the convention of all my global refs (there are about 5) have, uh, earmuffs.
19:50amalloywell, altering global refs is similar to rebinding
19:51amalloyexcept more evil :P
20:00technomancyamalloy: what are you using source dependencies for?
20:00amalloytechnomancy: i'm not really. i just wanted an easy way to get the source for a project
20:01technomancyI could see the use for a plugin that could pull in source and build a TAGS file if I had the misfortune to need such a thing.
20:02technomancyseems saner to inspect the <scm> element of the pom though
20:16pdkhm
20:16pdki'll ask again, for folks who preordered joy of clojure through amazon do you know if you still get early access that way
20:58TimMcWhat is the M in MEAP?
20:58TimMc(speaking of EAP)
21:00brehautManning (the publisher)
21:00brehaut(i think)
21:02TimMcHah, OK.
21:24amalloyindeed
21:30devnso erm, any idea on a good regex to capture sexps from strings?
21:32brehautdevn, do you want to just find them? or actually get sexps back?
21:32devnim typing in this line right now and then i do this (foo (bar (baz 4) "16") \c)
21:33devni want to capture (foo (bar (baz 4) "16") \c)
21:33Despite_ooo, fun!
21:33brehautdevn: theres not really a good solution to that with regexp
21:33devni figure this is a solved problem but, hm...
21:33amalloydevn: if you use regexes to do this you are asking for pain, and also are probably a satan worshipper, no offense
21:33Despite_you'll need perl for this!
21:33devnamalloy: well, how do you suggest i do it?
21:33brehautfor instance (is this) one or (two sexp) ?
21:34amalloy&(read-string "(foo (bar (baz 4) \"16\") \c)")
21:34sexpbotjava.lang.Exception: Unsupported escape character: \c
21:34brehautfnparse
21:34amalloy&(read-string "(foo (bar (baz 4) \"16\") \\c)")
21:34sexpbot⟹ (foo (bar (baz 4) "16") \c)
21:34devnhttps://gist.github.com/854070
21:34devnthat works right now, and it's fast
21:34devnbut im sick of that code. it's disgusting.
21:35Despite_wow
21:35brehautdevn: you really are outside of the bounds of regular grammars, and need to write areal parser
21:35amalloydevn: please comment on why read-string is no good?
21:36devn&(read-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \c)")
21:36sexpbotjava.lang.Exception: Unsupported escape character: \c
21:36devn&(read-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)")
21:36sexpbot⟹ hello
21:36amalloy&(with-in-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)" (take-while identity (repeatedly read)))
21:36sexpbotjava.lang.Exception: Unable to resolve symbol: with-in-string in this context
21:37amalloy&(with-in-str "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)" (take-while identity (repeatedly read)))
21:37sexpbotExecution Timed Out!
21:37amalloywell, something like that anyway
21:37amalloyyou probably need a try/catch for eof
21:38devnit doesn't need to be perfect and like...understand that \c is ok. it basically just needs to match an equal number of parens on both sides
21:38devn(((()))) is valid, for instance
21:39amalloydevn: the "regular" in regular expressions means that it has to be context-free, ie not tracking nested parens
21:39devn(1(j(4(d)))), same deal
21:39brehautdevn are you familiar with http://en.wikipedia.org/wiki/Pumping_lemma_for_regular_languages ?
21:40devnbrehaut: no, reading now
21:40devnamalloy: *nod*, fair enough
21:40amalloythese days regular expressions have some non-regular extensions that *do* allow you to do stuff like this, but there are so many reasons not to, especially when you have a whole dang compiler at your disposal
21:40TimMcdevn: TL;DR: You at least need a stack.
21:40amalloyheh
21:40devnlol
21:40devnpumping lemma sounds like a math porn movie
21:41TimMchawt
21:41amalloyTimMc: how much will it cost me to have you follow me around with tldr explanations of my verbose rubbish?
21:41TimMc:-P
21:43devnlol
21:44Despite_perl -MText::Balanced :)
21:44brehautdevn the 'best' you can use regexps for here is tokenisation such as ##(re-seq #"(\"(\\.|[^\"])*\")|[()]|[^()\"]*" "abc ( 1 2 ( c d \"ber\" ) ) ) asdf")
21:44sexpbot⟹ (["abc " nil nil] ["(" nil nil] [" 1 2 " nil nil] ["(" nil nil] [" c d " nil nil] ["\"ber\"" "\"ber\"" "r"] [" " nil nil] [")" nil nil] [" " nil nil] [")" nil nil] [" " nil nil] [")" nil nil] [" asdf" nil nil] ["" nil nil])
21:44brehautplease excuse the evil
21:44devnholy evil
21:44devnthat's almost worst than what i have now :D
21:44brehauthaha
21:44devn(but i appreciate the suggestion (and yes this should match too))
21:44brehautits also bound to be broken
21:45devni mean, here's the scenario so you have some context
21:45devnbecause maybe this changes things...
21:46devnim rewriting something i was messing with around a year ago that read-lines from the #clojure logs, pulls out s-exps and try to run them in a sandbox
21:46devnif they run, the expression as a string is the key, and their value is the result as a string
21:46devnthat happens in a try catch so i dont really care if its faulty, liberal with parens, etc.
21:47devni just want something that is good enough
21:49amalloy&1
21:49sexpbot⟹ 1
21:49brehaut$findfn [1 2 3] ([1 2 3] [2 3] [3] [])
21:49sexpbotjava.security.PrivilegedActionException: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: PersistentVector (NO_SOURCE_FILE:0)
21:50amalloydevn: that's a sexp you won't get right :P
21:55brehautdevn: (defn tails [s] (when (seq s) (lazy-seq (cons s (tails (rest s)))))) (defn horror [s] (keep #(try (read-string (str %)) (catch Exception e e)) (tails s)))
21:56brehautits missing an apply before str
21:57brehaut(defn horror [s] (keep #(try (read-string (apply str %)) (catch Exception e nil)) (tails s)))
21:57brehautmuch better (for a given value of better)
21:57brehautthat'll find all the legit clojure expressions in a string
21:57brehautincluding a bunch of stuff you dont want (eg, anything that looks like a symbol)
21:58amalloybrehaut: given input " 1" you'll generate a zillion instances of the expression "1"
21:58brehautamalloy: he said it had to be approximate ;)
21:58amalloyalso isn't tails just (partial reductions rest)?
21:59amalloyer not quite
21:59brehauti know theres a good way to do it
21:59brehautbut its late friday here and my brain is tired
21:59amalloybrehaut: late friday already?
21:59amalloyit's barely late thursday here
21:59brehautnew zealand, its the future
21:59brehautby late i mean late in te work day; about 4pm
22:00amalloyi guess i was reading late as 11pm
22:00brehaut(defn horror [s] (set (keep #(try (read-string (apply str %)) (catch Exception e nil)) (tails s))))
22:00brehauthows that :P
22:00amalloy(defn tails [s] (take-while identity (iterate #(subs % 1) s)))
22:00amalloybrehaut: my hero!
22:01brehauthah brilliant :)
22:01amalloyi use take-while/identity/iterate so often i need to give it a function
22:01amalloyname proposals?
22:01chouserTimMc: point 8 refers to the usage of ensure. You wish it used the words "write skew" in particular?
22:03brehautamalloy: its a "take-" something for sure
22:03brehautperhaps even just take-iterations ?
22:03amalloyi have trim-seq for take-while identity
22:03amalloyhm, sensible
22:03amalloyor just iterations
22:04brehautyeah that could work
22:05amalloybrehaut: putting that into my new little portably utils library now
22:06brehautawesome :)
22:07brehautamalloy: i see you have on-thread; why not join the lazier world and just use future :P
22:08amalloywell yes
22:08amalloybrehaut: i have that there because i grabbed everything from sexpbot.utils, and apparently Raynes has a reason to want different error semantics
22:08amalloymebbe i'll junk it
22:11brehautalso, (def make-str (transform-if keyword? name str)) instead of keyword you probably want (partial instance? clojure.lang.Named)
22:12amalloybrehaut: good point. that too was extracted from another application
22:12amalloyas you can see my util package is pretty new so it's rough around the edges
22:12brehautyeah for sure
22:12brehautno point creating a utilities package whole cloth
22:12amalloyheh
22:13amalloyi'll wait until i can use it to replace contrib, then release it
22:13brehauthaha
22:20brehautlater
22:46dnolendoes calling seq on a lazy-seq force evaluation of the first item?
22:46dnolento determine if it's non-empty?
22:48dnolenah
22:48dnolenit seems like it does.
22:49amalloydnolen: yes
22:50amalloynext is basically (comp seq rest)
22:50amalloyer, no it's not. but whatever
23:26amacthe docstring for future-cancel is hilarious
23:28tomojI never read it that way before :)
23:29amac:)
23:31spewn_,(doc future-cancel)
23:31clojurebot"([f]); Cancels the future, if possible."
23:31spewn_hah
23:34amalloyheh
23:34amalloyhopefully it always fails
23:35amalloyarguably it doesn't matter though. some kind of variation on the quantum bogosort
23:39amalloyman, the wikipedia article on quantum bogosort is terrible. if anyone is wondering why i would make such a stupid reference, see http://www.mathnews.uwaterloo.ca/Issues/mn11103/QuantumBogoSort.php
23:45amacMan, I hope some parallel asshole doesn't destroy our universe simply because his list was unsorted.
23:46amacI like this universe, it contains all my stuff.
23:47dnolenis it possible to get the name of a fn like (fn foo []) ?
23:48technomancydnolen: there's an open ticket for putting stuff like that in metadata
23:48technomancy(no patch, just an unhelpful "this should have metadata")
23:48dnolentechnomancy: heh, thx.
23:49amalloydnolen: you can kinda-sorta do it with ##(class (fn foo[]))
23:49sexpbot⟹ sandbox11264$eval13423$foo__13424
23:49dnolen,(println (fn foo[]))
23:49clojurebot#<sandbox$eval2577$foo__2578 sandbox$eval2577$foo__2578@1a707a0>
23:50dnolenI just need it for debugging really. would prefer to not get the mangled version.
23:50amalloydnolen: regexes for the win?