#clojure logs

2012-04-01

00:00TimMcy3di: Symbols that the compiler special-cases.
00:00TimMcThey're built into the compiler as literals.
00:02TimMcy3di: https://github.com/clojure/clojure/blob/1.3.x/src/jvm/clojure/lang/Compiler.java#L39
00:03TimMcNot everything that the compiler special cases is a special form; many of those are just for optimization or bootstrapping.
00:24y3diwait, whats the difference between binding and let?
00:32TimMcdynamic and lexical scope
00:32Frozenlockhttp://stackoverflow.com/questions/1523240/let-vs-binding-in-clojure
00:34FrozenlockIs there a function to compress files?
00:40FrozenlockThis might do : https://github.com/bonega/pacl
00:44muhoons_pablo: preroutes?
00:48ns_pablomuhoo: what do you mean?
00:48muhoons_pablo: http://www.webnoir.org/autodoc/1.0.0/noir.core-api.html#noir.core/pre-route
00:48ns_pabloafaik preroutes are used to aggregate behaviors for multiple routes, like checking for authentication
00:49ns_pablohow would I use preroutes in this way?
00:50ns_pabloI'm new with Noir, so forgive me if it's something obvious...
00:50muhooi dunno, exactly, it's just a guess.
00:50muhoohttp://www.webnoir.org/tutorials/routes
00:50muhooi'm new too
00:50muhoomaybe you could use resp/redirect
00:51muhooto redirect based on the "module" url
00:52muhoolike (pre-route "/foo" {} (resp/redirect "/soemwher/else")) ?
00:52FrozenlockI think it doesn't solve the basic issue, which if I'm right was to be able to simply specifiy a part of the url. "/test" instead of "/blog/test".
00:52ns_pablowell, that might work... I'll take a look at the source to see what exactly is preroute doing
00:52ns_pabloFrozenlock but it might be a start towards a homegrown solution
00:55ns_pablowhat I'm really looking for is something like this http://www.padrinorb.com/guides/mounting-applications
01:04ns_pabloThis would be actually pretty easy to accomplish with Moustache: http://pastie.org/3707127
04:10wei_aoeu
04:11wei_oops sorry
06:35espringeI've written a parser, which produces an in-memory sexpresion that can be eval'd or what not. But I want to transform it into a a string, that is valid clojure code. Is there a built-in function for that?
06:36espringee.g. when it turns the three letter string 'dog' into the five-lettter "dog" (adds quotes)
06:39morphlingespringe: pr
06:39espringemorphling: perfect, thanks
06:40bsteuberor pr-str
06:43laurusAre people still working on Incanter?
06:46bsteuberlaurus: given https://github.com/liebke/incanter/network - yes
06:49laurusbsteuber, interesting, thanks for that.
08:20jayunit100how does clojure "know" when its reached the end of a lazy-seq ?
08:20jayunit100(doc lazy-seq)
08:20clojurebot"([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?"
08:22jayunit100Im looking at the code for the partition function in https://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/string.clj..... and trying to figure out how it is that the (lazy-seq ... ) function ever returns.
08:26gfredericksjayunit100: without looking at it, the confusion probably comes from the fact that lazy-seq is a macro
08:26gfredericksmacros don't follow the normal rules of evaluation
08:26jayunit100oh duh
08:26jayunit100thanks that helps okay.
08:27jayunit100so... lazy-seq is probably taking my function and implementing the ISeq interfaces for me.
08:28gfrederickswhatever body you pass to lazy-seq has to return a seq
08:29gfrederickswhat lazy-seq does is prevent the body from being evaluated until necessary
08:30gfredericksregarding your earlier question about how clojure knows it has reached the end -- same as with a non-lazy seq. If the rest method returns nil (I believe) then that's the end
08:30gfredericksgive or take a few details
08:30gfredericksthe fact that it's lazy only changes when the sequence is computed, not how you interact with it
08:30gfredericksas a consumer of the seq
08:39jayunit100(macroexpand clojure.contrib.string/partition)
08:39jayunit100seems to return something not-useful
08:40raekjayunit100: macroexpand is a function so you have to give it the unevaluated code
08:40raek(macroexpand '(clojure.contrib.string/partition ...))
08:41raek,(macroexpand '(when x a b c))
08:41clojurebot(if x (do a b c))
08:42jayunit100hmmmmm
08:43raekalso, clojure.contrib.string is outdated
08:43raekif possible, use clojure.string instead
08:43jayunit100user=> (require 'clojure.contrib.string)
08:43jayunit100nil
08:43jayunit100user=> (macroexpand '(clojure.contrib.string/partition pattern largeString))
08:43jayunit100(clojure.contrib.string/partition pattern largeString)
08:43raekare you sure partition is not just a regular function?
08:44jayunit100it is . but i thought macroexpand would look for macros inside of it :)
08:44jayunit100I guess it doesnt work that way :(
08:44raekthe code in a function body is not inserted into the call site
08:44jayunit100but im surprised it didnt through an error.
08:44jayunit100throw i mean.
08:45jayunit100should macroexpand throw an error if a function is given as input
08:45raekmacroexpand takes an arbitrary expression and expands any macros in it
08:45raekin you case there were none, so the input was the same as the output
08:46raekthink of macroexpand as a pre-filtering step of the compiler
08:46raekjayunit100: anyway, you can copy the body of the partition source code and pass it to macroexpand
08:47raek,(macroexpand '(lazy-seq (when x (cons y z))))
08:47clojurebot(new clojure.lang.LazySeq (fn* [] (when x (cons y z))))
08:48raekhere you see a glimpse of how lazy seqs are implemented
08:57gfredericksjayunit100: one thing that may not be obvious is that because macros are effective at compile-time, a macro is only concerned with the _forms_ of the code that is given to the macro
08:58gfredericks(defmacro is-string? [x] (if (string? x) true false))
08:58gfredericks(is-string? "foo") will emit true
08:58gfredericks(let [s "foo"] (is-string? s)) will emit false
08:59gfredericksso when you wrote (macroexpand '(clojure.contrib.string/partition pattern
08:59gfredericks largeString))
09:00gfrederickseh nevermind I don't have anything else to say
09:02RickInGATheBusby: you around?
09:39Lajla&(:fart {:fart "lol"})
09:39lazybot⇒ "lol"
09:40Lajla&({:fart "lol"} :fart)
09:40lazybot⇒ "lol"
09:40Lajla&(:fart {:diarrhoea "lol"})
09:40lazybot⇒ nil
09:55gtrak``anyone ever write a physics engine? I'm getting some fun 'emergent' behavior :-), not sure where to go to learn about how to do this right: http://www.youtube.com/watch?v=415OTzYEXsk
09:57gfredericksgtrak``: what's going on in this video?
09:58gfredericksin particular with the all the balls falling to one side thing
09:58gtrak``ah, that's from user input, applying an acceleration
09:58AimHereHe forgot to switch the second law of thermodynamics on ;)
09:58gfredericksokay; that was my guess
09:58gtrak``the emergent parts are the collisions that should happen and don't and the funny orbiting and sticking
09:58tmcivergtrak``: yes, I'm curious too. It looks like the balls stick together sometimes.
09:59tmcivergtrak``: if you didn't intend for that behavior, it might be a bug with the collision detection.
09:59gfredericksmaybe he programmed in gravity :)
09:59gtrak``van der waals forces
10:00tmcivergtrak``: Really? Is it supposed to be a molecular simulator?
10:00gtrak``j/k about that, yea, collision detection's borken, fun thing about this kind of thing is it's impossible to test :-)
10:01gfredericksthat can't be true
10:01gfredericksis it deterministic?
10:01gtrak``well, *hard* to test
10:01gfredericksoh okay then :)
10:01tmciverYes, it should be testable.
10:02gtrak``yea, it's all functional except for a single atom swap! on top
10:02gfredericksrun the thing and expect that at each step the balls aren't closer than their radius
10:02gfrederickswatch the failures come piling in
10:03gfredericksoh I just imagined doing it multithreaded where each ball is a ref
10:03gtrak``oh gosh, haha, that would be awful
10:03gfredericksand you have a spatial index telling you which balls are nearby that you need to coordinate with
10:03gtrak``but actually the drawing thread is separate, the simulation runs at 500fps
10:04tmcivernice
10:04gtrak``no optimization really, I'm impressed with the jvm
10:06gtrak``gfredericks, yea, the spatial index is one way to avoid checking every object against every object, right now it's n^2
10:08y3diref and atoms are pretty similar
10:09gtrak``i imagine if you're doing all the calcs on one thread like me, an atom's much better
10:10gfredericksy3di: yeah using refs would allow you to do some updates in parallel
10:10gtrak``and there's an issue with throughput vs latency, it's always better to have predictable latency
10:11gtrak``in games i mean
10:12gtrak``i could use refs for scripted events, but not a tight simulation like this
10:12gfredericksI didn't mean it too seriously :)
10:12gfredericksalthough it'd be interesting to know what kind of scalability that would buy
10:13gtrak``hmm, i could probably pmap some things
10:13gtrak``if you're curious: https://github.com/gtrak/quilltest/blob/master/src/quilltest/balls.clj
10:15y3dihow come some functions like swap! have a bang at the end?
10:15y3diwhat does the ! represent?
10:15gtrak``! generally means mutable i think
10:15gfrederickssometimes mutation, sometimes hazardness...
10:15gfrederickssometimes it has to do with dosync specifically I think
10:15gfredericksin the case of swap!
10:16tmcivergtrak``: how is your collision checking n^2? I wrote a very simple 2D physics engine in Java some time ago but I believe my collision checking was something approximating n factorial: check one object against all others, if it wasn't colliding with anything, remove if from the list of objects to check. Then continue with the rest of them.
10:16tmcivers/remove if/remove it
10:16gfrederickstmciver: that sounds n^2 to me
10:16gfredericksyou're checking all pairs
10:17tmciverI'm terrible at this complexity stuff.
10:17gfrederickstmciver: it's addition vs multiplication
10:17gtrak``(filter (fn [[a b]] (p/colliding? (:rigid-body a) (:rigid-body b)))(for [x guys y guys [x y]))
10:17gfrederickstmciver: factorial is (apply * (range n)), whereas in this case it is (apply + (range n))
10:17gfrederickswhich is asymptotically equiv to n^2
10:18gtrak``i could fix that for to remove duplicate pairs if I keep a set
10:18gtrak``but it's still n^2
10:18tmcivergtrak``: you *may* be able to do better than that; aren't you chekcking objects against themselves and rechecking objects that can be known not to be colliding with anything?
10:19gfredericksI think that's what he means by removing duplicate pairs
10:19gtrak``yea, i can def do better, but like i said, it's totally fast enough right now for casual things :-), i want to make it right though
10:19gfrederickstmciver: if an algorithm has anything to do with factorials you don't have much hope for doing anything with more than 10 objects
10:21tmcivergfredericks: so the algo I described is something less than n^2. I don't know what kind of frame rate I was getting but my simulator seemed to move along with much more that 10 objects.
10:21gtrak``duplicate as in [:a :b] = [:b :a]
10:22gfrederickstmciver: less than n^2 steps in absolute terms, but in complexity terms it is still n^2
10:22tmcivergfredericks: makes sense.
10:22tmcivergtrak``: also duplicate as in checking :a against :a
10:22gtrak``n^2 -5 is still n^2, so is n^2 -5x
10:23gfredericksn^2-5n you mean? :)
10:23gtrak``tmciver, yea, I caught that one, just didn't paste it in
10:23gtrak``gfredericks, yes :-)
10:24gfredericksand most relevant to this case is that 0.5*n^2 is still n^2
10:34jayunit100what is a " body of expressions"
10:34y3diwhy would you use futures over a function that started a new java thread?
10:35y3dijayunit100: in context to defining macros?
10:35jayunit100yeah
10:36gfredericksy3di: futures are syntactically simpler, and take care of providing a box for the result of the computation to go in
10:36gfredericksthey might also be thread-pooled
10:37gfredericksand maybe even do the binding thing
10:38jayunit100im wondering... what it means to take a "body of expressions" as input. Is that synonymous to taking "n expressions"
10:38gfredericksyeah it means multiple experssions
10:38y3dijayunit100: i believe so
10:38gfredericksthe canonical example is do
10:38y3digfredericks: what's thread pooling?
10:39gfredericksy3di: runs the futures in a thread pool instead of creating a new thread for each one indiscriminately
10:39gfrederickswhich I assume means creating a million futures is more feasible than a million threads
10:39y3diso that means, oh ok, so futures will essentially wait for threeads to free up
10:39gtrak``y3di, i think in general you should separate computations (values) from the details of their execution, future is more abstract than a thread but gets the job done
10:40gfredericks&(->> (for [x (range 1000000)] (future x)) (map deref) (apply +))
10:40lazybotjava.lang.SecurityException: You tripped the alarm! future-call is bad!
10:41gtrak``if you look at haskell's 'everything's lazy', that's more obvious
10:41gtrak``they might take it too far, though
10:42gfredericksoh I guess that code snippet doesn't actually illustrate anything since it's lazy
10:42gfrederickswould have to doall before the map
10:43jayunit100hmmm it looks like (lazy-seq) cant have nils in the middle .... since that is the "end" of a the list.
10:44gfredericksjayunit100: nil values should be fine
10:44jayunit100then how will the lazy-seq "know" when the list is done ?
10:44jayunit100it would be infinitely long ?
10:44gfredericksit's when the entire rest of the sequence is null
10:44gfredericksnot just one of the entries
10:45jayunit100oh ok. so if "rest" is null
10:45jayunit100where rest is a list.
10:45gfredericksright
10:45gfredericks&(count (lazy-seq (cons 1 nil)))
10:45lazybot⇒ 1
10:46gfredericks&(count (lazy-seq nil))
10:46lazybot⇒ 0
10:46jayunit100is there a way to grep the history of my repl
10:46jayunit100like in bash?
10:46jayunit100,(history)
10:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: history in this context, compiling:(NO_SOURCE_PATH:0)>
10:53jayunit100that is, maybe someone knows where the repl stores history so i can hack it.
11:02jayunit100hmmm.. is there a way to reload the current lein namespace ?
11:02jayunit100i.e. reload the source without explicitly mentioning a file name.
11:03mega`youst lein not lein.core?
11:03mega`just*
11:03jayunit100you mean....
11:04jayunit100i ran "lein repl" from the root of a project.. and made some changes to multiple files.
11:04mega`i dont realy know the use case are you writing a plugin ?? why do you whant to reaload the source
11:04jayunit100can I reload the project in lein
11:04jayunit100no , much simpler than that.
11:04llasramjayunit100: (require 'your.namespace :reload) ?
11:04mega`oo the project
11:04jayunit100Im just editing more than one file in a clojure project
11:05jayunit100---- im used to clicking "clean" in eclipse. assuming there is an analog in lein ?
11:05jayunit100sorry about the confusion :)
11:07jayunit100(other than ctrl-c)
11:08jayunit100hmm this is interesting - looks like "time" doesnt evaluate an anonymous function that is passed in. I wonder why ?
11:09jayunit100,(time #(reduce + (range 1000)))
11:09clojurebot"Elapsed time: 0.429 msecs"
11:09clojurebot#<sandbox$eval27$ret__3993__auto____28 sandbox$eval27$ret__3993__auto____28@118b78d>
11:09mega`, (time (reduce + (range 10000)))
11:09clojurebot"Elapsed time: 69.498 msecs"
11:09clojurebot49995000
11:09mega`its a macro
11:11gtrak``,(time (#(reduce + (range 1000)))
11:11clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
11:11mega`missing a paren
11:11gtrak``,(time (#(reduce + (range 1000))))
11:11clojurebot"Elapsed time: 1.219 msecs"
11:11clojurebot499500
11:11gtrak``jayunit100, or for more clarity
11:12gtrak``,#(reduce + (range 1000)))
11:12clojurebot#<sandbox$eval139$fn__140 sandbox$eval139$fn__140@f2e01b>
11:13mega`, (macroexpand '(time (#(reduce + (range 1000)))))
11:13clojurebot(let* [start__3992__auto__ (. java.lang.System (clojure.core/nanoTime)) ret__3993__auto__ ((fn* [] (reduce + (range 1000))))] (clojure.core/prn (clojure.core/str "Elapsed time: " (clojure.core// (clojure.core/double (clojure.core/- (. java.lang.System (clojure.core/nanoTime)) start__3992__auto__)) 1000000.0) " msecs")) ret__3993__auto__)
11:14jayunit100okay....
11:14mega`clear as paj
11:15jayunit100Im trying to understand whats the difference when I wrap the anonymous functoin in a closure.
11:15jayunit100,#(reduce + [1 2])
11:15clojurebot#<sandbox$eval193$fn__194 sandbox$eval193$fn__194@5abaee>
11:15gtrak``huh?
11:15jayunit100,(#(reduce + [1 2]))
11:15clojurebot3
11:15jayunit100ha
11:15jayunit100 okay
11:15jayunit100wrapping it in clojure results in evaluation.
11:15gtrak``there it is, eureka!!!
11:15jayunit100:]
11:16gtrak``actually, the anonymous function is a closure, wrapping it in parens executes a function, just like anything else
11:16gtrak``,(1)
11:16clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
11:17jayunit100ok
11:24jayunit100(bump question about grepping through lein history).
11:32jayunit100i do see a .lein folder, but that seems not to have any history data in it.
11:53yoklovis there a better way to get the current value of 'this' in clojurescript than (js* "this")
11:54mega`theres a this-as macro
11:54yoklovis there?
11:55yoklovstill not really what I'm looking for.
11:55gtrak``huh, why wouldn't that be the same thing?
11:55yoklovoh wait
11:55mega`js/this maybe works
11:56yoklovi misunderstood what this-as did
11:56gtrak``http://www.chris-granger.com/2012/02/20/overtone-and-clojurescript/
11:56gtrak``there's an example
11:58mega`https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L205
11:58yoklovyup
11:58yoklovi was already on that page actually haha
11:58yoklovlooking for something like that.
11:59gtrak``gawd, extend-type is pretty intense
12:00mega`yea maybe extract some functions there
12:02yoklovthey'd have to be in the api if you did that though, right?
12:02yoklovbecause it's a macro and you couldn't defn- them
12:02mega`you can call functions from macros
12:02yoklovnot private ones though, right?
12:02yoklovin a separate namespace
12:03yoklovi actually am unsure how clojure deals with that, its an issue I always thought racket dealt with inelegantly
12:03mega`you can call them while generating the code
12:03yoklovright
12:03mega`you cant refere to them in the produced code but you cant do that in cljs anny way
12:04yoklovhm, i guess less of that is actual macro output than i thought at first glance
12:04mega`Oo o ok
12:04mega`yea its mostly code and branches
12:07jayunit100hungarian notation for clojure !
12:07jayunit100http://web.mst.edu/~cpp/common/hungarian.html
12:07mega`love it
12:07mega`start doing that
12:08TimMcnoooo, that's Systems Hungarian
12:08TimMchttps://en.wikipedia.org/wiki/Hungarian_notation#Systems_vs._Applications_Hungarian
12:09jayunit100ah good point
12:10mega`i had a robotics corse in scool where whe had to use a simelar notation
12:10jayunit100what about maps/arrays/lists
12:10mega`write o-* like in "object" :D
12:11jayunit100,(nth "ABC")
12:11clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$nth>
12:11jayunit100oops meant to put that in the repl
12:12yoklovcomma included? :p
12:12jayunit100yup
12:12jayunit100dont ask
12:12yoklovi mean, it is whitespace :)
12:12jayunit100ha
12:13jayunit100its funny b/c no joke then i did it in the repl to w/ the comma .
12:27jayunit100,(seq (.toCharArray "ASDF"))
12:27clojurebot(\A \S \D \F)
12:27jayunit100this seems awefully non-elegant
12:27mega`Oo
12:27mega`, (seq "ASDF")
12:27clojurebot(\A \S \D \F)
12:27mega`pew pew
12:28gtrak``what else would it be?
12:28gtrak``maybe it just looks ugly :-)
12:28jayunit100well.. figured ther'd be a function for it
12:29mega`, (apply str (seq "ASDF"))
12:29clojurebot"ASDF"
12:29jayunit100with all this "clojurscript", "clojure in python" stuff... Im thinking it might be best to avoid java artifacts when possible
12:29jayunit100,(seq "ASDF")
12:29clojurebot(\A \S \D \F)
12:29jayunit100ha
12:38mega`reddit has a time machine now :D :D :D :D
12:56jonasenlynaghk`: ping
13:02hhutchibdknox: are you around?
13:06jayunit100um need some newbie help on a find-first-repeated-character .
13:06jayunit100http://pastebin.com/iCTmxAX4
13:07jayunit100if anyone has 3 milliseconds to look. Error is : ClassCastException java.lang.Character cannot be cast to clojure.lang.IFn problems.core/eval816 (NO_SOURCE_FILE:196)
13:07mkjayunit100: you seem to be putting a character into a list and accidentally executing it
13:08mega`you are using underline in your names
13:08jayunit100no underlines ?
13:08mega`thats clearly the prob
13:08mega`ofc
13:08jayunit100wow
13:08mkjayunit100: the convention is to use - instead of _
13:09jayunit100(defn first-duplicate-char [str-in]
13:09jayunit100 (loop [list-Rem (seq str-in) set-Seen (set [])]
13:09jayunit100 (print (type list-Rem) " " list-Rem (next list-Rem) "\n")
13:09jayunit100 (if (= 0 (count str-in))
13:09jayunit100 nil
13:09jayunit100 (if (some #(= (first list-Rem) %) set-Seen)
13:09mega`also to create a set use #{}
13:09jayunit100 (first list-Rem)
13:09jayunit100 (recur
13:09jayunit100 (seq (next list-Rem))
13:09jayunit100 (conj set-Seen (first list-Rem)))))))
13:09dnolenjayunit100: please don't paste in channel
13:09jayunit100oh god that was ugly sorry wont do it again.
13:09mega`, (class #{})
13:10clojurebotclojure.lang.PersistentHashSet
13:10dnolen,(let [x_cool 1] (+ 1 x_cool))
13:10clojurebot2
13:10jayunit100I think underlines are okay.
13:10dnolenjayunit100: they are
13:11mkjust don't use them in your code if you want it to be easy to read
13:11dnolenjayunit100: as mk says, _ are not idiomatic in names
13:12jayunit100updated.... But still fails .... :(. Whats the best way to debug this ? http://pastebin.com/RCXHy7bb
13:12mk(first list_Rem) looks like it has 3 elements at a glance, while (first list-rem) has just 2
13:13TimMcmk: Huh, that hasn't been a problem for me.
13:13TimMc...but maye that's because I've been doing some Python programming
13:14lynaghkjonasen: pong
13:14jonasenlynaghk: I released 0.0.3
13:14mkTimMc: it's subtle. It's just a bit of extra noise that you don't need (like the capitals on Rem)
13:14lynaghkjonasen: yeah, I just saw that. Thanks!
13:15jayunit100yeah. the rem should be lower case.
13:15lynaghkI'll do one last run through with cljx and open source that later today
13:15jayunit100but of course... my concern is this weird cast thingy. it seems perfect to me. the recursion prints out the correct smaller list on every iteration.
13:16jayunit100update --- okay, its definetly failing when it completes. For some reason... the return value is being evaluated or something... rather than just printed out at the REPL.
13:17lynaghkjonasen: also, re: mailing list. I don't think it would hurt. There seem to be a lot of people watching Kibit, so it'd be interesting to see what everyone is doing with it. Github chats are skewed to people with, er, issues.
13:17mega`jayunit100: http://pastebin.com/3P9Qd8P7
13:17mega`jayunit100: just to show you some stuff
13:17dnolenjonasen: lynaghk: I know I've said this before, but kibit is awesome!
13:18jayunit100mega thanks
13:18jonasendnolen: thanks!
13:18jayunit100mega`: thanks i mean. :-]
13:18dnolenjonasen: lynaghk: I gave kibit 0.2 a run on Clojure itself and it ran suprisingly quickly.
13:18lynaghkdnolen: yes, it is crazy awesome!
13:18mkwhat does non-repetitive mean?
13:19mkwhich problem is this from?
13:19dnolenso kibit can easily handle 14000 lines of Clojure which is going to bigger than most Clojure / ClojureScript projects
13:19mega`jayunit100: the ` is dear to me
13:19lynaghkdnolen: your speed test might make this a moot point, but will the fork/join stuff work automagically once it's merged into core.logic?
13:20jayunit100ha
13:20jonasendnolen: I've done some optimizations on a private branch so I know how to make it run quicker if necessary :)
13:20dnolenlynaghk: probably, but I haven't looked into it quickly.
13:20dnolenjonasen: yeah as the rules get larger you probably want to do some indexing.
13:20dnolenI mean I haven't look into it deeply.
13:21dnolenjonasen: is it pretty easy to add your own rules right now?
13:21jonasendnolen: no. This release is mostly for Kevin ;) More to come!
13:22dnolenjonasen: yeah I imagine different shops would want to add rules for work practices.
13:22lynaghkdnolen: later today I'll be releasing a kibit-based lein plugin for rewriting sources. There is an option for custom rules in that
13:22lynaghkdnolen: depending on what you want to do with your custom rules.
13:23dnolenjonasen: one thing to think about is very complex rules really are possible - did the file ever get closed kind of thing. non thread safe Java types etc. You could probably even detect race conditions in ClojureScript.
13:24dnolenlynaghk: very cool!
13:27jayunit100ok migrated to stack overflow : I think the issue is that the return val is being evaluated. not sure why though. probably a good lesson in here, somewhere. http://stackoverflow.com/questions/9966483/clojure-return-value-being-evaluated ..
13:34TimMcjayunit100: (set []) is #{}, (seq (next ...)) is (next ...), #'some on a set should really be #'contains
13:34jayunit100TimMc ?
13:35TimMc&(contains? (set "hello") \o)
13:35lazybot⇒ true
13:35jayunit100oh i see, again not idiomatic.
13:35TimMcAnd I think you want rest, not next.
13:35jayunit100yeah, I was doing that just to validate the types and make them super explicit.
13:35jayunit100why rest not next?
13:36jayunit100,(= (rest [1 2]) (next [1 2]))
13:36clojurebottrue
13:36xeqi,(= (rest []) (next []))
13:36clojurebotfalse
13:36jayunit100touche.
13:37hhutchdnolen: have you used ibdknox's monet?
13:38dnolenhhutch: i have not
13:38jayunit100TimMc: same problem still exists, even after changing to "rest" .
13:38mfexjayunit100, the exceptions are probably thrown by functions using first-duplicate-char, rather than in the function itself
13:39hhutchdnolen: you've done a bit of canvas+clojurescript though, right?
13:39dnolenhhutch: actually not much
13:39dnolenhhutch: do you have a general question?
13:39hhutchdnolen: ok. i'm just concerned about the cpu usage
13:40dnolenhhutch: I would just program canvas directly w/ CLJS
13:41dnolenhhutch: monet I think monet may lean on some of the higher level CLJS features which is not so good of your doing lots of custom drawing and perf really matters.
13:41dnolenhhutch: ibdknox would know better than I tho I haven't looked at monet closely.
13:41hhutchdnolen: well, the issue with monet that i can see, which is just using canvas directly, is that it has a draw-loop which is redrawing the canvas constantly
13:41jayunit100mfex hmm. im calling it from the repl.
13:42jayunit100mfex:
13:42jayunit100OMG THANK YOU
13:42hhutchi have a cellular automata that is eating up 100% cpu when run in chrome
13:42jayunit100my problem was that I was wrapping the call in another closure somewhere.
13:42dnolenhhutch: just write your own thing :)
13:43hhutchdnolen: yeah i'm going to, i just wanted to see if anybody else had looked at the issue
13:43mfexjayunit100, the function can still use some work tho :)
13:43jayunit100Man.. It would be cool if clojure could embed some kind of safeguards for this. I always run into this problem.
13:43jayunit100Yeah, I was trying to hack it together as fast as possible without using the cheatsheet
13:43hhutchdnolen: thanks
13:43dnolenhhutch: fwiw, even pure JS I tend to avoid libraries for custom canvas drawing.
13:44jayunit100Im finding that i generally spend to much time w/ lein and docs when im learning new clojure stuff.. rather than focuing on writing stateless/dynamic lisp. the latter i think is more important as a first step .
13:44FrozenlockIs there a way to send a file to a Noir server by simply double clicking on an hyperlink shortcut? I want the user to be able to go the website and at the same time send pre-made data (small file). I'm thinking of using B64 encoded file in the url, but it feels like an ugly hack.
13:45TimMcjayunit100: I did a full answer on stackoverflow
13:46jayunit100Cool thanks. Im cleaning it up now.
13:49weavejesterHas anyone ran into problems with lein2 and trampoline?
13:49dnolenweavejester: yep
13:49dnolenweavejester: well I should qualify that - lein2 and lein-cljsbuild w/ trampoline doesn't seem to work.
13:49weavejesterdnolen: Are you getting an "Unreadable form" error?
13:50dnolenweavejester: hmm, no I wasn't getting a specific error - just wasn't working.
13:50weavejesterHm… I don't see any issues open like this. I guess I'll report it.
13:51TimMcjayunit100: Made some more edits. I think I'm done.
13:56TimMcjayunit100: Your problem was that (= 0 (count str-in)) never changes, so you eventually try to call first on nil.
13:56TimMcDon't know if you saw that -- I edited it in just now.
13:57AimHereIdiomatically, isn't (= 0 (count str-in)) better written as (zero? (count str-in)) or even better (empty? str-in) ?
13:57jayunit100TimMc: actually that wasnt causing the bug. it was the way i called it at the repl
13:58TimMc&(first nil) ; oh, you might be right...
13:58lazybot⇒ nil
13:58jayunit100AimHere: yeah. much more idiomatic to do it that way.
13:58andyfingerhutWould a github-related question be out of line here, if it is for a Clojure project on github?
13:58jayunit100TimMc: I suggest edit your answer to clarify that the function, inspite of its ugliness, works as is.
13:59jayunit100andyfingerhut: i think its okay to ask slightly off topic questions sparingly.
13:59TimMcAh, it does!
13:59dnolenandyfingerhut: all Clojure related things allowed ;)
13:59jayunit100TimMc: what does & do ?
14:00AimHereTells the bot to evaluate it
14:00AimHereIf you want a second opinion, use a comma instead
14:00AimHere,(first nil)
14:00andyfingerhutI forked someone else's project, committed some changes, made a pull request, they pulled them in, but they also had their own changes that aren't in my version. If I want to get up to the latest, should I delete my fork and create a new one based on their latest version, or is there a different way?
14:00clojurebotnil
14:00jayunit100sorry guys btw ....... im a hadoop developer so i never get to do any clojure and im constantly reusing variables and state... so i have a hard time getting back into clojureland.
14:02TimMcandyfingerhut: If you pull from upstream (their repo) into yours, you can get the changes.
14:02mega`andyfingerhut: your pull only needs to contain the changes you made.... are they in collition with there changes
14:02mega`?
14:03andyfingerhutTimMc: You mean in my local repo on my laptop, I do a "git pull" with some kind of additional args to indicate the pull should come from their github repo instead of my github repo?
14:04TimMcyep, don't remember the incantation off the top of my head
14:04andyfingerhutTimMc: Thanks, I'll look at some docs focused in that area. Probably need to figure out the correct remote branch name.
14:04TimMcgit remote add upstream git://... ; git fetch upstream ; git merge upstream/master
14:05mega`http://gitref.org/remotes/
14:05TimMcthose last two can probably be combined into git pull upstream master
14:05andyfingerhutThanks. Those are definitely going in my own personal git cheatsheet for future reference, since I won't be doing it very often.
14:06TimMcI had to go into my `history` list to find that.
14:07mega`no github related april fools?? seen
14:08TimMcThere's this, whatever it is: http://cloud.github.com/
14:09mega`pritty :P
14:10jayunit100how come the REPL can't evaluate a destructured list
14:10TimMc...but I don't know how old it is.
14:10jayunit100,[[head & tail] [1 2 3 4]]
14:10clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: head in this context, compiling:(NO_SOURCE_PATH:0)>
14:11mega`jayunit100: needs to be a let statment
14:11TimMcjayunit100: 1) Destructuring is a thing certain macros do, such as let
14:11TimMc2) evaluation is done on code, not data
14:12jayunit100i guess 1) explains why this fails :
14:12jayunit100,([[head & tail] [1 2 3 4]])
14:12clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: head in this context, compiling:(NO_SOURCE_PATH:0)>
14:12Bronsa.(let [[head & tail] [1 2 3 4]] [head tail])
14:12mega`, (let [[h & t] (range 1 5)] (inc h))
14:12clojurebot2
14:13xeqi,((fn [h & t] [h t]) [1 2 3 4])
14:13clojurebot[[1 2 3 4] nil]
14:13xeqiheh
14:13taapaHow does one decide on Hiccup or Enlive for web app? Each has its pros & cons.
14:13andyfingerhutYep, other macros are loop for doseq defn fn defmacro if-let when-let. There might be others, but those are most common places I've seen destructuring used.
14:14mega`https://www.google.com/intl/en/chrome/multitask.html
14:24TimMctaapa: Hiccup doesn't html-encode strings by default, which is kind of terrible.
14:24TimMctaapa: On the other hand, enlive is tricky to learn.
14:26taapaTimMc: thanks these are new to me. I like Enlive way of separating concern, cleaner. But just to know why people prefer Hiccup such as being the default in Noir.
14:26gfredericksTimMc: would there be an easy way to change hiccup so that it did?
14:26gfredericksI guess you could box up strings that you wanted kept raw
14:27yoklovtaapa: personal preference matters too.
14:28yoklovah, nm didn't see your 2nd message
14:28xeqitaapa: I think the desire to be simple wins there
14:28xeqiso that it is faster to get going
14:31hhutchtaapa: personally, I think enlive vs hiccup breaks down this way...
14:31taapaMy guess is Hiccup is an DSL, thus appealing if you want Clojure to be domain language of all your problems. But I wonder how do you code in Hiccup if you have a web designer that is not progammer.
14:31hhutchdev teams that consist entirely of clojure devs, or clojure devs are entirely responsible for the HTML markup, want to use hiccup
14:32hhutchif you are working with web designers who can produce html/css though, enlive is a dream
14:32taapahhutch: thanks
14:33hhutchtaapa: also enfocus now exists (the clojurescript version of enlive) ... which changes the landscape as well
14:33hhutchfrom what i've seen though, most ppl that use enlive also use hiccup
14:34taapaenfaces? will take a look.
14:34taapaenfocus I mean
14:34taapanot a bad idea to combine both I guess
14:35hhutchhttp://ckirkendall.github.com/enfocus-site/
14:35gf3ibdknox: yt?
14:36taapahhutch: thanks for the link.
14:36hhutchsure
14:40yoklovthere's also crate which is clojurescript hiccup :p
14:41taapahiccup vs enlive => enfocus vs crate :(
14:42hhutchtaapa: do you know jquery ?
14:42taapahhutch: no, mainly back end
14:43hhutchor, are you familiar with manipulating dom elements with css selectors?
14:44hhutchthat's all that enlive is. Also, if you ever have a need to do things like scrape html documents, enlive is very useful
14:46taapahhutch: guess i have to play with them a bit first. thanks for advice.
15:21kjellskiWhy is clooj showing only my input as output?
15:24Frozenlo`Is there a way to create a temporary file? One that is never written to disk?
15:25kjellskinvm… crashed after first start… now it works as expected...
15:25mega`Frozenlo: you on a unix system?
15:26Frozenlo`No..
15:26mkFrozenlo`: you can write to a bytebuffer of some sort
15:27mega`Frozenlo: so windows?
15:27FrozenlockYes, win7
15:27mkFrozenlock: otherwise, java allows you to create a temporary file in the system's default temp path (but this writes to disk)
15:28Frozenlockmk: bytebuffer seems good, assuming I can apply the same functions as for ordinary files.
15:28mega`Frozenlock: why a file are you going to pass it to some other program?
15:28mega`Frozenlock: nm
15:28FrozenlockI want to use https://github.com/bonega/pacl to zip some data, but it requires a file as input
15:29mkFrozenlock: you won't be able to treat it as a file, but you can use bufferedoutputstream etc. on it
15:30mkFrozenlock: "Just extracts all files from something that can be coerced into an inputstream"
15:31mkFrozenlock: you might want to check if the output does something similar
15:31FrozenlockI'll read about streams, brb :)
15:33mkFrozenlock: they wrap each other
15:45FrozenlockOk I'm lost. How does one send data to a stream?
15:45mkFrozenlock: what kind of data?
15:45FrozenlockA map in this case
15:46mkFrozenlock: depends. A stream is a stream - it's linear. How are you going to stuff a map into a stream?
15:46FrozenlockOr rather ultimately a string (once in a file)
15:46mkFrozenlock: any preference? if not, what are you plotting to do?
15:46FrozenlockWell like I said I want to zip it.
15:47rlbFrozenlock: if you just mean write it so you can read it back later, you can use (binding [*out* stream] (prn foo)).
15:47mkok, so you have some arbitrary string, and you want to turn it into an "inputstream" that the library you linked to can read
15:47FrozenlockExactly.
15:48FrozenlockUnless of course I'm doing extra steps for nothing and there's an easier way to achieve this goal...
15:48mkFrozenlock: http://stackoverflow.com/questions/782178/how-do-i-convert-a-string-to-an-inputstream-in-java#782183
15:50pedroteixeirahello folks! in clojurescript, any tips when getting "namespace already declared"?
15:51mkpedroteixeira: I know nothing of this, but perhaps try to change your namespace declarations to new ones
15:51pedroteixeiramk: ok, thanks
15:52mkpedroteixeira: there are a few different functions which might do something to the namespace, so check if you're defining it with one, and then with another
15:52rlbFrozenlock: with-in-str?
15:53rlb,(doc with-in-str)
15:53clojurebot"([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s."
15:53mkpedroteixeira: I'm not sure how cljs implements namespaces, but another issue might be that your namespace conflicts with something js already uses, like document.Math
15:53rlb,(with-in-str "drinkme" (read-line))
15:53clojurebot"drinkme"
15:54eirohello
15:54mkeiro: hey, welcome
15:54eirothanks
15:54rlbor
15:54rlb,(with-in-str "{:a 5}" (read))
15:55clojurebot{:a 5}
15:55Frozenlockmk: Unable to resolve classname: ByteArrayInputStream :(
15:55mkFrozenlock: it's in the package java.io - import the package, or qualify the name :)
15:57rlbFrozenlock: if you're just trying to *write* the map, then is prn not good enough?
15:57FrozenlockOh yes, it worked. Now the moment of truth ^^
15:57Frozenlockrlb: I really don't know... I will check what it does
15:57mkrlb: it needs to become an inputstream so that it can be passed to a library
15:58rlbmk: to a zip library?
15:58Frozenlockrlb: yes
15:58mkrlb: yep - I think it was linked above
15:59Frozenlockhttps://github.com/bonega/pacl
16:00rlbmk: right, I just misunderstood.
16:01FrozenlockGrrr... No method in multimethod 'compress' for dispatch value: class java.io.ByteArrayInputStream
16:01mkI think it might be possible to bind "string" to *in* and then pass *in* into the library?
16:01FrozenlockFrom the source: defmethod compress clojure.lang.IPersistentCollection
16:02mkFrozenlock: weird. Pass ["this is a dumb way to do it"] to the function
16:03FrozenlockThat's for me or the library? :p
16:03megais it ON?
16:03mkFrozenlock: for the library, and because we don't know how to use the library yet :)
16:03rlbif you don't mind everything being in RAM, you can prn to a string, then create a reader (*in*) from the string via with-in-str, but I don't know if that creates a reader that the zip lib will accept.
16:03mkin the end that might be a bad idea but it's worth testing
16:04mkI guess it's trying to serialize a collection?
16:04rlbOf course if you want to stream to the zlib lib, that'll take a bit more work.
16:05Frozenlock-> [Thrown class java.lang.NullPointerException]
16:06FrozenlockMeh, I might be better off trying to find something else to compress. Surely I'm not the first wanting to compress data?
16:06mkFrozenlock: hmm. Maybe there's a better way - do you just want to zip a string into a file? Do you need to get it out later?
16:07pedroteixeiramk: just to let others know, upgrading to clojurescript tag r1006 fixed it
16:07FrozenlockYes, but on another machine- so for now I really just need to compress it and dump it somewhere.
16:08mkpedroteixeira: thanks - glad you solved it
16:09mkwill it be easier to leave it uncompressed than it will be to solve the compression issue?
16:11FrozenlockSure, it would be easier.. but I don't want "easier", I want "fully working" :p
16:11FrozenlockAnd as a last resort I can print to file and then compress. However I don't like the idea of this extra file on the disk.
16:12mkFrozenlock: http://docs.oracle.com/javase/6/docs/api/java/util/zip/ZipOutputStream.html
16:13mkFrozenlock: you could also search for 'using zipoutputstream' or somesuch
16:18Frozenlockhttp://tripoverit.blogspot.ca/2008/04/java-create-zip-file-in-memory.html This looks promising
16:19FrozenlockAnd this too :D http://clojure-log.n01se.net/date/2011-05-23.html
16:19FrozenlockThank god for IRC logs.
16:21rlbFrozenlock: something like this:
16:21rlb?
16:21rlb(with-file [zip (java.util.zip.ZipOutputStream.
16:21rlb (clojure.java.io/output-stream "foo.zip"))]
16:21rlb (binding [*out* zip]
16:21rlb (prn some-map)))
16:21rlbs/with-file/with-open/
16:21mkmaybe some day someone searching will see the links you posted now. zip zipping compressing how to compress file string
16:23Frozenlockrlb: trying now!
16:24rlbOh, and I didn't test that at all (obviously) -- I just guessed...
16:25Frozenlock=> ZIP file must have at least one entry. The solution is near :)
16:25FrozenlockGive me some time, I want to try to figure this one out.
16:28rlbFrozenlock: certainly
16:34autodidaktoAnyone have any thoughts about the Expectations unit testing framework? (http://blog.jayfields.com/2011/11/clojure-expectations-introduction.html)
16:39Frozenlock(with-open [zip (java.util.zip.ZipOutputStream.
16:39Frozenlock (clojure.java.io/output-stream "foo.zip"))]
16:39Frozenlock (-> zip (.putNextEntry (java.util.zip.ZipEntry. "foo.txt")))
16:39Frozenlock (binding [*out* zip]
16:39Frozenlock (prn tt)))
16:39Frozenlock=> java.util.zip.ZipOutputStream cannot be cast to java.io.Writer
16:39FrozenlockWhat did I miss?
16:40rlbFrozenlock: oh, wait -- this is a *zipfile* class (i.e. zip/unzip) -- I was thinking about gzip...
16:40rlb?
16:40rlbs/this is/is this/
16:40mkFrozenlock: you have to construct a Writer, with zipoutputstream as a parameter
16:40rlbi.e. zip is file based, gzip is stream based.
16:40mkFrozenlock: PrintWriter, for example
16:41rlbOh, that -- right -- will (writer ...) handle it?
16:41rlbi.e. (java.io/writer (...))
16:41Frozenlockrlb: yes, it's a zip, not a gzip compression
16:41rlbas a wrapper
16:42rlbBut that will only work if the zipoutputstream is actually a normal output stream -- and I don't actaully know that (haven't looked).
16:42mkrlb: what do you mean by normal?
16:43rlbmk: just meant something that clojure.java.io/writer can handle.
16:43rlb,(doc clojure.java.io/writer)
16:43clojurebot"([x & opts]); Attempts to coerce its argument into an open java.io.Writer. Default implementations always return a java.io.BufferedWriter. Default implementations are provided for Writer, BufferedWriter, OutputStream, File, URI, URL, Socket, and String. If the argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to local...
16:44mkFrozenlock: create a PrintWriter(zipstream), and use its .append() or print or println methods to write your string
16:45rlbFrozenlock: do you really need a zip file (as opposed to a gzip file)?
16:45rlbIf not: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/zip/GZIPOutputStream.html
16:46rlbWhich I would assume behaves more like a normal stream.
16:46Frozenlockrlb: yes. However I will keep this for future references, thanks ^^
16:46mkrlb: writer might work, since it seems to wrap outputstreams
16:46RaynesFrozenlock: https://github.com/Raynes/fs/blob/master/src/fs/compression.clj#L10
16:46mkrlb: streams are just sequences of bytes (or characters, etc)
16:48rlbmk: I know -- I just meant that I hadn't checked to see if zipoutputstream was a normal stream (i.e. was actually subclassed from outputstream). It is.
16:48mkrlb: they can be fed into the disk, or into the network, or into a byte array. From that perspective, gzip and zip are identical
16:49rlbAnd the reason I had started to wonder was because zip is an archive format, rather than just a compresion format.
16:49mkrlb: it's usually very safe to assume that it is - I've never seen a class ending in OutputStream that didn't extend/implement the right things
16:49rlbBut they've obviously implemented the class as a normal outputstream.
16:49rlbmk: right, but since I wasn't sure, I wondered.
16:50mkrlb: sure, but you can implement outputstreams for archives that aren't compressed - streams are very flexible :)
16:50mkfor example, you can create various CryptoOutputStreams with parameters, and they'll encrypt according to your public key or what have you
16:51rlbI know -- I just wasn't *certain* about that class until I actually looked at that particular class's docs.
16:51mkyou can also attach HashOutputStreams (or Input) and feed data through them, and they'll tell you the MD5 or SHA1 of the bytes
16:52mkrlb: yep :) don't mind me, I'm just being overinformative
16:52FrozenlockRaynes: thanks, but I want to zip on-the-fly, without a prior file on the disk.
16:52RaynesFrozenlock: Oh, I thought you wanted to extract a zip file.
16:53RaynesFrozenlock: If you write something for that, please contribute it to fs.
16:53rlbmk: didn't know about the hash*streams.
16:53mkRaynes: String -> new zip file on disk
16:54FrozenlockRaynes: it's more like mk and rlb are writting it and I watch helplessly :P
17:00FrozenlockAlmost! The zip-file is there, an the foo.txt inside it. However the .txt is empty
17:00Frozenlock(with-open [zip (java.util.zip.ZipOutputStream.
17:00Frozenlock (clojure.java.io/output-stream "foo.zip"))]
17:00Frozenlock (-> zip (.putNextEntry (java.util.zip.ZipEntry. "foo.txt")))
17:00Frozenlock (.append (java.io.PrintWriter. zip true) "This is a string"))
17:00Frozenlock...
17:00FrozenlockI'll find a paste site
17:03Frozenlockhttps://gist.github.com/2278682
17:10mkFrozenlock: hmm, try using println instead of .append?
17:11radshas anyone tried using node.js with the latest version of lein-cljsbuid?
17:11FrozenlockI tried .write, .append, .print...
17:12FrozenlockOf course... it works with println!
17:12radsI'm getting an error with clojurescript r1006 with any node.js compilation I try
17:12Frozenlock:D
17:12FrozenlockBut why?
17:13mkFrozenlock: I don't actually know, unfortunately - random guess
17:13mega`rads: compiler error?
17:13rlbFrozenlock: you're probably not closing the stream -- i.e. println has a newline which is forcing the flush.
17:13radsmega`: yeah. I think it might have been fixed here: https://github.com/clojure/clojurescript/commit/7472ab9013ad5d2b3468daabe20ba3479546f287
17:14radsthe error I'm getting comes from dependency-order-visit
17:14rlbFrozenlock: you could probably also just flush the stream manually, but closing everything properly should handle it.
17:14mkwith-open doesn't auto-close?
17:14radsjava.lang.String cannot be cast to clojure.lang.Associative
17:14mkclosing a stream will flush it, and close (and flush) any sub-streams
17:15radsmega`: it happens even with a blank file with just an (ns) declaration
17:18mega`rads: 1.2.3?
17:18mega`rads: 0.1.5 ?
17:18radsyeah
17:18radsnode.js compilation breaks from 0.1.2 on
17:19radsthere was another clojurescript error in the version before r1006 too
17:20radsso I've been using 0.1.1 for now
17:20radswhen I use that version my code compiles and runs just fine
17:21mega`rads: ill test it out brb
17:25radsjust in case this didn't send since I got disconnected: mega`: awesome! thanks. I would test it out with r1006 myself, but I don't know much about adding my own development versions of dependencies with leiningen
17:25yoklovanyone want to checkout a neat clojurescript page i made? http://thomcc.github.com/hex/
17:26mkyoklov: pretty
17:27yoklovhaha, thanks
17:27dnolenyoklov: nice!
17:28dnolenyoklov: so you've done a CLJ and a CLJS app now :)
17:28yoklovhaha, yup
17:28yoklovi've done other clj stuff but nothing that interesting (and even more stuff that never got completed)
17:29dnolenyoklov: well I liked dunjeon!
17:29yoklovdnolen: dunjeon was a lot of fun to make
17:29mkit runs somewhat slowly if you do randomize
17:29yoklovyeah
17:29yoklovmk: the more cells on the board, the slower it runs :/
17:30yoklovi use `frequencies` and sets, which… take their toll.
17:31mkdo you precompute the next round? because if you do a timeout, and then compute, perhaps you should compute, and then timeout
17:31yoklovthe upshot of the way i do it now is it would be trivial to change to support an infinite grid if there were a faster hashmap implementation
17:31yoklovhm, i hadn't thought of reordering that
17:31dnolenyoklov: it's nice and I imagine it will only get faster w/ time.
17:32mkyoklov: what do the alive and dead mean?
17:33yoklovmk: they're the rules, if a cell has one of the yellow numbers in `alive` neighbors and is active, it will be alive in the next round, if it has one of the numbers in `dead` and is dead, it will come to life the next round
17:33yoklovif that makes any sense
17:34yoklovdnolen: yup, that was my thinking too;
17:35alexbaranoskywhen does Clojure wrap thrown exceptions in Runtime exceptions?
17:37yoklovmk: no dice, still crawls after doing randomize if i reorder those
17:37mkso alive applies to alive cells, and is a sort of "must be these to keep alive", and dead applies to dead, and means "this many to come alive"
17:37yoklovyup.
17:37yoklovactually i think it's faster in general if i do reorder them.
17:37mkyoklov: you shorten the timeout based on how long the computation took, yeah?
17:38yoklovno. i just do a timeout every 200ms
17:38mkyoklov: gotcha - initially I thought that alive meant what it took to come alive, and dead meant what it took to kill ;)
17:39yoklovyeah, i couldn't really think of any way to describe that in only a couple words
17:39mkyoklov: check system time before and after the calculation. So, start timer, display, calculate next round, stop timer, subtract now from start, subtract that from 200, timeout
17:39yoklovright no i'm familiar
17:40yoklovyou think it's really worth it though? it will still chug when it gets to the point that a computation takes more than 200ms
17:41mkyoklov: sure, why not? how long do the rounds take?
17:42yoklovafter random? i just timed one which took nearly a second :/
17:42amalloyalexbaranosky: only on 1.3 - that change is reverted in 1.4
17:43yoklov(according to chrome dev console timelines)
17:43mkthis hex pattern is rather pretty, and all of the combinations of alive/dead seem to produce very nice results - I'm trying nil/dead:1 now, and just starting with a dot
17:44alexbaranoskyamalloy, thanks
17:45yoklovmk: that one looks very cool.
17:47yoklovmk: the way i do it now hteres no chance of it skipping frames, if i did it the other way i think it would skip frames but keep a more consistent tick rate
17:47mkyoklov: you could also pretend that each cell is 3 units... and then have 8 states in each cell to check (or each cell 7, with 2^7 states)
17:48yoklovwell
17:48yoklovthe way i could get the biggest benefit is by just using a 2d array for the cells
17:48mk...that might actually be easier than it seems, since perhaps clojure could just calculate all those state values for you
17:49mkyoklov: nah, I think you're right to avoid the 2d array, they're boring :)
17:49yoklovthey are
17:50yoklovbut if i do it your way each cell would have 3 atoms in it?
17:50yoklovor hm
17:56mkdo we have the ability to stuff clojurescript into a <script> tag, and have it run?
18:02gfredericksmk: how would that work? send the cljs up to a compiler-service after it gets loaded in the browser?
18:03yoklovmk: no, the clojurescript compiler is written in clojure, and not clojurescript
18:04mkbut... clojurescript is clojure...
18:04gfrederickspeople should stop saying that
18:04mkso the compiler is written in clojurescript?
18:04yoklovno, it's written in clojure.
18:04yoklovif it were in clojurescript it could bootstrap itself.
18:04yoklovand you could use clojurescript in a script tag.
18:05gtrak``mk, you can't have macros without eval, clojurescript doesn't have either
18:05mkyoklov: yes, exactly - like with coffeescript :)
18:05mkhow much work would need to be done for a js compiler?
18:09yoklovwriting it in cljs is not really a goal for performance reasons (you'd need eval, i think, which can't happen if you do closure compiling)
18:10yoklovand writing in js? meh. no clue, sounds _extremely_ hard
18:11gfredericksit can't be impossible to do it in cljs
18:11gfrederickscompiling is just a function and cljs is turing complete...am I missing something?
18:11gfredericksis it just much messier?
18:12yoklovwell, just because something is turing complete doesn't mean it can do that.
18:12yoklovhtere are plenty of undecidable problems
18:12yoklovbut
18:12gtrak``it's not impossible? clojurescript was meant to be a step forward for clojure-in-clojure, you'd need a full clojure-in-clojure to do it
18:13yoklovi have no idea. i think the issue is that it would suck more to do.
18:13mkyoklov: the set of undecidable problems for any two given turing complete things are identical
18:13mkyes, it would suck more
18:13yoklovalso it would require rewriting the compiler into cljs
18:13mkis the compiler written in java?
18:14yoklovclojure!
18:14yoklovjvm clojure
18:14mkoh, well then that should convert right over to cljs...
18:15Frozenlockmk: I'm trying to put what I've learn earlier into a function taking optional argument (many files to zip), but I think I might have messed up with the recur. Would you mind to take a quick look? https://gist.github.com/2279100
18:15FrozenlockThe function works if I remove the (when.... (drop 2 remain)) part and use it for a single file to zip.
18:16amalloyi think you want [name cont remain], not [name cont & remain]
18:17yoklovmk: the languages aren't the same :/. they're very close, but certainly not identical. Also, if the cljs compiler were written in cljs, compilation would be slower than it already is
18:18FrozenlockWouldn't it be nil either way? (If I don't give other filename that is..)
18:19mkyoklov: yeah, I don't know too much about cljs. Compilation of a few lines shouldn't be too bad though
18:20yoklovwell you'd lose macros, is a proble
18:20Frozenlockamalloy: you were right... thanks :)
18:21mkyoklov: that might be alright, as a start
18:21yokloveh, i'd rather have macros than cljs-in-cljs
18:22yoklovthough maybe you could work around that, idk.
18:22yoklovreally i'd rather the compiler worked faster. even in its current state it's frustruating.
18:22FrozenlockNow I just need to find how to do the inverse... unzip on-the-fly without a file on disk.
18:22mkFrozenlock: I'd guess zipinputstream
18:23FrozenlockIndeed
18:26radsmega`: I tested my code with clojurescript r1006, and it seems to compile fine, so there must be something with lein-cljsbuild that breaks node.js compilation
18:30mega`rads: what did your test include?
18:39muhooi'm complietely baffled by this ppassage in hex: https://refheap.com/paste/1634
18:39Zokacemerick: CCW [0.7.0] beta looks great, no more printlns for me :)
18:39cemerickZoka: :-)
18:40cemerickIs that what you're planning on using from here on out?
18:40muhooit seems like it's calling a vector with something as an arg
18:41muhooah, vectors ara callbale, got it. nm
18:41muhoocallable even
18:41Zokacemerick: Yes, I could not use it before due to the nREPL conflict between ringMon and CCW
18:42cemerickah, right
18:42cemerickthat shouldn't change much at all from here on out
18:43cemerickthe easy stacking of HTTP on top has made me far more comfortable with the architecture, etc.
18:43yoklovmuhoo: yeah
18:43cemerick0.2.0 is still beta, so there's lots of little details to nail down, but it seems quite solid
18:43yoklovthat code… its a little bit hacky at poitns
18:44ZokaI did not have any problems so far
18:44yoklov(i'm happy people are looking at it though :)
18:45ZokaI am really glad that CCW is in good shape since Emacs is not my cup of tea :)
18:45muhooit's very cool. and it's only like 150 lines of cljs loks like
18:45cemerickInsofar as everyone using lein2 is using nREPL, it's gotten quite a beating from a testing perspective.
18:47ZokaMeanwhile, they should try lein2 webrepl, that works fine. :)
18:48muhoowebrepl? isnt' that himera?
18:48ZokaNo, Himera is for ClojureScript
18:49ZokaThis is similar, but for Clojure proper
18:49mkin ccw, I had trouble with it not using 1.3, and I didn't like that it opened a new repl view each time, rather than having one view with numerous repls hooked into debug and console...
18:50yoklovmuhoo: haha, yup, I usually try to be concise in my code.
18:50yoklovemacs 4 life!
18:51Zokamk: Now lets you use whatever is in your project.clj, but you have to do m2e import of pom.xml generated by 'lein pom'
18:51Zokamk: lein2 native support is comming shortly
18:52cemerickmk: numerous REPLs in one view? Is there another tool that works like that?
18:52mkZoka: sounds excellent
18:52mkcemerick: the console and debug views do this (not sure about other tools...)
18:53cemerickoh, in Eclipse you mean
18:53Zokacemirck: one man's feature is another man's bug
18:53cemerickYeah, I quite dislike how the Console view in Eclipse works.
18:54mkcemerick: yes. It would mean that I always had to move the view to the right place whenever a new one started
18:54muhooyoklov: it's very cool. though i had to do stuff like this in order to attempt to get my feeble brain around it: https://refheap.com/paste/1635
18:54mkcemerick: what's the problem with it? that you can't pull them apart?
18:54cemerickmk: they always start in the same region as where you put the last one
18:55cemerickI've always found the sub-view design very confusing
18:55mkcemerick: when I closed mine, it seemed to pick an arbitrary new position, perhaps beside console
18:55Zokacemerick: you can open more than one REPL tab in CCW to the same process?
18:55mkcemerick: why is that?
18:56cemerickZoka: sure, just connect to the same port
18:56cemerickI suppose a button in the REPLView to do that would be good
18:58Zokacemerick: that is feature I like, since you can run some slow thing in one tab, while dion normal stuff in another.
18:58Zokas /dion/doing/
18:59Zokacemerick: do you remember how to switch editor in structural mode in CCW?
19:00mkare haskell typeclasses essentially clojure protocols?
19:03yoklovhaskells typeclasses can also dispatch on returntype
19:03mkyoklov: dispatch? returntype?
19:03amalloymk: "use implementation X if the caller expects an Integer, and implementation Y if they expect a String"
19:04yokloverr, so they're polymorphic on the function's returntype, whereas protocols are only polymorphic on the function itself
19:04mkah, I see. Yes, that's right - thanks
19:05amalloy$heval read "5" :: Int
19:05lazybot⇒ 5
19:05yoklovso you can use `read` where something expects an integer, and it's the same as Integer/parseInt
19:05yoklovyeah.
19:05yoklovhad no clue lazybot was that talented.
19:06amalloythere's another haskell bot in here somewhere
19:06amalloy> 5
19:06amalloyexcept i can't remember how to trigger him
19:06gfredericksamalloy: have you tried a monad?
19:07amalloymaybe
19:08gfredericks~rimshot
19:08clojurebotBadum, *tish*
19:09mkI decided to learn about monads a couple of days ago, and ended up having to learn a bunch of haskell...
19:10mkI think I'm at the point where I'm close to understanding what a monad is
19:11yoklovit's been a while since i did anything with them, so i might be defining this too narrowly, but iirc its just a type which helps you thread a value through some computation
19:13mkyoklov: that's part of it, I think, but there's also the IO part, and other things
19:13yoklovIO is still computation.
19:13yoklovthough you could be right i don't recall. I remember reading about the list monad in haskell was what made them click for me.
19:13mkyoklov: what value do you thread through it?
19:14yoklovoh
19:14yoklovthe value representing the state of the world
19:14yoklovbrb
19:14mkyoklov: I've had several things click, but I don't think I get monads yet
19:16mkah, right. Yeah, and haskell is affecting or acting on the state. I've read a post that was suggesting that this was the wrong way to think of it, that IO basically left a bunch of unfinished computations that were waiting for main (or something like that)
19:26yoklovmaybe, but thats might be just because haskell has laziness to worry about
19:27yoklovin terms of thinking of monads in general i don't think that's a bad way to think about the specific case of IO
19:27yoklovi could be wrong though.
19:28mkthe world-state idea is still a bit confusing for me, since IO gains type String, for example
19:30yoklovyeah, you're probably better off asking #haskell.
19:30yokloverr, not with a period.
19:31jimduey_If you're interested in monads in clojure, may I humbly suggest http://clojure.net.
19:31yoklovor maybe someone else here can help
19:32gfredericksjimduey_: that's quite a domain name there
19:32jimduey_Yeah, I picked it up in the very early days of Clojure.
19:34mkyoklov: I tend to ask there when I get stuck. I did the whole "hey guys, what's a monad" thing a couple days ago, and it went from "it's just an interface" and "when you figure out what they are, you'll think 'is that all??' " to "you need to either learn haskell, or category theory in order to understand monads" over the course of a number of minutes
19:35jimduey_That middle comment could very well be from me. :)
19:36brehautIMO the best way to learn what a monad is is to spend time reading the code, performing reductions by hand, and writing implementations of your own
19:36mkjimduey_: thanks for the link - I'll read through the monads-in-clojure page
19:37jimduey_mk: feel free to shoot me any questions you might have.
19:37mkbrehaut: yeah, but that's also the slowest way, and requires you to be proficient in a monady language haskell
19:37brehautmk: it does not
19:38brehauti learn monads by writing implementations in javascript and python
19:38brehauts/learn/learnt/
19:38mkjimduey_: thanks
19:39mkbrehaut: any examples that were particularly enlightening? (I know js but not python)
19:39brehautmk: id start of trying to write an identity monad, and then a maybe
19:40mkbrehaut: I think I've done both, though I'm unsure if they meet the various criteria and functions associated with monads
19:44yoklovmk: if they say you need to understand cat. theory or haskell they're wrong
19:46brehautmk https://refheap.com/paste/1640
19:46brehautrough around the edges, but IdentityM and MaybeM in JS
19:46mkyoklov: I figured, but I don't know if the thing that will make people grok monads exists
19:47brehautthe thing to make you grok monads is to put in the work to grok monads
19:48mkbrehaut: definitely - but definitions of "work" vary, from "learn haskell or category theory" to "just think of it as an interface in java"
19:49brehautlearning category theory is about as far away from learning monads for function programming as you can get :P
19:50brehautand re haskell: any language with closures is a suitable enviroment for learning about monadic constructions
19:50brehauthaskells syntax just happens to make it much less painful to write large pieces of monadic code
19:52mkbrehaut: introduce corresponds to "return", I take it
19:52brehautyes
19:52mkI'm still hazy on the equivalence of bind with fmap and join
19:53brehautfor two reasons: a) return is a reserved word b) i think introduce is slightly clearer name for it when you are learning: it introduces a value into the monadic context
19:53justin1what's the easiest way to sort a map a custom order of its keys? ie I have a map {:a 1 :b 2 :c 3} and I want to get a sorted map ordered {:b :c :a}?
19:53brehaut(ie, theres less semantic overloading with what most programmers think return does)
19:55jimduey_justin1: Depends on what you want. If you want a sequence of the key value pairs from a map once, use a variant of 'sort'.
19:55jimduey_If you want an actual map that will always return the values in a sorted order, use a sorted map.
19:55jimduey_You can specify the comparator to sort with in both instances.
19:56mkjustin1: what jimduey_ said, and have a look at sorted-map-by. You might also find http://clojure.org/cheatsheet useful
19:56jimduey_brehaut: Nothing turns the light on for monads like actually working with them at the REPL.
19:56brehautjimduey_: absolutely
19:57justin1thanks guys, I'm just wondering if there's a quick way to build make a comparator to return a specific, arbitrary order based on the keys
19:57mkjimduey_: "A monadic function is a function that accepts a value and returns a monadic value" - can the value be itself a monadic value, and does a monadic function count as a monadic value?
19:57brehautjimduey_: although for state-m i found a simple example and then did all the reductions by hand on paper
19:57jimduey_And implementing a couple is a great exercise if you have the patience.
19:58mkjimduey_: by the value, I mean the value that is accepted
19:59jimduey_mk: The value passed in can be any value, even a monadic value. But in that case, it's treated like any other value. Nothing special happens just because it's a monadic value.
19:59jimduey_And a monadic function does not count as a monadic value.
20:00jimduey_Though in some monads, monadic values are functions. They are different than monadic functions in those monads. Which is where some of the confusion comes in.
20:00jimduey_I try to untangle that in some later posts.
20:00mkjimduey_: I take it that this is because it is unwrapped before being given to the Monad-wrapped function (my thoughts are burrito-explanation flavoured here)
20:02jimduey_If I get your question correctly, the answer is no. Any value passed to a monadic function is just used as is, there is no unwrapping. But the function returns a monadic value.
20:05mksupposing that 1,[1] -> [2] (this is just addition within a monad), what sort of function will allow [1][1]->[2]?
20:05brehautwell bind only takes a unary function, so you need to partial your addition
20:05brehautand then wrap it up in a return
20:06brehautso that it returns a monadic value
20:06jimduey_Yeah, a monadic function by definition only accepts a single parameter.
20:06brehautthat operation of taking a non monadic function and making it return a monadic value is called lifting
20:09brehautmk, i mucked up my bind definitions above
20:09mkhow far above?
20:10brehautmk in the refheap paste
20:10brehautmk, bind: function (f) { return (this.v !== null) ? f(this.v) : new MaybeM(null); }
20:11brehautmk: and usage would be new MaybeM(1).bind(function (v) { return new MaybeM(v + 1); }).v
20:11mkyou removed the monad wrapper around the returned value?
20:11brehautthats correct
20:11mkare you sure that's right?
20:12brehautyes
20:12mkbut then bind doesn't return a monadic value
20:12brehautexactly
20:12brehautwell
20:12brehautsort of
20:12brehautit does because the function passed to it does
20:14mkyes I see
20:14brehautthe type of the function bind takes is a -> m a
20:16mkone of the confusing things about monads is how bind can be seen either as taking a monadic value and a monadic function, returning a monadic value; or as taking a monadic value, and returning a function with a closure that takes functions and spits out the prior-mentioned result value
20:17jimduey_yeah, I can see how that's confusing when you first see monads. I typically only focus on the 1st perspective.
20:24gfredericks,(prn (keyword "foo (System/exit)"))
20:24clojurebot:foo (System/exit)
21:00FrozenlockIs there a way to put a default file name in (choose-file) in the seesaw library?
21:08jasoxNeed help people, can not configure slime to work with emacs24. Please can someone tell me what is easiest way to configure slime with emacs. If someone have links for useful dot files. ANYTHON !! Thanks
21:09bprdoes ring.middleware.wrap-file follow symlinks?
21:09mega`jasox: w8 for link
21:10Raynesw8? wait?
21:10mega`Raynes: yea dont play games much? :D
21:10RaynesPlease don't do that unless you're typing on a keyboard in klingon and you don't know how to spell 'wait' on it.
21:11mega`jasox: http://marmalade-repo.org/packages/starter-kit
21:11autodidaktoRaynes: omglol
21:11Raynesrofl
21:11autodidaktoRaynes: you're complaing about w8? srsly?
21:11Raynesyarly
21:11weavejesterbpr: The easiest way is to check it out, I think. It should do… because it just uses the normal Java I/O libraries.
21:11mega`Raynes: where in a chat this is absolutly the playes for w8, brb, etc ....
21:12jasoxYeah I instelled it. But can not configure it. What should I add in .emacs
21:12jasoxOfficial tutorial is not working for me :/
21:12RaynesYikes.
21:12weavejestermega`: I'm trying to decide if you're doing an april-fools :)
21:12RaynesYeah, I'm thinking he is. At least, I'll sleep better tonight if I think that.
21:13mega`jasox: create a .emacs.d directory
21:13mega`jasox: and make init.el file
21:13mega`jasox: o w8 i think 24 alreddy has package.el
21:13bprweavejester: It looks like it doesn't.
21:13jasoxand ?
21:14autodidaktoweavejester, Raynes: stop being a h8ter
21:14Rayneskk
21:14autodidaktoas mega said, he's absolutely the playa
21:14jasoxmega`, it has
21:14mega`jasox: so M-x and package-list-packages
21:15mega`jasox: and C-s to search for clojure-mode
21:15mega`jasox: press x to select the package for instalation
21:15jasoxk
21:15mega`jasox: i mean i to select it and x to install
21:16mega`jasox: get the test mode and clojurescript while your att it
21:16jasox "get the test mode and clojurescript while your att it" - don't get it
21:17mega`jasox: u can select multiple packages for install
21:17jasoxk
21:20mega`jasox: when your done whit that you need to get the swank-clojure plugin for leiningen
21:28jasoxmega`, ok what should I do then.
21:29mega`jasox: you have lein installed?
21:29jasoxyes
21:29mega`jasox: and swank-clojure?
21:30yoklovhow can i get a more, uh, useful string version (or print one out) of a structure in cljs? right now the best i've got in most cases is [object Object]
21:30jasoxmega`, yes
21:30mega`jasox: then navigate to your project
21:30mega`jasox: and use M-x clojure-jack-in
21:31jasoxWOW, finally. Thank you mega`
21:32timvisherhey kids
21:32timvishercan anyone point me to the rationale behind clojure's lack of support for currying?
21:32amalloytimvisher: varargs
21:32mega`timvisher: there the partial function
21:33timvishermega`: completely aware of that. That's not really currying in the Haskell sense.
21:33timvisheramalloy: that's the rationale? as in JVM varargs?
21:34amalloyno, as in clojure varargs
21:34amalloyhow do you curry the + function? it takes any number of args
21:34timvishergotcha
21:34yoklovtimvisher: think about things like zipWith3 in haskell.
21:34yoklovyou don't need ugliness like that in clojure.
21:34timvisheryoklov: i actually have no experience with Haskell ;)
21:34yoklov(as a result, you hava ugliness in partial application)
21:34yoklovah
21:34timvisherbut I'll take your word for it
21:34amalloyyoklov: it's an ugliness tradeoff, yeah
21:34autodidaktoClojure vs Haskell, as well as currying, also comes out in difference over pattern matching
21:35timvisherit's quite obvious once you state it that way
21:35amalloyautodidakto: well, that's a feature that can be added on top of what clojure already has
21:36xeqiautodidakto: core.match is pretty good
21:36mkclojure functions that take varargs can be thought of as taking lists, instead
21:37yoklovmk: doesn't solve the problem though, because during partial application they aren't taking a list
21:37autodidaktoxeqi: ah yes. I've been meaning to check that you
21:37autodidaktoamalloy: how would you go about it?
21:38amalloyi'd probably just ask dnolen to do it
21:38amalloyand then he'd be like "oh, i already did, mate, it's in core.match"
21:38amalloyassuming that for april fools he fakes an australian accent
21:38mkyoklov: the cases of partial application on vararg fns that I can think of involve the non-vararg parts (as if you're initializing the function) - is partial application of varargs common?
21:39yoklov,(map (partial + 5) [1 2 3])
21:39autodidaktoamalloy: kangaroo.match maybe, hehe heh
21:39clojurebot(6 7 8)
21:39autodidakto,(+ 5 [1 2 3])
21:39clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
21:40autodidaktooh duh, map
21:40yoklovthats usually when i use partial application
21:41autodidaktoyoklov: as a short/simple-function-like-shortcut?
21:41yoklovyeah
21:41autodidakto,(map #(+ %) [1 2 3])
21:41clojurebot(1 2 3)
21:41autodidaktodeer
21:41yoklovor if i want to express somethign iin a snooty way
21:41autodidakto,(map #(+ 5 %) [1 2 3])
21:41clojurebot(6 7 8)
21:41yoklov,(map (partial map +) [[1 2] [3 4]] [[5 6] [7 8]])
21:41clojurebot((6 8) (10 12))
21:42autodidakto*head explodes*
21:42mkyoklov: yeah somewhat, though you might as well think of add as (+ a b list-goes-here)
21:42yoklovlol, think of (partial map +) as `point-add`
21:42autodidaktothat's snooty. did you type that with your pinky fingers in the air?
21:42yoklovyeah.
21:43yoklov,(map (partial + 1 2 3) [4 5])
21:43clojurebot(10 11)
21:44yoklovmk: varargs and currying just don't mix well
21:44mk,(map (partial + 6) [4 5])
21:44clojurebot(10 11)
21:44mkI agree, but I'm not sure I'm a fan of either
21:44yoklovright, but you can only do that because you know that (+ a b c … rst) is the same as (+ (+ a b c) … rst)
21:45yoklovthats certainly not true in every case.
21:46mk+ is a pretty good case for varargs, but it's really just (sum [1 2 3...])
21:46mega`&(doc sum) ; dont think whe have sum
21:46lazybotjava.lang.RuntimeException: Unable to resolve var: sum in this context
21:47mega`mk: so yea + is the sum
21:47brehautsum is (apply + …)
21:47yoklovit's just apply +
21:47RaynesOr (reduce +)
21:47yoklov(partial apply +) :p
21:47yoklov(or reduce)
21:47Raynes#(apply + %)
21:47clojurebotCool story bro.
21:47mkthe reason I don't like varargs is that they are placed in arbitrary places in some of our functions (like in the middle), and some functions take lists when they may as well take varargs
21:48autodidakto,((partial apply +) '(1 2 3))
21:48clojurebot6
21:48mega`mk: in the midle?? what
21:48RaynesIn the middle of a gunfight.
21:48mkmega`: yeah, let me find it...
21:49autodidaktoRaynes: Never bring a vararg knife to the middle of a curry gunfight
21:49autodidaktoat least that's my understanding
21:49amalloybtw, since we're discussing apply vs reduce, my favorite explanatory tool is ##((juxt apply reduce) (partial list '+) (range 5))
21:49lazybot⇒ [(+ 0 1 2 3 4) (+ (+ (+ (+ 0 1) 2) 3) 4)]
21:50yoklovmk: i really wouldn't want to part with vararg map.
21:50autodidakto,(doc juxt)
21:50clojurebot"([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
21:50amalloyyeah, god help us if we had zipWith5 in the language. blech
21:51mkthe best way to explain apply on its own, I think, is as injecting the given function into the front of the given list. It's an injector.
21:51brehautamalloy: (partial list '+) (range 5) is cute, but why not just (list* '+ (range 5)) ?
21:51amalloyuhhh
21:51amalloybecause that doesn't illustrate the point?
21:51yoklovmk: well but then it gets hairy, because some languages (ruby, for one) call reduce inject :p
21:51yoklovsmalltalk too i think.
21:52amalloythe point is that reduce and apply do different things; i'm not just calling ((partial list '+) (range 5))
21:52RaynesThat's because it was named by a Japanese guy.
21:52mega`yoklov: .net cals it Aggregate
21:52yoklovright but he said it was injecting… yeah nevermind
21:52brehautoh right
21:52autodidaktoyoklov: inject is the more common synonym, but i like reduce is an alias to the method
21:52autodidakto*but i think reduce is
21:52RaynesThat's because .NET was created by suits with no human bodies inside.
21:52mkyoklov: map throws the varargs as params, so initially that looked fine - but then - have you used map to map into vararg functions? because that sounds interesting
21:52autodidaktoRaynes: Report to HR, immediately
21:53yoklovmk, you mean like my example above?
21:53yoklov,(map (partial map +) [[1 2] [3 4]] [[5 6] [7 8]])
21:53clojurebot((6 8) (10 12))
21:53amalloy&(apply map vector [[1 2 3] [4 5 6]])
21:53lazybot⇒ ([1 4] [2 5] [3 6])
21:53yoklovoh thats neat.
21:53amalloy~zip
21:53clojurebotzip is not necessary in clojure, because map can walk over multiple sequences, acting as a zipWith. For example, (map list '(1 2 3) '(a b c)) yields ((1 a) (2 b) (3 c))
21:54autodidakto*head explodes*
21:55autodidaktooh right right, when given multiple lists/vectors/maps.. map takes one from each at a time..
21:55mkright, yeah - those are in fact interesting
21:56mega`, (map + (range 0 4) (range 0 8))
21:56clojurebot(0 2 4 6)
21:57autodidaktoand stops when the shortest list ends...
21:57mkautodidakto: it takes all of the first elements in all of the given collections, and then shoves them into the given function as params (and then the second elements, then third...)
21:57mk,(apply map vector [1 2] {:a 8 :b 9})
21:57clojurebot([1 :a :b] [2 8 9])
21:57autodidaktomk: I see. thanks
21:58autodidaktobut what's that apply do?
21:58autodidakto,(map vector [1 2] {:a 8 :b 9})
21:58clojurebot([1 [:a 8]] [2 [:b 9]])
21:58autodidaktohmm
21:58xeqi,((partial map vector [1 2]) {:a 8 :b 9})
21:58clojurebot([1 [:a 8]] [2 [:b 9]])
21:58mega`&(doc apply)
21:58lazybot⇒ "([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args]); Applies fn f to the argument list formed by prepending intervening arguments to args."
21:59mkI like to imagine them as.. dropping down, so [1 2 3 4] becomes vertical, and them map runs the function down this vertical strip. When given varargs, they all just roll down vertically
22:00autodidakto,(map str [1a 2a 3a] [1b 2b 3b])
22:00clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.NumberFormatException: Invalid number: 1a>
22:01mkoh, apply is the one that takes varargs in the middle
22:01autodidakto,(map str ["1a" "2a" "3a"] ["1b" "2b" "3b"])
22:01clojurebot("1a1b" "2a2b" "3a3b")
22:01amalloyno it doesn't
22:01mega`mk: only the last one has varargs
22:01mkcould be wrong, I'll check
22:02autodidaktoscroll up to the last lazybot
22:03mkit lies
22:03mk,(apply vector 1 2 3 4 5 6 7 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 '(99 999))
22:03clojurebot[1 2 3 4 5 ...]
22:03amalloyokay...
22:04mkyou can put an arbitrary number of arguments into the middle, and they are all injected into "args"
22:04amalloyi mean, i guess i see what you mean by varargs in the middle, there
22:05mkwhat's described as "args" can actually only be one argument. If you try to apply into an apply, you'll end up applying... I'm going to cut that sentence off there
22:06mega`https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L596
22:07mkapply is what you pull out when you want to use a list as varargs
22:07mega`&(doc spread)
22:07lazybotjava.lang.RuntimeException: Unable to resolve var: spread in this context
22:07TimMcmega`: That's private, I think.
22:07mega`yea
22:08TimMc&(meta #'clojure.core/spread)
22:08lazybot⇒ {:ns #<Namespace clojure.core>, :name spread, :arglists ([arglist]), :private true, :static true, :line 574, :file "clojure/core.clj"}
22:08TimMc...and doesn't have :doc anyhow.
22:09mkit's two functions up in that link above
22:09amalloyspread is just list*, iirc
22:09amalloyexcept that it's a primitive used to define functions like apply and list*
22:09amalloy&(#'clojure.core/spread 1 2 [3 4])
22:09lazybotclojure.lang.ArityException: Wrong number of args (3) passed to: core$spread
22:10mega`takes a seq directly
22:10amalloyright, it's (partial apply list*)
22:10amalloy&(#'clojure.core/spread [1 2 [3 4]])
22:10lazybot⇒ (1 2 3 4)
22:10amalloy&((partial apply list*) [1 2 [3 4]])
22:10lazybot⇒ (1 2 3 4)
22:13autodidaktoamalloy: can you give me another clue to understanding apply?
22:13mkapply is kinda like a cons that gets evaluated
22:13scriptorautodidakto: what other languages do you know?
22:14mk,(cons '+ '(1 2 3))
22:14clojurebot(+ 1 2 3)
22:14autodidaktoscriptor: ruby
22:14mega`, (eval (cons '+ '(1 2 3)))
22:14clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
22:14scriptorhmm, not sure about the equivalent of apply in ruby
22:14mk(eval (cons '+ '(1 2 3)))
22:14mega`:(
22:15mkhmm
22:15mk> 6
22:15scriptorautodidakto: in a sense, apply is like ruby's send, except that it works on functions, not methods
22:15mega`:D
22:15amalloyscriptor: it's like ruby's splat operator
22:15mk(apply + '(1 2 3))
22:16amalloy(apply f a b c) => f(a, b, *c)
22:16scriptoryes, that too
22:16autodidaktohmm
22:17scriptorsplat + higher order func
22:17mkautodidakto: at first think of apply as taking two arguments - a function, and a list
22:18mkit puts the function at the front of the list, and then runs away (the new list is evaluated, as a list usually would be)
22:19mkalternatively, if you have a function and it's missing a bunch of arguments, apply removes the brackets from that list, and puts them at the end of the function
22:20mkapply fun '( 1 2 3) -> eval'd(fun 1 2 3)
22:20autodidakto,(str '(1 2 3))
22:20clojurebot"(1 2 3)"
22:20autodidakto,(apply str '(1 2 3))
22:20clojurebot"123"
22:20mk,(str 1 2 3)
22:20clojurebot"123"
22:21mkin your first expression, you gave a list to str, but it expects varargs
22:22mkapply is for turning any function that takes varargs into the same function, but taking a list
22:23autodidaktousing the individual items of the list as it's arguments?
22:23autodidakto*its
22:23mkyep
22:24mkvarargs can be thought of as being a list anyway
22:24autodidakto"alternatively, if you have a function and it's missing a bunch of arguments, apply removes the brackets from that list, " is this what amalloy was talking about with the splat operator?
22:25scriptorautodidakto: more or less
22:25amalloyi don't want to be held responsible for any description of apply that makes it sound like it's manipulating source forms like brackets
22:26mkright - keep in mind that's not what it actually does. But when you're looking at something like...
22:26scriptoryes, don't really think about it in terms of shuffling parentheses around, it takes the function f and uses the elements of the list as its arguments
22:27mk,(str '(1 2 3))
22:27clojurebot"(1 2 3)"
22:28scriptorautodidakto: what don't you still get?
22:29mkand you mess around with it and you find that (str 1 2 3) works just fine... well, the diff between the two is a pair of brackets. So you use apply
22:31autodidakto,(map vector [1 2 3] [4 5 6])
22:31clojurebot([1 4] [2 5] [3 6])
22:31autodidakto,(apply map vector [[1 2 3] [4 5 6]])
22:31clojurebot([1 4] [2 5] [3 6])
22:31autodidaktoI'm trying to see how apply, like, went into the outter [vector]
22:32mk,(map vector [1 2 3] [4 5 6])
22:32clojurebot([1 4] [2 5] [3 6])
22:32autodidaktooh, by putting map inside it...?
22:32mk,(apply map vector '( [1 2 3] [4 5 6]))
22:32clojurebot([1 4] [2 5] [3 6])
22:32mkby putting both map and vector inside it
22:33autodidaktothat would be the same as the "<mk> apply fun '( 1 2 3) -> eval'd(fun 1 2 3)" thing you said
22:33scriptorautodidakto: with your second expression, you're telling apply, "take the function map, and pass it 'vector' as the first argument, and [1 2 3] and [4 5 6] as the 2 and 3rd arguments"
22:34autodidaktoscriptor: ah. that helps too
22:34mkthe vararg thing is why I think it's easier to think of apply as shoving all the left-side arguments into the single right-side list
22:35mk(apply list 1 '(22) 3 '(4))
22:35mk,(apply list 1 '(22) 3 '(4))
22:35clojurebot(1 (22) 3 4)
22:36mk,(list 1 '(22) 3 , 4)
22:36clojurebot(1 (22) 3 4)
22:36autodidaktocould you say that apply is a way to "prepare" the arguments for a given function?
22:36yoklovautodidakto, sort of
22:37yoklovso i don't know if clojure does it this way
22:37autodidaktothough by the name "apply", i guess it would be the other way around
22:37yoklovhowever typically
22:37yoklovevaluators are made up of two runctions
22:37yoklov`eval` and `apply`
22:37scriptorautodidakto: there's no 'preparing' done, it's about applying a given function to a list of arguments
22:37yoklovapply takes a function and a list of arguments, and applies the function to the arguments
22:37scriptoror a vector of args
22:37yoklovand eval uses apply to eval everything
22:38yoklovso, when you type (apply foo '(bar baz)) it gets evaluated the same as (foo 'bar 'baz)
22:38mkautodidakto: you can think of it that way, because it's equivalent to how it's done, but not actually how it's done. Also, in (apply f :a :b '(1)), :a :b are arguments, too
22:39yoklovoh right, apply in clojure does that.
22:40yoklovright, and apply just calls .applyTo on the function
22:40yoklovwith the args made into a list
22:41mkautodidakto: do you have a good handle on the two-parameter apply? where it's just a function and a list (or vector, or seq)?
22:42autodidaktomk: good enough I think
22:42autodidaktoin that case i think "I have a list, but now I want to use the items in that list as my arguments"
22:43mk,(apply list :a :b [3 4])
22:43clojurebot(:a :b 3 4)
22:44mk,(apply (partial list :a :b) [3 4])
22:44clojurebot(:a :b 3 4)
22:44mkthat's how the multi-param version of apply works (or another way to think of it)
22:45autodidaktoin that first apply, how does it "know" to open up the vector?
22:45autodidakto(apply list :a :b [3 4] [5 6])
22:45autodidakto,(apply list :a :b [3 4] [5 6])
22:45clojurebot(:a :b [3 4] 5 6)
22:46mkautodidakto: it's the last argument
22:47autodidaktoi see
22:47autodidakto,(apply (partial list :a :b) [3 4] [5 6])
22:47clojurebot(:a :b [3 4] 5 6)
22:47mk,(apply (partial (partial list :a :b) [3 4]) [5 6])
22:47clojurebot(:a :b [3 4] 5 6)
22:48mk,(apply (partial list :a :b [3 4]) [5 6])
22:48clojurebot(:a :b [3 4] 5 6)
22:48mkthere's apply, then there's the stuff in the middle, and then there's the last item
22:49mkthe stuff in the middle is the function and its first few params
22:51autodidaktoIs there an easy way to describe the situation in which apply is needed and a simple (fn arg1 arg2) wouldn't work?
22:51mkyou have a list, and you need to use that list inside a function that takes varargs
22:52autodidaktowith the list as it's varargs? or all it's args?
22:52autodidakto*its
22:53mkas its varargs
22:53mk,(+ '(1 2 3))
22:53clojurebot#<ClassCastException java.lang.ClassCastException>
22:53mk,(apply + '(1 2 3))
22:53clojurebot6
22:54autodidaktogotcha
22:54mk(obviously if you were typing this in, you would just remove the brackets in the first case, but '(1 2 3) is meant to stand in for a symbol)
22:55autodidaktoi'll start looking around for examples of apply in use and think about what's going.
22:56autodidaktomk, scriptor, amalloy: thanks for the tutoring :)
22:57mknp. The only thing you need to know about apply is that if you have a list, and a vararg function, you can use apply
22:57autodidaktoah, yoklov too
22:57mk...apply could have been averted if none of our functions used varargs :P
22:58yoklovhaha, no clue if i helped at all :p
22:58yoklovmk: you'd still need it in eval
22:58mkyoklov: yeah yeah :)
22:58scriptorno prob, eventually you'll find a place where apply will come in handy and it'll all click
22:59autodidaktomk: does that have something to do you with rant about varargs?
23:00autodidaktoyoklov: I was intrigued about what you said about evaluators using eval/apply. I'm remembering the logo of the videos for the SICP book (which i havent finished *cough*)... the wizard with Eval/Apply in his crystal ball
23:00yoklovoh yeah
23:00yoklovexactly that.
23:00yoklovyou should finish that. sicp is amazing :)
23:01autodidaktoyoklov: the math-based examples make me squint at the screen
23:01mkautodidakto: yes. It also has to do with that part about varargs being in the middle, because that fun application of apply that you started with is... hard to start with
23:01mk,(apply map vector [[1 2 3] [4 5 6]])
23:01clojurebot([1 4] [2 5] [3 6])
23:01yoklovhah, the math in that book is a killer.
23:02yoklovregardless what i'm talking about was chapter 4
23:02autodidaktoyoklov: cool. I'll look it up
23:02autodidaktomk: i see
23:03mk...I just realized why ,(+ 1 2) works in my repl even though it has a weird symbol at the very front
23:06scriptorisn't , treated the same as whitespace?
23:06mkyes.
23:07autodidakto,(doc ,str)
23:07clojurebot"([] [x] [x & ys]); With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args."
23:07mk"cool, my repl accepts the same special initial symbols as clojurebot - that's pretty convenient for pasting"
23:08scriptorautodidakto: don't need the , before str
23:08mk, is whitespace
23:08clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: is in this context, compiling:(NO_SOURCE_PATH:0)>
23:09autodidaktoright right, just confirming your point
23:10autodidaktoyoklov: SICP is really quotable -> It is no exaggeration to regard this as the most fundamental idea in programming: The evaluator, which determines the meaning of expressions in a programming language, is just another program. To appreciate this point is to change our images of ourselves as programmers. We come to see ourselves as designers of languages, rather than only users of languages designed by others.
23:11yoklovhaha, sicp is really amazing. chapter 4 is my favorite :)
23:11mk,(apply apply apply map vector [[[[1 2 3] [4 5 6]]]])
23:12clojurebot([1 4] [2 5] [3 6])
23:13autodidaktomk: ouch, thanks :)
23:15muhooautodidakto: then what about people who design languages for designers of languages?
23:16autodidaktomuhoo: they sit in the lotus position, hovering 3 feet off the floor
23:17muhooor in a hammock.
23:17autodidaktomuhoo: taking the year off
23:18muhoo"In a hammock, nobody knows you're not sleeping." -- Rich Hickey
23:18autodidaktoWhich really sums up clojure development.... I think
23:20autodidaktoThere needs to be a comic of him lying in a hammock, taking the year off, and braiding his hair... hmm what other memes can i shove in there...
23:26autodidamuhoo: Is there an online collection of rhickey quotes taken wonderfully out of context?
23:30arohneris there an an await that works for future?
23:32mkautodida: you might try searching the logs at http://clojure-log.n01se.net/
23:32amalloyarohner: isn't that just...deref?
23:33RaynesOr download all of the logs from raynes.me/logs/irc.freenode.net/clojure and grep them.
23:33arohneramalloy: I was thinking await did something it didn't, which is block on all agents (i.e. without listing them)
23:33arohnerI'm writing some tests, and I'd like the test to block until all futures are finished, but I'd like to not explicitly list them
23:35autodidaaccording to clojure, rhickey hasn't been seen since 08?
23:35Raynes$seen rhicky
23:35lazybotI have never seen rhicky.
23:35Raynes$seen rhickey
23:35lazybotrhickey was last seen joining on clojure 1 week and 6 days ago.
23:35muhoowow, didn't know he used to be ini this channel.
23:35Raynesmuhoo: He used to talk on this channel a lot.
23:35muhoo2010, looks like
23:35TimMcHe pops in with announcements every once in a while.
23:36RaynesGuys. 1 week, 6 days ago.
23:36TimMcRaynes: "joining"
23:36RaynesYes, but he was here.
23:36RaynesIt's fair that he doesn't join very often though. With 400+ users every day, it can get a little hairy.
23:36slyrusbut he went out
23:37TimMcI remember him coming in and asking naming advice for what ended up being called "realized?"
23:37mkthere's actually a secret channel where all the oldhats talk about things
23:37TimMcI can see why he doesn't show up much.
23:37muhooi'm sure there is a backchannel still.
23:37technomancymk: it's called irc.thinkrelevance.com
23:37muhoohehehe
23:40muhoowell i'm sure linus doesn't hang around in #linux
23:41muhoonor guido in #python, etc etc
23:41autodidaktolinus: my sounds card breaks the drivers, what's with that?
23:43muhoohe was, however, active on the lkml for a long time, may still be even, i dunno.
23:44mkmany of the channels for more popular languages are pretty much tech support. Nobody stays around for long enough for there to be a productive community
23:45autodidaktomk: do the tech support conversations swamp the deeper ones? or?
23:46muhooi've seen people in #debian and #emacs who've been there over a decade though.
23:46brehautthey are all weighed down by their beards. they literally could not leave, even if they wanted to
23:47mkit's encouraging to see new users (especially when they're using your clojure libs), but devs start to leave if there's too much noise
23:47muhoobrehaut: that is awesome. thank you for that.
23:49autodidaktobeards stuck under those old school loud, big-key keyboards
23:49autodidakto10 years of tech support is enough to grey a beard, though
23:51muhooautodidakto: http://www.flickr.com/photos/two_pi_r/264672521/
23:52technomancynobody talks about Emacs in #emacs though, so that's different
23:52technomancyit's mostly politics and bot abuse
23:53autodidaktomuhoo: hehe yeah
23:53brehauttechnomancy: emacs is now sufficiently intelligent that it can maintain political discourse and nobody notices?
23:53brehautim not sure if that says more for emacs, or political debate
23:54technomancybrehaut: M-x no-u
23:55brehauti cant tell if thats a joke i havent got, or if an emacs package i havent got
23:56technomancypolitical "debate" these days consist mostly of "no, YOU're the one who is wrong!!!oneone"
23:56technomancyso it's easy to automate, I guess?
23:56brehautah. lol
23:56brehautheh yeah
23:56brehauthidden markov model ?
23:56brehautor just random
23:56technomancybrehaut: oh man
23:56brehautits not like either party is actually listening to each other
23:56technomancyjust ask rudybot about pretty much anything
23:56technomancyit's reminiscent of talk show radio
23:56brehautlol
23:57brehautis that a #emacs bot?
23:57technomancyyeah, he picks a random unlikely word from your line and searches his logs for a line that matches
23:57technomancyit's hilarious how often it almost makes sens
23:57technomancye
23:57brehauthaha
23:58autodidaktosounds like some kind of post-apocolyptic dystopia... uncaring robots have taken over.
23:59brehautid rather the uncaring robots than any american political faction
23:59autodidaktotalk show radio -> Rush Limbot
23:59brehautthe robots are at least logical
23:59muhoopolitics for me is a particularly insidious form of bikeshedding