0:02 amac: Even dumping into a template throws a 'let requires a vector for its binding' error
0:04 err, my original question should have said dynamic vector.
0:06 tufflax: what do you mean by dynamic vector?
0:08 amac: something changable, so I want a let binding where the bound values (and their bound symbols) would be different dependant on what was passed into the macro
0:09 (bleh [a 2]) -> (let [a 2] body), (bleh [b 3]) -> (let [b 3] body)
0:10 TimMc: Seems straightforward enough.
0:10 amalloy: amac: that's literally how the implementation you already gave actually works
0:12 amac: when I try to pass a vector into the let form it cries though, ex. (def a [b 3]) (let a body)
0:12 amalloy: that is 100% not what you said you wanted. macros just don't work that way
0:13 amac: yeah, I was having a hard time phrasing the question
0:14 amalloy: amac: the macro runs at compile time. it sees 'a, not '[b 3]. there's a few things you can do about that, but they're all evil and wrong
0:14 amac: hmmm...
0:15 tufflax: amac are you just playing or do you have a real problem? :p
0:15 amac: bit of both, mostly playing
0:15 :)
0:16 tufflax: ok, well if you want you could describe the problem and we might be able to help with that
0:16 amac: the problem is kind of evil
0:16 tufflax: hehe
0:17 clojure is the bane of all that is evil
0:18 amac: tell me about it, it certainly gets rid of bad habits quickly
0:19 the problem is actually that I want to capture a bunch of symbols and tie them to some fns, but the symbols I'm trying to capture aren't constant (they're generated into a binding-like vector based on a bunch of other stuff)
0:20 which is wrong in a few ways...
0:21 but handy (at least, I think it will be) for this bigger thing I'm building
0:21 amalloy: so you have to make sure that stuff happens at compile time
0:21 see http://
0:22 amac: amalloy: whoa, that's going to take me some time to digest.
0:22 bbiab
0:28 tufflax: Couldn't a vector be built similar to what happens in when-let for example: (let [form (bindings 0) tst (bindings 1)]. Wouldn't that allow amac to do what he wants?
0:29 I'm not sure I understand what he wanted though
0:39 amalloy: tufflax: in fairness, neither does he
0:39 tufflax: hehe
0:42 ibdknox: warning to folks using CLJS
0:42 writing macros with let in them seems to not do what you would expect
0:46 I'm looking to make my remote calls in Pinot prettier
0:46 and I think the nicest way to do that is through a let syntax
0:46 thoughts on if it should be letr letrem letremote?
0:53 amalloy: ibdknox: i don't actually use any cljs, but i'm curious how let could break only from within macros
0:56 ibdknox: amalloy: I didn't look into it too deeply, but from what I can tell it was closing over a variable and trying to pass the closure into my form as opposed to passing the value itself
0:56 I'm not sure, what I know is that it worked fine in Clojure
0:57 and didn't in CLJS
0:59 amalloy: huh
0:59 chouser: ibdknox: I'd be interested to see a simple test case that demonstrates that.
0:59 ibdknox: chouser: once I get this working, I'll try and make it happen again :)
0:59 chouser: there was a fix for closures in loops not too long ago. Dunno if it would be related.
1:00 ibdknox: chouser: no loop here
1:00 it was a version of me writing this: https://
1:01 chouser: loop and let implementations are closely related in Clojure and ClojureScript
1:02 ibdknox: ah
1:02 could be then
1:11 amalloy: ibdknox: uh, having func# not be a gensym is kinda bizarre, just fyi
1:12 ibdknox: amalloy: can you explain?
1:12 amalloy: (let [func# ...] `(... ~func#))
1:13 func# is just a regular symbol named "func#" in the scope of remote, not gensymmed at all
1:13 ibdknox: ah, whoops
1:14 that's from when I was doing it a bit differently
1:14 * ibdknox goes to fix it
1:48 ibdknox: chouser: ping?
2:26 fhd: Morning
2:26 So what's the testing framework to use these days? clojure.test? Midje? Lazytest? Something else?
2:31 thorwil: that may be the first time i hear of lazytest
2:32 i guess for both midje and lazytest, clojure.test was looked at and considered unsatisfying
2:36 from http://
2:43 Guest9666: just curious... are protocols in clojure somethign similar than in objective-c ?
2:49 fhd: thorwil: Doesn't sound like I really need the features of either framework. Was just wondering if nobody was using clojure.test anymore, considering the number of alternatives
2:49 thorwil: I personally like clojure.test, does the trick for me. Some stubbing would be nice, but I can do that with bindings.
4:18 thorwil: how do i make the repl forget things that were defined by compling previous versions of the files i'm working on?
4:32 fliebel: What would be the best way to keep track of libraries developed for ClojureScript?
4:36 Hm, maybe Github... https://
7:29 manutter: Any Eclipse/CCW users on?
7:30 depywork: I've tried it but that's it...
7:30 manutter: Yeah, I'm just playing around with it myself, I was wondering how the day-to-day workflow goes
7:31 especially how you go about adding dependencies like compojure
7:31 depywork: I never got beyond simple clojure scripts... :/
7:32 manutter: I get the impression not many people actually use it--I've been asking this question at various times for the past 3 days and haven't found anyone yet who actually uses it on a day-to-day basis.
7:32 clgv: manutter: I use CCW.
7:32 manutter: whoa, a nibble!
7:32 :D
7:33 clgv: so how do you handle dependencies? Do you use lein, or the built-in Eclipse library functions?
7:33 clgv: you add dependency by just adding the jar to the classpath in eclipse
7:33 I download them via leiningen
7:34 manutter: ok, that makes sense
7:34 I'm guessing you omit clojure itself from project.clj, since Eclipse/ccw adds it in already
7:35 clgv: you could write a launcher for leiningen to be able to just click a button in eclipse but I didnt try that yet. since switching to console 3-4 times a day is ok
7:35 manutter: Yeah, I did get lein pom to work as an external command
7:35 clgv: manutter: no I have it in project.clj and change eclipse classpath settings to the lib/ location
7:36 manutter: Ah, ok
7:36 clgv: but since I am on clojure 1.2.1 it's not supposed to change anyway ;)
7:36 manutter: heh :)
7:37 Ok, that's the info I was looking for, tks much
7:44 thorwil: i get differing results depending on whether i call this from the repl, or use it via an url handler: http://
7:49 manutter: hmm, my first guess would be that you're getting an error calling (ds/save! (Article....
7:49 and the error message is getting lost
7:50 but I'm only saying that because it's the only way I can see to interrupt the program execution before the second (ds/save!
7:50 thorwil: it's the second call ds/save! that doesn't work in the through-handler case
7:51 and the (ds/save! (Article. ... does exactly what it should
7:51 manutter: Yeah, so if there was some kind of post-success error in the first one, it would never execute the second one
7:51 Is there any other output from that function? Do you have any kind of logging installed?
7:52 I'd insert a debug logging statement before and after the 2nd (ds/save!) call to see which code snippet is failing to execute.
7:54 thorwil: no logging yet, ok
8:27 comes out i was calling a function with a similar name, instead 0.o
8:27 * thorwil sometimes wonders how he got to any functioning code, at all
8:27 gtrak`: programming by probability?
8:38 Hodapp: THORWIL!
8:38 you're still around?
8:39 thorwil: =8-D
8:39 Hodapp: why screaming?
8:39 Hodapp: where'd I run into you first anyway? #lad or something?
8:40 clgv: gtrak`: or theological computer science, i.e.e just writing the code and then praying that it works ;)
8:40 gtrak`: clgv, oh, I haven't tried that yet
8:40 fhd: Funny that I never needed this before, but there is a way to redefine globals created with (def), right?
8:40 opqdonut: yes, just def again
8:40 clgv: fhd: alter-var-root
8:40 fhd: I thought it was (set!), but I get a IllegalStateException (can't change/establish root binding)
8:40 thorwil: fhd: def again?
8:40 opqdonut: or alter-var-root, yeah
8:41 fhd: thorwil: Worked in the REPL, not in my code
8:41 clgv: def-ing again, seemed not to work in clojure 1.3 anymore, when I tried porting some code few weeks ago
8:41 thorwil: Hodapp: if not #lad, it could have been #ardour perhaps. i don't think i saw you in ubuntu channels?
8:41 Hodapp: It was probably #lad. I never hung out in #ardour.
8:42 haven't been there in awhile.
8:43 fhd: thorwil: Okay, I made a mistake, defing again works
8:52 * fliebel does not understand closure compiler
8:54 manutter: fleibel: what don't you understand?
8:55 fliebel: manutter: its dependency layer.
8:56 manutter: I'm trying to use it with CouchDB, so I can;t just compile everything into one big file.
8:58 So either I need to emit one big JSON file directly, or spit out the right bits to the right place, to let couchapp push it to the database.
9:05 So I guess the question is... How can I compile an application with multiple entrypoints?
9:06 As in, different views on CouchDB, and code running in the browser.
9:08 manutter: Yeah, I can see how that would be difficult, Closure is oriented towards producing one big (minified) JS file, for web optimization
9:09 You should be able to write independent libs with a formal API though
9:12 clgv: Is there already a tool out there, that can analyse my clojure sources whether they contain superfluous :require, :use and :import statements in my ns-statements?
9:19 joegallo: slamhound
9:19 https://
9:21 clgv: joegallo: thx
9:23 devn: manutter: closure is not about minification. it's about advanced optimization, dead-code elimination
9:24 *and* minification
9:39 manutter: devn: yes, exactly
9:56 clgv: args! clojure's (rand) uses Math/random which is synchronized and slowas down my threads... :(
9:56 ok, one PRNG for each thread now...
9:58 indeed all I do is adding doubles and calculating random numbers... ;)
9:59 mattmitchell: how can i get the character in a string at a particular position?
9:59 for example... (str-at-pos 0 "TEST") would yield "T"
9:59 clgv: like this: ##(nth "TEST" 2)
9:59 lazybot: ⇒ \S
10:00 mattmitchell: agh right!
10:00 clgv: thanks
10:27 fliebel: How can I update a compiled Jar? I ran jar xf foo.jar bar.class, fumbled with bar.class and called jar uf foo.jar bar.class, but now I get a security exception.
10:34 nilsg: hello
10:35 I have a problem with the executor framework and getting back values from clojure fns used as Callables
10:35 i do: (def *pool* (Executors/newFixedThreadPool 2))
10:36 and : (.get (.submit *pool* (cast Callable #(+ 2 3))))
10:36 what I get back is nil, not 5 ... Any idea what I am doing wrong?
10:39 manutter: nilsg: I think what you're getting back is the result of the .submit operation, not the result of the function you submitted
10:40 (caveat: I'm not familiar with the executor framework, so I may not know what I'm talking about)
10:40 nickmbailey: all functions already implement the thread and callable interfaces so you don't need to cast it
10:40 but i don't think thats your problem
10:41 manutter: The way I get output back from threads is to define a global atom somewhere, and have the thread call (swap! *global-atom* my-fn)
10:41 nilsg: nickmbailey: I wanted to be sure it was not using Runnable interface instead
10:42 nickmbailey: oh that could be it
10:43 nilsg: manutter: yes I could do that, but this interop problem is bothering me, I'd like to understand :)
10:43 nickmbailey: the cast function will implement both so i'm not sure if casting will help, if thats the problem
10:44 i.e. the cast will be done inside the runnable
10:44 nilsg: hmm ok, I didn't know that
10:44 nickmbailey: i'm just speculating though
10:44 nilsg: maybe I can try to pass a proxy implemeenting only callable, just to be sure
10:46 raek: nilsg: hrm. weird.
10:46 manutter: Try (let [call-fn (cast Callable #(+ 1 2))] (.get (.submit *pool* call-fn)))
10:46 raek: the cast shouldn't be necessary
10:47 * manutter is reading up on Executor, submit, and Interface Future<V>
10:47 nilsg: manutter: still nil
10:47 nickmbailey: what version of clojure and java
10:47 just tried and I get 5
10:47 raek: nilsg: try adding a type hint instead
10:47 nilsg: raek: actually, I get the same result with and without the cast
10:48 raek: nilsg: (let [^Callable f #(+ 1 2)] (.get (.submit *pool* f)))
10:48 nilsg: raek: I tried this too: (defn submit [^Callable f] (.submit *pool* f))
10:48 then (.get (submit #(+ 1 2)))
10:48 but no luck either, still nil
10:48 raek: same result?
10:48 ok
10:49 nilsg: side-effects inside the fn are executed however
10:49 manutter: nilsg: what JVM ?
10:49 nickmbailey was saying it worked for him
10:49 nilsg: openjdk I think... Let me check
10:49 raek: ~source future-call
10:50 nilsg: Well, I've looked at it, that's how I thought about the type-hint :)
10:51 java version "1.6.0_22"
10:51 OpenJDK Runtime Environment (IcedTea6 1.10.3) (ArchLinux-6.b22_1.10.3-1-x86_64)
10:51 OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
10:51 raek: the implementation of future-call, which does exactly this thing, does not even type hint it
10:51 oh, it does...
10:51 but it's the same as your submit function
10:52 nilsg: does (deref (future-call #(+ 1 2))) return 5 on your machine?
10:53 nilsg: well it returns 3, but yes...
10:53 raek: nilsg: try typehinting *pool*
10:53 eh
10:53 (where did I get the 5 from?)
10:54 nickmbailey: his initial question did (+ 2 3) somehow we moved to (+ 1 2) :)
10:54 raek: (def ^ExecutorService pool (Executors/newFixedThreadPool 2))
10:54 wastrel: 2 plus 3 is 5
10:55 raek: the source of future-call accesses a java field, so the compiler probably gets the type from there
10:55 nilsg: (set! *warn-on-reflection* true) can be useful in these situations
10:56 nilsg: Yes I have a reflection warning
10:57 raek: so my theory is that while you hinted the function, you did not hint the executor sevice. because of this, the compiler could not figure out the type and generated reflective code instead (which does not use any of the typehints, apparently)
10:58 and the reflective code just picks the first matching method it finds
10:59 nilsg: does (def ^ExecutorService pool (Executors/newFixedThreadPool 2)) solve the problem?
11:00 nilsg: nope, actually I still get the reflection warning on both get and submit
11:00 howerver, now the cast is necessary, without it I get an exception about being more than one matching submit
11:01 (the one for runnable and callble i guess)
11:01 also I find the reflection message for get surprising: reference to field get can't be resolved.
11:02 perhaps I should hint FutureTask?
11:04 raek: probably
11:04 nilsg: even when doing this : (def f ^FutureTask (.submit pool (cast Callable #(+ 2 3))))
11:05 raek: but isn't it a Future? (at least by the interfaces definition)
11:05 nilsg: I get the reflection warning for reference to field get can't be resolved
11:06 hmm, yes I think Future is the interface, you're right
11:07 raek: (defn submit [^ExecutorService exe ^Callable f] (.submit exe f))
11:07 (.get (submit pool #(+ 1 2)))
11:07 nilsg: this returns 3 for me
11:08 nilsg: yes, this works for me too, thanks!
11:08 raek: and with this I don't get reflection for .get: (defn ^Future submit [^ExecutorService exe ^Callable f] (.submit exe f))
11:09 nilsg: iep, same here for me :) thanks a lot!
11:09 raek: nilsg: I also wrote this, but it seems that you are already familiar with how these classes are used: http://
11:10 nilsg: Yes, actually I found your post back in my bookmarks while working on the problem :)
11:11 Bronsa: Hi
11:11 I am reading core.clj
11:11 I cannot understand what this means
11:11 636 (defn ^:static ^clojure.lang.IChunk chunk-first ^clojure.lang.IChunk [^clojure.lang.IChunkedSeq s]
11:11 637 (.chunkedFirst s))
11:11 nilsg: raek: however you didn't seem to need the type-hints at the time to get it to work
11:12 Bronsa: what is the meaning of the second hint?
11:12 what does it applies to?
11:13 raek: nilsg: no, I realized I only used the .invokeAll method which only accepts Callables
11:13 I should probably add this to the post
11:15 nilsg: raek: Yes, that would be great. Thanks for your help anyhow, not understanding this was driving me mad :)
11:22 coopernurse: I'm reading the appengine-magic readme, and I'm confused about some syntax on the last line that inits the webapp
11:22 (ae/def-appengine-app simple-example-app #'simple-example-app-handler)
11:22 what does the #' signify to clojure?
11:22 does that invoke the function?
11:26 manutter: coopernurse: #' means "get the var itself, not the current value of the var"
11:27 so if the value of simple-example-app-handler changes after the def-appengine-app, it will use the updated value
11:27 coopernurse: manutter: ah, cool. ok, so in this case I'm trying to wrap the handler
11:28 using: (compojure.handler/api simple-example-app-handler)
11:28 so that POST data is decoded
11:28 but it's not working, presumably because of the line above.. would I need to somehow nest that?
11:29 something like: (ae/def-appengine-app simple-example-app (compojure.handler/api simple-example-app-handler))
11:29 I know that's incorrect, but I'm a little unclear on how to express it correctly
11:34 manutter: I think you want something more like (def wrapped-handler (compojure.handler/api simple-example-app-handler)) (ae/def-appengine-app simple-example-app #'wrapped-handler)
11:34 i.e. put it into a var first so that you can pass #'the-var to def-appengine-app
11:38 coopernurse: manutter: ah, thanks, I'll try that
11:44 leo2007: does clojure compile to java byte-code?
11:45 jonabbey: yes
11:46 leo2007: can that directly run on the jvm such as the one from android without installing anything else?
11:47 jonabbey: i expect so, though you'd need some clojure library classes installed
11:48 http://
11:48 lnostdal: hm, i think the jvm bytecode needs to be translated into dalvik type bytecode
11:48 jonabbey: yeah, it would
11:48 but the android dev tools take care of that for you
11:48 http://
11:50 mattmitchell: anyone know of a way to capitalize a string, without lower casing the rest of the string like clojure.contrib.string/capitalize does?
11:51 or... is there a super useful string lib out there besides contrib?
11:51 arohner: mattmitchell: look at the source of that capitalize
11:51 it does
11:52 (str (.toUpperCase ^String (subs s 0 1))
11:52 (.toLowerCase ^String (subs s 1))))
11:52 jonabbey: so (str (.toUpperCase ^String (subs s 0 1)) (subs s 1))
11:52 ,((str (.toUpperCase ^String (subs s 0 1)) (subs s 1)) "helloMom")
11:52 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:0)>
11:53 jonabbey: ,(#(str (.toUpperCase ^String (subs % 0 1)) (subs % 1)) "helloMom")
11:53 clojurebot: "HelloMom"
11:53 mattmitchell: cool thanks!
11:54 lnostdal: is there some way of controlling how a structure, say a map, is printed -- or similar? .. i'm getting stack overflows constantly because i have nested structures that point to each other (circle)
11:54 arohner: mattmitchell: clojure.repl/source is extremely useful
11:54 mattmitchell: arohner: what does that do?
11:54 arohner: mattmitchell: it prints the source of the fn, if it can be found on the classpath
11:55 mattmitchell: and I assume you already know about doc?
11:55 jonabbey: that's handy
11:55 mattmitchell: arohner: yes, i probably need to use doc more :)
11:55 arohner: didn't know about clojure.repl/source though, that's awesome
11:55 arohner: yes it is
11:56 somebody should write the bytecode version of it. I think that's guaranteed to work, even when the source can't be found
11:58 jonabbey: it likely wouldn't be very satisfactory. there is a significant loss of information going from clojure source code to the compiled output
11:58 arohner: meh. JVM bytecode isn't that hard to read
11:59 especially java method calls
12:01 hugod: ritz contains a disassembler that can display the bytecode for a function
12:02 arohner: lnostdal: you can try binding/setting *print-length* and *print-level*
12:02 lnostdal: http://
12:06 raek: lnostdal: you can set *print-level*
12:25 cemerick: hiredman: so are you preferring infinispan over e.g. hazelcast then?
12:25 * cemerick likes to continue conversations from hours and days prior with no warning :-P
12:55 jsnikeris: What's the idiomatic way for handling configuration parameters in Clojure? The kind of data you'd store in .properties files in Java.
12:56 technomancy: jsnikeris: (read-string (slurp (io/resource "config.clj"))) is common
12:58 jsnikeris: technomancy: alright, thanks
12:58 lnostdal: arohner / raek, thanks!
13:04 dnolen: hmm so I guess you could pattern match on Java types just by extending them to ILookUp and using a guard...
13:14 hiredman: cemerick: haven't really used either
13:24 b
13:51 TimMc: cemerick: You're WRONG! (re: last week's comment on macros)
14:03 cemerick: TimMc: link? I can't remember what I wrote yesterday, nevermind last week… :-D
14:22 amalloy: cemerick: i think that was TimMc continuing a conversation without warning
14:24 Hodapp: that was like a drive-by
14:24 ibdknox: chouser: ping
14:24 cemerick: aaach, burned by my own hand!
14:25 ibdknox: for those of you with CA's, were you notified when it was received?
14:26 technomancy: ibdknox: no
14:27 dnolen: ibdknox: nah, your name will appear on this list http://
14:27 Scriptor: how long does it usually take?
14:27 ibdknox: should I just apply for clojure-dev then?
14:27 amalloy: ibdknox: i think he goes over them about once a month?
14:27 ibdknox: last time I applied I got rejected
14:27 dnolen: ibdknox: ?
14:28 ibdknox: dnolen: "Hello ibdknox@gmail.com, Your subscription to Clojure Dev was not approved."
14:28 technomancy: it helps if you slip a few $20s in with the paperwork
14:28 ibdknox: haha
14:29 I had assumed this was because they hadn't received my CA yet
14:29 or someone really hates me already :D
14:29 Scriptor: probably the CA thing
14:33 ibdknox: dnolen: speaking of clojure-dev, I would definitely love a watch in cljs, as a stop-gap I wrote noir-cljs, but that only really helps if you're using it on the web and don't mind having noir running.
14:34 dnolen: ibdknox: yup. would save a lot of time.
14:36 TimMc: cemerick: amalloy is correct. I guess the joke fell flat.
14:36 gtrak``: vectors aren't seqs?
14:36 Chousuke: nope. but they are seqable
14:37 cemerick: TimMc: See, I went for a run after my question to hiredman, so I had totally forgotten my own comment. :-)
14:41 TimMc: oh no!
14:41 I guess that teaches me about meta-humor revolving around lack of context.
14:42 s/meta-humor/using \1/
14:42 Guest95270: <TimMc> I guess that teaches me about using 1 revolving around lack of context.
14:42 TimMc: um...
14:42 gtrak``: ,(inc 1)
14:42 clojurebot: 2
14:42 TimMc: Guest95270: Is that you in there?
14:42 gtrak``: &(inc 1)
14:42 Guest95270: ⇒ 2
14:42 gtrak``: sexpbot?
14:42 clojurebot: sexpbot is not a clojurebot
14:46 ibdknox: wow
14:46 I just got denied again
14:47 Is there some thing I'm missing about Clojure-Dev?
14:47 cemerick: You need to be on the CA list to subscribe.
14:48 ibdknox: ah, so even more than just have it sent in
14:48 that sucks.
14:49 technomancy: yep.
14:50 pjstadig: remember there are classes of clojure users
14:50 cemerick: If that's even part of what keeps the signal/noise ratio up near 1, seems like a small price to pay.
14:51 gtrak``: say I have a map of keys to vectors of vals, is there a simple way to convert that to a map of key to vals if there's only one val in the val vector? I did some loop recur nonsense but it seems dirty
14:54 ibdknox: just use map and something like (if (second val) val (first val))
14:55 gtrak``: ah
14:57 cemerick: pjstadig: classes?
14:57 o.0
14:58 pjstadig: yeah?
14:58 should i have said castes?
14:59 cemerick: perhaps nothing at all if those are the two options
15:00 talking about classes or castes is pretty over-the-top when the subject is a *mailing list*
15:00 pjstadig: there are CA signers and not-CA signers
15:00 ibdknox: cemerick: my life's worth is attached to that list. Don't take this lightly ;)
15:01 cemerick: ibdknox: Same here, and I don't. I just don't think it's worth some of the rhetoric that's tossed about.
15:02 ibdknox: lol
15:02 pjstadig: what? should i have said "groups"?
15:03 i guess you're reacting to the connotation of the words i'm using, but the fact is the fact
15:04 cemerick: I presumed you were using those words precisely because of their connotation.
15:04 TimMc: clojurebot: Are you an Untouchable?
15:04 clojurebot: I don't understand.
15:04 cemerick: Yeah, there's people that have opted into the rules that have been set, and those that haven't. Constantly hurling stones because of it is silly.
15:05 And maybe worse than that depending upon the details.
15:05 gtrak``: how do I make a map from a seq of vectors ([:key val] [:key2 val2])?
15:06 cemerick: gtrak: see zipmap
15:06 hiredman: incorrect
15:06 (into {} ...}
15:07 gtrak``: ah
15:07 zipmap is for things that look like zippers
15:07 hiredman: cemerick: I don't think pjstadig is refering to those that have signed the CA vs. those that haven't
15:08 cemerick: gtrak``: sorry, I read your Q too fast :-|
15:08 gtrak``: hiredman, that's very succinct thanks
15:10 cemerick: hiredman: Fair enough; I thought it was clear, but OK.
15:11 We're in year X of this topic though, so I'm sure there aren't a lot of new things to cover.
15:12 gtrak``: hiredman, is there a shortcut for duplicate keys?
15:12 hiredman: shortcut for duplicate keys?
15:13 gtrak``: say I have that seq of vectors, but some keys are duplicate (multiple values), I'd have to fold the vals into a vector
15:13 basically the opposite of what I was trying to do before
15:14 hiredman: you'll want to map over the vectors turning them into {:key [:value]} and then merge-with into
15:14 arohner: first world clojure problems: my program is only pegging 2 of my 8 cpus
15:14 hiredman: perhaps you should do some more io
15:15 arohner: hiredman: actually, zipping my input would probably speed things up...
15:15 I'm parsing a 4 GB xml file
15:15 zippy314: Hi folks. This works to call all the key-value pairs of a map onto some two parameter function and return a list of the results: (map (fn [[x y]] (some-two-param-function x y) ) some-hash-map) But I'm wondering if there's a more ideomatic way of doing it. Suggestions?
15:17 hiredman: (map f (keys m) (vals m))
15:17 amalloy: arohner: you can also do the vector conversion with reduce/update-in
15:17 arohner: that's probably slower though, if speed is important
15:18 amalloy: vector conversion?
15:18 dnolen: ,(map (partial apply +) {1 2 3 4})
15:18 clojurebot: (3 7)
15:18 gtrak``: arohner, I think he was talking to me
15:18 amalloy: oh, sorry, gtrak
15:19 &(reduce (fn [m [k v]] (update-in m [k] (fnil conj []) v)) {} [[:a 1] [:b 2] [:a 3]])
15:19 Guest95270: ⇒ {:b [2], :a [1 3]}
15:23 amalloy: zippy314: fwiw i prefer your first way. map a destructuring function over the map, rather than a two-arg function over its keys and vals. i do prefer using (for [[k v] m] ...) rather than (map (fn [[k v]] ...) m), though
15:24 gtrak``: I think the simplest for my case will be using map and into
15:26 zippy314: amalloy: yah, I just saw that (for [kv some-hash-map] (apply some-two-param-function kv)) will work too. You like just because you don't have to declare the fn?
15:27 amalloy: it's not like functions are expensive. declaring them is easy. but for has better nesting properties if the algorithm isn't trivially simple
15:28 and it has nice built-in :let/:when options
15:30 zippy314: yah. That's nice
15:33 gtrak``: check it out: https://
15:34 joly: is there a built in function for splitting a list into two based on a predicate? something like (f even? [1 2 3 4 5]) --> ([2 4] [1 3 5]) Hopefully in one pass if possible
15:36 amalloy: (juxt filter remove)
15:38 joegallo: my god, it's full of functions
15:38 pjstadig: hiredman: i was in fact just talking about the CA/non-CA split
15:38 joly: hmm, not one pass, but maybe laziness will help me more than I'm currently thinking
15:39 hiredman: pjstadig: pardon me
15:43 arohner: ,(doc partition-by)
15:43 clojurebot: "([f coll]); Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions."
15:43 arohner: hrm. not quite
15:45 ,(doc group-by)
15:45 clojurebot: "([f coll]); Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."
15:45 arohner: ,(group-by even? (range 10))
15:45 clojurebot: {true [0 2 4 6 8], false [1 3 5 7 9]}
15:46 joly: arohner: thanks, that's what I was looking for :)
16:15 amac_: amalloy: figured out my problem from last night, your blog post helped -- thanks!
16:22 fliebel: &(+ 1 1)
16:22 Guest95270: ⇒ 2
16:22 fliebel: ??? Does Lazybot/sexpbot have a new name again?
16:25 amalloy: fliebel: when Raynes graces us with his presence he'll make lazybot identify, i suspect
16:25 well, whatever. i'll just restart him; i think that's what Raynes does anyway
16:26 fliebel: amalloy: Oh, right. I still need to catch Raynes in here somewhere anyway. I saw he wrote a memcached backend for Jiraph.
16:28 amalloy: &(+ 1 1)
16:28 lazybot: ⇒ 2
16:28 fliebel: &(print "good morning")
16:28 lazybot: ⇒ good morningnil
16:30 amalloy: fliebel: you wanted to use the memcache backend to interface with couchdb's memcache api or something?
16:30 fliebel: amalloy: You use Jiraph at that company of yours, right? Which backend do you use, just the cabinet?
16:30 amalloy: Right :)
16:30 amalloy: I suspect I'll have to add a JSON backend to careal to make it work properly, but I think it's a nice idea.
16:31 amalloy: fliebel: i mentioned your desire to ninjudd yesterday, he thinks it's kinda bizarre to try to do that instead of just writing a couchdb layer
16:31 Hodapp: hm, I should examine this NoSQL bandwagon
16:31 if for no other reason than to piss off the greybeard DBAs
16:32 fliebel: amalloy: Do you think you can get any decent query speed with http and platters? The memcached api is in-memory.
16:33 amalloy: dunno, man
16:33 i can barely use jiraph, myself
16:35 * fliebel is confused.
16:36 arohner: can you use type hints to make clojure pick the right method on a java class?
16:36 I have to call a java class, that has two methods: "Object foo(Object o)" and String foo (String s)"
16:37 I want to call the string version, and I pass it a string, yet I get "no matching method"
16:37 fliebel: amalloy: What was the name of your company again? (does ninjudd also work there?)
16:37 amalloy: geni. and yes, he's my boss
16:39 fliebel: amalloy: How comes you can barely use Jiraph? I imagine Geni as one massive graph application.
16:39 amalloy: meh. there's plenty of other stuff going on.
16:43 dnolen: arohner: type hints should work for that yes, but you need to type the Java class and the argument
16:43 arohner: dnolen: thanks, but I was just wrong. I was getting no matching method because I thought it was static, and it wasn't
16:52 fliebel: dnolen: What was stm-couchdb about? Links to your github, but leads to starwars.
16:55 dnolen: fliebel: an experiment with seeing how fast you could insert documents into Couch
16:56 fliebel: Couch does better with bulk inserts, so I setup a simple ref that would wait till it received at least 50 docs before doing the insert.
16:57 you could insert a million docs in about 3 mins.
16:58 probably better now, they've made a lot of perf improvements it looks like. those tests were from a year ago.
17:03 fliebel: dnolen: So, it only saves on HTTP overhead, right? Because CouchDB already has a 'lazy' setting.
17:07 dnolen: fliebel: yes, tho the http overhead seemed pretty significant, 1 million docs is ~5550 docs inserted a second.
17:07 fliebel: I tried different bulk insert sizes, 50 was optimal at the time.
17:08 fliebel: dnolen: Doesn't that depend on the size of the docs you are uploading?
17:09 dnolen: fliebel: of course.
17:09 fliebel: pure microbenchmark, I was just playing around.
17:10 fliebel: dnolen: I would go for the 0MQ approach: send inserts at maximum speed, but queue when waiting for the server.
17:11 dnolen: fliebel: waiting?
17:12 fliebel: dnolen: You can push only so much data over the wire. Let mee see if I can find the 0mq thing.
17:13 hiredman: thats just async io
17:13 dnolen: fliebel: my experiment seemed to suggest the limiting factor was disk write perf, not the network. but I didn't look into super closely.
17:14 fliebel: Clojure would be done sending the data over the network in oh I dunno like 30 seconds
17:14 fliebel: dnolen: Then why would bulk inserts be beneficial? Just the append-only b-tree characteristics?
17:14 dnolen: the 3 minutes was just Couch writing all the data to disk.
17:16 fliebel: none of this was scientific, just two hours of playing around on a AWS Computer Cluster instance.
17:16 Compute
17:17 fliebel: dnolen: yeayea, I know, I'm just curious what would be the most efficient way to insert loads of data.
17:18 dnolen: if anyone's in NYC next week, I'll be talking about match and predicate dispatch, http://
17:19 fliebel: dnolen: I'm not even close. But I heard some people say it was a more important talk than ClojureScript.
17:21 dnolen: fliebel: ha! ClojureScript is much more important IMHO.
17:23 fliebel: It's comparing apples to peathers. But from what I understand, a predicate dispatch system that is okay with rhikey has a larger potential impact on the whole of Clojure.
17:24 I need sleep. Bye
18:11 Raynes: $mail fliebel The memcached backend isn't finished. I forgot why right now, but we abandoned it, at least temporarily.
18:11 lazybot: Message saved.
18:12 gfrlog: making a memoized recursive function hurts my head
18:15 maybe it's easier with letfn...
18:18 amalloy: gfrlog: memoization isn't really for that anyway. for what purpose do you think you need this?
18:20 gfrlog: amalloy: let's say for a simple example that I'm defining pascal's triangle recursively
18:21 I thought this would be easy but my the repl keeps complaining about my arg counts...
18:22 amalloy: you can do that with iterate, for example
18:22 gfrlog: oh I just realized why the arg count fails...I'm using (partial g g) where I would need (partial g (partial g (partial g (partial g....))))
18:23 amalloy: how would I do such a thing with iterate?
18:23 given that each call causes two recursions
18:24 omitting base cases, the function is essentially (fn f [n k] (+ (f (dec n) k) (f (dec n) (dec k))))
18:25 amalloy: gfrlog: https://
18:27 gfrlog: so you create that lazy structure and then make a function that indexes into it?
18:27 amalloy: and this is totally lazy, of course. computing the millionth row doesn't require you to hold any more than two rows in memory at once
18:27 gfrlog: uh, do whatever you want with it. this generates the triangle
18:27 gfrlog: right
18:27 amalloy: you don't say what you're doing
18:27 gfrlog: yeah
18:28 amalloy: thanks
18:28 dnolen: clojurebot: max people
18:28 clojurebot: max people is 317
18:29 gfrlog: clojurebot: min people
18:29 clojurebot: programming clojure is http://
18:30 amalloy: i don't think he actually counts people. someone just told him once that "max people is 317"
18:30 technomancy: clojurebot: forget max people
18:30 clojurebot: max people is 317
18:30 technomancy: clojurebot: botsmack
18:30 clojurebot: clojurebot evades successfully!
18:30 gfrlog: clojurebot: min people is 5
18:30 clojurebot: c'est bon!
18:30 st3fan: wy does lein create directories with underscores? is that because windows can't handle hyphens?
18:30 amalloy: java can't handle hypens
18:30 technomancy: st3fan: it's a problem with the JVM, not windows
18:30 st3fan: ohh of course
18:31 too bad .. they are so ugly :-/
18:31 amalloy: poor java has a "lexer" because it can't handle real syntax trees
18:44 gfrlog: did a bit of double-checking, and my iterative/lazy solution blows the stack. concat/for is a tricky combination
18:48 stuck a (map doall) in there and tried to compute the hundred thousandth row. no stack overflow, but it's been at about 130% cpu for several minutes now
18:56 gfrlog: amalloy: fortunately those details got replaced by the details of my actual function
18:56 which, in case you're interested, is computing the catalan triangle
18:57 amalloy: $google catalan triangle
18:57 lazybot: [Catalan's Triangle -- from Wolfram MathWorld] http://
18:58 gfrlog: oh I should try that factorial equation
18:58 the OEIS link had a closed form, but either I did it wrong or it's wrong
18:58 amalloy: yes, if you're only looking for a single row
18:58 gfrlog: I'm looking for a single entry
18:59 I assumed that C(.., ..) in OEIS referred to the choose function, but when I implemented it it started spitting out rationals
18:59 amalloy: gfrlog: yeah, i don't know how you'd know whether you'd done it wrong, with that completely illegible formula
19:00 it is Choose, though, as you can tell because the Maple definition includes binomial(...)
19:00 gfrlog: amalloy: the one I was going off of was: T(n,k) = C(2*n-k, n-k)*(k+1)/(n+1)
19:00 maybe I did my choose wrong :/
19:01 (fn [n k] (/ (factorial n) (* (factorial (- n k)) (factorial k))))
19:01 that matches what I have in my head...
19:01 amalloy: gfrlog: they probably mean 2n - k, not 2*(n - k). the formatting makes it hard to parse
19:01 gfrlog: yeah that's how I interpreted it too
19:02 amalloy: your choose looks right
19:02 gfrlog: maybe math doesn't work as well today
19:02 * gfrlog googles the schedule for math-maintenance
19:03 amalloy: gfrlog: fwiw though, you could write that as (/ (! n) (! (- n k)) (! k)) - the extra * step is unnecessary
19:05 gfrlog: I didn't know / was vararg
19:05 nor was I clever enough to think of the obvious use of the ! symbol
19:05 you've learnt me twice
19:15 triyo: can one dissoc all non-required keys from a map passed in a function as an argument; meaning that the map argument should only contain keys I want.
19:16 dakrone: ,(doc select-keys)
19:16 clojurebot: "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"
19:16 dakrone: triyo: ^^
19:17 triyo: right, but not possible as a fn arg destructuring capability
19:17 ?
19:17 dakrone: (defn foo [{:keys [:foo :bar :baz] :as argmap}] ...)
19:17 the :as is optional, only if you need the entire map for something
19:18 gfrlog: that wouldn't give him exactly what he was asking for though...
19:18 triyo: gfrlog, yup you are right, not quite what I want
19:18 dakrone: no, it doesn't
19:19 gfrlog: triyo: I don't know why you want it though :)
19:19 triyo: Ok let me explain.
19:19 gfrlog: sure
19:21 triyo: I have a function that receives a map; this map contains some keys that actually represent the values that are passed on to sql insert/update statement as a *record*
19:21 take note of *some keys(
19:21 *
19:21 gfrlog: right
19:21 so far this is a use-case for select-keys
19:22 triyo: So think of it as an html form with many fields. I don't want to send "submit" field, :submit key to the insert statement..
19:23 so yes, select-keys seems most appropriate.
19:23 So I was just saying that it maybe would be cool if you could destructure in to that directly at function arg level
19:24 gfrlog: :/
19:24 I guess it doesn't seem like it would save all that much
19:24 syntactically
19:24 triyo: I guess you right, well regardless select-keys is cool
19:25 gfrlog: yessir
19:28 amalloy: gfrlog: i just looked at my previous solution to pascal's triangle on 4clojure
19:28 i defined !, but i did (/ foo (* bar baz)). shame on me
19:28 gfrlog: :)
19:29 I like how (/ foo) parallels (- foo)
19:30 amalloy: hm? in that it's 1-x or 1/x?
19:30 gfrlog: 0-x, isn't it?
19:31 amalloy: right
19:31 gfrlog: it's different from + and * in that the one-arg case is special
19:31 but they're consistend with respect to each other
19:31 and more useful than if they acted like + and *
20:24 dnolen: or patterns, https://
20:28 now for :as and :when
20:38 hiredman: ooo
20:43 technomancy: dnolen: 1.3 only, or is there backwards-compatibility?
20:44 dnolen: technomancy: nothing in match requires 1.3.
20:44 technomancy: cool
20:44 have you tried the lein-multi plugin?
20:44 lets you do "lein multi test" across arbitrary dependency sets
20:44 dnolen: technomancy: nice! I'll check it out.
20:45 technomancy: I use it for swank (though the tests there leave a fair bit to be desired); pretty handy
21:31 dnolen: k, being able to pattern match Java objects is going to be kinda … awesome, https://
21:33 drewr: yes! (except that constructor to j.u.Date doesn't do what you think it does)
21:33 dnolen: drewr: ?
21:33 hiredman: dnolen: beautiful
21:37 semperos: dnolen: nice!
21:38 drewr: dnolen: hm, I guess it did do what you thought it does
21:39 ,(java.util.Date. 2010 10 1 12 30)
21:39 clojurebot: #<Date Tue Nov 01 12:30:00 PDT 3910>
21:39 drewr: ,(.getYear (java.util.Date. 2010 10 1 12 30))
21:39 clojurebot: 2010
21:39 drewr: ,(java.util.Date.)
21:39 clojurebot: #<Date Thu Aug 11 18:42:04 PDT 2011>
21:39 drewr: that 3910 threw me off
21:40 but getYear() returns the right year
21:40 *shrug*
21:54 scgilardi: drewr: all the years above are 1900 off because date is kinda crazy and most of its member functions and constructors are deprecated.
21:55 dnolen: huh, does Scala have or patterns as well?
21:56 drewr: scgilardi: I know about (most of) Date's funkiness, just surprised that the 1900 is added to the printed obj represenation
21:57 scgilardi: the year value is defined to be 1900 + whatever you passed in. that constructor call created a date object representing a date in the year 3910.
21:57 getYear for today should return 111
21:58 drewr: it doesn't, thus my surprise
21:59 scgilardi: ,(.getYear (java.util.Date.))
21:59 clojurebot: 111
22:02 drewr: oh, I was confused by my rabbit trail above
22:02 grumble