#clojure logs

2011-08-11

00:02amacEven dumping into a template throws a 'let requires a vector for its binding' error
00:04amacerr, my original question should have said dynamic vector.
00:06tufflaxwhat do you mean by dynamic vector?
00:08amacsomething 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
00:09amac(bleh [a 2]) -> (let [a 2] body), (bleh [b 3]) -> (let [b 3] body)
00:10TimMcSeems straightforward enough.
00:10amalloyamac: that's literally how the implementation you already gave actually works
00:12amacwhen I try to pass a vector into the let form it cries though, ex. (def a [b 3]) (let a body)
00:12amalloythat is 100% not what you said you wanted. macros just don't work that way
00:13amacyeah, I was having a hard time phrasing the question
00:14amalloyamac: 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
00:14amachmmm...
00:15tufflaxamac are you just playing or do you have a real problem? :p
00:15amacbit of both, mostly playing
00:15amac:)
00:16tufflaxok, well if you want you could describe the problem and we might be able to help with that
00:16amacthe problem is kind of evil
00:16tufflaxhehe
00:17tufflaxclojure is the bane of all that is evil
00:18amactell me about it, it certainly gets rid of bad habits quickly
00:19amacthe 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)
00:20amacwhich is wrong in a few ways...
00:21amacbut handy (at least, I think it will be) for this bigger thing I'm building
00:21amalloyso you have to make sure that stuff happens at compile time
00:21amalloysee http://hubpages.com/hub/Clojure-macro-writing-macros for one of my blog posts with stuff that might be related
00:22amacamalloy: whoa, that's going to take me some time to digest.
00:22amacbbiab
00:28tufflaxCouldn'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?
00:29tufflaxI'm not sure I understand what he wanted though
00:39amalloytufflax: in fairness, neither does he
00:39tufflaxhehe
00:42ibdknoxwarning to folks using CLJS
00:42ibdknoxwriting macros with let in them seems to not do what you would expect
00:46ibdknoxI'm looking to make my remote calls in Pinot prettier
00:46ibdknoxand I think the nicest way to do that is through a let syntax
00:46ibdknoxthoughts on if it should be letr letrem letremote?
00:53amalloyibdknox: i don't actually use any cljs, but i'm curious how let could break only from within macros
00:56ibdknoxamalloy: 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
00:56ibdknoxI'm not sure, what I know is that it worked fine in Clojure
00:57ibdknoxand didn't in CLJS
00:59amalloyhuh
00:59chouseribdknox: I'd be interested to see a simple test case that demonstrates that.
00:59ibdknoxchouser: once I get this working, I'll try and make it happen again :)
00:59chouserthere was a fix for closures in loops not too long ago. Dunno if it would be related.
01:00ibdknoxchouser: no loop here
01:00ibdknoxit was a version of me writing this: https://github.com/ibdknox/pinot/blob/master/src/pinot/macros.clj#L17
01:01chouserloop and let implementations are closely related in Clojure and ClojureScript
01:02ibdknoxah
01:02ibdknoxcould be then
01:11amalloyibdknox: uh, having func# not be a gensym is kinda bizarre, just fyi
01:12ibdknoxamalloy: can you explain?
01:12amalloy(let [func# ...] `(... ~func#))
01:13amalloyfunc# is just a regular symbol named "func#" in the scope of remote, not gensymmed at all
01:13ibdknoxah, whoops
01:14ibdknoxthat's from when I was doing it a bit differently
01:48ibdknoxchouser: ping?
02:26fhdMorning
02:26fhdSo what's the testing framework to use these days? clojure.test? Midje? Lazytest? Something else?
02:31thorwilthat may be the first time i hear of lazytest
02:32thorwili guess for both midje and lazytest, clojure.test was looked at and considered unsatisfying
02:36thorwilfrom http://www.lispnyc.org/blog/ericlavigne/a-tour-of-the-clojure-landscape: Midje encourages a separation between the actual tests and "checkers" that determine whether a test passed. Lazytest can be set up to watch your project's files, and rerun the tests automatically whenever your source code changes.
02:43Guest9666 just curious... are protocols in clojure somethign similar than in objective-c ?
02:49fhdthorwil: 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
02:49fhdthorwil: I personally like clojure.test, does the trick for me. Some stubbing would be nice, but I can do that with bindings.
04:18thorwilhow do i make the repl forget things that were defined by compling previous versions of the files i'm working on?
04:32fliebelWhat would be the best way to keep track of libraries developed for ClojureScript?
04:36fliebelHm, maybe Github... https://github.com/search?type=Repositories&language=&q=clojurescript&repo=&langOverride=&x=23&y=19&start_value=1
07:29manutterAny Eclipse/CCW users on?
07:30depyworkI've tried it but that's it...
07:30manutterYeah, I'm just playing around with it myself, I was wondering how the day-to-day workflow goes
07:31manutterespecially how you go about adding dependencies like compojure
07:31depyworkI never got beyond simple clojure scripts... :/
07:32manutterI 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.
07:32clgvmanutter: I use CCW.
07:32manutterwhoa, a nibble!
07:32manutter:D
07:33manutterclgv: so how do you handle dependencies? Do you use lein, or the built-in Eclipse library functions?
07:33clgvyou add dependency by just adding the jar to the classpath in eclipse
07:33clgvI download them via leiningen
07:34manutterok, that makes sense
07:34manutterI'm guessing you omit clojure itself from project.clj, since Eclipse/ccw adds it in already
07:35clgvyou 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
07:35manutterYeah, I did get lein pom to work as an external command
07:35clgvmanutter: no I have it in project.clj and change eclipse classpath settings to the lib/ location
07:36manutterAh, ok
07:36clgvbut since I am on clojure 1.2.1 it's not supposed to change anyway ;)
07:36manutterheh :)
07:37manutterOk, that's the info I was looking for, tks much
07:44thorwili get differing results depending on whether i call this from the repl, or use it via an url handler: http://paste.pocoo.org/show/456528/
07:49manutterhmm, my first guess would be that you're getting an error calling (ds/save! (Article....
07:49manutterand the error message is getting lost
07:50manutterbut I'm only saying that because it's the only way I can see to interrupt the program execution before the second (ds/save!
07:50thorwilit's the second call ds/save! that doesn't work in the through-handler case
07:51thorwiland the (ds/save! (Article. ... does exactly what it should
07:51manutterYeah, so if there was some kind of post-success error in the first one, it would never execute the second one
07:51manutterIs there any other output from that function? Do you have any kind of logging installed?
07:52manutterI'd insert a debug logging statement before and after the 2nd (ds/save!) call to see which code snippet is failing to execute.
07:54thorwilno logging yet, ok
08:27thorwilcomes out i was calling a function with a similar name, instead 0.o
08:27gtrak`programming by probability?
08:38HodappTHORWIL!
08:38Hodappyou're still around?
08:39thorwil=8-D
08:39thorwilHodapp: why screaming?
08:39Hodappwhere'd I run into you first anyway? #lad or something?
08:40clgvgtrak`: or theological computer science, i.e.e just writing the code and then praying that it works ;)
08:40gtrak`clgv, oh, I haven't tried that yet
08:40fhdFunny that I never needed this before, but there is a way to redefine globals created with (def), right?
08:40opqdonutyes, just def again
08:40clgvfhd: alter-var-root
08:40fhdI thought it was (set!), but I get a IllegalStateException (can't change/establish root binding)
08:40thorwilfhd: def again?
08:40opqdonutor alter-var-root, yeah
08:41fhdthorwil: Worked in the REPL, not in my code
08:41clgvdef-ing again, seemed not to work in clojure 1.3 anymore, when I tried porting some code few weeks ago
08:41thorwilHodapp: if not #lad, it could have been #ardour perhaps. i don't think i saw you in ubuntu channels?
08:41HodappIt was probably #lad. I never hung out in #ardour.
08:42Hodapphaven't been there in awhile.
08:43fhdthorwil: Okay, I made a mistake, defing again works
08:54manutterfleibel: what don't you understand?
08:55fliebelmanutter: its dependency layer.
08:56fliebelmanutter: I'm trying to use it with CouchDB, so I can;t just compile everything into one big file.
08:58fliebelSo 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.
09:05fliebelSo I guess the question is... How can I compile an application with multiple entrypoints?
09:06fliebelAs in, different views on CouchDB, and code running in the browser.
09:08manutterYeah, I can see how that would be difficult, Closure is oriented towards producing one big (minified) JS file, for web optimization
09:09manutterYou should be able to write independent libs with a formal API though
09:12clgvIs 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?
09:19joegalloslamhound
09:19joegallohttps://github.com/technomancy/slamhound
09:21clgvjoegallo: thx
09:23devnmanutter: closure is not about minification. it's about advanced optimization, dead-code elimination
09:24devn*and* minification
09:39manutterdevn: yes, exactly
09:56clgvargs! clojure's (rand) uses Math/random which is synchronized and slowas down my threads... :(
09:56clgvok, one PRNG for each thread now...
09:58clgvindeed all I do is adding doubles and calculating random numbers... ;)
09:59mattmitchellhow can i get the character in a string at a particular position?
09:59mattmitchellfor example... (str-at-pos 0 "TEST") would yield "T"
09:59clgvlike this: ##(nth "TEST" 2)
09:59lazybot⇒ \S
10:00mattmitchellagh right!
10:00mattmitchellclgv: thanks
10:27fliebelHow 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:34nilsghello
10:35nilsgI have a problem with the executor framework and getting back values from clojure fns used as Callables
10:35nilsgi do: (def *pool* (Executors/newFixedThreadPool 2))
10:36nilsgand : (.get (.submit *pool* (cast Callable #(+ 2 3))))
10:36nilsgwhat I get back is nil, not 5 ... Any idea what I am doing wrong?
10:39manutternilsg: I think what you're getting back is the result of the .submit operation, not the result of the function you submitted
10:40manutter(caveat: I'm not familiar with the executor framework, so I may not know what I'm talking about)
10:40nickmbaileyall functions already implement the thread and callable interfaces so you don't need to cast it
10:40nickmbaileybut i don't think thats your problem
10:41manutterThe 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:41nilsgnickmbailey: I wanted to be sure it was not using Runnable interface instead
10:42nickmbaileyoh that could be it
10:43nilsgmanutter: yes I could do that, but this interop problem is bothering me, I'd like to understand :)
10:43nickmbaileythe cast function will implement both so i'm not sure if casting will help, if thats the problem
10:44nickmbaileyi.e. the cast will be done inside the runnable
10:44nilsghmm ok, I didn't know that
10:44nickmbaileyi'm just speculating though
10:44nilsgmaybe I can try to pass a proxy implemeenting only callable, just to be sure
10:46raeknilsg: hrm. weird.
10:46manutterTry (let [call-fn (cast Callable #(+ 1 2))] (.get (.submit *pool* call-fn)))
10:46raekthe cast shouldn't be necessary
10:47nilsgmanutter: still nil
10:47nickmbaileywhat version of clojure and java
10:47nickmbaileyjust tried and I get 5
10:47raeknilsg: try adding a type hint instead
10:47nilsgraek: actually, I get the same result with and without the cast
10:48raeknilsg: (let [^Callable f #(+ 1 2)] (.get (.submit *pool* f)))
10:48nilsgraek: I tried this too: (defn submit [^Callable f] (.submit *pool* f))
10:48nilsgthen (.get (submit #(+ 1 2)))
10:48nilsgbut no luck either, still nil
10:48raeksame result?
10:48raekok
10:49nilsgside-effects inside the fn are executed however
10:49manutternilsg: what JVM ?
10:49manutternickmbailey was saying it worked for him
10:49nilsgopenjdk I think... Let me check
10:49raek~source future-call
10:50nilsgWell, I've looked at it, that's how I thought about the type-hint :)
10:51nilsgjava version "1.6.0_22"
10:51nilsgOpenJDK Runtime Environment (IcedTea6 1.10.3) (ArchLinux-6.b22_1.10.3-1-x86_64)
10:51nilsgOpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
10:51raekthe implementation of future-call, which does exactly this thing, does not even type hint it
10:51raekoh, it does...
10:51raekbut it's the same as your submit function
10:52raeknilsg: does (deref (future-call #(+ 1 2))) return 5 on your machine?
10:53nilsgwell it returns 3, but yes...
10:53raeknilsg: try typehinting *pool*
10:53raekeh
10:53raek(where did I get the 5 from?)
10:54nickmbaileyhis initial question did (+ 2 3) somehow we moved to (+ 1 2) :)
10:54raek(def ^ExecutorService pool (Executors/newFixedThreadPool 2))
10:54wastrel2 plus 3 is 5
10:55raekthe source of future-call accesses a java field, so the compiler probably gets the type from there
10:55raeknilsg: (set! *warn-on-reflection* true) can be useful in these situations
10:56nilsgYes I have a reflection warning
10:57raekso 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:58raekand the reflective code just picks the first matching method it finds
10:59raeknilsg: does (def ^ExecutorService pool (Executors/newFixedThreadPool 2)) solve the problem?
11:00nilsgnope, actually I still get the reflection warning on both get and submit
11:00nilsghowerver, now the cast is necessary, without it I get an exception about being more than one matching submit
11:01nilsg(the one for runnable and callble i guess)
11:01nilsgalso I find the reflection message for get surprising: reference to field get can't be resolved.
11:02nilsgperhaps I should hint FutureTask?
11:04raekprobably
11:04nilsgeven when doing this : (def f ^FutureTask (.submit pool (cast Callable #(+ 2 3))))
11:05raekbut isn't it a Future? (at least by the interfaces definition)
11:05nilsgI get the reflection warning for reference to field get can't be resolved
11:06nilsghmm, yes I think Future is the interface, you're right
11:07raek(defn submit [^ExecutorService exe ^Callable f] (.submit exe f))
11:07raek(.get (submit pool #(+ 1 2)))
11:07raeknilsg: this returns 3 for me
11:08nilsgyes, this works for me too, thanks!
11:08raekand with this I don't get reflection for .get: (defn ^Future submit [^ExecutorService exe ^Callable f] (.submit exe f))
11:09nilsgiep, same here for me :) thanks a lot!
11:09raeknilsg: I also wrote this, but it seems that you are already familiar with how these classes are used: http://blog.raek.se/2011/01/24/executors-in-clojure/
11:10nilsgYes, actually I found your post back in my bookmarks while working on the problem :)
11:11BronsaHi
11:11BronsaI am reading core.clj
11:11BronsaI cannot understand what this means
11:11Bronsa636 (defn ^:static ^clojure.lang.IChunk chunk-first ^clojure.lang.IChunk [^clojure.lang.IChunkedSeq s]
11:11Bronsa637 (.chunkedFirst s))
11:11nilsgraek: however you didn't seem to need the type-hints at the time to get it to work
11:12Bronsawhat is the meaning of the second hint?
11:12Bronsawhat does it applies to?
11:13raeknilsg: no, I realized I only used the .invokeAll method which only accepts Callables
11:13raekI should probably add this to the post
11:15nilsgraek: Yes, that would be great. Thanks for your help anyhow, not understanding this was driving me mad :)
11:22coopernurseI'm reading the appengine-magic readme, and I'm confused about some syntax on the last line that inits the webapp
11:22coopernurse(ae/def-appengine-app simple-example-app #'simple-example-app-handler)
11:22coopernursewhat does the #' signify to clojure?
11:22coopernursedoes that invoke the function?
11:26manuttercoopernurse: #' means "get the var itself, not the current value of the var"
11:27manutterso if the value of simple-example-app-handler changes after the def-appengine-app, it will use the updated value
11:27coopernursemanutter: ah, cool. ok, so in this case I'm trying to wrap the handler
11:28coopernurseusing: (compojure.handler/api simple-example-app-handler)
11:28coopernurseso that POST data is decoded
11:28coopernursebut it's not working, presumably because of the line above.. would I need to somehow nest that?
11:29coopernursesomething like: (ae/def-appengine-app simple-example-app (compojure.handler/api simple-example-app-handler))
11:29coopernurseI know that's incorrect, but I'm a little unclear on how to express it correctly
11:34manutterI 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:34manutteri.e. put it into a var first so that you can pass #'the-var to def-appengine-app
11:38coopernursemanutter: ah, thanks, I'll try that
11:44leo2007does clojure compile to java byte-code?
11:45jonabbeyyes
11:46leo2007can that directly run on the jvm such as the one from android without installing anything else?
11:47jonabbeyi expect so, though you'd need some clojure library classes installed
11:48jonabbeyhttp://clojure.org/compilation discusses .class file generation using clojure
11:48lnostdalhm, i think the jvm bytecode needs to be translated into dalvik type bytecode
11:48jonabbeyyeah, it would
11:48jonabbeybut the android dev tools take care of that for you
11:48jonabbeyhttp://www.deepbluelambda.org/programming/clojure/creating-android-applications-with-clojure
11:50mattmitchellanyone know of a way to capitalize a string, without lower casing the rest of the string like clojure.contrib.string/capitalize does?
11:51mattmitchellor... is there a super useful string lib out there besides contrib?
11:51arohnermattmitchell: look at the source of that capitalize
11:51arohnerit does
11:52arohner (str (.toUpperCase ^String (subs s 0 1))
11:52arohner (.toLowerCase ^String (subs s 1))))
11:52jonabbeyso (str (.toUpperCase ^String (subs s 0 1)) (subs s 1))
11:52jonabbey,((str (.toUpperCase ^String (subs s 0 1)) (subs s 1)) "helloMom")
11:52clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:0)>
11:53jonabbey,(#(str (.toUpperCase ^String (subs % 0 1)) (subs % 1)) "helloMom")
11:53clojurebot"HelloMom"
11:53mattmitchellcool thanks!
11:54lnostdalis 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:54arohnermattmitchell: clojure.repl/source is extremely useful
11:54mattmitchellarohner: what does that do?
11:54arohnermattmitchell: it prints the source of the fn, if it can be found on the classpath
11:55arohnermattmitchell: and I assume you already know about doc?
11:55jonabbeythat's handy
11:55mattmitchellarohner: yes, i probably need to use doc more :)
11:55mattmitchellarohner: didn't know about clojure.repl/source though, that's awesome
11:55arohneryes it is
11:56arohnersomebody should write the bytecode version of it. I think that's guaranteed to work, even when the source can't be found
11:58jonabbeyit likely wouldn't be very satisfactory. there is a significant loss of information going from clojure source code to the compiled output
11:58arohnermeh. JVM bytecode isn't that hard to read
11:59arohnerespecially java method calls
12:01hugodritz contains a disassembler that can display the bytecode for a function
12:02arohnerlnostdal: you can try binding/setting *print-length* and *print-level*
12:02arohnerlnostdal: http://blog.n01se.net/?p=85
12:06raeklnostdal: you can set *print-level*
12:25cemerickhiredman: so are you preferring infinispan over e.g. hazelcast then?
12:55jsnikerisWhat's the idiomatic way for handling configuration parameters in Clojure? The kind of data you'd store in .properties files in Java.
12:56technomancyjsnikeris: (read-string (slurp (io/resource "config.clj"))) is common
12:58jsnikeristechnomancy: alright, thanks
12:58lnostdalarohner / raek, thanks!
13:04dnolenhmm so I guess you could pattern match on Java types just by extending them to ILookUp and using a guard...
13:14hiredmancemerick: haven't really used either
13:24hiredmanb
13:51TimMccemerick: You're WRONG! (re: last week's comment on macros)
14:03cemerickTimMc: link? I can't remember what I wrote yesterday, nevermind last week… :-D
14:22amalloycemerick: i think that was TimMc continuing a conversation without warning
14:24Hodappthat was like a drive-by
14:24ibdknoxchouser: ping
14:24cemerickaaach, burned by my own hand!
14:25ibdknoxfor those of you with CA's, were you notified when it was received?
14:26technomancyibdknox: no
14:27dnolenibdknox: nah, your name will appear on this list http://clojure.org/contributing
14:27Scriptorhow long does it usually take?
14:27ibdknoxshould I just apply for clojure-dev then?
14:27amalloyibdknox: i think he goes over them about once a month?
14:27ibdknoxlast time I applied I got rejected
14:27dnolenibdknox: ?
14:28ibdknoxdnolen: "Hello ibdknox@gmail.com, Your subscription to Clojure Dev was not approved."
14:28technomancyit helps if you slip a few $20s in with the paperwork
14:28ibdknoxhaha
14:29ibdknoxI had assumed this was because they hadn't received my CA yet
14:29ibdknoxor someone really hates me already :D
14:29Scriptorprobably the CA thing
14:33ibdknoxdnolen: 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:34dnolenibdknox: yup. would save a lot of time.
14:36TimMccemerick: amalloy is correct. I guess the joke fell flat.
14:36gtrak``vectors aren't seqs?
14:36Chousukenope. but they are seqable
14:37cemerickTimMc: See, I went for a run after my question to hiredman, so I had totally forgotten my own comment. :-)
14:41TimMcoh no!
14:41TimMcI guess that teaches me about meta-humor revolving around lack of context.
14:42TimMcs/meta-humor/using \1/
14:42Guest95270<TimMc> I guess that teaches me about using 1 revolving around lack of context.
14:42TimMcum...
14:42gtrak``,(inc 1)
14:42clojurebot2
14:42TimMcGuest95270: Is that you in there?
14:42gtrak``&(inc 1)
14:42Guest95270⇒ 2
14:42gtrak``sexpbot?
14:42clojurebotsexpbot is not a clojurebot
14:46ibdknoxwow
14:46ibdknoxI just got denied again
14:47ibdknoxIs there some thing I'm missing about Clojure-Dev?
14:47cemerickYou need to be on the CA list to subscribe.
14:48ibdknoxah, so even more than just have it sent in
14:48ibdknoxthat sucks.
14:49technomancyyep.
14:50pjstadigremember there are classes of clojure users
14:50cemerickIf that's even part of what keeps the signal/noise ratio up near 1, seems like a small price to pay.
14:51gtrak``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:54ibdknoxjust use map and something like (if (second val) val (first val))
14:55gtrak``ah
14:57cemerickpjstadig: classes?
14:57cemericko.0
14:58pjstadigyeah?
14:58pjstadigshould i have said castes?
14:59cemerickperhaps nothing at all if those are the two options
15:00cemericktalking about classes or castes is pretty over-the-top when the subject is a *mailing list*
15:00pjstadigthere are CA signers and not-CA signers
15:00ibdknoxcemerick: my life's worth is attached to that list. Don't take this lightly ;)
15:01cemerickibdknox: Same here, and I don't. I just don't think it's worth some of the rhetoric that's tossed about.
15:02ibdknoxlol
15:02pjstadigwhat? should i have said "groups"?
15:03pjstadigi guess you're reacting to the connotation of the words i'm using, but the fact is the fact
15:04cemerickI presumed you were using those words precisely because of their connotation.
15:04TimMcclojurebot: Are you an Untouchable?
15:04clojurebotI don't understand.
15:04cemerickYeah, 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:05cemerickAnd maybe worse than that depending upon the details.
15:05gtrak``how do I make a map from a seq of vectors ([:key val] [:key2 val2])?
15:06cemerickgtrak: see zipmap
15:06hiredmanincorrect
15:06hiredman(into {} ...}
15:07gtrak``ah
15:07gtrak``zipmap is for things that look like zippers
15:07hiredmancemerick: I don't think pjstadig is refering to those that have signed the CA vs. those that haven't
15:08cemerickgtrak``: sorry, I read your Q too fast :-|
15:08gtrak``hiredman, that's very succinct thanks
15:10cemerickhiredman: Fair enough; I thought it was clear, but OK.
15:11cemerickWe're in year X of this topic though, so I'm sure there aren't a lot of new things to cover.
15:12gtrak``hiredman, is there a shortcut for duplicate keys?
15:12hiredmanshortcut for duplicate keys?
15:13gtrak``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:13gtrak``basically the opposite of what I was trying to do before
15:14hiredmanyou'll want to map over the vectors turning them into {:key [:value]} and then merge-with into
15:14arohnerfirst world clojure problems: my program is only pegging 2 of my 8 cpus
15:14hiredmanperhaps you should do some more io
15:15arohnerhiredman: actually, zipping my input would probably speed things up...
15:15arohnerI'm parsing a 4 GB xml file
15:15zippy314Hi 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:17hiredman(map f (keys m) (vals m))
15:17amalloyarohner: you can also do the vector conversion with reduce/update-in
15:17arohnerthat's probably slower though, if speed is important
15:18arohneramalloy: vector conversion?
15:18dnolen,(map (partial apply +) {1 2 3 4})
15:18clojurebot(3 7)
15:18gtrak``arohner, I think he was talking to me
15:18amalloyoh, sorry, gtrak
15:19amalloy&(reduce (fn [m [k v]] (update-in m [k] (fnil conj []) v)) {} [[:a 1] [:b 2] [:a 3]])
15:19Guest95270⇒ {:b [2], :a [1 3]}
15:23amalloyzippy314: 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:24gtrak``I think the simplest for my case will be using map and into
15:26zippy314amalloy: 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:27amalloyit's not like functions are expensive. declaring them is easy. but for has better nesting properties if the algorithm isn't trivially simple
15:28amalloyand it has nice built-in :let/:when options
15:30zippy314yah. That's nice
15:33gtrak``check it out: https://gist.github.com/1140545 they are equivalent
15:34jolyis 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:36amalloy(juxt filter remove)
15:38joegallomy god, it's full of functions
15:38pjstadighiredman: i was in fact just talking about the CA/non-CA split
15:38jolyhmm, not one pass, but maybe laziness will help me more than I'm currently thinking
15:39hiredmanpjstadig: pardon me
15:43arohner,(doc partition-by)
15:43clojurebot"([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:43arohnerhrm. not quite
15:45arohner,(doc group-by)
15:45clojurebot"([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:45arohner,(group-by even? (range 10))
15:45clojurebot{true [0 2 4 6 8], false [1 3 5 7 9]}
15:46jolyarohner: thanks, that's what I was looking for :)
16:15amac_amalloy: figured out my problem from last night, your blog post helped -- thanks!
16:22fliebel&(+ 1 1)
16:22Guest95270⇒ 2
16:22fliebel??? Does Lazybot/sexpbot have a new name again?
16:25amalloyfliebel: when Raynes graces us with his presence he'll make lazybot identify, i suspect
16:25amalloywell, whatever. i'll just restart him; i think that's what Raynes does anyway
16:26fliebelamalloy: Oh, right. I still need to catch Raynes in here somewhere anyway. I saw he wrote a memcached backend for Jiraph.
16:28amalloy&(+ 1 1)
16:28lazybot⇒ 2
16:28fliebel&(print "good morning")
16:28lazybot⇒ good morningnil
16:30amalloyfliebel: you wanted to use the memcache backend to interface with couchdb's memcache api or something?
16:30fliebelamalloy: You use Jiraph at that company of yours, right? Which backend do you use, just the cabinet?
16:30fliebelamalloy: Right :)
16:30fliebelamalloy: 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:31amalloyfliebel: 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:31Hodapphm, I should examine this NoSQL bandwagon
16:31Hodappif for no other reason than to piss off the greybeard DBAs
16:32fliebelamalloy: Do you think you can get any decent query speed with http and platters? The memcached api is in-memory.
16:33amalloydunno, man
16:33amalloyi can barely use jiraph, myself
16:36arohnercan you use type hints to make clojure pick the right method on a java class?
16:36arohnerI have to call a java class, that has two methods: "Object foo(Object o)" and String foo (String s)"
16:37arohnerI want to call the string version, and I pass it a string, yet I get "no matching method"
16:37fliebelamalloy: What was the name of your company again? (does ninjudd also work there?)
16:37amalloygeni. and yes, he's my boss
16:39fliebelamalloy: How comes you can barely use Jiraph? I imagine Geni as one massive graph application.
16:39amalloymeh. there's plenty of other stuff going on.
16:43dnolenarohner: type hints should work for that yes, but you need to type the Java class and the argument
16:43arohnerdnolen: thanks, but I was just wrong. I was getting no matching method because I thought it was static, and it wasn't
16:52fliebeldnolen: What was stm-couchdb about? Links to your github, but leads to starwars.
16:55dnolenfliebel: an experiment with seeing how fast you could insert documents into Couch
16:56dnolenfliebel: 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:57dnolenyou could insert a million docs in about 3 mins.
16:58dnolenprobably better now, they've made a lot of perf improvements it looks like. those tests were from a year ago.
17:03fliebeldnolen: So, it only saves on HTTP overhead, right? Because CouchDB already has a 'lazy' setting.
17:07dnolenfliebel: yes, tho the http overhead seemed pretty significant, 1 million docs is ~5550 docs inserted a second.
17:07dnolenfliebel: I tried different bulk insert sizes, 50 was optimal at the time.
17:08fliebeldnolen: Doesn't that depend on the size of the docs you are uploading?
17:09dnolenfliebel: of course.
17:09dnolenfliebel: pure microbenchmark, I was just playing around.
17:10fliebeldnolen: I would go for the 0MQ approach: send inserts at maximum speed, but queue when waiting for the server.
17:11dnolenfliebel: waiting?
17:12fliebeldnolen: You can push only so much data over the wire. Let mee see if I can find the 0mq thing.
17:13hiredmanthats just async io
17:13dnolenfliebel: my experiment seemed to suggest the limiting factor was disk write perf, not the network. but I didn't look into super closely.
17:14dnolenfliebel: Clojure would be done sending the data over the network in oh I dunno like 30 seconds
17:14fliebeldnolen: Then why would bulk inserts be beneficial? Just the append-only b-tree characteristics?
17:14dnolenthe 3 minutes was just Couch writing all the data to disk.
17:16dnolenfliebel: none of this was scientific, just two hours of playing around on a AWS Computer Cluster instance.
17:16dnolenCompute
17:17fliebeldnolen: yeayea, I know, I'm just curious what would be the most efficient way to insert loads of data.
17:18dnolenif anyone's in NYC next week, I'll be talking about match and predicate dispatch, http://www.meetup.com/Clojure-NYC/events/16166963/
17:19fliebeldnolen: I'm not even close. But I heard some people say it was a more important talk than ClojureScript.
17:21dnolenfliebel: ha! ClojureScript is much more important IMHO.
17:23fliebelIt'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:24fliebelI need sleep. Bye
18:11Raynes$mail fliebel The memcached backend isn't finished. I forgot why right now, but we abandoned it, at least temporarily.
18:11lazybotMessage saved.
18:12gfrlogmaking a memoized recursive function hurts my head
18:15gfrlogmaybe it's easier with letfn...
18:18amalloygfrlog: memoization isn't really for that anyway. for what purpose do you think you need this?
18:20gfrlogamalloy: let's say for a simple example that I'm defining pascal's triangle recursively
18:21gfrlogI thought this would be easy but my the repl keeps complaining about my arg counts...
18:22amalloyyou can do that with iterate, for example
18:22gfrlogoh 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:23gfrlogamalloy: how would I do such a thing with iterate?
18:23gfrloggiven that each call causes two recursions
18:24gfrlogomitting base cases, the function is essentially (fn f [n k] (+ (f (dec n) k) (f (dec n) (dec k))))
18:25amalloygfrlog: https://gist.github.com/gists/1140970/edit
18:27gfrlogso you create that lazy structure and then make a function that indexes into it?
18:27amalloyand 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:27amalloygfrlog: uh, do whatever you want with it. this generates the triangle
18:27gfrlogright
18:27amalloyyou don't say what you're doing
18:27gfrlogyeah
18:28gfrlogamalloy: thanks
18:28dnolenclojurebot: max people
18:28clojurebotmax people is 317
18:29gfrlogclojurebot: min people
18:29clojurebotprogramming clojure is http://www.pragprog.com/titles/shcloj/programming-clojure
18:30amalloyi don't think he actually counts people. someone just told him once that "max people is 317"
18:30technomancyclojurebot: forget max people
18:30clojurebotmax people is 317
18:30technomancyclojurebot: botsmack
18:30clojurebotclojurebot evades successfully!
18:30gfrlogclojurebot: min people is 5
18:30clojurebotc'est bon!
18:30st3fanwy does lein create directories with underscores? is that because windows can't handle hyphens?
18:30amalloyjava can't handle hypens
18:30technomancyst3fan: it's a problem with the JVM, not windows
18:30st3fanohh of course
18:31st3fantoo bad .. they are so ugly :-/
18:31amalloypoor java has a "lexer" because it can't handle real syntax trees
18:44amalloygfrlog: did a bit of double-checking, and my iterative/lazy solution blows the stack. concat/for is a tricky combination
18:48amalloystuck 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:56gfrlogamalloy: fortunately those details got replaced by the details of my actual function
18:56gfrlogwhich, in case you're interested, is computing the catalan triangle
18:57gfrloghttp://oeis.org/A033184
18:57amalloy$google catalan triangle
18:57lazybot[Catalan's Triangle -- from Wolfram MathWorld] http://mathworld.wolfram.com/CatalansTriangle.html
18:58gfrlogoh I should try that factorial equation
18:58gfrlogthe OEIS link had a closed form, but either I did it wrong or it's wrong
18:58amalloyyes, if you're only looking for a single row
18:58gfrlogI'm looking for a single entry
18:59gfrlogI assumed that C(.., ..) in OEIS referred to the choose function, but when I implemented it it started spitting out rationals
18:59amalloygfrlog: yeah, i don't know how you'd know whether you'd done it wrong, with that completely illegible formula
19:00amalloyit is Choose, though, as you can tell because the Maple definition includes binomial(...)
19:00gfrlogamalloy: the one I was going off of was: T(n,k) = C(2*n-k, n-k)*(k+1)/(n+1)
19:00gfrlogmaybe I did my choose wrong :/
19:01gfrlog(fn [n k] (/ (factorial n) (* (factorial (- n k)) (factorial k))))
19:01gfrlogthat matches what I have in my head...
19:01amalloygfrlog: they probably mean 2n - k, not 2*(n - k). the formatting makes it hard to parse
19:01gfrlogyeah that's how I interpreted it too
19:02amalloyyour choose looks right
19:02gfrlogmaybe math doesn't work as well today
19:03amalloygfrlog: fwiw though, you could write that as (/ (! n) (! (- n k)) (! k)) - the extra * step is unnecessary
19:05gfrlogI didn't know / was vararg
19:05gfrlognor was I clever enough to think of the obvious use of the ! symbol
19:05gfrlogyou've learnt me twice
19:15triyocan 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:16dakrone,(doc select-keys)
19:16clojurebot"([map keyseq]); Returns a map containing only those entries in map whose key is in keys"
19:16dakronetriyo: ^^
19:17triyoright, but not possible as a fn arg destructuring capability
19:17triyo?
19:17dakrone(defn foo [{:keys [:foo :bar :baz] :as argmap}] ...)
19:17dakronethe :as is optional, only if you need the entire map for something
19:18gfrlogthat wouldn't give him exactly what he was asking for though...
19:18triyogfrlog, yup you are right, not quite what I want
19:18dakroneno, it doesn't
19:19gfrlogtriyo: I don't know why you want it though :)
19:19triyoOk let me explain.
19:19gfrlogsure
19:21triyoI 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:21triyotake note of *some keys(
19:21triyo*
19:21gfrlogright
19:21gfrlogso far this is a use-case for select-keys
19:22triyoSo 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:23triyoso yes, select-keys seems most appropriate.
19:23triyoSo I was just saying that it maybe would be cool if you could destructure in to that directly at function arg level
19:24gfrlog:/
19:24gfrlogI guess it doesn't seem like it would save all that much
19:24gfrlogsyntactically
19:24triyoI guess you right, well regardless select-keys is cool
19:25gfrlogyessir
19:28amalloygfrlog: i just looked at my previous solution to pascal's triangle on 4clojure
19:28amalloyi defined !, but i did (/ foo (* bar baz)). shame on me
19:28gfrlog:)
19:29gfrlogI like how (/ foo) parallels (- foo)
19:30amalloyhm? in that it's 1-x or 1/x?
19:30gfrlog0-x, isn't it?
19:31amalloyright
19:31gfrlogit's different from + and * in that the one-arg case is special
19:31gfrlogbut they're consistend with respect to each other
19:31gfrlogand more useful than if they acted like + and *
20:24dnolenor patterns, https://github.com/swannodette/match/blob/d19de55df925cc846e4946a4453521b95c72b724/test/match/test/core.clj#L102
20:28dnolennow for :as and :when
20:38hiredmanooo
20:43technomancydnolen: 1.3 only, or is there backwards-compatibility?
20:44dnolentechnomancy: nothing in match requires 1.3.
20:44technomancycool
20:44technomancyhave you tried the lein-multi plugin?
20:44technomancylets you do "lein multi test" across arbitrary dependency sets
20:44dnolentechnomancy: nice! I'll check it out.
20:45technomancyI use it for swank (though the tests there leave a fair bit to be desired); pretty handy
21:31dnolenk, being able to pattern match Java objects is going to be kinda … awesome, https://gist.github.com/1141252
21:33drewryes! (except that constructor to j.u.Date doesn't do what you think it does)
21:33dnolendrewr: ?
21:33hiredmandnolen: beautiful
21:37semperosdnolen: nice!
21:38drewrdnolen: hm, I guess it did do what you thought it does
21:39drewr,(java.util.Date. 2010 10 1 12 30)
21:39clojurebot#<Date Tue Nov 01 12:30:00 PDT 3910>
21:39drewr,(.getYear (java.util.Date. 2010 10 1 12 30))
21:39clojurebot2010
21:39drewr,(java.util.Date.)
21:39clojurebot#<Date Thu Aug 11 18:42:04 PDT 2011>
21:39drewrthat 3910 threw me off
21:40drewrbut getYear() returns the right year
21:40drewr*shrug*
21:54scgilardidrewr: all the years above are 1900 off because date is kinda crazy and most of its member functions and constructors are deprecated.
21:55dnolenhuh, does Scala have or patterns as well?
21:56drewrscgilardi: I know about (most of) Date's funkiness, just surprised that the 1900 is added to the printed obj represenation
21:57scgilardithe 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:57scgilardigetYear for today should return 111
21:58drewrit doesn't, thus my surprise
21:59scgilardi,(.getYear (java.util.Date.))
21:59clojurebot111
22:02drewroh, I was confused by my rabbit trail above
22:02drewrgrumble