#clojure logs

2014-01-26

00:02quizdrthe beauty of 4clojure is in learning that your function (fn [& a] (apply concat (map #(list % %2) (first a) (second a)))) can be rewritten simply as mapcat list, had you only known mapcat existed.
00:06devnthis is also a little bit closer i guess...
00:06devn,(map second (filter #(= 'clojure.core/declare (when (coll? %) (first %))) (macroexpand-1 '(defrecord fooBaz [x y z]))))
00:06clojurebot(->fooBaz map->fooBaz)
00:06devn,(resolve 'fooBar)
00:06clojurebotnil
00:09devnerr
00:09devn,(defrecord fooBar [])
00:09clojurebotsandbox.fooBar
00:09devn,(ns-resolve *ns* 'fooBar)
00:09clojurebotsandbox.fooBar
00:12cark,(def test "hello")
00:12clojurebot#<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>
00:12carkhum
00:12carkclojurebot shouldn't let you define records i think
00:13cark,(->fooBat)
00:13clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ->fooBat in this context, compiling:(NO_SOURCE_PATH:0:0)>
00:13cark,(->fooBar)
00:13clojurebot#sandbox.fooBar{}
00:13devnwhy not?
00:14carkyou can polute the namespace, maybe dos it by defining many record types
00:14devnit does it in a sandbox
00:14carkright but the sandbox is still there isn't it
00:14devnfor now
00:15devni think it gets cleaned up regularly
00:15carkyou could write a script to make it go out of memory, and maybe crash
00:15carkthen why not let me def a var ?
00:15carksame problem
00:16devn,(let [shadow 1] (+ shadow 1))
00:16clojurebot2
00:16devn,(let [shadow "shadow"] (str shadow " puppets"))
00:16clojurebot"shadow puppets"
00:17devnmaybe he runs it in an env that makes that not matter
00:18oracle_How to understand the: (map #(%1 %2) (cycle [inc identity]) [1 2 3 4 5 6 7 8 9 10])?
00:18carkhe can't be "out of memory" proof
00:18oracle_what's the meaning of "(cycle [inc identity])"?
00:18carkor i want his box
00:19carkoracle_: it's an infinite list : '( in identity inc identity ....)
00:19devncark: im saying that maybe it (the vm/machine/whatever) just gets axed if it lives beyond its means
00:19carkoracle_: it's an infinite list : '(inc identity inc identity ....)
00:19dissipateclojurebridge is just for women? wtf
00:19dissipatethat's ridiculous
00:19devnis it really?
00:20dissipatedevn, as a man, why can't i get free workshops? :(
00:20devnidk, you can if you're in my town
00:20devni dont know where you read that
00:20dissipatedevn, which town?
00:20devnMadison, WI
00:21devndissipate: my suggestion is to not read the "for women" part too seriously
00:21oracle_but if I run " (take 10 (cycle [inc identity]))" it didn't return a list, instead it return "(#<core$inc clojure.core$inc@3e353f6a> ......"
00:21devnjust show up
00:22carkoracle_: look a this :
00:22devninc is a function
00:22cark,(take 10 (cycle [1 2]))
00:22clojurebot(1 2 1 2 1 ...)
00:22devnidentity is a function
00:22devn,identity
00:22clojurebot#<core$identity clojure.core$identity@fbbe3f>
00:22devn,inc
00:22clojurebot#<core$inc clojure.core$inc@1d1fda>
00:22devn,(take 4 (cycle [inc identity]))
00:22clojurebot(#<core$inc clojure.core$inc@1d1fda> #<core$identity clojure.core$identity@fbbe3f> #<core$inc clojure.core$inc@1d1fda> #<core$identity clojure.core$identity@fbbe3f>)
00:23devn,(take 4 (cycle ['inc 'identity]))
00:23clojurebot(inc identity inc identity)
00:23devn,(take 4 (cycle '(inc identity))
00:23clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
00:24carkit's pretty hard at first to see functions used as common data, stored in lists and whatnot
00:24devn,(take 4 (cycle '(inc identity)))
00:24clojurebot(inc identity inc identity)
00:24TEttingerztellman, those google ads were brilliant
00:24jack_rabbit,(doall (range))
00:24clojurebot#<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>
00:24ztellmanTEttinger: ha, thanks
00:24devnjack_rabbit: dont break the bot :(
00:24jack_rabbitdevn, He can survive it. :)
00:24devn(inc ztellman)
00:24lazybot⇒ 8
00:24carkit's the "kill clojurebot" night
00:24TEttinger(inc ztellman)
00:24lazybot⇒ 9
00:24devncark: id like to see you try
00:24quizdr(inc clojurebot)
00:24lazybot⇒ 33
00:25devnive run a couple millions sexps in a sandbox from this channel
00:25devnand had no issues
00:25carkdevn : i don't want to write that script we talked about, but you may do it =P
00:25devnmillion*
00:25TEttingeralso, ztellman have you considered a counterpart to primitive-math that provides primitive-coerced math ops?
00:25devncark: my guess is you couldn't actually DDoS him with it
00:25devnerr DoS
00:25carkdevn : got to try it to be sure
00:25devnwhichever worked i guess
00:26ztellmanTEttinger: can you expand on that? I'm not sure what you mean
00:27dsrxgot an http-kit question. if I run this namespace from lein run, and I connect and send messages the printlns inside the on-close and on-receive handlers print to the console. but if I load that namespace into a repl and (start) there, I do not see anything printed to the repl https://www.refheap.com/27692
00:27TEttingerwell to avoid the warnings primitive-math gave me (about 400 in one file I think), I changed all my non-float arithmetic to use some macros like +_ and *_ . those just coerce both args to long and add them
00:27TEttingerI don't know if there's a faster way
00:28carkdsrx: there is an annoying phenomenon with printing out of the main thread and nrepl
00:28ztellmanTEttinger: coercion at the point of the arithmetic call isn't necessarily the right thing to do
00:28ztellmanideally you change something upstream, so it's not boxing at all
00:28carkdsrx: sometimes work and sometimes doesn't
00:28devncark: im tempted
00:28dsrxcark: ah, I see
00:28devnim afraid of hiredman, but i feel like he probably took care of this scenario
00:29TEttingerI think I was using type hints incorrectly on my functions that returned numbers
00:29devnshall we try it?
00:29dsrxcark: well, I guess i can always swap messages into an atom and read them that way :P
00:29devn,(doseq [x (repeatedly 100000 #((comp symbol str) (java.util.UUID/randomUUID)))] (eval `(defrecord ~x [])))
00:29clojurebotExecution Timed Out
00:29TEttingerha!
00:29dsrx,(launch-missiles)
00:29clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: launch-missiles in this context, compiling:(NO_SOURCE_PATH:0:0)>
00:30ztellmanTEttinger: sometimes you need to just coerce, for instance if you're pulling numbers out of a Clojure data structure, but often that's not the case
00:30devncark: toldyaso
00:30ztellmanalso, it's not clear at compile time whether it should be integer or floating point arithmetic
00:30carkdevn make it smaller and do it again and again =)
00:30ztellmanyou'd have to do that at runtime, which is effectively what Clojure already doe
00:30ztellmandoes*
00:31devncark: your turn. i created the PoC, my work here is done. :)
00:31carkdevn : i'm a pacifist at heart, let the poor clojurebot live
00:31TEttingerztellman, that's why I chose a different fn name
00:31cark~botsnack
00:31clojurebotThanks! Can I have chocolate next time
00:31ztellmanit's a valid approach in some cases, but not all
00:32devnDo you guys know of any interesting ways to capture ->fooBar and map->fooBar when (defrecord fooBar []) is defined?
00:32ztellmanin a lot of cases it would just be papering over the underlying issues
00:32ztellmandevn: capture how?
00:33ztellmanor rather, in what sense?
00:33devnthat's the question, i suppose. kovas posted about not being able to programatically find map->fooBar when given fooBar.
00:33devnwithout string munging, that is
00:34ztellmanstring munging is valid
00:34devn,(map second (filter #(= 'clojure.core/declare (when (coll? %) (first %))) (macroexpand-1 '(defrecord fooBaz [x y z]))))
00:34clojurebot(->fooBaz map->fooBaz)
00:34ztellmanand the prize for most fragile solution goes to...
00:34devnthat was my thought, but yeah, i suppose munging is just fine
00:35devnhahaha
00:35devnztellman: *flick*
00:35devnthere are 100 ways to find it
00:35devni was just curious what clever sorts of things people would come up with
00:36joshuafcoleIs there a simple way to test whether an expression supports a particular protocol? (e.g. ISeq?). Currently I'm using a condp statement to compare against known types, but that's awfully verbose and it doesn't support duck typing (when all the underlying mechanisms do)
00:36devnjoshuafcole: #'clojure.core/satisfies?
00:36joshuafcoleI'm hoping for something core (such that it would be applicable to cljs)
00:36joshuafcoleOh, awesome! I'll check it out
00:36joshuafcolethanks
00:37devnjoshuafcole: there's also extends? and implements?
00:39devnztellman: thanks for collection-check
00:39ztellmandevn: oh, you used it?
00:39ztellmanwhat for?
00:42maravillasdsrx: you're using cider/nrepl? have you looked for your output in *nrepl-server*?
00:44TEttingerztellman, I guess I'm not entirely sure what causes reflection in the first place. (def width (long 33)), (- width 2) seems to cause a warning -- do you know why?
00:44devnztellman: i was messing around with making an ordered invokable map. in general i just appreciate the lib because it provides a certain level of documentation
00:44TEttingerwould (- width (long 2)) change it?
00:44ztellmanTEttinger it might make more sense if you used no.disassemble to look at what that actually turns into
00:45ztellmanbut in this case, 'width' isn't known to be a long
00:45ztellmanit might change later
00:45ztellmanso any code that references it gets the value out of the var, and it comes out as an Object
00:45ztellman(- (long width) 2) fixes it
00:45devnztellman: a CsvRecord type to allow for transformations while maintaining the header order
00:46ztellmandevn: strongly encourage using potemkin unless you get hives thinking about that as a dependency
00:46ztellmanmakes it infinitely easier to do map variants
00:46devnztellman: yes, i've seen you messing with generating nonvariadic invocations and what-not
00:47TEttingerztellman, so you said I should prefer... "ideally you change something upstream", but if def makes an Object...
00:47devnztellman: potemkin.types is what i guess i'm referring to
00:48TEttingerwould there be trouble if I wrapped the whole file in a toplevel let?
00:48ztellmanTEttinger if it's really just a value, (def ^:const width 2) will just put '2' wherever you use the var
00:49TEttingerthat's much better
00:49devnztellman: alan dipert and i were chatting and he got me into this whole invokable thing. i guess i hadn't noticed, but clojure is different from other lisps in that it expands invokability to maps, vectors, etc.
00:50ztellmanit's a fun thing to play around with, it's just a bear to make a new data structure that quacks like a Clojure data structure
00:51devnztellman: yeah, i am more in "fun time" mode right now with what im working on
00:51devnbut i still appreciate coll-check as a template for checking your own stuff works with clojure proper
00:52ztellmanha, yeah, I found issues with everything I had written beforehand
00:52devnthat's just what simple-check does to you in general
00:52dsrxmaravillas: aha! thank you
00:52devni was messing with order on a set of fns that should have been idempotent over maps
00:52dsrx(inc maravillas)
00:52lazybot⇒ 2
00:53maravillaswelcome!
00:53devnaka #'this #'that #'another were all fns which operated on {...}
00:53devnand no matter the order, they should all have produced Result: {...}
00:53devnsimple-check just made me sad
00:53devnit's like lein-pedantic
00:53devnprior to deps tree
00:53devnit could just be incredibly sad to run sometimes
00:57devnztellman: which reminds me. i think i'm going to work on a tool to generate tests based on simple-check gen/any test results.
00:58devna repl-driven sort of thing where you can optionally nail down input shapes and output shapes when it starts to become clear that fn isn't going anywhere
01:00ztellmanthat's a big space to explore blind
01:01ztellmanI'd imagine you need some sort of hinting
01:01devnyeah, maybe. i think in general my mind is just wandering to: where all all the sub-repl envs?
01:01devns/all all/are all/
01:02devni want to do: (hmmmm '(my-fn 1))
01:03devnand live in a separate development repl for a moment to analyze my code, profile it, etc.
01:03devnsort of a dashboard for repl-based code analysis
01:09eggheadif there is a cljs lib I want to use that isn't published to clojars, how can I install it for use locally?
01:10egghead(assuming I have access to the project from github)
01:10dsrxegghead: clone the git repo, lein install
01:10dsrxshould work right?
01:10eggheadprobably...
01:11noonianyep
01:14eggheadah okay, I just had to do a cljsbuild clean too
01:14eggheadthx dsrx noonian
01:21dsrxnp
03:35d11wtqCan I get javadoc info from inside the REPL, without opening a browser?
03:38xuserd11wtq: with the lein repl you can
03:40xuserd11wtq: oh never mind, haven't tried it :D
03:41xuserthough (javadoc) could do it
03:42d11wtqxuser: Yeah, #'javadoc tries to open your browser, which doesn't work in a headless environment (like SSH'd into a server)
04:32deadghosthttp://i.imgur.com/yUfD59c.png
04:32deadghostjust wanted to show off my crappy compojure/enlive app before going to bed
04:46logic_progis there a way, in cljs, to register a function to be called when a channel is gc-ed ?
06:20AeroNotix,(go (prn (+ 1 1)))
06:20clojurebot#<OutOfMemoryError java.lang.OutOfMemoryError: PermGen space>
06:23carkdevn : see that ?
06:24cark,(+ 1 2)
06:24clojurebot3
06:24carkmhh
06:24cark,(go 1)
06:24clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: go in this context, compiling:(NO_SOURCE_PATH:0:0)>
06:24AeroNotix,(go (prn (+ 1 1)))
06:24clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: go in this context, compiling:(NO_SOURCE_PATH:0:0)>
06:24AeroNotixgremlins
06:25carkrestarted maybe
06:26carka defracord would go to permgen wouldn't it ?
06:26carkdefrecord
06:26cark,(defrecor someRecord [])
06:26clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: defrecor in this context, compiling:(NO_SOURCE_PATH:0:0)>
06:26cark,(defrecord someRecord [])
06:26clojurebotsandbox.someRecord
06:26AeroNotixI have 1.5.1 but I don't have clojure.core.async, do I need to download it separately?
06:27AeroNotix(require '[clojure.core.async :as async :refer :all])
06:27AeroNotixis how I'm trying to use it
06:27carkyes you need to add it to your project
06:27AeroNotixok
08:11wei__mini puzzle for you guys. I have a list of booleans and want to transform it to take a value from list A if it's true, and a value from list B if it's false. so for example, (take-multiplex [false true false true true true] (range) [:a :b :c :d :e :f :g]) should give me [:a 1 :b 2 3 4]. four from list A and two from list B.
08:13wei__^ actually, the result should be [:a 0 :b 1 2 3] since range starts from 0
08:24gfredericks,(defn tm [[b & bs' :as bs] [x & xs' :as xs] [y & ys' :as ys]] (lazy-seq (when (seq bs) (if b (cons x (tm bs' xs' ys)) (cons y (tm bs' xs ys'))))))
08:24clojurebot#'sandbox/tm
08:24wei__here's what I got, maybe there's a better way using seq functions rather than recursion. https://www.refheap.com/27931
08:24gfredericks,(tm [false true false true true true] (range) [:a :b :c :d :e :f :g])
08:24clojurebot(:a 0 :b 1 2 ...)
08:25wei__ah, lazy-seq. i always forget about that one
08:25gfrederickswei__: I think this is too weird for seq fns, but lazyseq+recursion is better than recur
08:26wei__i like seq functions because they're more clojurey, but is there an actual performance difference?
08:26gfredericksI'm not sure what you're comparing to what
08:26wei__your solution vs mine
08:27gfredericksI don't think there's an assymptotic difference. You can plug them into criterium to see
08:27gfredericksremembering that mine is lazy so you might want to doall or something
08:28wei__laziness is a a nice feature
08:28wei__anyways thanks
08:28wei__(inc gfredericks)
08:28lazybot⇒ 38
08:29wei__gluck with your kid
08:30voldymanhey guys, i am learning compojure my routes look like http://pastie.org/8668891 is this the right way?
08:58gfredericksvoldyman: no
08:59gfrederickswell depends on what the dummy handler stuff means
09:08sobelso, i'm selfteaching clojure with http://www.braveclojure.com/do-things/ but i am wondering if there are better tutorials
09:09sobeli'm also wondering just what the effort level is like for transfering my clojure knowledge to other lisps like Clozure
09:10voldymansobel: try braveclojure its a good resource
09:10sobelvoldyman: i do like it, and i'm getting through the syntax and types pretty easily
09:16voldymangfredericks: the handler fn s take the values from params and would fetch data from the sql db
09:21gfredericksvoldyman: you need to handle it inline or call your functions, not just mention them
09:23voldymangfredericks: hmm, rightnow the functions are being automatically called with the request map, to call them i would have to destructure them first then pass as argument {subject :as request} (subject-handler request subject) ??
09:23lazybotvoldyman: Uh, no. Why would you even ask?
09:23voldymanlazybot: because i am learning, and most sample code does it differently
09:23dsrxlol... rude, lazybot
09:23gfredericksvoldyman: I'm surprised the functions are being called
09:24sobelis it normal to go code-blind with lisp really easily, coming from a java/C++ background?
09:25hyPiRionvoldyman: lazybot is just a bot reacting to ?? and ???, just fyi. Right, lazybot???
09:25lazybothyPiRion: Yes, 100% for sure.
09:25sobeli think my eyes are looking for ECMA style blocks and just not finding them
09:25voldymansobel: lisp's are like LSD for nerds. first you don't understand whats happening and when you do its a whole other world.
09:26sobelvoldyman: i'm familiar with the concept.. just trying to figure out how long i'll feel dyslexic reading functional code
09:28voldymanafter reading just one tutorial i began to understand clojure, but with am totally lost after trying to read lots haskell
09:28sobeli'm trying to get my head around side-effect free programming
09:28sobeli hope/suspect that is the conceptual leap i need to make
09:37jonathanji wonder if anyone else thinks it's weird that "(inc x)" mutates x :P
09:38jonathanjin the context of the bot, i mean
09:38gfredericksmutable numbers!
09:39gfredericks$google github flexnum
09:39lazybot[CSS3 Flexible Box Layout Explained | Smashing Coding] http://coding.smashingmagazine.com/2011/09/19/css3-flexible-box-layout-explained/
09:39jonathanjhaha
09:39gfredericks$google github fredericksgary flexnum
09:40gfredericksbah
09:46sobelok, i already like lisping in clojure. where's the fast-forward tutorial for a seasoned java developer? i understand all the OS interfaces are (familiar) java classes
09:48gfredericksclojure.org maybe? :)
09:48RickInAtlantahave you read the book "the joy of clojure"?
09:48sobeli've tried nada. that's why i'm asking around here.
09:49Phonatacidoh hi. I think I need some advice in designing a simple "debugger" for clojure. Motivation : reading clojure code you wrote can be pretty difficult. Usually, when I come back to code I wrote a long time ago, I tend to commentize all the forms in the concerned function and then decommentize them gradually, just to see how the "data flow" evolves through the function. Goal : my goal is to write a tool that will record all
09:49Phonatacidvalues of intermediate forms so that I don't have to apply the debugging scheme described above. Instead I would simply hover the mouse over the form via a web interface / text-editor plugin and have the intermediate values displayed in a popup window. Approach : I know this can turn out to be a pretty complex problem to solve. However I just intend to hack something very simple in just a couple hundreds lines. Problem :
09:49PhonatacidI'm not doing static analysis (but might be forced to) should I use clojure.tools.analyzer ?
09:49sobelwell, i've bootstrapped syntax with braveclojure and will keep that one handy for a little while but i'm short on details needed to use arbitrary java classes
09:51RickInAtlantasobel last week I did a short blog post where I just walked through some examples of using java classes to access microsoft's blob store. will let you see java interop in action. onbeyondlambda.blogspot.com
09:51RickInAtlantaI don't know if it is exactly what you are looking for, but its a start
09:51clojurebotIn Ordnung
09:55ornicarhello, I'm a scala dev giving clojure a try!
09:55RickInAtlantahello
09:55ornicarI'm coding a project involving a HTTP/JSON client now
09:56ornicarI read the great lein tutorial https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#readme and it leaves me with one question
09:56ornicarhow do you reload the code in lein, after you save your .clj file?
09:57sobelRickInAtlanta: thanks, i'm taking a look at it. jdbc is my first target, so that's not too far off
09:59RickInAtlantasobel: this page on clojure.org walks through interop http://clojure.org/java_interop
09:59Phonatacidornicar: (use 'my-project.core :reload)
09:59ornicarthanks, trying that now
09:59Phonatacid(besides : "mais ou et donc or ni car" ?)
10:00Phonataciddon't forget the apostrophe at the beginning of the namespace name. :reload-all also reload used/required namespaces
10:00ornicarworks \o/
10:01ornicarI'm used to sbt (scala build tool) automatically applying changes on file save, tho. I'm gonna give https://github.com/paraseba/lein-reload a try.
10:02ornicarI'm so excited to finally discover lisp :)
10:02sobelRickInAtlanta: thanks, both those refs are hitting the spot
10:03sobelit's gonna be weird getting used to chopping up java classpaths with /
10:03sobel(outside of the filesystem or jarpath)
10:04PhonatacidI'm not sure to which extent scala is dynamic, but function definition actually work like side-effect inducing functions. So if you load a namespace, delete a function in the associated file, then reload the namespace, the deleted function will still be there ine memory. THis sort of repl-ly behavior can also induce namespace conflicts. Usually, exiting & restarting the repl works.
10:06RickInAtlantasobel for jdbc you might look at https://github.com/clojure/java.jdbc
10:07sobelthat looks like it'll be handy
10:49sobelother than the obvious java interop stuff, how portable is clojure code to other lisps?
10:50borkdudesobel it's not very portable I think. Clojure is clojure.
10:51borkdudesobel it has its own idea about immutability, etc
10:52sobelinteresting. good to know as a new-to-lisp person.
10:52sobelclojure is my first
10:52borkdudenice choice
10:54RickInAtlantasobel there are a lot of syntax differences too.
10:55RickInAtlantafirst and rest in clojure are car and cdr in lisp and scheme
10:55sobelis there any "common ground" for things like library implementations of extremely common/popular algorithms?
10:56RickInAtlantamost libraries that you will want to use are stored in a repository called clojars. leiningen searches clojars and maven for dependencies
10:57RickInAtlantawhat I do is google what I am looking for which usually takes me to libraries on github
10:57sobelok, i am aware of lein and clojars. i guess what i'm asking is, is there any notation or syntax limitation that is used to convey portable lisp or is that just right out with syntax differences?
10:58RickInAtlantasobel I would say it is right out.
10:58sobelcool
10:58RickInAtlantaA lot of the ideas from lisp are very useful to understand how to do things
10:59RickInAtlantahowever one of the things clojure does is it provides a standard way of doing things. particularly the sequence functions
11:00RickInAtlantaI haven't read too deeply into lisp stuff, but what i have seen, seems like "ok, here is how you do this with recursion, and here is how you can generalize that into working with an arbitrary function on an arbitrary list ..." where as Clojure has aloready done that with seq's
11:01sobelhuh. sounds pretty useful.
11:02RickInAtlantayeah, I spent some time going through OnLisp (only made it about 1/3 of the way through) and translating the examples into Clojure. It made me really happy I started with Clojure
11:02sobelah, persistent immutable generators
11:03sobeleverything i learned about sql lately has impressed on me the value of MVCC
11:05sobelno. wtf, must copy source array to get full immutability?
11:06sobelis there a copy-on-write data type?
11:08RickInAtlantanot sure what you mean. clojure's data structures are immutable, java arrays are not.
11:10sobelnevermind, i think nonlazy seqs are what i need there
11:11llasramsobel: What are you trying to do?
11:11sobelllasram: ultimately, learn to think about data concurrency in lisp the same way i do in sql
11:14llasramHuh
11:17llasramWell, the first step is to probably to stop worrying about thinking about it as "in Lisp." Pretty much all Lisp-family languages have in common is the s-expression syntax, homoiconicity of those s-expressions, and some aesthetics
11:19llasramBut I'm not sure what you mean by the comparison to SQL
11:19sobelspecifically MVCC
11:20llasramYeah, that's not really a thing at the language level
11:20sobelcan i lock a var in lisp such that another thread waits?
11:20sobeli'm sure that's the wrong mindset but i don't know the right one
11:21RickInAtlantasobel: ask about clojure, not lisp. you can do mvcc in clojure
11:22RickInAtlantaa "ref" in clojure is a data type that can only be modified inside a transaciton
11:22llasramClojure has it's own collection of "reference types" mostly implemented in terms of a software transactional memory system, which does internally leverage an MVCC implementation
11:22sobelawesome
11:22llasramBut I have never seen real code use it
11:22llasramhttp://clojure.org/concurrent_programming
11:23llasramHas a big chunk of the details if that's what you care abotu
11:23sobelthanks, i do :)
11:23llasramkk
11:25RickInAtlantasobel pluralsight.com has a courese on clojure concurrency. I think you can get a free trial there to check it out
11:26RickInAtlantait is several years old, so it won't have things like core.async but it does cover vars, refs atoms and agents
11:27sobelknowing it's language-embedded tells me everything i need
11:28dabdwhy am I getting a NPE here?
11:28dabd,(update-in [0 1 2] [0 1] inc)
11:28clojurebot#<NullPointerException java.lang.NullPointerException>
11:28dabdshouldn't the second argument be a list of keys?
11:29sobel,(System/getProperty "java.vm.version")
11:29clojurebot#<SecurityException java.lang.SecurityException: denied>
11:29sobelhaha
11:30sobelnicely secured
11:31RickInAtlanta,(update-in [0 [0 1 2] 2] [1 2] inc)
11:31clojurebot[0 [0 1 3] 2]
11:32AeroNotix,(go (+ 1 1))
11:32clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: go in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:32AeroNotix,(clojure.core.async/go (+ 1 1))
11:32clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.core.async>
11:32AeroNotixYEH WTVR
11:32insamniac,(update-in [0 [0 1 2] 2] [1 1] inc)
11:32clojurebot[0 [0 2 2] 2]
11:32dabdright it has to be nested
11:32insamniacoh i get it
11:33ponpal,(map inc [1336 41])
11:33clojurebot(1337 42)
11:33sobel,(inc 31336)
11:33clojurebot31337
11:33sobel\o/
11:33jonasendnolen: how close is https://www.refheap.com/27985 to how cursors work in Om?
11:36dnolenjonasen: that's the basic idea w/o optimizations & supporting more collection operations
11:37jonasendnolen: cool! Then I think I understand a little better how Om works. Thanks!
11:38jonasenYour cursor idea could probably be useful outside of Om also
11:42dnolenjonasen: yes I think so too. It really isn't so different from the getter/setter aspect of lenses.
11:43RickInAtlantaI am working through the reasond schemer, and I am having trouble translating ch 3 # 45. I think i have this line wrong (loto ((g g) (e w) (x y) . z))
11:44RickInAtlantamy version is (loto (lcons [['g 'g] ['e w] [x y]] z))
11:45RickInAtlantacan I not replace lists with vectors?
11:46algernonRickInAtlanta: try (loto (lcons ['g 'g] (lcons ['e w] (lcons x y))) z)
11:46RickInAtlantafor simpler expresions, like (loto (lcons ['g 'g] z)) it seems to wrok
11:48lvhj #python
11:48lvhOops.
11:49algernonRickInAtlanta: lcons takes two args, a head and a tail. (lcons [['g 'g] ['e w] [x y]] z)) => (((g g) (e w) (x y)) . z)
11:51RickInAtlantaalgernon yeah, so I think the two ways you expressed it are the same
11:51AeroNotixhow does the scheduling work with go blocks?
11:51AeroNotixI've got some code and it seems my go blocks are not executing
11:52RickInAtlantaalgernon: maybe my problem is in the next line (== (w (x y) z) r)))
11:52RickInAtlantaI tried writing that with vectors, I am going to try rewriting with lcons
11:53algernonthat line seems fine.
11:53algernonwell, mostly, a few ' here and there.
11:53algernonor, no, they're all LVars, nvm. that line should be correct with vectors.
11:54RickInAtlantaalgernon I think that is my problem, figuring out how to prevent the list from being evaluated as a function, but still allowing w x y z to be evaluated as lvars
11:54algernonvectors
11:54RickInAtlantayeah, as vectors, doesn't work
11:54algernonbecause your loto line is wrong :)
12:03RickInAtlantaalgernon: I appreciate the help... wondering now if I implimented loto wrong. More coffee, then lots of digging :)
12:04Raynesdevn: ping
12:05algernonRickInAtlanta: how's your loto line looking now? is it still (loto (lcons [['g 'g] ['e w] [x y]] z)) ?
12:05RickInAtlantaI tried it like that, and as the nested lcons like you suggested
12:06RickInAtlantaNow I am trying expressions combining loto and == to see if I can find where the disconnect is
12:06algernonmhm, in that case your loto may be wrong, yes. the nested lcons should work.
12:06algernonI'd try running the command, see what it returns, and compare it to the expected one, by hand
12:07RickInAtlantayeah, just breaking it into the small pieces and following all the steps. = good learning
12:10devnRaynes: pong
12:11Raynesdevn: It never occurred to me that you lived in Madison before. You should hang out with a friend of mine, Erik Price, who goes to college there.
12:11Raynes<3
12:11devnI will hang out with this friend of yours.
12:12RaynesI'll tell him I found him a new friend.
12:12Raynes;p
12:17devnmy internets are extremely slow
12:34gfredericksMadison is the Chicago of Chicago
12:38AeroNotixhttps://gist.github.com/AeroNotix/9927cc922e8c40c521fa I'm tring to spawn off a few goroutines which will launch filewatchers on directories. Not all of the watchers are being enabled. Can anyone see anything glaringly wrong with this? I wrote it pretty much how I would use Go's goroutines..
12:43devngfredericks: heh
13:03AeroNotixany ideas ^^
13:03gfredericksAeroNotix: does awizo/attach-handler block?
13:04AeroNotixgfredericks: yes
13:05gfredericksthis is not the intended use of go afaik
13:05AeroNotixThen why do people say it's used like the `go' statement in Go?
13:06AeroNotixHow are they scheduled?
13:06AeroNotixpreemptively or co-operatively ?
13:06gfrederickson a thread pool
13:06gfredericksand the point is that lexically inside the go macro you are using things like >! and <!
13:06gfrederickswhich is where the scheduling magic occurs
13:06AeroNotixDo these invoke cooperative scheduling?
13:07gfredericksin your case there is no scheduling
13:07gfredericksall you're doing is taking a thread pool thread and keeping it
13:07gfredericksso when all the threads are used up you can't run any more code
13:07AeroNotixWell, it'd be great if the docs mentioned this
13:07AeroNotixAll the videos/talks lead me to believe it was semantically the same as Go's concurrency
13:08AeroNotix,(doc clojure.core.async/go)
13:08clojurebotGabh mo leithscéal?
13:08AeroNotix:/
13:09gfredericksAeroNotix: the docs sort of mention it
13:09gfrederickskeyword is "visible"
13:10AeroNotixSo, what are my options for user-space threading in Clojure?
13:10AeroNotixpre-emptively scheduled
13:10AeroNotix(last
13:10AeroNotix(last thing is not 100% necessary but would be nice)
13:10gfredericksthis watcher lib can only work by blocking a thread?
13:10AeroNotixgfredericks: you can poll, too
13:12gfredericksoh this is your lib?
13:15gfredericksso the lib requires that to watch N files you need N threads polling
13:15gfredericksthat might be the place to tweak
13:16AeroNotixgfredericks: eugh
13:17gfredericksclojure doesn't have a way to grope the JVM internals and give you transparent green threads. async/go is just a macro that looks at the body of the macro and does a fancy transformation into a state machine
13:17gfredericksthen those state machines are run on thread pools
13:20gfredericksI would either incorporate core.async into the lib directly, or have it deal with handler functions from another thread so that it can be easily wrapped with async channel logic
13:21gfrederickshttp://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
13:32CigitiaI have a question—let’s say I have a macro: (defmacro aaa [expr] (if (-> expr first (= `clojure.string/lower-case)) (first expr) `(+ 5 3))).
13:32CigitiaThen (aaa (clojure.string/lower-case)) will expand to clojure.string/lower-case, which is what I want.
13:33CigitiaBut if I do (require '[clojure.string :as string]), I’d like (aaa (string/lower-case)) to expand into the same…but it’ll expand into (+ 5 3) instead, since string/lower-case does no equal clojure.string/lower-case.
13:34CigitiaIs it possible for the (-> expr first (= `clojure.string/lower-case)) to determine that string/lower-case is the same as clojure.string/lower-case?
13:34andyfCigitia: Maybe a use of resolve on the symbol will achieve what you want, and then compare the return value of resolve against the var #'clojure.string/lower-case ?
13:35CigitiaHmm…
13:36Cigitiaresolve seems to return a var. The problem with that, I think, is that I’m using this macro inside ClojureScript, whose vars I don’t think are available in Clojure macro expansion.
13:37CigitiaIs there a way to resolve the symbol into another symbol during macro expansion, but inside a ClojureScript namespace using its namespace aliases? Maybe some sort of double quoting–splicing thing, but I’m not sure…
13:46gfredericksCigitia: I'm curious what you're trying to achieve
13:49Cigitiagfredericks: I have a macro that wraps an expression in an outer expression. But the wrapping is unnecessary when the inner expression is a call on a certain function; I want the macro to just return the inner expression itself when it starts with that function’s symbol, whether it’s namespace-qualified or not.
13:51gfredericksthat sounds brittle/difficult/impossible to do at macroexpansion time
13:52gfredericksat least if you allow edge cases
13:52gfrederickswait scratch that; the thing I was thinking of is not
13:52CigitiaMm, yes. I think I might need to do something like (defmacro aaa [expr] `(let [inner-result# ~expr] (if (a-result-of-that-special-function? inner-result#) inner-result# (outer-wrapping inner-result#)), somehow using a new a-result-of-that-special-function? function, heh.
13:53CigitiaEr, that should be closed with a few more parentheses, heh.
13:53gfredericksdoing this at runtime is not acceptable?
13:55CigitiaThe reason why I’m not doing that is because that special function that I want to detect to prevent a redundant wrapping—it itself returns a function at runtime, so I can’t distinguish its results from other expressions at runtime.
13:55CigitiaI can modify that special function to return a data structure, though, which seems to be necessary in this case.
13:56gfredericksyou can also put metadata on functions if that helps
13:58CigitiaOh, that’s right; that should work. Thanks a lot!
13:58gfredericksnp
13:58gfredericksanother win for the first rule of macro club
14:00CigitiaI still need to make it a macro because the inner expression, when it needs to be wrapped, must not be evaluated at runtime before being wrapped. But I can still do the testing for whether it needs to be wrapped at all at runtime.
14:00CigitiaRight, this works; thanks again.
14:12dkinzerI'm seeing an unexpected behavior in how the repl behaves when I initialize one of two different forms which on the face of it look like they are equivalent. In one case I use (do ...) and in the other I use (doseq ...). These don't behave the same even though though I'm passing what appear to be equivalent expressions in the body: https://gist.github.com/dkinzer/8637554
14:12darklajidIf I have gazillion strings (and most of them are the same), do I need to nudge clojure to intern these strings to save memory? Is that even possible?
14:13gfredericksdarklajid: (.intern s) should return a canonical object
14:13AimHeredkinzer, doseq and do do very different things
14:14gfredericksdkinzer: oh man this is slippery
14:15AimHeredkinzer, hmmm, could it be that ns is a macro not a function?
14:15dkinzerAimHere: so for (doseq) I"m under the imprssion that I pass it a list and I can run an expression with side effects in the body expression.
14:15AimHereI did try (doseq [i <stuff>] (ns i)) and it namespaced me to 'i' which suggests that it doesn't evaluate the first argument at all
14:16dkinzerAimHere: It could be. I tried looking ath repl.clj on lein code but I couldn't really decipher it.
14:16clojurebotIt's greek to me.
14:16gfredericksyeah ns is a macro so that kind of programmatic use is not going to work
14:17dkinzerAimHere: yeah but then I tried (doall (for ..)) which apparently is supposed to force an evaluation and I get the same issue.
14:17gfredericksdkinzer: that doseq form won't work in a repl either
14:17RickInAtlanta,(doc ns)
14:17clojurebot"([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class .....
14:17AimHereCould you try writing a macro that evaluates to a list of (ns foo (whatever)) calls?
14:17eggheadAimHere: what do you expect that to mean?
14:18dkinzergfredericks: What I don't understand is why the (do) expression is working.
14:18eggheadare you trying to define many namespaces in a single form? clj is one ns per file
14:19dkinzergfredericks: Shouldn't they both fail? The are essentially doing the same thing.
14:19clojurebotGabh mo leithscéal?
14:19gfredericksdkinzer: because you have the ns name directly in the ns form in that case
14:19gfredericksdkinzer: this is confusing because of the difference between macros and functions
14:20dkinzergfredericks: Yeah, but if I don't pass the name as a symbol in the (doseq) body then it throws. I have to pass it in as 'namespace
14:21dkinzerI would love to be able to use the (doseq) becuase without it I'm doing a bunch of repitive calls to (ns ) but with different arguments. It looks ugly.
14:24pyrtsadkinzer: Did you check in-ns?
14:24gfredericksdkinzer: your goal is to have some special namespaces created every time your repl starts?
14:24pyrtsa,(in-ns)
14:24clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: >
14:24pyrtsa,(doc in-ns)
14:24clojurebot"([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."
14:25dkinzerpyrtsa: hmmm I don't remember. Maybe I'll give that a try.
14:27dkinzergfredericks: Acutaly my goal is get the repl to work nicely with the clojure-koans and vim-fireplace. Using the (do) expression fixes the issue but it's not nice and I want to make sure that I can explain to the clojure-koans maintainer that I tried all the options.
14:28dkinzergfredericks: one thing I tried that should have worked was to just add the (ns) expressios directly to the koan files but this only gets me half way. And the repl server still throws.
14:29AeroNotixgfredericks: sorry I didn't reply, power cut
14:30AeroNotixSo, ok, I can rewrite all this to use purely channels with polling events. Thus allowing the go blocks to schedule
14:30AeroNotixYeah I didn't know that the go blocks *required* channel reads to schedule.
14:30AeroNotixGo is a little similar (or at least) was in this regard.
14:32gfredericks,(macroexpand-1 '(ns foo (:use bar)))
14:32clojurebot(do (clojure.core/in-ns (quote foo)) (clojure.core/with-loading-context (clojure.core/refer (quote clojure.core)) (clojure.core/use (quote bar))) (if (.equals (quote foo) (quote clojure.core)) nil (do (clojure.core/dosync (clojure.core/commute (clojure.core/deref (var clojure.core/*loaded-libs*)) clojure.core/conj (quote foo))) nil)))
14:33gfredericksdkinzer: why do those namespaces being created make the repl play nicely/
14:33gfredericks?
14:36dkinzergfredericks: sorry was trying out (in-ns) wihtout luck. It throws.
14:37dkinzergfredericks: For one there is a function defined in koan-engine.core called meditations that has to be in scope when any evaluation happens on a koan file via vim-fireplace.
14:38gfredericksare you creating one namespace per koan?
14:38gfredericksfrom the project.clj?
14:39dkinzergfredericks: well.. that's only part of it. The weird thing is that I can get the same result if I add the (ns expression directly to the koan file). But what is different from the (do) expression as an option passed in via project.clj is that it wont throw even though technically all the koans should fail before they fixed.
14:40gfredericksyou want an exception thrown from your repl init code?
14:41dkinzergfredericks: The oppossite. I don't wan the exception thrown because this makes vim-fireplace fail completely.
14:42dkinzergfredericks: So when it works properly I can for instance do a doc lookup from inside vim on any function.
14:43abaker_say is there a way for incanter to deal with column names with spaces, e.g. in canter you can do (with-data … ($ [:col-name]), where col names are automatically turned to keywords. Works fine when the column name doesn't have a space, but not sure how it handles the keyword-ization of column names with spaces in it
14:43dkinzergfredericks: The funnny thing is that I kind of stumbled onto the fix becuase it doesn't make any sense why it should matter where and how that (ns) expression is loaded. But for whatever reason it seems to. Though it's ugly.
14:46dkinzergfredericks: I have pull request in at https://github.com/functional-koans/clojure-koans/pull/68 there is another one that addes the (ns) expressions direclty to the files but like I said that doesn't actually fix my issue.
14:51gfredericksdkinzer: so the intention is that the user opens a file and then evals the file to run the code?
14:54dkinzergfredericks: yes that, which should fail (of course); but also be able to do partial evaluations which should pass (espcially... (doc ). It's the second part that fails with the former strategy but all works using just the (do) expression like I have in my PR
14:54dkinzergfredericks++
14:55dkinzerI'm not sure I'll get the bottom of this, but I'm very glad for your imput and for that matter everyone else who has tried helping me :)
14:57RickInAtlantadkinzer: just want to make sure, you are trying to do an experiment to use repl with koans, and not just trying to do koans, right?
14:57dkinzerOn a side note. I've noticed a lot of exception thrown that essentially say Class such and such could not be found when you pass it in a namespace. That confuses me becuase I thought there aren't any classes in clojure.
14:58gfredericksclojure's written in Java and does not try to hide it
14:58dkinzerRickInAtlanta: correct.
14:59gfredericksdkinzer: yeah your approach is ugly, as you noted, and haxy in ways that are hard to explain. I definitely expect there's something better but I'd have to understand the structure of the koans code better and how it's expected to be used
14:59scape_anyone use korma? I don't understand how I am supposed to use the connection-pool function? I want to set idleConnectionTestPeriod manually
15:00gfredericks,(class :foo) ;; dkinzer: classes in clojure :)
15:00clojurebotclojure.lang.Keyword
15:02dkinzer,(class ns)
15:02clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/ns, compiling:(NO_SOURCE_PATH:0:0)>
15:02dkinzer,(class in-ns)
15:02clojurebotclojure.lang.RT$1
15:02dkinzer,(class do)
15:02clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:03dkinzer,(class doseq)
15:03clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/doseq, compiling:(NO_SOURCE_PATH:0:0)>
15:03dkinzer,(class 1)
15:03clojurebotjava.lang.Long
15:03dkinzerOK.
15:11benmossanyone seen the "Uncaught TypeError: Cannot call method 'call' of undefined" exception coming from core.async in Clojurescript?
15:11benmossi saw this thread but i double-checked my core.async and clojurescript versions and seem to both be latest
15:11benmosshttps://groups.google.com/forum/#!msg/clojurescript/P902i4FKA4w/3ndE9ax62_gJ
15:12benmossthe stack trace just points to my (go (while true)) line that reads from the chan
15:12dkinzergfredericks: Thanks for your help. I have to put this aside now. Cheers.
15:12carkbenmoss: when i had this kind of error, a "lein cljsbuild clean" helpe
15:13carkhelped
15:13benmossill try that
15:13benmossi had tried just manually deleting the compiled JS
15:13scape_anyone use korma? I don't understand how I am supposed to use the connection-pool function, I want to set idleConnectionTestPeriod manually
15:13carkbenmoss: the cullprit is the out directory
15:14benmossor 'target'?
15:14carkbenmoss: depending on your setup =)
15:15benmosshmm yeah i was deleting that too, and it still is erring after 'lein cljsbuild clean'
15:16carkoh but if you're refering to this post for latest verion, you're in the wrong
15:16carkthe best way is to use search.maven.org
15:16dnolenbenmoss: it nearly always means you've called something that doesn't exist, generally you get compiler warnings about this
15:16benmossoh no i am not
15:16carkand search for latest clojurescript and core.async
15:16benmossi'm on cljs 0.0-2138 and core.async 0.1.267.0-0d7780-alpha
15:17benmossdnolen: no compiler warnings :(
15:17dnolenbenmoss: post a complete gist of what isn't working for you
15:17carkbenmoss: that's latest afaik
15:19benmossdnolen: if you don't mind the whole repo, https://github.com/benmoss/chess . the repro step is just to click on any of the pieces
15:19seancorfieldcljx question... just trying it out for the first time and when i run lein cljx, it tells me it is transforming my source but doesn't create the output files...
15:19dnolenbenmoss: I'm going to look at a whole repo
15:19dnolenbenmoss: you need to replicate this in the small
15:19carkdnolen: missing a not somewhere =)
15:20benmossyeah i think you meant *not* going to look at a whole repo?
15:20dnolenbenmoss: sorry I'm not going to look at something w/ that much context
15:20benmossok
15:20benmossi understand its just effort to boil it down
15:20seancorfieldhere's my project tree and project.clj and the output of lein cljx https://www.refheap.com/28087
15:21carkdnolen: while you're here, I wanted to ask you something. There is no extend in clojurescript, right ?
15:21dnolencark: no
15:21carkdnolen: allright, i've seen there was something to do it on a per instance basis
15:22carkdnolen : actually forgot the name... but anyways, it doesn't work with function maps
15:22carkdnolen: so in clojurescript there is no way to do mixins ?
15:22dnolencark: specify exists today, and the scope is much smaller than some of the things that were propose
15:23carkright that was specify =) ... but it doesn't work at all like extend, it's more like extend-type or extend-protocol for instances
15:23dnolencark: exactly, there is nothing at all like extend in CLJS
15:25carkdnolen: allrigth, so how would it be possible to add code and functions to an instance (a per instance mixin if you will) ?
15:25carkdnolen: or is it what specify does ?
15:25dnolencark: you can use specify provided the instance implements ICloneable
15:26carkdnolen: mhh i will consider that, thanks !
15:38benmossi knew it'd happen, but i attempted to boil down the bug and it doesn't happen anymore :)
15:38RickInAtlanta:)
15:46benmossthis is the fun "checkout to known good state, still broken" kind of bug
15:47benmosshrmm
15:52carkdnolen: one last question, oes ICloneable nee to implement deep cloning or shallow is good enough ?
15:52carkneed*
15:53dnolencark: for Clojure data structures shallow cloning is deep cloning
15:53dnolencark: JS data structures are out of luck
15:53carkdnolen: so I need to deep clone JS data ?
15:53dnolencark: if you don't want bad things to happen in your program that don't make sense
15:54carkdnolen: what if it is newly created data, like in a make-my-data function
15:54carkeverything fresh and new
15:55dnolencark: it's fine if you can guarantee it won't leak
15:55carkdnolen: allright, thanks again
15:55carkdnolen: if you ever come to belgium i owe you at least a full barell of beer already
15:56dnolencark: haha, will take you up on that if I'm ever in the neighborhood :)
15:56cark=)
16:03seancorfieldno one using cljx?
16:04seancorfieldwould it be better to post the to clojure list or the clojurescript list do you think?
16:11gufo__Hi ! can anybody give me a hint how to deal with unsigned int 32 in clojure ? ( the root of the question is icfp contest 2006, I'm trying to reimplement the vm)
16:12dnolenseancorfield: lots of people using cljx, best directed at cljs mailing list I think
16:15eggheadif I have a seq of maps, what is the simplest way to provide a map to 'join' (filter) by ?
16:15devnis it possible to specify the type of keys a defrecord will use on creation?
16:15devnif you want new records to be created with keys as strings for instance
16:15seancorfieldthanx dnolen - email sent... i'm sure i'm just doing something dumb
16:16eggheadlemme take a peek seancorfield
16:17eggheadah seancorfield
16:19eggheadseancorfield: I think you want to type 'lein cljx once'
16:20seancorfieldno, chas spotted it on the mailing list immediately: my cljx file was named clj instead :(
16:20eggheadoh, derp
16:20seancorfieldI knew it would be a stupid mistake... Didn't think it would be _that_ stupid tho'!
16:21eggheaddnolen: have you tried core.match with om yet?
16:21seancorfieldMy first foray into cljs with shared code!
16:21dnolenegghead: I haven't
16:22eggheadseancorfield: i like cljx + prismatic, share resource schemas between client and server :)
16:23piranhadnolen: sorry, maybe I don't understand something, but it seems that in will-update next-props contain exactly the same data as (get-props owner), while I expected them to be different
16:23skyl(def stooges ["Moe" "Larry" "Curly" "Shemp"])(some #(instance? Number %) stooges) ; I'm curious why this is nil instead of false
16:24piranhadnolen: or to put it other way: can I get difference of my state between render calls? I'm trying to integrate with an existing library and I need to remove/add things by hand
16:24piranhadepending on their presence in my state...
16:24eggheaddnolen: I'm playing with using it for event handlers in om
16:24dnolenpiranha: I'm pretty sure that isn't the case, but if you can create a minimal example that demonstrates this that would be helpful.
16:24eggheadrealizing i am using cljs core async, core.match and om ... THANKS
16:25skylnvm, I googled it https://groups.google.com/forum/#!topic/clojure/JHGozQzOwFQ ..
16:25piranhaok, not today then :) time to sleep already, just thought that could be a small misunderstanding of the code :)
16:25piranhaegghead: how do you use it? :)
16:26dnolenpiranha: if you look at the Om source I just take nextProps from React and pass it on
16:26dnolenpiranha: not saying there isn't a bug of course
16:27piranhadnolen: yeah that's what I saw, so I'm quite confused right now as you can imagine :)
16:27piranhasure, I'll try to replicate that in a smaller project tomorrow
16:27eggheadpiranha: nothing special on the cljs side yet re: core.match, just using it as a fancy condp =
16:28eggheadom took me a while to wrap my head around but it's really cool once it clicks
16:28piranhait is :)
16:28benmossdnolen: figured it out, it was coming from using om/read still. didn't read your changelog announcement closely enough, and your todo-mvc example still uses it
16:29piranhato be honest that's mostly react being cool though :)
16:29dnolenbenmoss: I updated todo-mvc for 0.3.0
16:29eggheadhey dnolen fyi the current version of om pushed doesn't have IDeref
16:29eggheadon MapCursor
16:30eggheadmaster works wonderfully tho
16:30benmossegghead: I am using it right now so I believe it does
16:30dnolenegghead: pretty sure that isn't true since I've tried it several times
16:30egghead:O
16:30benmossyou are probably having the same issue I had which was you have to delete the target directory
16:30benmossor perhaps the compiled js directory, I'm actually not sure which one was the right thing
16:30eggheadaah benmoss
16:31eggheadya lemme try a cljsbuild clean
16:32eggheadyup, derpin on my end again
16:33eggheaddo core async chans get gc'd ? if I init them in an om component and then that component gets unmounted?
16:35sobelnoob question: what is the var function? i don't follow what the Var object does
16:36skyl(def more-stooges (conj stooges "Shemp")) ; -> ("Shemp" "Moe" "Larry" "Curly") .. I'm using 1.5.1 and it seems that conj appends in this case rather than prepending as the tutorial says here .. did this change?
16:37carkstooges is a vector
16:37carkconj acts differently depending on the collection it works with
16:38dissipatecark, what happens if you conj a vector vs. a map?
16:38carkif you conj on a map, you get a map, that's not specifically ordered
16:38carkconjing on a vector adds to the end, on a list to the begining
16:39dissipatecark, BTW, have you ever run into performance issues with Clojure's built in data structures?
16:40carki wouldn't mlake a game with clojure, but it's fast enough for anything business related
16:40Wild_CatI'd probably write a game *server* in Clojure, though.
16:40carkWild_Cat: yes
16:40sobeli would write a web game in clojurejs
16:41dissipatecark, why not? people are making games with Python (e.g. PyGame). clojure is higher performance than python, no?
16:41dissipateWild_Cat, wouldn' t you write a game server in Go?
16:41carkdissipate: it is. We discussed that last week, it all depends on the type of game =)
16:41tbaldridgedissipate: it depends what you call a game. For example, EVE Online is mostly Python in the engine and client, but all the GFX is C++
16:42dissipatetbaldridge, sounds like Panda3D which has Python wrappers for the underlying C++ API.
16:42eggheadanyone know how you'd test something like om?
16:42tbaldridgeEven the, World of Warcraft uses Lua for tons of stuff, but none of it is engine related.
16:42carki'm not holding my breath for waiting for the next clojure FPS =)
16:42Wild_Catdissipate: because the JVM is a rock solid runtime with pretty much any lib I'd want to use, Clojure is a pleasure to write and Go's neat ideas have been ported to it as core.async.
16:43Wild_Catalso, no need to bother with cross-compilation and dependency management because Leiningen and Maven kick ass.
16:43carkgo has some weirness to it too
16:43dissipateWild_Cat, where does Haskell fit into all this?
16:43carkweirdness*
16:43tbaldridgedissipate: don't say the H word...
16:43tbaldridge:-P
16:43Wild_Cat(also, Clojure's emphasis on immutability is great)
16:43dissipatetbaldridge, sorry. :P
16:44Wild_Catdissipate: the Haskell ecosystem is meh, and every time I've tried to use it I've found most documentation hard to read and the community far too deep into its own academic arse.
16:44dissipateWild_Cat, well, Docker should be eliminating all that anyways.
16:44sobelDocker will eliminate what?
16:44dissipatesobel, dependency management.
16:44tbaldridgedissipate: for me, the big "win" for Clojure is immutability + being a dynamic lang. No other language has the correct combination of a fast JIT, GC, immutability and dynamic typing.
16:44sobeldissipate: wrong layer
16:44Wild_Cat(generalized abstract arrow combinator combinator transformer combinator meta-libraries)
16:45dissipatesobel, have you used docker? seems like a godsend for deployment.
16:45sobeldissipate: yes, Docker is my other new learning thread. it's pretty awesome.
16:46Wild_Catdissipate: however, I still think Haskell's type system is second to none.
16:46dissipatesobel, the possibilities for deploying super lightweight linux desktop apps seems quite interesting
16:46Wild_Cattypeclasses are an awesome idea.
16:46sobeldissipate: but i'm not seeing that i would want to delegate jar/clojar management to Docker containers when i sorta consider that something that should be in the programmer's hands
16:47Wild_Catsobel: tbh I doubt the JVM ecosystem is the one where stuff like Docker yields the highest gains, because dependency management in Java/Clojure is a solved problem, thanks to Maven/Lein.
16:47Wild_Catnow in *Python*, though...
16:47sobeldissipate: yeah, i have some plans for making a 2-4 layer set of host containers for our main app at work. layers to rope it dev/qa stuff.
16:47dissipatesobel, clojars could be docker images that spin up a service that you connect another container to. that way the author of the clojar can have their library run *as intended* in the environment they developed it in.
16:48bbloomWild_Cat: "dependency management" and "solved" in the same sentence? lol yeah ok
16:48sobeli know there's a lot of ways to do it, i hadn't really applied a lot of time or thought to using Docker for java deployment yet. i'm real green at Docker but i have an instance running on my VM.
16:48bbloomWild_Cat: the JVM is only marginally less bad than some other things
16:49Wild_Cat(Python packaging, distribution and deployment are a nightmare)
16:49bbloomdependency management is bad everywhere
16:49sobelbbloom: +1
16:49bbloomhere we use (inc name) :-)
16:49dissipateWild_Cat, what is the equivalent to virtualenv for clojure?
16:49sobellet's not turn ideologue over dep management. it's a mundane and ugly task but it's gotta be done right
16:49Wild_Catdissipate: intuitively I'd say lein uberjar.
16:49tbaldridgedissipate: it's not needed, as you can specify all that in a project.clj file
16:50ivandependency management will be solved when you have some guarantee that the jars you're running have any correspondence to the source
16:50Wild_Catbut what tbaldridge said.
16:50bbloomsobel: the best/simpliest solution on the JVM, just as it is anywhere else on unix, is to put all dependencies in a directory and use CLASS_PATH or similar
16:50bbloomit's far from ideal & many better solutions are available, but it's predictable and trivially simple
16:50sobelbbloom: inorite? i am so not about system installations of jar libraries. that never made sense to me.
16:51dissipatebbloom, and what about non-java depdendencies, such as stuff you run from /usr/bin?
16:51Wild_Catdissipate: the reason we need virtualenv in Python is twofold: 1. The default installation method for Python libs/programs is centralized/systemwide with no conflict resolution; 2. There is no default way to *uninstall* a Python lib/app
16:51sobelsame with system tomcat instance. wtf? do deb package maintainers even...java?
16:51carkthis docker thing is unix only =P
16:51Wild_Catand 3. Python 2 has no stable ABI, meaning that dependencies with C extensions need to be recompiled when you upgrade your Python version.
16:52sobelcark: really new linux only, too
16:52Wild_Cat(of course it's supposed to be a solved problem in Python 3, but, y'know. Python 3.)
16:52dissipatecark, good luck porting Docker to proprietary OSes like Mac OS and Windows.
16:52carkahwell it sucks then =)
16:52sobelI'm here because python is neat but not neat enough
16:52sobelI'm confident Docker has the attention of other OS makers
16:52dissipatecark, you realize that is a problem caused by the corporations developing those OSes, right?
16:53Wild_Catoh, and just for the fun of it, 4. Python installation scripts are imperative Python programs, making it really hard to analyze how any of this works.
16:53carki code my clojure stuff on windows, an deploy as is on solaris
16:53sobelIt's a really smart step in virtualization
16:53tbaldridgeI write my code on Irix and deploy to Windows 98
16:53sobelcark: i do that too. i love jar portability.
16:54carksobel : haha yes ; install instructions are "drop the jar somewhere, launch it"
16:55dissipatecark, and non-java deps?
16:55sobelso, i can make an executable clojar, right? :)
16:55sobeldissipate: bad style ;)
16:55dissipatesobel, /usr/bin stuff?
16:56carkdissipate: i'm half jocking, but it certainly is the instructions for upgrading
16:56carkkill java, replace jar, launch
16:57dissipatecark, you do realize there are non-java deps that have to be deployed in a lot of cases?
16:58carkyesss
16:58dissipatecark, so i don't see how jar files eliminate the need for a virtual environment or something like docker
16:58carklike postgres =(
16:59carkdissipate: since i can't use it on solaris, the need is completely eliminated
16:59Wild_Catdissipate: an uberjar is a self-contained version of your app (including all its Java deps), meaning you don't need a virtual environment at all.
16:59carknow why the customer is using solaris, i really can't tell
17:00Wild_Catas for non-Java deps... Yeah, that sucks. And it sucks even worse that a lot of those have to be deployed on different boxes entirely.
17:01Wild_Catand it's often up to your devops guy to make that process simpler.
17:01dissipateWild_Cat, sounds like a better way to go. :P
17:01carkright, if they want virtualisation, let them do it
17:02dissipateWild_Cat, or if you have a good PaaS, it will do that for you from a config file. isn't this the age of NoOps? :P
17:02Wild_Catdissipate: yeah, figures. ~The Clouuuuuuuuud!~
17:06dissipateis there a clojure equivalent to capistrano or fabric?
17:09sobeldissipate: thing is, it depends on how much of that deployment is system/static and how much is subject to change in the hands of developers. there's a role-responsibility transition, going from dev to deploy
17:10sobelfor example, i'll be really glad to have Docker containers ready to run my java apps: vm installed, native bits if any, whatever else i deem is part of the app container. then i'll stuff jars into that container. same container can host most any java (server) app.
17:12bbloomdissipate: pallet is probably the closest thing
17:13dissipatesobel, well, in theory you should have 1 container per app/database engine. docker reuses base layers of the images anyways, and the processes run on the host machine directly.
17:14dissipatethe problem with docker right now is that i don't think it's fit for all use cases due to lack of other tools to manage the containers properly, and i'm not even sure if it's even stable yet.
17:14sobeldissipate: i know i'm butchering the specific terminology
17:15sobeli've seen a recipe for deploying a nodejs app straight to docker
17:16dissipatesobel, yep, there are tons of recipes for docker. a number of projects on github now have a docker file in the repo to build a docker image for the app.
17:17dissipatesobel, from an ops perspective though, managing all the containers could turn into a nightmare. you could have hundreds or thousands of containers running god knows where. there are management tools like Shipyard, but outside of a PaaS type setup, nothing that's automated.
17:19technomancyspeaking of non-java deps, we could use some help from someone who uses native deps in leiningen to get them documented for the next release
17:19technomancyafaik none of the regular contributors use native deps, so while they technically work their use is not documented at all
17:31alewtechnomancy: how do native deps work?
17:33sobeli figure the same JNI policy applies to clojure as to java
17:33sobelwhich for my use, means there are none
17:45kristofOh! Just had a thought
17:45kristofporting Clojure to SBCL. That could be interesting (and introduce tail call optimization)
17:45kristofAnd you'd get this lovely lisp clojure interop
17:45kristof...and reader macros! But I digress.
17:45technomancyalew: specifically in Leiningen, it looks inside all the jars and extracts .so files, etc appropriate for the current platofrm/architecture into target/ and sets a specific native load path to match
17:50AeroNotixkristof: and what features of SBCL is there that Clojure doesn't really have?
17:50AeroNotixbesides the obvious like CLOS and restarts
17:51carkAeroNotix: what does clojure really have besides macros and persistent data structures ?
17:51cark=P
17:51AeroNotixcark: concurrency primitives
17:51carkand that !
17:52AeroNotixBut with interopping with the JVM/CLR you get access to a wealth of standard library stuff, with SBCL... the standard library is pretty meh, open-source code is all over the shop and there's a very small number of people trying to fix that issue (Xach e.g.)
17:52AeroNotixQuickLisp came out 20 years too late
17:52carkAeroNotix: there's the tail call optimization
17:52AeroNotixcark: clojure has recur\
17:53carkthat's really a problem with clojure
17:53carkclojure is for tail recursion
17:53carknot general tail call
17:53AeroNotixFWIW, there's nothing about Common Lisp which states it must have TCO.
17:53carknope but all implementations have it
17:53AeroNotixWrong
17:54AeroNotixCLISP doesn't really have it
17:54carkthose that i know about
17:54carkah possible, never really used that one
17:54AeroNotixIt's pretty popular
17:54carki've been using mainly lispworks
17:54AeroNotixWhy?
17:54hyPiRionI haven't actually found a place where it really is a problem, except for DFAs maybe. Perhaps I'm working on the right type of problems
17:54clojurebotWhy is startup slow is busy compiling the `for` macroexpansion
17:54devnAm I missing something, or is this weird given the docstring?
17:54devn,(with-meta {:x 1 :y 2} {:a 1})
17:54clojurebot{:y 2, :x 1}
17:54carkAeroNotix: it's nice on windows
17:54devnbah, nevermind
17:54AeroNotixcark: lolwat
17:55AeroNotixDevelopment on windows with a fringe language, do you hate yourself?
17:55carkAeroNotix: it served me well =)
17:55carkAeroNotix: and support was top notch
17:55AeroNotixI'm sure some people can make it sing
17:55AeroNotixI just feel dirty thinking about it :)
17:56AeroNotixcark: so aside from TCO what do you want by putting Clojure on SBCL
17:56carki don't specially want it, but if you put aside every goodie, then there's no reason to ever target any platform
17:57carki've been bitten with TCO while doing monad stuff in clojure
17:57AeroNotixI didn't put aside any goodie, CLOS is not a good reason to switch, really.
17:57AeroNotixcark: sounds like you were programming clojure wrong
17:57carkCLOS is fantastic =)
17:57AeroNotixDunno if "monad support" is a big Clojure feature :)
17:57carkit isn't ...because of TCO
17:58carkbut hey, i'm here, so yes i find clojure very nice =)
17:59AeroNotixWell, there is that guy on reddit
17:59kristofAeroNotix: A variety of things, many of which have just been stated. Reader macros, TCO, CLOS, MOP, restarts/handlers, and some nice special control operators that are in the CL standard
17:59kristofAeroNotix: But more importantly, I really like Common Lisp, and I really like Clojure. So: "why not both? :D"
18:00AeroNotixthen go for it, I watch sbcl on github, it's pretty actively developed
18:00carkthe loop macro (*hides*)
18:00AeroNotixcark: now you're just trolling
18:00carkhehe yes i must confess
18:02AeroNotixNot saying that `loop' isn't very useful
18:02kristofAeroNotix: SBCL itself, or a SBCLclj (made up the name)?
18:02AeroNotixkristof: SBCL itself
18:02kristofAh, well, I'm already a regular user and I sometimes read Christophe's blog posts about computational adventures related to SBCL :)
18:03carkAeroNotix: wouldd you consider clojure to be a fringe language too ?
18:03AeroNotixcark: Not really
18:03carki think not anymore
18:03AeroNotixcark: here in Krakow there are a lot of Clojure shops it seems
18:03AeroNotixWe're an Erlang shop and we just started a portion of a new project in Clojure
18:04AeroNotix(primarily for JVM interop because reasons)
18:06AeroNotixand coming from Erlang clojure is *such* a breath of fresh-air
18:06AeroNotixthe productivity boost the JVM libraries give is crazy
18:06carkthe syntax of erlang is just terrible
18:07pdurbinAeroNotix: which libraries?
18:07AeroNotixcark: Lies.
18:07carkAeroNotix: who's trolling now ?
18:07technomancyit's no lisp, but it's nicer than C descendents
18:08AeroNotixcark: when you program Erlang for a while you start to see why it's the way it is. It has pattern matching built into the very core. You need to make syntactic allowances for that.
18:08AeroNotixAnd pattern matching is a great way to program.
18:08AeroNotix(Not played full with core.match, yet)
18:08AeroNotixpdurbin: the main one is Authorize.net's SDK which is why we chose Clojure for this project.
18:09AeroNotixI'll end up releasing a clojure wrapper for it eventually, but it's inside our codebase at the moment. Probably will do the same for the PayPal SDK later this year, too.
18:11AeroNotixpdurbin: indeed.
18:11AeroNotixpdurbin: we need to integrate with that.
18:11AeroNotixTerrible documentation, SOAP/xml interface, they provide a Java SDK. So we went with that
18:11AeroNotixthe alternative is to somehow figure out their API from very poor docs and write soap calls in Erlang (not fun!)
18:12pdurbinAeroNotix: sounds like you're pretty happy with clojure's java interop then
18:12AeroNotixpdurbin: very much so
18:12AeroNotixit's been a lifesaver
18:12AeroNotixlein's very cool as well, compared to rebar it's on a whole different level
18:13AeroNotixe.g. rebar's so dumb that if a project's dependency changes location, it won't do anything / detect this, despite clearly having access to all pieces of information
18:13AeroNotix(rebar is unfortunately the de facto Erlang 'package manager', if you can call it that)
18:14AeroNotixI had so much fun this week
18:16pdurbinthe groovy and scala interop with java I saw in a talk at java one kinda scared me. seemed brittle and weird: http://irclog.greptilian.com/javaee/2013-09-26#i_25930 ... "have to go to `ls` to figure out to use ScalaClass$.MODULE$.greet()"
18:16pdurbinbut I don't really know what I'm talking about
18:17AeroNotixnever looked at either in depth, Scala just seems like:
18:17AeroNotix"Let's put all our ideas into a hat, shake it up, take them all out and implement them in that order"
18:19pdurbin"If you like programming languages and food, here's the culinary equivalent of Scala" -- https://twitter.com/bos31337/status/425524860345778176
18:19gfrederickstrying to do your own OOP on top of java's is inevitably confusing
18:19AeroNotixpdurbin: :)
18:28pdurbinC++ is to C as Scala is to Java, right? a bridge... some familiar stuff, some new stuff (functional programming)
18:28bbloompdurbin: that's how i see it
18:29carki would argue that idomatic c++ is nothing like c
18:29AeroNotixYeah, they're completely different languages.
18:29bbloompdurbin: i dislike both raw java and raw C, but i much rather use them over scala and c++ for their respective use cases
18:29AeroNotixbbloom: +1
18:34gfrederickspdurbin: nice analogy
18:35gfredericks(inc pdurbin)
18:35lazybot⇒ 1
18:40dobry-denhttp://clojure.org/agents says that observation of the state of an agent (deref) is always immediate since it demands no cooperation/coordination. Is that not that case for Atoms?
18:44bbloomdobry-den: it is the case for atoms. it only points it out to clarify against the fact that the agent is otherwise asynchronous
18:47dobry-denbbloom: thanks
18:48dobry-denalso, is it correct that you should only contain the computation within a `swap!` that deals with the old value of the atom, and any other computation should happen outside of it?
18:49bbloomdobry-den: rather than answer yes/no, i'll say that the function given to swap! may be re-run several times if a faster swap! occurs while it's working
18:51bbloomdobry-den: if the nature of a compare-and-swap isn't second nature to you, then it's pretty likely that you're not coding something that is going to be crazy high volume contentious writes... so just focus on correctness, not performance
18:52bbloomdobry-den: with respect to correctness, anytime you see more than one @ you should be weary that they may be inconsistent in the face of concurrency (somebody writes between the reads) and you should prefer to move more logic inside the swap function
18:52bbloomdobry-den: does that help?
18:54dobry-deni see. basically, my case is that my use of noir.util.cache/cache! on my homepage is holding up everyone whenever it's invalidated (and someone makes it recalculate)
18:54dobry-den(https://github.com/noir-clojure/lib-noir/blob/master/src/noir/util/cache.clj#L30)
18:55bbloomdobry-den: without studying closely, i'd be concerned about that code. it really should only deref once
18:56bbloomdobry-den: ah ok and i see the problem you're talking abouyt
18:56bbloomdobry-den: seems like it renders stuff inside the swap function
18:56bbloomprobably a bad idea
18:56dobry-den(cache! "stats/post-count" (db/get-total-post-count))
18:56dobry-denseems like that holds everyone up when it's invalidated
18:56bbloomyeah
18:57bbloomwhat it should be doing is swap!-ing in a flag that says it's pending & then send that work to a queue & then block on a delay for the result
18:57bbloomif other threads ask for the same id, they will see a pending flag & then get the same delay object
18:57bbloomwhen the work is finished, all the delays will be released
18:58bbloomthat prevents duplicate work and also does minimal work inside the swap
18:58bbloomdobry-den: does that make sense?
18:59dobry-denyeah. it seems that for such a simple cache (like displaying total post count), you want users to just deref something without doing any logic, and rather do the swap! in a background thread. like something that runs every 10 seconds.
19:02dobry-deneven a (go-loop [] (<! (timeout 10000)) (swap! cache <recalculate>) (recur)))
19:03gfrederickshuh...core.async as just a scheduler?
19:03warzis there a clojure socket library, or do i just use java interop?
19:04dobry-denwarz: Sockets with java is great
19:07dobry-dengfredericks: i'm so naive here but it's what i have come up with so far for such a trivial thing. (alts! [invalidator (timeout 10000)] ...) would be the logic for (recalc every 10 seconds unless you manually invalidate it).
19:08gfredericksdobry-den: seems legit
19:09gfredericksI just realized I'm using core.async in production o_O
19:09gfredericks(the weird part being that I only just now realized it)
19:10dobry-deni considered http://clojurequartz.info/ but it was heavier than what i needed. and the only way i could think of doing it would be to hit an http endpoint like "/flush-cache"
19:11pdurbincark: your point about idiomatic c++ is well taken
19:19pandeirois there a way to exclude files in cljsbuild?
19:19rtyerCould someone help me wrap my head around a problem parsing xml into a usable map? I'm using clojure.xml/parse with the goodreads api and have a very nested structure (maps and vectors) of :tag/:content. I'd like to transform it so that I have a map with a key of every :tag value and a value of every :content value.
19:19rtyerfairly new to clojure so not exactly where to start looking on how to transform this
19:20pandeiroi want to keep my *_spec.cljs files right next to my actual cljs, but they cause runtime errors if included in the app's output b/c of jasmine stuff
19:29reyttThink I may have found the answer to my question with org.clojure/data.zip.
19:54_ericwhat is the idiomatic way to iterate over a sequence when I don't care about the result?
19:54_eric(map) seems excessive
19:54_eric(doseq)?
19:56S11001001_eric: dorun
19:59_ericI don't think I'm asking the question very well. I guess I want to run some code based on each of the things in the seq
19:59_ericlike Enumerable#each in ruby
20:01ivandoseq then
20:01rplaca_eric: if you don't care about the result, dorun is what you want
20:02rplacaor doseq to specifically enumerate elements of the seq
20:03_ericit seems like using (for) here is not the right thing to be calling: https://github.com/papertrail/slack-hooks/blob/master/src/slack_hooks/service/mandrill.clj#L53-L57
20:03rplaca_eric: I said that badly: I think doseq is what you want
20:05rplaca_eric: yeah, that "for" is lazy *and* it retains all the results
20:06_erichah
20:06rplacahowever, that may not matter because the prn will force evaluation (and why do you say you don't care about the result if you're printing it?)
20:07_ericI believe the (prn) was added to figure out why the (for) wasn't doing what was expected
20:07_ericand I believe the thing that wasn't expected was that the (for) was lazy
20:07_eric(lols all around)
20:07rplacaah-ha. when laziness is the problem, printing can confuse the issue (by forcing evaluation that was otherwise never forced)
20:07_ericdoes this (for) make sense over being a (map)?
20:07_erichttps://github.com/papertrail/slack-hooks/blob/master/src/slack_hooks/service/mandrill.clj#L33-L42
20:08rplacafor and map are really two ways of saying the same thing
20:08_eric(I'm asking as for as what someone experienced would generally do in that situation)
20:09bitwalkerThe semantics are usually slightly different though, for consuming a collection versus transforming elements of a collection
20:09rplacaexcept that map evaluates the collections "in parallel", that is (f (nth a 0) (nth b 0)), (f (nth a 1) (nth b 1)), etc
20:10bitwalkerGood point
20:10rplacaand for uses its bindings combinatorically
20:10_ericso (map (fn [event] ...) my-seq) would be a better way to do it
20:10rplacawhich to use is more a matter of taste in different situations, I would say
20:11_ericthough in this case, neither are going to really hurt/help me
20:11rplaca_eric: the map would be the same in this case
20:11_ericokay
20:11rplacaI would say that the for is *usually* preferable in this case
20:12rplacabut really doseq is what you want :)
20:12_ericyeah, I'm going to fix the bottom use of for to use doseq
20:12_ericjust trying to figure out if I should change the upper use of for to use map (or something else)
20:13warzwhy are there so few results for "clojure irc client" on google? thats like the hello world of the internet
20:13rplacagenerally, when you want side effects, use doseq unless you have a compelling reason to build a lazy sequence (cause you want to use HOF operators or something) in which case force the sequence with dorun after you've created it
20:14rplaca_eric: the upper for looks good, but stylisticly, only use the "do" when you bundling multiple steps
20:15_ericI was going to ask if tho (do) was needed
20:15_ericit didn't seem like it was doing anything
20:15andyf_eric: I may be missing some of the comments already said, but if the goal of those lines is to iterate over some sequence and print something out for each one, 'format' doesn't do anything but create and return a string. Do you want something like (println (format ...)) there?
20:15_ericthat :let notation feels strange to me
20:15rplacanope.
20:15_eric(it doesn't feel nessesary)
20:15_ericandyf: nope, we're trying to format the string and then eventually send that over HTTP
20:16rplacayeah, you can always just use (let [] ...) inside the for rather than using the :let
20:16andyf_eric: So you do want this function to return a sequence of strings?
20:16_ericandyf: correct
20:16andyf_eric: The do is unnecessary
20:16_ericrplaca: do people generally do one over the other?
20:17_eric(the :let vs (let))
20:17scape__eric: the link to your code is 404
20:17andyf_eric: Each of the things you name in the :let bindings is used only once, I think, so it is really a matter of style whether you want to give them explicit names, or just use those expressions once each
20:17rplacaI'm not sure there's a set style. With this many syms I might use (let ) myself
20:17andyf_eric: Also, are you familiar with using :keys to bind multiple keys of a map all at once?
20:18rplacabut it's totally a matter of taste
20:18rplaca_eric: +1 to what andyf said
20:18_ericandyf: yes, we've used it in other places: https://github.com/papertrail/slack-hooks/blob/master/src/slack_hooks/service/tender.clj#L58-L67
20:18andyf_eric: For example, the last 3 lines of your :let bindings could be rewritten as {:keys [email sender subject]} message, then use email, sender, and subject in the body
20:19rplacabut again, matter of taste - both are very readable
20:19_ericthe :keys stuff really weirds me out at this point
20:19_ericI need to get more comfortable with it
20:19_ericbut I've felt like doing it explicitly looks more approachable to me
20:20rplaca_eric: you get used to it and it weirds you out not to have it in other languages
20:20andyf_eric: Understood. It can look a bit strange at first.
20:20rplacabut I think python has something like it now
20:20_ericthis project is a sort of hack project for us to get used to clojure
20:20rplacaiirc
20:20_ericand learn what the idiomatic way to do things is
20:21rplaca_eric: fwiw various kinds of destructuring are very idiomatic in clojure
20:21andyf_eric: Peronsally for me, the thing that stands out as oddest about that function is the unnecessary do. Everything else looks clear and understandable.
20:21_ericcool
20:21_ericremoving that
20:21_erichttps://github.com/papertrail/slack-hooks/pull/10/files
20:22andyf_eric: Did you want to return a sequence of strings, or the concatenation of all of them?
20:22_ericreturn a sequence of trings
20:22_ericstrings
20:22rplacathe nice thing about destructuring is that it clearing shows the relationship of where things come from
20:22_ericso each one gets reported separately
20:22_ericI think part of the reason for not using the destructuring here was to be able to name the things better
20:22Bronsa_eric: you could turn that whole for in (for [{:keys [msg event]} (json/read-str ..) :let [{:keys [email sender subject]} msg]] ..)
20:22rplacas/clearing/clearly/
20:23_eric:msg -> message, :email -> recipient
20:23_ericbronsa: I hadn't considered that I could use the destructuring in the first argument to for
20:23_ericthat's neat
20:23andyfBronsa: I think it was pretty quick to update Eastwood for latest t.a(.jvm) changes. Output from crucible is back to what it was before, since the only thing you changed that Eastwood depended upon was :tag-kind
20:23rplaca_eric: makes sense, esp. if you have no control of what the keys are because they come from somewhere else
20:24_ericso much amazingness
20:24_ericrplaca: exactly
20:25Bronsaandyf: good to hear. I think I'm going to cut a beta release in a couple of days once I get a bunch of fixes in.
20:26Bronsa_eric: you can use destructuring everywhere you are binding something
20:26_erichurray for mind-expanding exercises
20:26_ericthis sure is different than ruby :)
20:26_ericor java
20:27scape_:)
20:28_ericthanks for the help, guys
20:39RaynesI think gf3 and I communicate exclusively through snapchats now.
20:40hiredman /win 23
20:41rgrinbergis there a fundamental reason why clojurescript doesn't implment stm?
20:41andyfrgrinberg: No parallelism in JavaScript engines
20:42andyfAt least that is what I suspect would be the fundamental reason. I didn't implement it.
20:45rgrinbergghcjs supposedly supports it
20:45aaronj1335rgrinberg i'm new to clojure... but pretty familiar w/ JS, so why would you want stm in JS when you've got persistent data structures?
20:45dnolenrgrinberg: that's because they reify the entire TRS system, which is a horrible idea IMO
20:45dnolens/TRS/RTS
20:45dnolenrgrinberg: JS engines are single threaded there's no point in supporting STM
20:46aaronj1335^ makes sense from JS perspective
20:46rgrinbergdnolen: why is it such a bad idea? i've only heard that it compiles to really fat js
20:47dnolenrgrinberg: because it means that they need a custom schedular that yield to the browser
20:47dnolenrgrinberg: I don't know they can guarantee a good behavior given the browser doesn't provide sensible hooks for proper scheduling
20:48dnolenrgrinberg: GHCJS is working (may even be available) building w/o the RTS at all because it isn't a good idea
20:48dnolenworking on
20:51rgrinbergfrom the ghcjs blog: "Keep in mind that long-running JavaScript computations (called through the FFI or directly outside of Haskell code) will block all Haskell threads" yeah that does seem a little janky
20:52kristofjanky being, of course, a technical phrase used in many white papers
20:53kristof"In this paper, we measure the effective jankiness of certain language constructs in the context of delimited continuations."
20:56TEttingerkristof, and the scale is based on reaction gif memes
20:56devnreduce-kv instead of, or in combination with persistent!/transient, reducers
20:56devnso much to think about
20:58devn(map (persistent! (reduce-kv (fn [x k v] (building-up-a-new-map)) (transient {}) {:a 1 :b 2}) [{:a 1 :b 2} {:c 3 :d 4}]))
20:58devnwhoops
20:58devn(map #(persistent! (reduce-kv (fn [x k v] (building-up-a-new-map)) (transient {}) {:a 1 :b 2}) [{:a 1 :b 2} {:c 3 :d 4}]))
21:30devnhm, bummer
21:30quizdrhey fellas. can anyone explain what the runtime for something like LightTable is like, if it is basically clojurescript, which compiles to Javascript, then wouldn't the runtime be something like a browser?
21:32akhudekquizdr: I think it might be node-webkit.
21:33kristof^
21:33quizdrdoes that compile down into an actual executable, or is the runtime interpreted in real-time like javascript?
21:33kristofreal time, I believe
21:34kristofYou can edit the clojurescript configuration maps and it'll update your application
21:34quizdrintresting, ok
22:07tutysaraddellacosta: hi good afternoon
22:07ddellacostatutysara: hi, saw your pull requests, will dig into them ASAP
22:07ddellacostatutysara: thanks for all your efforts!
22:08tutysaraddellacosta: yw, thanks :)
23:07mattmitchellI have a few folks asking what the best clojure book is. Any recommendations?
23:07RaynesI'm fond of Chas Emerick's book.
23:08RaynesClojure Programming
23:08RaynesThe Joy of Clojure is a slightly more advanced book, but is also exceptional.
23:10locksJoC requires some fortitude, given the quite brisk pace
23:10locksbut it pays off
23:11mattmitchellGreat thanks. Do they both cover v 1.5?
23:12mattmitchellOr geez I can check on that :)
23:12locksWHAT'S INSIDE
23:12locksCovers Clojure 1.5
23:12locksJoC 2ED ;)
23:13mattmitchellAwesome
23:25dsrxyep, Clojure Programming is a very good overview so far. Joy of Clojure was confusing when I read it the first time, I may go back and review it once i finish clojure programming