#clojure log - Mar 17 2011

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 rata_: I've used visualvm to detect the bottleneck... and it was that fn... but didn't know how to check if reflection was a bottleneck for that fn

0:01 technomancy: you should see a lot of clojure.lang.Reflector frames in the traces I think

0:02 that code looks unlikely to reflect a lot since it doesn't look like it makes any Java method calls. pure Clojure shouldn't reflect.

0:03 amalloy: rata_: i doubt it will make a difference, but you could pull the multiplication from the inner loop up into the outer one, with (apply * rate (mapcat (fn [[mol freq]] [(get-molecule state mol) freq]) lhs))

0:03 that would probably reduce the amount of boxing and unboxing you do, since you call * in fewer places

0:03 technomancy: one thing you could do is switch to primitive math, another would be to use a transient map.

0:04 you could also replace for with reduce to avoid laziness overhead

0:04 rata_: how do I switch to primitive math in 1.2? or should I move to 1.3?

0:05 technomancy: 1.3 is only needed if you need your primitives to cross function boundaries

0:06 rata_: ok, I think this is not the case

0:06 then how do I use primitive math inside that fn?

0:07 amalloy: &(doc unchecked-add)

0:07 sexpbot: ⟹ "([x y]); Returns the sum of x and y, both int or long. Note - uses a primitive operator subject to overflow."

0:07 amalloy: &(doc int)

0:07 sexpbot: ⟹ "([x]); Coerce to int"

0:07 rata_: &(doc long)

0:07 sexpbot: ⟹ "([x]); Coerce to long"

0:08 rata_: perfect, so it should be (apply unchecked-math (long rate) (map long (mapcat ... lhs)))?

0:09 or does that (map long ...) won't work?

0:09 symbole: Do clojure projects use the Spring framework in any extensive way?

0:10 amalloy: rata_: you'll lose the casting if you map it to long - it'll just be boxed it back up into a Seq full of Longs

0:10 that would probably just make it slower

0:12 scottj: symbole: not unless they have to, from what I've seen

0:12 technomancy: symbole: never heard of anyone using Spring with clojure

0:12 amalloy: i don't have much experience with primitive optimization though so take my advice with a lot of skepticism here

0:15 rata_: hmmm... then (unchecked-multiply (long rate) (reduce (fn [result [mol freq]] (unchecked-multiply (long result) (unchecked-multiply (long (get-molecule state mol)) (long freq)))) 1 lhs))

0:16 it'll anyway do some boxing and unboxing

0:18 amalloy: are the math fns you mentioned before, those that throw an error when overflow, present in 1.2?

0:18 amalloy: i don't think so

0:18 rata_: ok

0:19 and does anyone know when 1.3 will be beta or stable?

0:22 amalloy: rata_: fwiw i just tried (reduce * (range 2 50)) and (reduce unchecked-multiply (map long (range 2 50)))

0:22 unchecked-multiply is a bazillion times slower due to all the boxing

0:23 clarify: it's a lot slower, and *i* think it's cause of the boxing

0:23 sproust: nrepl.el is born (5 minutes ago).

0:24 amalloy: sproust: neat

0:25 rata_: amalloy: so maybe using unchecked-math before 1.3 is pointless?

0:25 sproust: Just mucking around with the protocol at this point.

0:26 amalloy: rata_: no, it's certainly faster in the right circumstances. i think this example would have the same behavior in 1.3

0:27 rata_: it shouldn't, because 1.3 doesn't box automatically, does it?

0:27 technomancy: rata_: 1.3 allows you to write functions that don't box their args

0:28 rata_: ok

0:28 I imagine that'd be very useful here

0:28 amalloy: but reduce will still have to box at every step, no?

0:29 but would apply * work?

0:31 rata_: amalloy: you could write your own reduce that doesn't box

0:31 amalloy: yes

0:31 rata_: but I don't know if apply or reduce won't box by default

0:32 in fact, I know very little about 1.3 features =P

0:35 scottj: is there a function you can call on x to see if it's a boxed or unboxed long?

0:36 tomoj: functions box their args (at least in 1.2)

0:37 scottj: sorry, in 1.3

0:40 amalloy: isn't there a function somewhere to tell you what the compiler thinks of a sexp?

0:41 i've seen chouser using it, and that's more or less the only way i can think of that you could use to see whether something is being treated as primitive

1:10 dsantiago: If you call seq on a map, you get a seq of vectors of key/value pairs. Is there a function to get a map back from that?

1:11 tomoj: there's into

1:12 they're actually MapEntrys

1:12 &(key [1 2])

1:12 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

1:12 tomoj: &(key (first {1 2}))

1:12 sexpbot: ⟹ 1

1:13 tomoj: but into will work with vectors too

1:19 amalloy: ugh. i've been trying to figure out how to get the compiler to analyze an expr for me. i've gotten as far as finding clojure.lang.Compiler$LetExpr$Parser, which *seems* to have a no-arg constructor, but if i try ##(clojure.lang.Compiler$LetExpr$Parser.) it doesn't work

1:19 sexpbot: java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.Compiler$LetExpr$Parser

1:20 amalloy: can anyone see why? Compiler.java has "new LetExpr.Parser()" in a scope that's not closing around anything, and LetExpr is a static inner class

1:21 dsantiago: tomoj, thanks! I knew about into, but didn't realize it did that.

1:22 tomoj: weird: ##(->> (range (* x 10) (* (inc x) 10)) (partition 2) (map vec) (into {}) (for [x (range 10)]) (into {}))

1:22 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$for

1:22 tomoj: hmm

1:22 well, that was a terrible way to illustrate the weirdness anyway

1:23 hiredman: amalloy: I thing there is a static analyze method on Compiler, I would see what that does

1:23 amalloy: tomoj: (for (big-old-expr) [x (range 10)] (into))...

1:23 tomoj: amalloy: works fine for me here

1:23 amalloy: hiredman: i couldn't figure out how to get an Expr object to pass it

1:23 tomoj: ,(->> (range (* x 10) (* (inc x) 10)) (partition 2) (map vec) (into {}) (for [x (range 10)]) (into {}))

1:23 clojurebot: {0 1, 32 33, 64 65, 96 97, 2 3, 34 35, 66 67, 98 99, 4 5, 36 37, ...}

1:24 tomoj: &(conj {} (map first [{1 2} {3 4} {5 6}]))

1:24 sexpbot: ⟹ {5 6, 3 4, 1 2}

1:24 tomoj: that's the weirdness

1:25 so that (into {} s) where s is a seq of seqs of MapEntrys works, strangely

1:25 hiredman: amalloy: you can use the specials map near the top to get a Parser object for a given special form, then call .parse

1:25 amalloy: oh of course. why make my own when there's one right there. thanks

1:26 tomoj: amalloy: maybe the default constructor is not public?

1:26 amalloy: tomoj: it is though. none is specified at all

1:26 tomoj: right, those are public?

1:27 seems its supposed to be the same as the class

1:27 and the class isn't public

1:28 ..or does that nested class inherit public from LetExpr? brings back bad memories of the java cert test

1:29 &(into {} [{1 2} {3 4}])

1:29 sexpbot: ⟹ {1 2, 3 4}

1:29 tomoj: maybe that's why it works?

1:30 amalloy: ,(.parse (get Compiler/specials 'let*) nil '([x 1] (long x)))

1:30 clojurebot: java.lang.IllegalArgumentException: Bad binding form, expected vector

1:35 amalloy: ,(.parse (get Compiler/specials 'let*) nil '(let [x 1] (long x)))

1:35 clojurebot: java.lang.NullPointerException

1:49 * devn wishes he could keep up with the changes in evaluation syntax for the meta-reader irc bots

1:50 amalloy: devn: what?

1:52 rata_: amalloy: it got better =) 65% now with mapcat and just one *

1:52 amalloy: hey cool. never would have guessed my suggestion was any good, there

1:55 rata_: I'll try with reduce as well, but now it's time to sleep

1:55 thank you amalloy =)

1:56 metadaddy1: Anyone having problems with ring/ring-httpcore-adapter 0.3.7?

1:56 I was using it fine yesterday, now lein deps fails w a maven error

1:56 rata_: I hope I get that fn to run fast, I think it shouldn't use more than 20% of the time

1:57 metadaddy1: and it's missing from http://clojars.org/repo/ring/ring-httpcore-adapter/

1:57 rata_: but maybe I'm too optimistic

1:57 see you guys, good night

1:57 metadaddy1: http://clojars.org/repo/ring/ring-jetty-adapter/0.3.7/ is there

2:10 dnolen: brehaut: there you go, https://github.com/swannodette/bratko-logos/blob/master/src/bratko_logos/monkey_banana.clj in 18 lines of Clojure.

2:10 brehaut: dnolen: that is very nice

2:11 dnolen: now sleep

2:12 brehaut: dnolen: ive been pondering the existance of the move type symbols; are they strictly necessary? seems to me they only exist to clarify it for the humans

2:12 dnolan: gnight

2:36 metadaddy1: figured it out, I think

2:56 letronje: had a n00b doubt

2:56 waxrosecabal: amalloy, Does lein actually install 1.3 and swank-clojure or is it just for dependencies?

2:56 letronje: (defn test [n] (do (println "\ntrying " n "\n") (> n 2)))

2:56 (first (filter test [1 2 3 4 5 6 7 8 9 10]))

2:57 if filter is lazy, why does it go through the entire the vector after it finds 3 ?

2:57 amalloy: &(class (seq [1 2 3 4]))

2:57 sexpbot: ⟹ clojure.lang.PersistentVector$ChunkedSeq

2:58 amalloy: letronje: vectors are chunked

2:59 not sure why that's actually related to your question though, now that i think about it

2:59 letronje: exactly :)

3:00 tomoj: &(class (next (filter identity [1 2 3])))

3:00 sexpbot: ⟹ clojure.lang.ChunkedCons

3:00 tomoj: filter preserves chunkiness

3:00 amalloy: like donuts

3:01 letronje: is there a function that lets me apply a predicate on a sequence and return the first item in the sequence for which it is true ?

3:02 amalloy: (comp first filter)

3:02 letronje: ((comp first filter) test [1 2 3 4 5 6 7 8 9 10]) ?

3:02 * brehaut wonders, aimlessly, if the fold and map fusion laws hold in clojure…

3:03 amalloy: that would work

3:03 letronje: @amalloy: I still see 10 prints

3:03 amalloy: usually it's written as (first (filter ...)), but it really should be its own function

3:03 letronje: i wanted something like some

3:03 amalloy: like tomoj said, filter preserves chunkiness

3:04 tomoj: letronje: is the problem that you're actually doing side effects? or that applying the pred to a whole chunk is too slow?

3:04 letronje: the actual predicate that i plan to give to filter is costly ( CPU + IO )

3:05 so i want it to immediately stop once it finds it

3:05 amalloy: letronje: the easy solution is not to give it something it *can* chunk

3:05 ie not a vector

3:05 tomoj: sounds strange. but I think there's an unchunker somewhere?

3:06 amalloy: there is

3:06 &(filter (juxt identity println) (range 4))

3:06 sexpbot: ⟹ (01230 1 2 3)

3:06 amalloy: &(filter (juxt identity println) [0 1 2 3])

3:06 sexpbot: ⟹ (01230 1 2 3)

3:06 amalloy: &(filter (juxt identity println) '(0 1 2 3))

3:06 sexpbot: ⟹ (010 21 32 3)

3:07 amalloy: &(first (filter (juxt identity println) '(0 1 2 3)))

3:07 sexpbot: ⟹ 0 0

3:07 amalloy: &(first (filter (juxt identity println) [0 1 2 3]))

3:07 sexpbot: ⟹ 0 1 2 3 0

3:08 amalloy: would have been a better demo :P

3:08 letronje: not sure i understand, n00b here

3:09 amalloy: the point is that only vectors and (range) are chunked currently, i think

3:09 brehaut: letronje: its confused because the println and the result are on the same line

3:09 amalloy: so if you filter on something that is neither of those, it won't chunk, and it will be as lazy as you want

3:09 brehaut: &(let [n 1] (println n) (println "this is the return >") n)

3:09 sexpbot: ⟹ 1 this is the return > 1

3:09 tomoj: letronje: what's the IO?

3:09 letronje: yup

3:10 tomoj: network IO

3:10 tomoj: I mean, what is it

3:10 what are you actually doing? just curious

3:10 letronje: scraping a url

3:10 tomoj: yeah, having that inside the pred seems fishy to me anyway

3:11 though an alternative doesn't quickly spring to mind

3:11 letronje: a set works

3:11 amalloy: my irc client hates me. going to bed before it gets worse

3:11 letronje: ((comp first filter) test #{1 2 3 4 5 6 7 8 9 10})

3:11 prints only till 3

3:12 amalloy: letronje: sets do not maintain order

3:12 &(class (list* [1 2 3]))

3:12 sexpbot: ⟹ clojure.lang.PersistentVector$ChunkedSeq

3:12 amalloy: dang it

3:12 letronje: yes, just validated that they are not chunked :)

3:12 amalloy: &(class (apply list [1 2 3]))

3:12 sexpbot: ⟹ clojure.lang.PersistentList

3:13 amalloy: &(filter (juxt println identity) (apply list [1 2 3]))

3:13 sexpbot: ⟹ (121 32 3)

3:13 amalloy: &(first (filter (juxt println identity) (apply list [1 2 3])))

3:13 sexpbot: ⟹ 1 1

3:13 amalloy: so you can use apply list to unchunk something, too

3:13 letronje: ok

3:14 thnx

3:14 what does juxt do btw ?

3:15 tomoj: doesn't it seem like the fact that these problems happen suggests you aren't supposed to do this?

3:15 letronje: &(map (juxt println identity) [1 2 3 4 5 6 7 8 9 10])

3:15 sexpbot: ⟹ (12345678910[nil 1] [nil 2] [nil 3] [nil 4] [nil 5] [nil 6] [nil 7] [nil 8] [nil 9] [nil 10])

3:15 tomoj: but how else would you do it?

3:15 letronje: (loop (recur )) ?

3:16 tomoj: basically reimplement filter without the chunking.. that doesn't seem right either :(

3:16 brehaut: letronje: it takes n functions and returns a new function; that new function passes all the arguments to all the functions returning a vector of the results

3:16 letronje: it juxtaposes the functions :)

3:16 &(juxt inc dec)

3:16 sexpbot: ⟹ #<core$juxt$fn__3661 clojure.core$juxt$fn__3661@1354d59>

3:16 brehaut: sexpbot: thanks

3:16 &((juxt inc dec) 1)

3:16 sexpbot: ⟹ [2 0]

3:17 letronje: ah

3:17 interesting :)

3:17 why use identity ?

3:18 oh ok got it

3:18 so that filter gets the orig value ?

3:18 brehaut: (defn dechunk [xs] (lazy-seq (when xs (cons (first xs) (dechunk (rest xs)))))) ?

3:18 tomoj: won't that blow the stack?

3:19 brehaut: tomoj: lazy-seq should avoid that shouldnt it?

3:19 tomoj: er, infinite seq I mean?

3:19 need next instead of rest or (when (seq xs)) or both, I think

3:19 brehaut: tomoj: i dunno thats just a naive first guess

3:19 you are correct

3:20 lets go with both.

3:20 letronje: &(map (juxt inc dec) [ 1 2 3 4 5 6 7 8 9])

3:20 sexpbot: ⟹ ([2 0] [3 1] [4 2] [5 3] [6 4] [7 5] [8 6] [9 7] [10 8])

3:21 tomoj: right, with next but without seq (dechunk []) is (nil)

3:21 letronje: &(filter (juxt inc dec) [ 1 2 3 4 5 6 7 8 9])

3:21 sexpbot: ⟹ (1 2 3 4 5 6 7 8 9)

3:21 letronje: &(filter (juxt inc dec) [ 1 2 3 4 nil 5 6 7 8 9])

3:21 sexpbot: java.lang.NullPointerException

3:21 letronje: &(filter (juxt inc dec) [ 1 2 3 4 false 5 6 7 8 9])

3:21 sexpbot: java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number

3:23 brehaut: &(letfn [(dechunk [xs] (lazy-seq (when (seq xs) (cons (first xs) (dechunk (next xs))))))] (first (map prn (dechunk (iterate inc 1)))))

3:23 sexpbot: ⟹ 1 nil

3:23 brehaut: have i dont something to upset sexpbot?

3:23 tomoj: that seems to work

3:24 (in terms of not blowing the stack to bits on lazy seqs)

3:24 im sure there is something dumb about how it works though

3:24 tomoj: I had thought the unchunker I remembered seeing was more mysterious

3:24 brehaut: tomoj: yeah exactly

3:25 tomoj: only problem I can think of though is lazy seq overhead which is no problem here

3:25 and anyway, how could any unchunker not have that overhead?

3:26 sort of the point I guess

3:26 brehaut: im going to dig into joy of clojure

3:27 i think chouser has one

3:27 tomoj: the unchunker in JoC appears to reify clojure.lang.ISeq

3:27 tomoj: and its called seq1 apparently

6:19 * ZabaQ has just discovered Enlive..

6:19 ZabaQ: intetesting..

6:28 what's this -SNAPSHOT business in the version names?

6:29 angerman: I assume it's autogenerated (e.g. on a daily basis) stuff from the head of the dev. branch.

6:29 raek: they act as in-between version numbers

6:29 waxrosecabal: Basically a nightly build?

6:30 raek: yes

6:30 a non-snapshot version of a project should not have snapshot dependencies

6:31 waxrosecabal: Do you know if the clojure-install from Emacs pulls from the snapshot?

6:31 raek: Leiningen will always check for new versions of a snapshot dependency when doing lein deps, even if there is a version is in the cache

6:31 waxrosecabal: hmm

6:32 raek: waxrosecabal: swank-clojure.el (which contains clojure-install) is old and deprecated

6:33 waxrosecabal: Man, I think every installation process I've found has been deprecated. :/

6:33 raek: these things changed substantially when Leiningen appeared

6:35 my emacs installation routine: install clojure-mode, slime and slime-repl using package.el and technomancy's repo (included with emacs-starter-kit)

6:35 add [swank-clojure "1.2.1"] to :dev-dependencies and start a swank server with "lein swank"

6:35 connect to it from emacs with M-x slime-connect

6:36 (this assumes you have leiningen and a created a project with it)

6:36 and that's basically it.

6:36 waxrosecabal: Cool, thanks. I was just a little confused at lein's roll.

6:36 raek: I use technomancy's durendal to start the swank server nowaday

6:37 just run M-c durendal-jack-in when you have a source file of the project open

6:37 *M-x

6:37 so that replaces the "lein swank" step

6:38 waxrosecabal: I'll try that in a little bit. Thanks. Need to update my notes. :P

6:38 * raek wonders why he hasn't written a blog post about this yet

6:39 waxrosecabal: Do you have any experience with Clojure on Google App Engine?

6:40 If so, thoughts?

6:40 raek: not yet :)

6:40 only ring + moustache + enlive (and a little bit of compojure + hiccup)

6:41 I've heard that you use the ring stack for the servlet part of a GAE app

6:42 waxrosecabal: I was going to give Compojure a try first since I've seen a mini guide about it. And yeah, that is what I believe is used.

6:42 mini guide on GAE*

6:44 raek: this sums up my workflow with the ring stack: http://groups.google.com/group/clojure/browse_thread/thread/4d8a1fc669a5a2df/9a7551ecfc851309?lnk=gst&q=rasmus+app+engine#9a7551ecfc851309

6:44 some of it could be useful for GAE development

6:46 waxrosecabal: Thanks for the link.

6:47 Yeah, looks helpful already.

7:01 joelr: technomancy: ping

7:31 hsuh: does the - in (defn -main..) has any meaning to the reader, or its just convention?

7:32 clgv: it needs to be there in case you create a jar and want it to be the main-method called

7:32 hsuh: can it be main instead of -main ?

7:33 angerman: (or want it to be the entry point for $ lein run -m package.class)

7:33 clgv: hsuh: I dont think so. you can only specify the namespace that contains -main in leiningen afaik

7:33 hsuh: ok

7:34 clgv: it doesnt hurt much anyway, I think ;)

7:36 hsuh: about that, in my top directory i have src/ and script/, and script/ has run.clj inside, which runs swank and then my -main... but after updating lein, i'm getting "Caused by: java.io.FileNotFoundException: Could not locate script/run__init.class or script/run.clj on classpath"

7:36 i'm trying lein run -m script.run (i used to do lein run script/run.clj)

7:37 angerman: seems like a classpath issue. no?

7:37 lein has a command to show the classpath it thinks is correct. iirc.

7:37 e.g. $ lein classpath

7:38 so that should at least contain "."

7:38 hsuh: ok, but i thought lein was useful exactly because it handled that :)

7:40 angerman: I don't know what is with your lein. Haven't had a problem myself.

7:40 hsuh: lein version ?

7:41 angerman: 1.4.2

7:41 hsuh: ok, same here..

7:42 clgv: I guess it doesnt know about your scrip directory

7:43 angerman: if script was in src. I assume it would work.

7:43 clgv: is "script" a default leiningen directory?

7:43 yeah then it definitely should

7:47 hsuh: does you run.clj file has a (ns..) declaration? (mine doesnt)

7:48 clgv: that might be an issue. shouldnt every regular clj-file have an ns declaration? clojure config files lik project.clj excluded

7:58 I am tempted to use some sort of callback function for a deftype. this callback is specific problem dependent behavior which can't be determine by the general implementation. Is there a better or more idiomatic way to do this in clojure?

8:06 hsuh: angerman, clgv: yeah, adding an ns and putting the file into src/ works, i liked the older organization though.. but its time to be pragmatic .........

8:06 but ty

8:08 raek: hsuh: "-" is the default prefix for gen-class. you can override it with the :prefix option: http://clojuredocs.org/clojure_core/clojure.core/gen-class

8:09 hsuh: oh, interesting... thanks. i wont change it, just wanted to understand where did it came frmo

8:09 clgv: hsuh: there is  :repl-init-script option for leiningen. see  https://github.com/technomancy/leiningen/blob/stable/sample.project.clj

8:09 hsuh: great, i can develop with lein repl than! thanks!

8:09 raek: hsuh: leiningen run feature is a bit different (and opinionated) when compared to the lein-run plugin

8:09 hsuh: 8then

8:09 *then

8:10 raek: leiningen also has run? now i dont know if im using the plugin or not...

8:10 raek: from your description it looks like you have the built in one

8:10 hsuh: that explains a lot...

8:10 raek: i.e. lein run takes a namespace as a parameter rather than a file

8:11 and loads plus calls -main, instead of just loading it

8:11 hsuh: sure, i get it now.. thats why things "changed" so much.. after updating i stopped using the plugin and started using lein's run...

8:11 raek: heh

8:20 angerman: hm. Is there a funtion that takes a list of bool and return if all are true?

8:20 e.g. (apply and lst) but that doesn't work iirc.

8:20 ,(apply and [true true true])

8:20 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/and

8:23 clgv: $findfn [true true true] true

8:23 sexpbot: [clojure.core/== clojure.core/sequential? clojure.core/second clojure.core/last clojure.core/reversible? clojure.core/distinct? clojure.core/boolean clojure.core/vector? clojure.core/counted? clojure.core/associative? clojure.core/< clojure.core/peek clojure.core/fir... http://gist.github.com/874233

8:24 angerman: $findfn [true true true false true] false

8:24 sexpbot: [clojure.core/keyword? clojure.core/chunked-seq? clojure.core/fn? clojure.core/not= clojure.core/nil? clojure.core/string? clojure.core/sorted? clojure.core/false? clojure.core/true? clojure.core/symbol? clojure.core/number? clojure.core/integer? clojure.core/seq? cl... http://gist.github.com/874235

8:24 angerman: no.

8:24 ,(every? identity [true true true])

8:24 clojurebot: true

8:24 clgv: hm ok not the appropriate use case for that findfn

8:25 ,(every? [true true true])

8:25 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$every-QMARK-

8:25 angerman: every? expects a predicate

8:25 clgv: ,(find-doc "all")

8:25 clojurebot: -------------------------

8:25 clojure.contrib.seq/fill-queue

8:25 ([filler-func & optseq])

8:25 filler-func will be called in another thread with a single arg

8:25 'fill'. filler-func may call fill repeatedly with one arg each

8:25 time which will be pushed onto a queue, blocking if needed until

8:25 this is possible. fill-queue will return a lazy seq of the values

8:25 filler-func has pushed onto the queue, blocking i...

8:27 clgv: $help findfn

8:27 sexpbot: clgv: Finds the clojure fns which, given your input, produce your output.

8:28 angerman: findfn need more predicates. e.g. given 3 inputs and expected outputs.

8:28 clgv: yep^^

8:28 angerman: Something is weird. My radio clock on the wall is spinning since 9 o'clock.

8:29 There must be some issue with the signal.

9:19 Japan looks /really/ bad.

9:19 Fossi: in general?

9:20 angerman: well, about half a week ago, i thought there was a chance that this could end semi-lucky.

9:21 but since then, I'm loosing faith in the success by the hour :/

9:25 Fossi: and in general, that's going to be a very hard setback for japan. High devastation, radiation, national depth at 200% and rising :(

9:25 __name__: amalloy_: Is sexpbot FOSS?

9:26 Fossi: so far the radiation is really low

9:26 __name__: angerman: *debt?

9:26 Fossi: if there hasn't been something big happening in the last hour

9:27 angerman: Fossi: I guess the question is where and whom you ask. The graphs near the plant look really bad.

9:27 __name__: yes.

9:27 Fossi: and what are you going to do with the plant's region and it's sourrounding?

9:28 Fossi: guess it depends on what's "really bad" to you

9:28 the highest reading i heard of was 900mSv

9:29 that won't even cause sustained damage really

9:29 and that was like 3 days ago

9:30 angerman: Fossi: mSv or muSv?

9:30 Fossi: mSv

9:31 since you are german: http://www.grs.de/informationen-zur-lage-den-japanischen-kernkraftwerken-fukushima-onagawa-und-tokai

9:31 is a really good summary

9:31 angerman: Fossi: yep, that's what I'm reading.

9:31 Fossi: highest reading at the frontdoor was something like 12mSv

9:35 angerman: Fossi: yes. But what happens to the particles that got in the air, as far as I understand, depending on what escapes it's halflife is from 8 days to multiple years.

9:36 Fossi: I understand that there was an elevated radiation level in the athmosphere during the time of atomic bomb tests.

9:40 Fossi: well, atomic bomb test are something entirely different from this

9:40 and from the readings it's so far pretty obvious that not a whole lot of radioactive material has "escaped" the containments

9:41 the higher readings are from venting the containment

9:42 choffstein: Does clojure have pattern matching besides multi-methods (e.g. a 'match' method or something similar)?

9:42 My google-fu is failing me for a concrete answer

9:43 Basically, I want my method to do one thing when an input is an empty list, and another when the list has objects in it

9:43 wtetzner: you can use cond

9:44 raek: choffstein: well, you have cond, case and (unconditional) destructuring, but nothing like matching in Haskell or Scala

9:44 wtetzner: (cond (empty? lst) do-something :else do-something-else)

9:44 choffstein: So just cond and destructure then?

9:44 raek: if-let can be useful too

9:45 ...in some cases

9:46 choffstein: hmmm, okay, thanks

9:46 raek: choffstein: also, check out https://github.com/dcolthorp/matchure

9:47 angerman: hmm… http://www.brool.com/index.php/pattern-matching-in-clojure ?!

9:47 that's been the first google result for me.

9:54 raek: I like the syntax of that one

9:54 (https://github.com/brool/clojure-misc)

9:57 angerman: it looks a little more like the pattern matching syntax I'm used to then matchure looks.

9:58 raek: I wonder if it supports [a & d] patterns

10:02 heh, the documentation does not mention which namespace to use

10:04 tmountain: if you have a bunch of items in a collection and want to dispatch a function based upon some characteristic of the item, would it be more idiomatic to use protocols and types or something like multimethods?

10:05 raek: with protocols, you can only dispatch on the type of the first argument

10:06 multimethods can dispatch on anything

10:08 (use 'pattern-match) (match [1 2 3] [fst & rst] rst) => (2 3)

10:10 tmountain: are protocols intended more as a Java bridge technology, or are they first-class citizens IRT program design. for some context, I'm messing around with some basic game logic. when the game server "heartbeat" occurs, all entities in the game need to respond

10:11 I could wrap all that up in a protocol and guarantee that the objects can respond to the event, but I wonder if I'm straying too far from FP design principles there...?

10:11 angerman: tmountain: clojure is not pure fp

10:12 raek: they are intended to be a more performant, but restricted, variant of multimethods (with grouping of methods)

10:12 but they are not a mere interop feature

10:13 tmountain: angerman: yeah, I know, it's more pragmatic, I just tend to want to treat it as such

10:14 raek: that makes sense, so as long as I'm content with being restricted to dispatching on the first argument, protocols are a good choice?

10:14 angerman: tmountain: my render should be able to render points, edges and faces. So I could either write structmaps or records and multimehtods to allow one method `render' to work for all, or just go the protocol way.

10:14 the letter one looks cleaner.

10:14 https://github.com/angerman/planarity/blob/master/src/geometry/renderer.clj

10:17 raek: tmountain: I haven't done much design using protocols, so I simply do not know...

10:18 but to me it sounds like protocols is a language feature that could indeed be used to solve yout problem

10:18 tmountain: angerman: what does the _ argument to the protocol method signatures imply?

10:18 angerman: well _ is just a throw away place holder.

10:18 tmountain: raek: no worries, you've been helpful in helping me draw distinctions between strategies

10:18 angerman: tmountain: could be `this' or `self' as well.

10:18 tmountain: angerman: basically a placeholder for "this" or the first arg

10:18 ok

10:19 thanks guys

10:19 raek: that name is what you see in the arglist in the docs (or in the minibuffer of emacs)

10:20 (hrm, don't know whether autodoc actually supports protocols as a doc source)

10:22 joelr: good day! how do i find the latest version of composure to depend on?

10:22 same for lein-ring for that matter

10:30 raek: joelr: I usually look in the project.clj of the project (if it's on github, for example) or at http://clojars.org/repo/

10:30 joelr: raek: thanks!

10:33 raek: (also, do not use SNAPSHOT dependencies when releasing non-snapshot versions of you project)

10:48 choffstein: If I have two lists of maps that are identified by a unique key, like [{:a 5, :b 6} {:a 6, :b 5}] and [{:a 5, :c 7} {:a 6, :c 8}, is there any way to combine them by unique key to get a list that is: [{:a 5 :b 6 :c 7} {:a 6 :b 5 :c 8}]?

11:06 joly: ,(map into [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 6, :c 8}])

11:06 clojurebot: ({:a 5, :b 6, :c 7} {:a 6, :b 5, :c 8})

11:06 joly: choffstein: ^ but I'm not sure that solves the problem you're asking

11:06 raek: ,(map merge [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 6, :c 8}])

11:06 clojurebot: ({:c 7, :a 5, :b 6} {:c 8, :a 6, :b 5})

11:08 clgv: ,(map merge [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 7, :c 8}])

11:08 clojurebot: ({:c 7, :a 5, :b 6} {:c 8, :a 7, :b 5})

11:08 clgv: is that intended or did you look for a join-semantic?

11:09 devn: damn beat me to it

11:11 choffstein: awesome. thanks!

11:15 clgv: choffstein: thats ok for you? ##(merge {:a 1, :b 5} {:a 999, :c 8})

11:15 sexpbot: ⟹ {:c 8, :a 999, :b 5}

11:17 choffstein: Hmm, on second thought, not quite.

11:17 I need to be able to define the key I am merging on

11:18 clgv: it's just merging the maps. it has no sql-like join semantics on any of the keys

11:18 clojurebot: maps are functions

11:18 clgv: clojurebot: a cookie for you

11:18 clojurebot: It's greek to me.

11:19 choffstein: i think I might have it

11:19 elegant_knight: ;this may not be a clean way.. do it do the job?

11:19 (defn merge-map-lists

11:20 "merges the 2 lists of maps"

11:20 [list1 list2]

11:20 (let [merged (merge (first list1) (first list2))])

11:20 (if (or (= (count list1) 1) (= (count list2) 1))

11:20 (cons merged [])

11:20 (cons merged (merge-map-lists (rest list1) (rest list2)))))

11:22 angerman: why is it `every?' and `some'?

11:22 clgv: angerman: pure evilness ;)

11:24 raek: angerman: some not only checks whether there is an element, but can also return it

11:24 clgv: choffstein: you could use merge-with I guess ##(doc merge-with)

11:24 sexpbot: ⟹ "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

11:27 raek: choffstein: map merge will take the first map of the left list and the first map of the right list and merge them. did you want to merge one the value for a certain key, rather than on the position in the list=

11:27 ?

11:50 amalloy: (cons foo []) is the same as (list foo)

11:53 elegant_knight: amalloy:got it!

11:54 i have a list of values. i want to find the index of maximum value in that. whats the easiest way to do it

11:54 scottj: why does https://gist.github.com/874276 call shutdown-agents if there's no call to agent in the code?

11:56 mrBliss: ,(let [l [1 2 3 2]] (.indexOf l (reduce max l)))

11:56 clojurebot: 2

11:57 mrBliss: ,(let [l [1 2 3 2]] (apply max-key l (range 0 (count l))))

11:57 clojurebot: 2

11:58 mrBliss: elegant_knight: ^^

12:00 The second one is 3x faster than the first (on my machine)

12:00 jkkramer: only works on vectors

12:00 mrBliss: jkkramer: correct

12:01 ounce: hi

12:03 jkkramer: scottj: previous versions appeared to use pmap, which uses futures, which use the agents thread pool

12:06 mrBliss: ,(loop [l '(1 2 3 2), i 0, max -1, max-i -1] (if-let [[head & tail] l] (if (> head max) (recur tail (inc i) head i) (recur tail (inc i) max max-i)) max-i))

12:06 clojurebot: 2

12:06 mrBliss: Ugly loop, but faster than the previous two

12:09 scottj: jkkramer: ok that's what I thought

12:10 elegant_knight: mrBliss : thanks. i have a lazy sequence. so the first way of using .indexOf worked just fine.. second one looks elegant!

12:14 angerman: is there any logic faillure in (defn any? [pred coll] (every? (complement pred) coll)) ?

12:15 clgv: angerman: yes. you determine "none?" since you have an "and" over all negated predicates

12:15 amalloy: more of a vocab failure than a logic failure :)

12:16 angerman: yea right. fail's on me.

12:17 clgv: you want to know if not all predicate applications are false?

12:17 angerman: clgv: as in: (if (none? impossible […]))

12:18 hmm that's none? impossible? :D

12:19 mrBliss: ,(find-doc #"not-.+\?")

12:19 clojurebot: -------------------------

12:19 clgv: you'll get true in your definition for the case that at least one predicate is true when you negate the every? like (not (every? ...))

12:19 clojurebot: clojure.core/not-any?

12:19 ([pred coll])

12:19 Returns false if (pred x) is logical true for any x in coll,

12:19 else true.

12:19 -------------------------

12:19 clojure.core/not-every?

12:19 ([pred coll])

12:19 Returns false if (pred x) is logical true for every x in

12:19 coll, else true.

12:20 angerman: there's not-any? wtf.

12:20 jkkramer: (def any? (comp boolean some))

12:21 angerman: ,(some nil? [nil nil nil])

12:21 clojurebot: true

12:22 clgv: angerman: yeah that logic what functions to include there is a bit inconsistent ;)

12:22 angerman: clgv: I'm getting confused with them too often :/

12:28 clgv: wrtie your own "some?" and you are safe ;)

12:47 angerman: is ^ still the meta reader macro?

12:47 ,(:foo ^(with-meta 'x {:foo 'y}))

12:47 clojurebot: Metadata must be Symbol,Keyword,String or Map

12:47 fogus`away: ,(doc meta)

12:47 clojurebot: "([obj]); Returns the metadata of obj, returns nil if there is no metadata."

12:48 angerman: ok, so I need to use (meta ...)

12:59 dakrone: is there a way to make a non-seqable string easily?

13:00 amalloy: dakrone: waaaat?

13:00 dakrone: I'll take that as a "no one needs that so you're doing it wrong"

13:01 amalloy: dakrone: well i don't understand what it is you want

13:02 $mail choffstein see also not-empty for your empty-list-finding needs: (if-let [l (not-empty input)] (do stuff with l) (whoops input was empty))

13:02 sexpbot: Message saved.

13:03 amalloy: you want a sequence of characters that can't be treated as a sequence of characters, is all i can get from the original question. i'd say maybe use ##(symbol "some-string"), which keeps all the information and makes it non-seqable, but it's a weird thing to do

13:03 sexpbot: ⟹ some-string

13:03 raek: dakrone: there is no way to have something that is a java.lang.String that noone can call seq on

13:03 dakrone: nevermind, I was doing it wrong, as I suspected

13:03 amalloy: *chuckle*

13:04 raek: the question is, what problem is non-seqable string the solution for?

13:06 dakrone: missing a [] in a lazy-seq and staring at it too long, that's what

13:45 mattmitchell: i'm trying to create a wrapper around 2 functions that are together like this: (sql/with-connection db-conn (sql/with-query-results res ["my query"]) ...)

13:46 the problem is that the with-query-results is a macro and creates "res" -- so I'm not sure how to handle it?

13:47 as a first try, this doesn't work: https://gist.github.com/874777

13:51 amalloy: mattmitchell: your function will have to be a macro

13:51 mattmitchell: amalloy: ok i was kinda thinking that

13:52 amalloy: also did you intend to throw away the query arg?

13:52 mattmitchell: amalloy: woops, no

13:53 amalloy: anyway it probably looks basically like (defmacro wqr [query form] `(sqlwc db/conn (sql/wqr ~'res ~query ~@form)))

13:54 raek: mattmitchell: you can also do something like this: (defn with-query-results [query f] (... (sql/with-query-results res (f res))))

13:55 amalloy: good point

13:56 mattmitchell: raek: right thanks

13:56 raek: macros really are contagious... this way you can "kill it to keep it from spreading"

13:57 mattmitchell: raek: i've just barely scratched the surface of macros, it will be a while until i "get" it :)

13:58 thanks amalloy

13:58 amalloy: haha

14:42 rcadena: 1

15:08 mrBliss: k

16:01 khaliG: hm ive noticed lein uberjar isn't including the jars in lib/dev .. is this normal?

16:03 Null-A: khaliG: if I had to guess, yes

16:03 khaliG: ok well that would explain why my jar doesn't work :)

16:04 Null-A: khaliG: dev dependencies would be like swank server or lein extensions

16:04 khaliG: ahhh! ok

16:04 so maybe i need to rewrite my project.clj file

16:04 Null-A: sounds like it

16:04 khaliG: thank you!

16:04 Null-A: you could probably put testing dependencies in dev-dependencies too

16:09 khaliG: hm there is one library which i can't move out from dev .. clj-time

16:09 http://clojars.org/clj-time .. seems it has to be the snapshot?

16:11 raek: khaliG: yup. they should release a stable version.

16:11 khaliG: ah damn, so i can't make a jar until they do :/

16:11 raek: khaliG: you can, but your project has to be a snapshot version too

16:11 khaliG: i see

16:13 raek: khaliG: you could also reate an issue for it, so that they become aware of that this is a problem for people

16:13 https://github.com/getwoven/clj-time/issues

16:14 khaliG: i will do that now cheers

16:15 raek: (a completely different alternative is to use joda-time directly using java interop. in many cases it's just a matter of calling .fooBarBaz insead of boo-bar-baz, since joda-time is very compatible with the clojure philosophy)

16:18 khaliG: raek, hm i'd rather not do that, i use it quite heavily :/

16:22 bed time, thanks for the help guys.

16:38 technomancy: wow, clj-time doesn't bother with releases?

16:38 that's like the third library recently I've heard of that does that. what would prompt someone to actually bother bumping the version number if they haven't released?

16:39 boggling.

16:44 amalloy: technomancy: so their version number goes straight from 0.1.0-SNAPSHOT to 0.2.0-SNAPSHOT or something?

16:45 technomancy: amalloy: yes. ಠ_ಠ

16:45 raek: amalloy: indeed so: http://clojars.org/repo/clj-time/clj-time/

16:47 gtrak: with lein test, anyone ever get "Exception in thread "main" java.io.FileNotFoundException: Could not locate robert/hooke__init.class or robert/hooke.clj on classpath:" after adding the :test-selectors map to project.clj?

16:47 brehaut: technomancy: at least enlive and moustache have had real released

16:48 technomancy: brehaut: staying on a snapshot can be forgiven if it's the same snapshot. bumping to another snapshot shows you're at least paying some attention to the version number without getting it right.

16:48 gtrak: ah, nevermind, I found it

16:48 technomancy: gtrak: it should give you a better error message; shoot

16:49 gtrak: yes, I found I have to add a dev dependency

16:50 this same issue: http://j.mp/crcQcy

16:50 brehaut: technomancy: sure that makes sense

16:51 gtrak: excuse me, a different one http://j.mp/hgOgby

16:53 technomancy: gtrak: it shouldn't be a dev dependency

16:54 does it say dev-dependency somewhere? if so that needs to be fixed.

16:54 gtrak: that fixes it for me, same as the issue reporter

16:55 technomancy: hooke is an implied dev-dependency of every lein project

16:56 TimMc: Any way to get swank-clojure in all projects by default?

16:56 gtrak: right, that's what was confusing me, we already are using hooks

16:56 for some reason 'lein test' didn't care

16:56 this is 1.4.2

16:56 TimMc: I see that I can use an init.clj, but I don't know what to put in it.

16:57 amalloy: TimMc: cake project or lein project?

16:57 TimMc: Wait, nvm. lein plugin should do it

16:57 raek: TimMc: you can copy the swank-clojure jar to ~/.lein/plugins/

16:58 technomancy: raek: yeah, lein plugin actually does that

16:58 raek: oh. :)

16:58 TimMc: OK, so now from Emacs, how do I get connected to swank?

16:58 amalloy: M-x slime-connect

16:59 i bound that to C-c s, because i'm clever enough to do that but not clever enough to get it to autoload or manage multiple swank sessions

17:08 TimMc: I assume the usual usage is to send each top-level form to the REPL as you edit it, yeah?

17:08 How do I do that?

17:09 raek: TimMc: the whole file: C-c C-k, the top-level form that encloses the point: C-M-x

17:10 TimMc: thanks

17:10 raek: and to change namespace: C-c M-p (requires it to be loaded)

17:12 TimMc: loaded = eval'd?

17:13 raek: yes

17:13 amalloy: raek, TimMc: i use C-c C-c rather than C-M-x. doubt it matters, but i like having all the interesting commands start with C-c

17:14 raek: (well, the ns form needs to be evaled. otherwise the namespace does not exist and slime will say "no match" or something)

17:17 jlf: raek: i like ,!p to change namespaces

17:21 waxrosecabal: raek, I'm still a little confused at how things are connected, so does Lein make it so that projects have clojure and not the actual system?

17:23 brehaut: TimMc: did you have more luck with your parser?

17:23 TimMc: brehaut: Working on it.

17:23 waxrosecabal: TimMc, o/

17:24 TimMc: hey, waxrosecabal

17:24 technomancy: C-M-x is a elispism

17:24 of sorts

17:24 brehaut: TimMc: cool :)

17:24 TimMc: Tryng to parse numbers.

17:25 I just need pos/neg decimal integers and positive hex

17:25 Right now I'm trying to figure out why my semantics hook isn't being called.

17:27 brehaut: Any reason why an inline anonymous fn would be called and not a defn'd function? :-/

17:27 brehaut: it'll not be called if the parser fails for some reason

17:27 TimMc: #(println %&) works fine, as-decimal-number is never called.

17:28 brehaut: otherwise if its not running it should throw an error

17:28 TimMc: that's surprising!

17:28 TimMc: Oh... my bad

17:28 Forgot to eval that form.

17:28 New at this interactive development thingy.

17:32 brehaut: oh right :D

17:32 waxrosecabal: :P

17:35 TimMc: brehaut: https://gist.github.com/875176 <-- I've got register numbers being extracted, still figuring out the use of semantics.

17:40 brehaut: TimMc: your use of semantics looks correct to me. you have a bug waiting to trip you up in hex-imm; its using decimal-digit

17:42 raek: waxrosecabal: to lein, a version of clojure is "just a dependency" of the project. (does that answer your question?)

17:43 waxrosecabal: raek, Yeah it does. Just matching sure I understand it correctly.

17:44 brehaut: TimMc: you can replace [[& digit-chars]] with digit-chars in your semantics though i think

17:44 raek: "the project has a version of clojure" is the case rather than "the system has a version of clojure"

17:44 waxrosecabal: ah

17:48 amalloy: brehaut: really? i don't think so

17:48 oh i guess so

17:49 brehaut: amalloy: hmm i did remove too many brackets

17:49 amalloy: haha

17:49 brehaut: amalloy: destructuring a sequence into just a remainder is an identity operation is it not?

17:49 amalloy: yeah. that was such a glaring error i didn't even notice it; i knew what you meant

17:50 brehaut: yeah. i think of [:as foo] being equivalent to foo, but never really use & that way

17:50 raek: has anyone made a lib that can catch uncaight exceptions at the top level of an application and (offer the user to) send the stacktrace to the application developer?

17:50 amalloy: (this is a total lie. i'm just trying to justify my clearly incorrect claims)

17:53 raek: or does anyone know what terms I should search for in order to find such a lib?

17:57 xkb: Hi

17:58 Can anybody recommend a current compojure tutorial?

17:58 waxrosecabal: raek, Thanks for the tips. Got every thing hooked up.

18:00 raek: hrm, turns out log4j could be used for my need...

18:00 waxrosecabal: np.

18:40 TimMc: brehaut: Ah, thanks for the digit-chars thing. That was there for hysterical raisins.

18:40 brehaut: TimMc: haha :) no worries

18:40 TimMc: And hex-imm is in progress.

18:48 raek: anyone have any recommendation for a clojure logging tutorial?

18:50 also, does tools.logging include the recent rewrite of clojure.contrib.logging?

18:54 technomancy: raek: it does

19:10 TimMc: The good news: I found out that ##(.intValue (java.math.BigInteger "ffffffff" 16)) works.

19:10 sexpbot: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn

19:10 TimMc: ,(.intValue (java.math.BigInteger. "ffffffff" 16))

19:10 clojurebot: -1

19:10 TimMc: The bad news: All my hex inputs are actually unsigned values. >_<

19:10 brehaut: timmc use longs

19:11 TimMc: Nah, I don't need them.

19:11 They're < 32 bit.

19:11 Memory address literals.

19:13 brehaut: TimMc: im not following. is it a problem??

19:13 s/?$//

19:13 TimMc: The bad news was simply that I didn't have any use for the neat solution.

19:20 java.lang.ClassCastException: org.timmc.mipsiss.instructions.Instr cannot be cast to org.timmc.mipsiss.instructions.Instr

19:21 That's a new one for me.

19:22 brehaut: it does appear surprising doesnt it

19:22 amalloy: wrong classloader?

19:23 ie if two classloaders load the same class, they'll have the same name but not be the same class (nor even related)

19:24 raek: ,(= "org.timmc.mipsiss.instructions.Instr" "org.timmc.mipsiss.instructions.Instr")

19:24 clojurebot: true

19:25 TimMc: I *am* doing something that is probably naughty. https://gist.github.com/875355

19:25 The exception is thrown on the last line of code.

19:26 I should probably convert this to a memoized function.

19:29 brehaut: TimMc: you could rewrite #(vector …) as (juxt :name identity)

19:30 TimMc: I was running a computation involving a defrecord (from the same file) at compile time. :-\

19:30 brehaut: but btw

19:30 err just

19:30 oh

19:30 TimMc: brehaut: But then I wouldn't be able to read it!

19:31 brehaut: TimMc: really?!

19:31 * amalloy uses (juxt identity foo bar ...) so often he's named it (decorate foo bar)

19:31 TimMc: ,((juxt :name identity) {:name 5})

19:31 clojurebot: [5 {:name 5}]

19:32 TimMc: Hmm, I suppose. But is it really any clearer?

19:32 amalloy: yes

19:32 brehaut: TimMc: it juxtaposes your functions

19:32 much!

19:33 amalloy: it proclaims to the world "here are two functions! i am calling them both on the same object! next up: the object i will call them on!"

19:33 brehaut: (caveat: #clojure has a serious juxt fetish)

19:33 TimMc: brehaut: I noticed.

19:33 amalloy: where is the setting to give me a highlight/notify every time someone does something that should be replaced with juxt?

19:34 TimMc: /hilight (

19:35 brehaut: amalloy i think the regexp /[/ should cover it

19:35 amalloy: brehaut: are you crazy? that wouldn't even catch his one case

19:35 brehaut: amalloy: im sorry

19:35 amalloy: /hilight \.

19:40 brehaut: talking of naming random small functions, ive been tempted to write (defn arguments [& r] r)

19:40 TimMc: brehaut: "unapply"

19:40 brehaut: or alias vec or something

19:41 TimMc: hmm. interesting suggestion

19:41 TimMc: Do you really need that that often?

19:41 brehaut: i have also convinced my self that aliasing vector is wrong

19:41 TimMc: often enough

19:46 TimMc: i could just use vector most of the time, but i like the clarity of giving it its own name for the purpose

19:46 and vector isnt lazy

19:49 i have just discovered the seque function and am curious about what it could be used for

19:49 (doc seque)

19:49 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

19:49 brehaut: ,(doc seque)

19:49 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

19:53 amalloy: brehaut: (def arguments list)

19:54 TimMc: brehaut: I notice that the example JSON parser built on fnparse passes a struct around instead of a raw token stream.

19:54 brehaut: amalloy: i dont think thats lazy either

19:55 amalloy: oh all right. list* if you want lazy

19:55 brehaut: &(first (apply (fn [ & r ] r) (iterate inc 1)))

19:55 sexpbot: ⟹ 1

19:55 brehaut: &(first (apply list (iterate inc 1)))

19:55 got a link?

19:55 amalloy: ah right

19:55 sexpbot: Execution Timed Out!

19:55 TimMc: brehaut: https://github.com/joshua-choi/fnparse/wiki/Sample-JSON-parser

19:55 amalloy: &(first (apply list* (range)))

19:55 sexpbot: java.lang.StackOverflowError

19:55 brehaut: &(first (apply list* (iterate inc 1)))

19:55 sexpbot: java.lang.StackOverflowError

19:55 amalloy: lol

19:55 what

19:55 brehaut: double fial

19:55 amalloy: ,(first (apply list* (range)))

19:55 clojurebot: java.lang.StackOverflowError

19:56 amalloy: why would this overflow

20:01 brehaut: TimMc: i suspect its a struct because its older than records and it is more than just {:remainder ... } because it also stores column and line information (for error) using get-info and set-info

20:02 TimMc: ah it uses update-info in nb-char and b-char to track that information

20:04 TimMc: Do I only nee to do something like that if I want debugging info in my parser?

20:04 brehaut: TimMc: if you look at parse-error you'll see its pulling those out of the state

20:05 parse-error is called by parse-error

20:06 what am i say

20:06 by expectation-error-fn which is used by failpoint in various places

20:06 correct

20:08 well, there might be additional state you need for specific parsers (a python or haskell parser would need to track indentation for example)

21:27 mec: ,('m)

21:27 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: Symbol

21:37 amalloy: &('m '{m 10})

21:37 sexpbot: ⟹ 10

21:37 mec: interesting, i thought that was only keywords

21:40 amalloy: mec: keywords are a lot better at it than symbols are

21:42 in that you don't have to quote them, and they're faster

22:13 zakwilson: I want to move a symbol that was defined in namespace a, which is used by namespace b to namespace b without restarting Clojure. Doable?

22:16 brehaut: zakwilson: you can reload a namespace in your repl (require 'namespace.b :reload)

22:17 zakwilson: brehaut: thanks

22:17 TimMc: zakwilson: or even better, :reload-all

22:19 zakwilson: Hmm... that's not working. I still get an IllegalStateException. I should note I'm using Clojure 1.2.

22:35 trptcolin: ok, so i'm re-reading JoC and noticed a sidebar i missed the first time around that says positional destructuring works w/ java.util.regex.Matcher

22:35 ,(let [[a b c] (re-matcher #".*test.*" "this is a test. testing. only a test.")] [a b c])

22:35 clojurebot: [nil nil nil]

22:35 trptcolin: what am i missing here?

22:38 TimMc: ,(re-matcher #".*test.*" "this is a test. testing. only a test.")

22:38 brehaut: ,(let [[a b] (re-matches #"a(b)c" "abc")] [:a a :b b])

22:38 oh my bad

22:38 clojurebot: #<Matcher java.util.regex.Matcher[pattern=.*test.* region=0,37 lastmatch=]>

22:38 [:a "abc" :b "b"]

22:39 TimMc: Ah, re-matche*s*

22:40 brehaut: TimMc: yeah i used the wrong func

22:42 amalloy: zakwilson: you want ns-unmap

22:42 (ns-unmap *ns* 'var-i-want-to-move)

22:42 brehaut: trptcolin: the matcher i get back from your expression raises 'illegalstateexception:no match found' when i try to call nth on it

22:42 trptcolin: interesting, seems the regex capture changes the output semantics here

22:42 ,(let [[a b] (re-matches #"abc" "abc")] [:a a :b b])

22:42 clojurebot: [:a \a :b \b]

22:43 zakwilson: amalloy: thanks, that sounds like what I'm looking for.

22:43 amalloy: &(let [[a b] (re-find #"abc" "abc")] [a b])?

22:43 sexpbot: ⟹ [\a \b]

22:44 amalloy: feh. destructuring regex matches seems like such a weird idea it's no wonder the syntax is hard to get right

22:44 trptcolin: ah, because re-groups returns a string when there are no match groups

22:45 cemerick: amalloy: I think it's a complete misfeature

22:45 trptcolin: amalloy: word. i saw the sentence and immediately ran to the REPL, because i can't think of a good use case for it...

22:46 amalloy: cemerick: that seems like an overstatement to me. there should be *some* way to destructure a match-like-thing into its groups

22:46 brehaut: trptcolin: but re-matches returns a vector so destructuring is straight forward, re-matcher returns the actual object you mention

22:46 trptcolin: yup

22:46 phenom_: hmmm type hinting is done with the hat right? eg (defn my [^MyType type] ...)

22:46 for clojure 1.3

22:46 cemerick: amalloy: oh, I thought we were talking about java.util.regex.Matcher objects

22:47 amalloy: cemerick: we probably are

22:47 i can't keep that whole package straight

22:48 cemerick: amalloy: re-matches returns vectors and strings. re-matcher returns a Matcher object.

22:48 brehaut: cemerick amalloy we were initially, then i screwed up and muddied the water with re-matches

22:48 cemerick: ah, my bad then

22:49 trptcolin: yeah, the question of whether Matcher actually destructures was my confusion

22:49 brehaut: cemerick: nah i think you were right

22:51 ,(let [match (re-matcher #".*test.*" "this is a test. testing. only a test.")] (destructure [['a 'b 'c] match]))

22:51 clojurebot: [vec__5270 #<Matcher java.util.regex.Matcher[pattern=.*test.* region=0,37 lastmatch=]> a (clojure.core/nth vec__5270 0 nil) b (clojure.core/nth vec__5270 1 nil) c (clojure.core/nth vec__5270 2 nil)]

22:53 TimMc: phenom_: type hinting like ^String foo works in 1.2 as well

22:55 trptcolin: ok, right, so if nth doesn't work on it, it's not gonna fly.

22:55 brehaut: trptcolin: if i bind that matcher to a name, call .matches and then call nth it works, but not if omit the .matches

22:56 cemerick: brehaut: that's because Matcher is a stateful thing

22:56 trptcolin: ok, so depends on lastmatch being set then

22:56 cemerick: which is why I was saying that the fact that it's destructurable is a misfeature

22:57 brehaut: cemerick: i now understand why you would say that

22:57 amalloy: haha

22:57 cemerick: e.g. you can't destructure it twice, etc

22:57 capture it with :as, and it's useless

22:57 (er, maybe you can reset it or something :-/)

22:57 amalloy: cemerick: the act of destructuring it causes it to call .find()

22:58 ?

22:58 cemerick: amalloy: no, .matches

22:58 amalloy: $google javadoc regex util matcher

22:58 sexpbot: First out of 2510 results is: Pattern (Java 2 Platform SE v1.4.2)

22:58 http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html

22:58 cemerick: Sequential destructurability is a consequence of something being nth-able, and Matchers are (perhaps rightfully) nth-able

22:59 amalloy: really, it calls matches, not find?

22:59 cemerick: no, *you* need to call .matches

22:59 nth works only on a matcher that's been init'ed properly (via find or matches)

22:59 ,(nth (re-matcher #".*" "foo") 0)

22:59 clojurebot: java.lang.IllegalStateException: No match found

23:00 amalloy: in that case i don't follow your statement about destructuring it making it become useful

23:00 useless

23:00 cemerick: ,(nth (doto (re-matcher #".*" "foo") .matches) 0)

23:00 clojurebot: "foo"

23:00 amalloy: the destructuring itself has no side effects, you just have to call .matches to make it work

23:00 phenom_: TimMc for some reason my hints aren't working

23:01 amalloy: phenom_: hints are not type-checkers

23:01 phenom_: it still's using reflection (which i see in the stack trace)

23:02 cemerick: amalloy: ah, sorry -- I was thinking of the scenario where one is using .find and destructuring

23:03 Then the same Matcher object (potentially) destructures into different values as it goes along the input.

23:04 amalloy: yes. of course if you're doing that sort of thing you should be using re-seq anyway

23:05 cemerick: anytime someone says "oh, you're just doing it wrong", there's something gone awry in the system

23:06 amalloy: if there were a system so well-designed as to make mistakes impossible, it wouldn't need us humans

23:06 cemerick: 'course, any j.u.List or j.u.Map is destructurable and potentially mutable too, so I guess I'll go sit quietly elsewhere ;-)

23:06 I've just been so spoiled with immutability that anything else just seems irretrievably broken.

23:07 amalloy: heh

23:07 it is hard to go back

Logging service provided by n01se.net