#clojure logs

2015-06-06

00:29amalloyluxbock: (defmacro on-error-goto-next ...)
00:42luxbock(into {} x) is always eager right?
00:42luxbocki.e. I don't have to wrap the for in (into {} (for [...])) into a doall
00:43justin_smithluxbock: iirc into is as strict as the data structure, since it is just apply conj
00:43luxbockah ok
00:43justin_smith$source inot
00:43lazybotSource not found.
00:43justin_smith$source into
00:43lazybotinto is http://is.gd/caQYZB
00:44justin_smithwell not *just* reduce conj, but essentially :)
00:44luxbockright, I should've known that
03:00spaceplukhi, is there any way to get a repl running on ios with lein-fruit?
03:15Viestihum, which is more idiomatic, (clojure.string/join "" xs) or (apply str xs)?
03:29alexyakushevIf you need it once per namespace, apply str is fine. Otherwise it's better to import join
03:30alexyakushevThat's my rule of a thumb
03:31alexyakushevBesides, separator argument to join is optional
03:31alexyakushev,(clojure.string/join [1 2 3])
03:31clojurebot"123"
03:45amalloyuse whichever one you want. nobody is very religious about this, except apparently alexyakushev
03:48alexyakushevPsst, wanna *join* this new cool cult?
03:49alexyakushevamalloy: Jokes aside, I expect apply anything version to be slower on large sequences
03:49amalloyno
03:49amalloyjoin is just implemented as a call to apply str. how else could it work?
03:49alexyakushevSure about that? :D
03:50amalloy~def clojure.string/join
03:50alexyakushevAh, OK, I see now
03:50alexyakushevNo-separator version is just apply str
03:50alexyakushevI accept my defeat
03:51amalloyand of course the body of str looks like the with-separator version of join
03:54alexyakushevStill, if join was implemented with explicit loop, it could be faster than apply, right?
03:55amalloyno
03:55amalloyapply str *is* implemented with the explicit loop you are talking about
03:57alexyakushevI'm kinda confused with this `spread` thing
03:58amalloyspread is just apply list
03:58amalloybut it's implemented before apply exists, in order to implement apply
04:07alexyakushevThe world I've been living in crumbles, what you gonna do
04:07alexyakushevThanks for the revelations
04:08alexyakushevI also found out that `reduce str` is much slower than `apply str`. Now I understand why is that, but before I would never think apply is sometimes faster than reduce
04:12amalloyalexyakushev: generally if apply and reduce do the same thing for a particular function, apply will always be at least as fast
04:13amalloybecause apply can just delegate to reduce, but the opposite is not true
04:14amalloyand it's often faster, because as you can see in the case of str, it can perform "global" optimizations that aren't available from the keyhole perspective of reduce
04:18mmeixso (apply + ...) would be preferable to (reduce + ...) in all cases?
04:19mmeix(for this one function '+', of course)
04:19mmeix?
04:21alexyakushevMultiarity + is implemented via reduce
04:23amalloywell. it turns out the question is more complicatd, with transducers and reducers, because reduce can actually act on things which aren't really sequences anymore
04:24amalloymy advice is to not actually worry about which one you use
04:24mmeixso if in doubt decide for readability/understandability
04:25mmeixad hoc question - re naming: what would be preferable: :stemup :stemUp :stem-up?
04:26mmeixstylewise
04:26mmeix(with the other one being :stemdown ...)
04:26amalloythe -
04:27mmeixthanks
04:27mmeix(thought so)
05:10kaffeeboehnchenHi. So i have core.clj (with the namespace test.core) and something.clj (namespace test.something). Now I want to use a function of that namespace (something/run-this). As far as I understood I have to require (ns … (:require something)) and it will load my file. How can I access the function then?
05:15scottjkaffeeboehnchen: you require test.something not something.
05:15scottjkaffeeboehnchen: test.something/run-this if you just have that basic require
05:16TEttinger:as can be used to make the name shorter
05:16TEttinger,(require '[clojure.string :as cs])
05:16clojurebotnil
05:16scottjkaffeeboehnchen: and :refer [run-this] so you can just refer to run-this
05:16TEttinger,(cs/replace "hey guys" #" " ", all you ladies and ")
05:16kaffeeboehnchenah, yeah, sorry, I have [test.something :as something] already.
05:16clojurebot"hey, all you ladies and guys"
05:17kaffeeboehnchen(it says "no such var run-this" by the way)
05:18kaffeeboehnchen*something/run-this
05:18kaffeeboehnchenhm
05:20kaffeeboehnchenthis is my code: https://paste.xinu.at/m-Vpp/
05:21scottjkaffeeboehnchen: in run-test, are you sure you want ((create-db).. not (create-db)...?
05:22scottj(not re your problem)
05:22kaffeeboehnchenscottj: Well, that fixed my problem. I thougt I was importing it wrong :D
05:22kaffeeboehnchenThanks!
05:23scottjkaffeeboehnchen: maybe there was a compile error you didn't see
05:37mmeixI have a function, which works, but my beginner's gut tells me, this could be made simpler/conciser: https://www.refheap.com/102147
05:38mmeix(ah, didn't try reduce ... never mind)
05:39TEttingerhmmm
05:51TEttingermmeix:
05:51TEttinger,(apply merge-with vector (map hash-map (map :pos c) (map :step c)))
05:51clojurebot{:s1 [1 5], :s2 2}
05:52TEttingerthat was fun, is it accurate?
05:52TEttinger(I defined c in a privmsg to clojurebot)
05:53mmeixyes, this is quite similar with what I've found in the meantime:
05:53mmeix,(let [c [{:step 1, :pos :s1}
05:53mmeix {:step 2, :pos :s2}
05:53clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
05:53mmeix {:step 5, :pos :s1}]]
05:53mmeix(->> (map #(hash-map (:pos %) (:step %)) c)
05:53mmeix (apply merge-with vector)))
05:54mmeixumpf
05:54TEttingerheh
05:54mmeix,(->> (map #(hash-map (:pos %) (:step %)) c) (apply merge-with vector))
05:54clojurebot{:s1 [1 5], :s2 2}
05:55mmeixah!
05:55TEttingernice!
05:55mmeixnow if I wanted every val to be a vector?
05:59mmeix{:s1 [1 5], :s2 [2] }
05:59TEttinger,(apply merge-with #(into [] %&) (map hash-map (map :pos c) (map :step c)))
05:59clojurebot{:s1 [1 5], :s2 2}
05:59TEttingerhm
06:01mmeixah!
06:01mmeix,(->> (map #(hash-map (:pos %) [(:step %)]) c)
06:01mmeix (apply merge-with into))
06:01clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
06:01mmeixurx
06:01mmeix, (->> (map #(hash-map (:pos %) [(:step %)]) c) (apply merge-with into)))
06:01clojurebot#error {\n :cause "Unable to resolve symbol: c in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: c in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: c in this context"\n ...
06:02mmeix,(let [c [{:step 1, :pos :s1} {:step 2, :pos :s2} {:step 5, :pos :s1}]] (->> (map #(hash-map (:pos %) [(:step %)]) c) (apply merge-with into)))
06:02clojurebot{:s1 [1 5], :s2 [2]}
06:02mmeixbingo
06:03mmeixjust learned a lesson: make every element the same shape
06:03mmeixbefore into'ing
06:04mmeix(does clojurebot garbage collect defs?)
06:05TEttingeryes
06:05mmeixso c vanished after a short time - nice!
06:05TEttinger,(def c [{:step 1, :pos :s1} {:step 2, :pos :s2} {:step 5, :pos :s1}])
06:05clojurebot#'sandbox/c
06:05TEttinger,(->> (map #(hash-map (:pos %) [(:step %)]) c) (apply merge-with into)))
06:05clojurebot{:s1 [1 5], :s2 [2]}
06:05mmeixgreat
06:06mmeixthanks for brain storming!
06:09TEttingeryeah, glad to help!
06:10mmeixthe Clojure mindset is growing :)
06:10TEttingerit's a fun break from the macro madness I've been dealing with trying to "reinvent" the fn special form for my clojuresque language that compiles to lua
06:10mmeixwow!
06:10TEttinger(hilariously, the hardest bug would never have happened in clojure, since I was missing a return statement)
06:11mmeixis Lua something to be interested in?
06:11TEttingerso it was going past the part where it evaluated the macro (correctly), and into a different section where it tries to use it as a normal function call :)
06:11mmeixbrain twisting ...
06:12TEttingerI'm not sure. LuaJIT is absolutely amazing as far as dynamic language compilers go
06:12TEttingerI've been taking a functional programming lib for Lua and making it... more clojurey.
06:12TEttingerhttps://github.com/rtsisyk/luafun
06:12TEttingerI added reductions and made a correct partition
06:13TEttinger(before there was a function called partition that I think has a different name in clojure, and it isn't a very useful one. it's (fn [f coll] [(filter f coll) (remove f coll)]) )
06:14mmeixquite a undertaking! (to much for a beginner's mind :-)
06:14justin_smithTEttinger: that's like an anemic group-by
06:14TEttingerall of this has been great fun
06:14mmeixI can imagine that
06:16mmeixcould that become: (fn [f coll] ((juxt filter remove) f coll)) ?
06:17mmeix(I do have a love affair with juxt since yesterday)
06:17mmeix:D
06:17TEttingeryep!
06:18justin_smithmmeix: ##((juxt #(% true) #(% false)) (group-by even? (range 10)))
06:18lazybot⇒ [[0 2 4 6 8] [1 3 5 7 9]]
06:18justin_smithit's better because it only walks once (but worse because not lazy)
06:18oddcully,(map (just :pos :step) c)
06:18clojurebot#error {\n :cause "Unable to resolve symbol: just in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: just in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: just in this co...
06:19oddcullyjust that is... brain was typing and reading stuff from ju[sx]tin
06:19TEttingeroddcully with the long distance pass!
06:35oddcullymmeix: if you want to just get rid of the (:x %) calls there you could also use destructuring (fn [{:keys [step pos]}] {step pos})
06:35mmeixafter trying, I see the elegance of (juxt :pos :step), but I'm not sure, what this buys me ...
06:35mmeixbut I have to refill to maps and then merge-with ...
06:37mmeixright now it is a two-liner:
06:37mmeix(fn [c] (->> (map #(hash-map (:pos %) [(:step %)]) c) (apply merge-with into)))
06:37mmeixbut destructuring - yes!
06:37mmeixtrying more variations ...
06:39oddcullydestructing won't help the golfing. i just find it easier to read
06:40mmeix(no aspiring for golfing, just a concise form)
06:40mmeix(and learning, of course)
06:44oddcullyand there is select-keys
06:45justin_smith,(select-keys (group-by even? (range 10)) [true false])
06:45clojurebot{true [0 2 4 6 8], false [1 3 5 7 9]}
06:54mmeixtwo new versions:
06:54mmeixhttps://www.refheap.com/102152
06:54mmeixpondering, which one I like more ...
06:56jtmarmon_can anyone give me a hand writing this macro? i'm trying to get this sucker to work: https://gist.github.com/jtmarmon/5980c80ea98cc8cc2b59 . the problem with the one on top is that it won't work if the 3rd item in the let clause is nil.
06:59mmeix(scratch that, of course: https://www.refheap.com/102153)
07:14justin_smith,(apply zipmap ((juxt (comp list :pos) (comp list vector :step)) {:step 1, :pos :s1}))
07:14clojurebot{:s1 [1]}
07:15mmeixah ...
07:15justin_smithpoint-free, heh
07:18mmeixelegant! just trying ... has to work on a coll like [{:step 1, :pos :s1} {:step 2, :pos :s2}]
07:18justin_smithright, you would map it
07:19justin_smith,(map (partial apply zipmap ((juxt (comp list :pos) (comp list vector :step))) [{:step 1, :pos :s1} {:step 2 :pos :s2}]))
07:19clojurebot#error {\n :cause "Wrong number of args passed to keyword: :pos"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Wrong number of args passed to keyword: :pos"\n :at [clojure.lang.Keyword throwArity "Keyword.java" 97]}]\n :trace\n [[clojure.lang.Keyword throwArity "Keyword.java" 97]\n [clojure.lang.Keyword invoke "Keyword.java" 110]\n [clojure.core$comp$fn__4493 invoke "core.c...
07:19justin_smitherr
07:19justin_smith,(map (partial apply zipmap (partial (juxt (comp list :pos) (comp list vector :step))) [{:step 1, :pos :s1} {:step 2 :pos :s2}]))
07:19clojurebot#object[clojure.core$map$fn__4547 0x33a58260 "clojure.core$map$fn__4547@33a58260"]
07:20justin_smitherr...
07:20justin_smithsomething like this, I probably should go back to sleep
07:31mmeixlots of options!
07:34justin_smith,(map (comp (partial apply zipmap) (partial (juxt (comp vector :pos) (comp vector vector :step)))) [{:step 1, :pos :s1} {:step 2 :pos :s2}])
07:34clojurebot({:s1 [1]} {:s2 [2]})
07:34justin_smithpoint free starts to get kind of silly
07:36justin_smith,(map (comp (partial apply zipmap) (juxt (comp list :pos) (comp list vector :step))) [{:step 1, :pos :s1} {:step 2 :pos :s2}])
07:36clojurebot({:s1 [1]} {:s2 [2]})
07:42TEttingernice try, justin_smith
07:43justin_smith,(map (comp (partial apply hash-map) (juxt :pos (comp vector :step))) [{:step 1, :pos :s1} {:step 2 :pos :s2}])
07:43clojurebot({:s1 [1]} {:s2 [2]})
07:44TEttinger,(def c [{:step 1, :pos :s1} {:step 2, :pos :s2} {:step 5, :pos :s1}])
07:44clojurebot#'sandbox/c
07:46justin_smith,(apply merge-with into (map (comp (partial apply hahs-map) (juxt :pos (comp vector :step))) c))
07:46clojurebot#error {\n :cause "Unable to resolve symbol: hahs-map in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: hahs-map in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: hahs-ma...
07:46TEttingerhah
07:46justin_smith,(apply merge-with into (map (comp (partial apply hash-map) (juxt :pos (comp vector :step))) c))
07:46clojurebot{:s1 [1 5], :s2 [2]}
07:46TEttingerhahsmap
07:46TEttingerthere we go!
07:46justin_smithpoint-free is crazy
07:46TEttingerwhat is point-free?
07:47TEttingerno definitions?
07:47justin_smithTEttinger: no named bindings
07:47TEttingerah
07:47justin_smithwhere % also counts as a name
07:47TEttingeris %& a named binding?
07:47justin_smithyes
07:47justin_smithit's a name, you can position it arbitrarily in a form
07:47TEttingerhow would you do varargs in point-free
07:47TEttingererr
07:47TEttingercan you?
07:48justin_smithTEttinger: sure, apply
07:48TEttingeroh nvm
07:48justin_smithwell, apply explits existing varargs
07:48TEttinger,(defn [& args other] (apply str other args))
07:48clojurebot#error {\n :cause "First argument to defn must be a symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: First argument to defn must be a symbol, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.IllegalArgumentException\n :message "First argument to defn must be a s...
07:48TEttinger,(defn guh [& args other] (apply str other args))
07:48clojurebot#error {\n :cause "Unexpected parameter"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unexpected parameter, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.RuntimeException\n :message "Unexpected parameter"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n :tr...
07:49justin_smithTEttinger: do you mean [other & args] ?
07:49TEttinger<justin_smith> it's a name, you can position it arbitrarily in a form
07:49TEttingerthat was what I was testing
07:49justin_smithTEttinger: not the binding vector
07:49justin_smiththe binding you create
07:49TEttingerit's still a form, the binding vector!
07:50justin_smithTEttinger: yes, in [& args] args is a binding, because you can use args anywhere in the following form
07:50TEttingergood ol' sleeping pills making me trollishly pedantic
07:50justin_smithI was not meaning to imply you can rearrange the binding vector itself, that's just silly
07:50justin_smithhaha
07:51mmeixmadstructuring, so to say :D
07:51mmeix(mmeix returns to listening & learning)
07:52justin_smithTEttinger: anyway, if you have a binding form of any sort, you definitely aren't point-free
07:52TEttingerah!
07:53justin_smithlet me see if I can recall all the ingredients needed for point-free in clojure...
07:53TEttinger,(partial + (map inc (range 5)))
07:53clojurebot#object[clojure.core$partial$fn__4525 0xad60240 "clojure.core$partial$fn__4525@ad60240"]
07:53justin_smithjuxt, comp, partial, apply
07:53TEttinger((partial + (map inc (range 5))) (range 10 20))
07:53justin_smithsadly we don't have flip
07:53TEttinger,((partial + (map inc (range 5))) (range 10 20))
07:53clojurebot#error {\n :cause "clojure.lang.LazySeq cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.LazySeq cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.core$_PLUS_ invoke "core.clj" 955]\n [clojure.core$partial$fn__4525 invoke "core...
07:53justin_smithI think you need apply there
07:54TEttingerhow would you get the partial to take 1 of 2 seq arguments?
07:54TEttingermap can take any number of seqs
07:54TEttingerwhat if you want a partial that only has one of them supplied
07:55justin_smith,((partial map + (map inc (range 5))) (range 10 20))
07:55clojurebot(11 13 15 17 19)
07:55TEttingeroh herp
07:55TEttinger(inc justin_smith) ; a thousand times again
07:55lazybot⇒ 260
07:56mmeixis point-free-ness something to strive for, besides elegance?
07:56justin_smith,((partial map + (map inc (range 5))) (range 10 20) (range 420 42))
07:56clojurebot()
07:56TEttingermmeix, oh ni
07:56TEttingerno
07:56justin_smith,((partial map + (map inc (range 5))) (range 10 20) (range 42 420))
07:56clojurebot(53 56 59 62 65)
07:56TEttingerit impairs readability IMO
07:56justin_smithmmeix: it's considered a style to strive for in haskell
07:56TEttingerprogramming is about assigning good names to complex things
07:56justin_smithbut without currying it makes much less sense
07:57justin_smithand even with currying people find it baffling
07:57mmeixbut it is good training :-)
07:57mmeixsomething I wanted to ask yesterday: do let-bindings bring a performance penalty with them?
07:57justin_smithit's a good thought exercise, I find
07:58justin_smithmmeix: not noticible ones, no
07:58mmeixor a memory
07:58mmeixpenalty
07:58justin_smithclojure does locals clearing
07:58justin_smithso not usually an issue
07:58mmeixso they get garbage collected early
07:58justin_smithmmeix: if the compiler can know they can't escape scope, yes
07:59mmeixah, sounds logical
07:59justin_smithbut the compiler is intentionally a bit daft
07:59justin_smithwe don't try to make the compiler super clever, unlike most mainstream languages
08:00mmeixhow does this look in clojurescript? would I strive for memory/speed in this way? (thinking tablets etc.)
08:03mmeixI always thougt, "partial" is currying ...
08:11stainmore (partial)?
08:12mmeix?
08:12stainah, it's a different discussion. it was discussed earlier in the week, lambda vs partial
08:13mmeixno, the context here was point-free functions, and their usefulness/...
08:14mmeixif I got that right :)
08:18stainah
08:18mmeixJustin wrote a solution for a function I tried
08:18stainlazy sequences are kind of also in the same field.. but that's more with performance than with doing a pipeline style
08:19stainin my never-available time I try to write a workflow language for composing clojure functions, where you just state the connections
08:19TEttingernice, stain
08:20mmeixthat sounds interesting
08:20stainit's not very different from working with futures
08:20stainexcept that I want it to be push rather than pull
08:24mmeixwould this resemble a glorified threading macro?
08:25mmeix(sorry, glorified is not a proper word maybe, bear with non native speakers ...)
08:25stain(defstep dostuff [a b] (str a b)) (defstep otherstuff [c] (str "x" c)) (link dostuff otherstuff :c) (link "fred" dostuff :a) (link "soup" dostuff :b) (println (deref otherstuff))
08:25stainsomething like that.. just independent connections from outputs to parameters
08:25stainobviously you can link the same output to multiple destinations
08:26mmeixreminds me of old school Moog Synthesizers :D
08:26stainbut not so easily the other way around
08:26mmeixin studio language the use fan-in and fan-out for that
08:27stainyeah, I've worked on a workflow system called Apache Taverna, and there we have lots of magic like if there's multiple links to an input port/parameter, they are merged into a wrapping list
08:27mmeixmultiple inputs would need a standard "summing" function, I guess
08:27stainand if you give a list to somethign that expects a value, autoamtic (map)
08:27mmeixah!
08:27stainbut that's a bit trickier in Clojure where generally parameters don't have a defined list depth
08:27stainbut perhaps my defstep could allow that
08:28stainit would mean a more complex workflow compilation which can't be done before the whole workflow is defined
08:28mmeixexciting!
08:29mmeixneeds a HyperREPL
08:29stainreally I am just looking at a way to throw out our existing Taverna workflow engine and translate to Clojure code
08:29stainas then it could basically be compiled down to run directly on the JVM.. currently it runs in kind of "interpreted" mode
08:30staine.g. the code for running a step will push out the values downstream, which then sees if the other values have arrived, which then execute and push furthe retc
08:30mmeixI could use something like that for my music project
08:30stainmmeix: so then you would have basically an endless stream of signals, right?
08:31mmeixright
08:31stainit sounds like you would need a clock-based workflow
08:31mmeixnot necessarily
08:31mmeixit could produce several related versions of something
08:32mmeixreminds me a bit of http://en.wikipedia.org/wiki/Max_(software)
08:32stainlet's say left-hand side of your workflow takes much longer time than right-hand side, and the last step is say to mix them, will you wait for the whole thing to finish a clock cycle before merging their signals, or just merge them at best effort and just hope the delays are not too bad?
08:33staindepends if you want digital or analog synth in a way :)
08:33mmeixyes
08:33stainin analog you would appreciate those kind of aritfacts
08:33mmeixsome signals could be Audio related
08:33mmeixsome would carry semantic data
08:34mmeixor notation
08:34mmeixexample: https://cycling74.com/2013/01/24/bach-beta-0-7-release/
08:36mmeixWeb Audio has a similar concept
08:36staincool stuff
08:36mmeixyes ... the MAX people are around for a long time now
08:37mmeixthis is coming from developments in Paris IRCAM initally
08:37mmeixand Clojure lends itself to those concepts
08:37mmeixthis is, why I'm learning it now
08:38mmeixthere is a very long tradition of using LISPs in music generation
08:38mmeixdecades, in fact
08:38mmeixit makes sense: musical data is a stream of values, and lists
08:39mmeix:D
08:39stainsomeone used Taverna workflows to compose music as well: http://www.taverna.org.uk/introduction/taverna-in-use/arts/composition-of-music/
08:39mmeixah, thanks for the link!
08:39stainso what I am hoping with my workflow thing is to make it possible to define such workflows in Clojure, open them in Taverna to see them graphically and do some rewiring, and then run them again in Clojure
08:40stainbut that's a bit of a long shot
08:40mmeixlet me know of the project! or can I follow you somewhere?
08:40stainas I don't have time to replicate the more powerful workflow engine features (e.g. automatic retries on failures)
08:40stainuhm.. it's.. mainly in my head!
08:40stainI'm on the twitter @soilandreyes
08:40mmeixnp
08:40stainyou've inspired me to have a go :)
08:41mmeixwe live in excitig times, I find
08:41staintoo many ideas, too little time
08:41mmeixyes, same here
08:41mmeixjust now coming to grips with Clojure while programming a web based music notation lib
08:42mmeixwith thinking about implementing musical semantics on a deeper level
08:43mmeixso lot of ideas too :-)
08:43sobelseems like this discussion might be incomplete without mentioning Overtone
08:43mmeixYes, O know Overtone
08:43mmeixI
08:43mmeixthe synthesis side of it is great, the underlying musical semantics a bit to naive, I find
08:43sobelagreed
08:44sobeli looked straight at building instruments and puked at the amount of work left to the music developer
08:44mmeixmusical semantics go through many levels
08:44mmeixthe MIDI-centered view is not expressive enough
08:45sobeli wasn't looking for a combined music+tooling learning curve at the time and it went fully technical on music, of course
08:45mmeixClojure can do better, I think
08:45mmeixyes
08:45kaffeeboehnchenAnyone has an idea how I can create a foreign key with java.jdbc?
08:45sobelagreed again on MIDI-centric being a poor model
08:45mmeixMIDI was invented for making another synth play
08:45mmeixso it has really very little meaning
08:45sobelright. in a pretty generic sense.
08:46sobelworse, it assumes stateful controllers and a bunch of other crud
08:46mmeixmusical structure is a very deep thing
08:46sobel:)
08:46sobeltalk to me
08:46mmeixas I can confirm
08:47mmeix(I'm teaching music theory in Vienna University for music)
08:47sobelexcellent
08:47mmeixyeah, and very happy to have found Clojure as a medium to work in
08:47mmeixnow leraning frantically
08:47mmeixas the people here can attest ;-)
08:48mmeixlots of beginner's questions from my side
08:48sobeli'm still learning my way around some new tools. i used to be a regular sax player but now i am mostly an avid electronica and classical listener.
08:48mmeixgreat!
08:49sobelClojure being the more familiar part. I have Ableton/MAX but I'm sortakinda not a GUI person anymore. It's horrible but I'm more productive at the CLI.
08:49mmeixwhy not?
08:49sobeldownside is i still suck at it and the tooling isn't polished like Ableton so, lotsa pitfalls
08:50mmeixyes ...
08:50sobelwhy am i not a GUI person anymore? probably broken by years of software eng
08:50mmeixLOL
08:50mmeixbut thinking in functions is very similar to thinking music
08:50sobelthat is, exposure to crummy GUIs starting in the early 90s continually pushed me toward traditional unix tools which were mature, if utterly lacking in GUI
08:51mmeixja, they are ugly often
08:51mmeixwe will change that :-)
08:51mmeixwhen I have my music notetion engine running, I'll dive deep into semantics
08:51mmeixhopefully this summer
08:52mmeix*notation
08:52sobeloh yeah, well, brief history of my programming life: i've always been a bit of a functional thinker, but i barely studied CS academically, and got distracted by OO through the early 2000s. i quit that when i figured out Lisps are the functional language for me.
08:52mmeixyou are a professional programmer?
08:52sobelyes
08:52mmeixoh, great
08:53mmeixI envy the pros a bit right now
08:53mmeixbut everything can be learned
08:53sobelyeahwell, we all envy each other for opportunities not taken ;) i try to turn that envy into collaboration because man, i did not live enough lifetimes to master all the topics and skills i can orchestrate in practice
08:54sobelhell, i envied pros when i was right around 10 years experienced, and thinking, geeze, does this ever get easy? where's the top of this mountoin, such that i'll be able to see a lot farther once i get to it?
08:55sobeland i'm sure someone at 5 years was thinking, i wish i could sql and java like sobel. not a hobby for the impatient. :)
08:55mmeixcomputer technology seems to evolve very fast - but on the other side the return of LISPs from decades ago gives some hope
08:55mmeixfor me
08:56mmeixso it's learning and learning
08:56mmeixI like this, OTOH
08:56sobelwhen the discipline was identified as a new science it got a lot of core research. imo, it's not surprising that so much amazing stuff was discovered and forgotten quickly.
08:57mmeixback to the fathers!
08:57mmeix(same as back to JSBach :-)
08:58mmeixand Rich is a musician too, I learned ...
08:58sobeldisappointing, though, that we don't have better theoretical analysis tools for evaluating syntax and other language properties. oh wait, we do, and that analysis is pretty damn hard. and people went against it on purpose to create things like Java, with full knowledge they were breaking things experts relied on.
08:58sobelwhen i was a band student, most the programmers i knew were marching on the field with me every morning
08:59mmeix:-)
08:59sobelthe rest dropped out of band in 9th grade. music/CS seem to be a really common combo, probably for the synergy.
08:59sobelor maybe it's due to the whole deal with musicians growing denser dendrite networks
09:00mmeixI heard a talk lately, which showed that the whole brain is exercised in musical activity
09:00sobeli think what i'd ideally like, is to be able to cram patterns into Ableton from a clojure repl
09:00mmeixI guess, we wouldnt need Ableton for that, but it should be possible ...
09:01sobelmmeix: oh, i think i may have seen that one cross my screen but didn't watch it. consciousness being an emergence of harmonies and other patterns in brain waves
09:01sobelmmeix: i'd like to express patterns with dynamics in closed form at the REPL
09:02mmeixone could try OSC as a intermedita medium, I guess
09:02sobelinstead of clicking them out or playing them in, then changing over to the controller view to draw the dynamic, etc
09:02mmeixI'm not sure, if Ableton supports OSC
09:02mmeixOSC is much richer than MIDI
09:02sobelthere's a MIDIOsc server
09:02mmeixwill think about that
09:02mmeixah, ok
09:02mmeixOSC is simple text
09:03sobeldunno if it would meet the need but i used it to integrate a silly ipad app to ableton once
09:03mmeixso should totally be doable with Clojure as generator
09:03mmeixI used LEMUR for that
09:03mmeixgreat stuff
09:03mmeixmore ideas for the summer :D
09:04sobeldoes LEMUR come with an app that makes midi from the LEMUR messages?
09:04mmeixja
09:04mmeixthere's a the usual desktop server app
09:04mmeixand LEMUR in itself has a rich scripting language
09:05mmeixhttps://liine.net/en/products/lemur/
09:05sobeloh, this is random, but.. i need to debounce midi messages from a WX-11 (wind controller) that produces a lot of spurious intermediate notes at note transitions.
09:05mmeixshould be easily doable in MAX
09:06mmeixthere is a throttling module
09:06sobelit yields them at an insane rate when the switches transition, so a change involving 5 buttons can yield quite a range of shit
09:06mmeixI forgot
09:06sobeloh cool
09:06sobeli usually don't end up on the max side (bad at GUIs!)
09:08mmeixhttps://docs.cycling74.com/max5/refpages/max-ref/speedlim.html
09:09mmeixI guess this could do what you want
09:09mmeixGUI-wise: three or four nodes to click together
09:10mmeixshouldn't be that bad
09:10sobelhmm. i don't want a rate limiter, i want to throw away the ones that are too fast.
09:10mmeix"Sets an initial minimum time between outputs. Time can be specified in any of the time formats used in Max. If there is no argument, the minimum time is 0 milliseconds."
09:10sobelso necessarily a slight delay
09:11mmeixif it's less than 20 ms or so, one woldn't perceive it, I guess
09:11mmeixand MIDI isn't that fast anyway :-)
09:11sobelnot real MIDI
09:12mmeixthere is an example on the bottom of the page, where they limit pitchbends
09:13sobelIIRC oh dear, the original spec was 3.125Kbps. i got on board when it was routinely run over 100k, ISTR.
09:14mmeixI have to leave, but hopefully we meet again here ... I'll be online a lot with pestering the pros with beginner's questions (ask justin_smith :-)
09:15sobeli bother justin_smith occasionally as well :) i'm around on and off throughout the year. be well!
09:15mmeixyou too!
10:14mmeixwhat is common wisdom re default values for defrecord?
10:14mmeixI'm reading here: http://cemerick.com/2010/08/02/defrecord-slot-defaults/
10:14mmeixhe does a macro for this
10:15mmeixthe article is from 2010 though, so maybe there is some common practice now?
10:16crocketDo clojurists use try/catch often?
10:16crocketIn java, I did.
10:16crocketChecked exceptions were evil.
10:20kaffeeboehnchenIs there any way to use google groups without google id? I wanted to ask something on the java.jdbc group :(
10:20oddcullymmeix: the way i do it is with a new-something method, that calls map->Something where i merge defaults
10:21mmeixI just found this article: http://stuartsierra.com/2015/05/17/clojure-record-constructors
10:22mmeixthanks! this makes sense ...
10:41mmeixso this would be a simple form of a constructor:
10:41mmeix(defn pitch [step & accidental] (map->Pitch {:step step :accidental :none}))
10:41mmeixclojury?
10:49TimMckaffeeboehnchen: I think you have to create a Google account, but you can have it go to your real email.
11:05oddcullymmeix: where is your accidental used?
11:08mmeixsome note have accidentals, other not
11:08mmeixpitch would be part of a chord [pitch1 pitch2 pitch3]
11:09mmeixchord would be part of a graphical unit
11:09mmeix[chord stem flag dots]
11:10mmeixthis unit has to do a lot of calculations to place symbols where they belong
11:10mmeixfor example a function which cares for accidental placement
11:10mmeixand so on
11:11mmeixWould it be better to omit :accidental :none ?
11:13mmeixso the accidental machinery would collect all pitches and build a stem with noteheads out of it, and a stack of accidentals, which go left of the notehead/stem/flag-combo
11:14mmeixthis is the use case
11:15mmeixbut if I do (defrecord Pitch [step accidental]) I'm obliged to supply a value for both, right?
11:16mmeix,(defrecord Pitch [:step :accidental])
11:16clojurebot#error {\n :cause "defrecord and deftype fields must be symbols, sandbox.Pitch had: :step, :accidental"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.AssertionError: defrecord and deftype fields must be symbols, sandbox.Pitch had: :step, :accidental, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.core$validate_fields invoke "core_deftype.clj" 292]}\n {:type ja...
11:17mmeixerr
11:17mmeix,(defrecord Pitch [step accidental])
11:17clojurebotsandbox.Pitch
11:19mmeix,(def n1 (->Pitch 7)
11:19clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
11:19mmeix,(def n1 (->Pitch 7))
11:19clojurebot#error {\n :cause "Wrong number of args (1) passed to: sandbox/eval48/->Pitch--63"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval48/->Pitch--63, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3628]}\n {:type clojure.lang.ArityException\n :message ...
11:20mmeix,(defn pitch [step & acc] (map->Pitch {:step step :acc :none}))
11:20clojurebot#'sandbox/pitch
11:21mmeix,(def n1 (pitch 7))
11:21clojurebot#'sandbox/n1
11:21mmeix,(def n2 (pitch 4 :sharp))
11:21clojurebot#'sandbox/n2
11:22mmeix(sorry for generating unnecessary error stacks)
11:23mmeix,(def chord [n1 n2])
11:23clojurebot#'sandbox/chord
11:23borkdudefor anyone interested in migration a project from leiningen to boot, first steps: http://blog.michielborkent.nl/blog/2015/06/06/from-leiningen-to-boot/
11:23mmeix,(map :step chord)
11:23clojurebot(7 4)
11:23oddcullyi ask because of step & acc and then acc never beeing used
11:23mmeix,(map :acc chord)
11:23clojurebot(:none :none)
11:24mmeixah - silly me
11:24mmeixok
11:28mr_rmdoes anyone know if it's possible to make vsclojure NOT separate the '.' from a property or method name when it reformats the document with ctrl-E,D?
11:28mr_rmsorry for kind of off topic but nobody talking in #vsclojure
11:29mr_rme.g. reformatting changes (-> obj .Foo) to (-> obj . Foo) and this frequently causes errors
11:43mr_rmok different question... does anyone think Clojure on .Net will ever be anything other than a novelty? I love Clojure/JVM and use it all the, and Clojurescript seems to get a lot of mindshare, but the .Net world is... different. I'm just really wondering if looking there is even worth the time. Could be learning F# instead
12:14hadronzooWith reader conditionals, is it now possible to define and use macros within the same cljc file when targetting clojurescript?
12:21hadronzooAh, just figured it out using #?(:cljs (:require-macros [current-ns]))
12:46dhardison i'm working on an app and i'm trying to understand the scope of a variable i've defined using (def active-piece -1). I want to update the value inside a block of code -- should i be using def or let?
12:47wasamasalet establishes local bindings shadowing outer bindings
12:48dhardisonso i should just use def -- correct?
12:48gfredericksdhardison: def isn't designed for mutation
12:48dhardisonfor this case at least
12:48wasamasadef would work, but isn't ideal
12:48dhardisonah - hmmm well is there a way i can have a global mutable value
12:48gfredericksideally you would figure out a way to not have one
12:48dhardisoni'm trying to keep it simple for now
12:48gfredericksbut if you really want one
12:48dhardisonwhile i figure all this out.
12:49gfredericks,(def active-piece (atom -1))
12:49clojurebot#'sandbox/active-piece
12:49gfredericks,(swap! active-piece + 10)
12:49clojurebot9
12:49gfredericks,(swap! active-piece + 10)
12:49clojurebot19
12:49gfredericks,(swap! active-piece inc)
12:49clojurebot20
12:49gfredericks,(reset! active-piece 9000)
12:49clojurebot9000
12:49gfredericks,(deref active-piece)
12:49clojurebot9000
12:50gfredericksalso http://clojure.org/state
12:50dhardisongotcha, thank you very much
12:51Jickelsen,(go (let [foo (<!
12:51Jickelsen (#(let [c (chan)] (>! c "bar") c))
12:51Jickelsen )]
12:51Jickelsen foo))
12:51clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
12:53JickelsenReturns #<[Object Object]>
12:53Jickelsennil
12:53Jickelsenfor me
12:54gfredericksis it a channel?
12:54gfredericksgo always returns a channel
12:54justin_smithJickelsen: has to be on one line, clojurebot does not do multi line input
12:54justin_smithJickelsen: and clojure bot does not do core.async :P
12:54gfredericksand clojure bot only evaluates haskell
12:54JickelsenI suspect it could lead to a whole lot of shenanigans!
12:55gfredericksand clojure bot does not exist
12:55gfredericksand we are all different slices of a very finely sliced pumpkin pie
13:02JickelsenI tried switching out foo for a global atom
13:02Jickelsen(go (reset! foo (<!
13:02Jickelsen (#(let [c (chan)] (>! c "bar") c))
13:02Jickelsen )) but the value of foo has not been changed
13:02JickelsenAlso I forgot to paste in a closing parenthesis, sorry
13:02justin_smithJickelsen: go returns a channel
13:03gfredericksjustin_smith: which is the point of switching to an atom
13:03justin_smithand your block inside also puts a channel into c
13:04justin_smithgfredericks: ahh, OK
13:04justin_smithand what's the point of (#(...)) instead of (...)
13:06gfredericksprobably nothing
13:06Jickelsen(>! (chan) "bar") only returns true though, won't it?
13:07justin_smithJickelsen: sure, but you are not using the return value of that anyway
13:07justin_smith,(let [] 42 :a)
13:07clojurebot:a
13:17JickelsenTrue! I switched to an atom since the return value of the block wasn't very helpful. Could have used a print statement though. So it seems the MVP (eeh) should have been
13:17Jickelsen(go (reset! foo (<!
13:17Jickelsen (let [c (chan)] (>! c "bar") c))))
13:17JickelsenThe atom, however, remains unfazed
13:18justin_smithJickelsen: I'm trying to remember, there may be rules about reading and writing the same channel in one block?
13:19dhardisonwhat's the proper syntax to return true/false at the end of a function call?
13:19justin_smithdhardison: true
13:19justin_smithor maybe false
13:19justin_smith,((fn [] (print "did something") true))
13:19clojurebotdid somethingtrue
13:20dhardisonjustin_smith: must it happen at the end or can i do it within an if statement
13:20Jickelsenjustin_smith: I think you're right!
13:20justin_smithdhardison: you can only return from the end of a function (but an if statement can change where the "end" is)
13:20dhardisonk thanks
13:26justin_smithJickelsen: https://www.refheap.com/102178
13:27justin_smithJickelsen: I can reproduce, doing it inside one go block fails
13:29justin_smithJickelsen: in case you loaded already, refresh, I added extra lines demonstrating that the value "foo" was still in c after, and that by putting another value in c I could make that eventually end up in result
13:30justin_smithso yeah, it's definitely the "don't read and write the same chan in one go block" rule in action
13:38Jickelsen1Thank you, now at least I know why my async-jousting in the repl wasn't working :)
13:39justin_smithI hope the stuff I was trying to demonstrate in that refheap paste is clear
13:41justin_smithlike, it did read and write the same channel in one go block, but just not to / from itself at all...
13:46mmeixok, there must be a better way (bare with me, as always):
13:46mmeix,(defrecord Simpson [name hair])
13:47clojurebotsandbox.Simpson
13:47mmeix,(defn new-simpson [name & [hair]]
13:47mmeix (map->Simpson {:name name :hair (or hair "blond")}))
13:47clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
13:47dhardisonwhat does syntax similar to :refer or :black etc mean in clojure
13:47mmeix,(defn new-simpson [name & [hair]](map->Simpson {:name name :hair (or hair "blond")}))
13:47clojurebot#'sandbox/new-simpson
13:48mmeix,(def lisa (new-simpson "Lisa"))
13:48clojurebot#'sandbox/lisa
13:48mmeix,(def marge (new-simpson "Marge" "blue!"))
13:48clojurebot#'sandbox/marge
13:48mmeix,lisa
13:48clojurebot#sandbox.Simpson{:name "Lisa", :hair "blond"}
13:48mmeix,marge
13:48clojurebot#sandbox.Simpson{:name "Marge", :hair "blue!"}
13:49mmeixthis doesn't feel right for me: "[name & [hair]"
13:49mmeix"[name & [hair]]"
13:49mmeixjust to avoid parens in the val
13:49gfredericks,(defn new-simpson ([name] (new-simpson name "blond")) ([name hair] (->Simpson name hair)))
13:49clojurebot#'sandbox/new-simpson
13:50mmeixok
13:50mmeixthanks
13:51gfredericksI'd like a better syntax for default args
13:51Jickelsen1justin_smith: I get the gist of it, I need to read up a bit on when to use put! though
13:51gfredericksI don't like [name & [hair]] because you get a squishier function that accepts any 1+ args
13:52mmeixI tried {:keys ...}
13:52mmeixbut that feels a bit convoluted too
13:54mmeixin a simple case of 1-3 args a variadic func is easy enough
13:54mmeixthanks again
14:02mmeixfollow-up:
14:02mmeix,(defrecord Pitch [step acc])
14:02clojurebotsandbox.Pitch
14:02mmeix,(defn pitch ([step] (pitch step nil)) ([step acc] (->Pitch step acc)))
14:02clojurebot#'sandbox/pitch
14:02oddcullymmeix: if you have many different optional params you can allow passing a map as last param, merge with your defaults and send it to map->Record
14:03justin_smithJickelsen1: (put! c val) is usually the better equivalent of (go (>! c val)) - it is for async offering of a value to a channel
14:03justin_smithgfredericks: stuartsierra's latest blog post was on that topic http://stuartsierra.com/2015/06/01/clojure-donts-optional-arguments-with-varargs
14:04mmeix(ja, just read that article)
14:04justin_smithdhardison: ##(type :foo)
14:04lazybot⇒ clojure.lang.Keyword
14:05mmeixmy question was:
14:05justin_smithdhardison: keywords are symbols that only stand for themselves, they never get resolved directly to a binding (though they are commonly used as keys in maps by which bindings are looked up)
14:05mmeixwould it be better to do "(defn pitch ([step] (pitch step nil)) ..."
14:05mmeixor "(defn pitch ([step] (pitch step :none))..." ?
14:05justin_smithmmeix: ahh
14:06justin_smithyeah, nil is idiomatic for "none" I think
14:06mmeixok
14:06mmeixoddcully will try the merge
14:06dhardisonjustin_smith: thanks
14:06justin_smithit's a decent "none of the above" value, since things like or or if handle it nicely
14:07justin_smithmmeix: a good addition, if using nil for none and merging, is a function that removes keys if they have a nil value
14:07mmeixAHA!
14:08mmeix(sorry for shouting.. )
14:08justin_smith(defn without-nil-keys [m] (into (empty m) (remove (comp nil? second) m))
14:08gfredericksI hate computers
14:09justin_smithor (merge-with #(or %2 %) m1 m2)
14:09justin_smithgfredericks: haha
14:10gfredericksI just made this refactor that changes things to use strictly fewer function calls and it made everything like 5% slower: https://github.com/clojure/test.check/commit/71fb1bd185025d55e10ed1cdaf1b1c64d240fc10
14:10mmeix(thanks for abundance of patience)
14:11gfrederickslife is a lot easier when you don't measure how fast things go
14:11justin_smithgfredericks: mo' criteria mo' problems
14:12justin_smithgfredericks: which is why I only use one simple test to make all decisions
14:12gfredericks"is it dope?"
14:12justin_smithhaha
14:12justin_smithdope has a complex dependency tree
14:12justin_smithcoin flips are isolated :)
14:13gfredericksthis is the OOP version of "simple"
14:13gfredericksall I have to do is call it.isDope() how could anything be simpler
14:14gfredericksanyhow so while you're all here I'm been thinking about activerecord-envy and wondering if there are things that could be done
14:15gfredericksI'm thinking specifically about solving problems of CRUD, type conversion, key spelling style conversion, and maybe other things, with minimal boilerplate and ideally no magic
14:16justin_smithgfredericks: this is a bunch of what Caribou was / is about, though it is not as advanced as nuanced as what you have in mind I bet
14:19gfredericksoh hey I haven't seen that
14:20gfrederickswhich lib?
14:20gfrederickscarbiou-core?
14:20justin_smithcaribou-core is the db and modeling layer
14:20justin_smithcaribou-admin is the web UI for CRUD
14:20justin_smithallows point and click / drag and drop modeling
14:21gfredericksdefinitely haven't been thinking about webby stuff
14:21justin_smithmy intro to clojure was getting hired to work on Caribou
14:22gfrederickshow does this interact with java.jdbc
14:22justin_smithgfredericks: it wraps variou jdbc drivers (right now mysql, postgres, and h2 have full support)
14:23justin_smith*various
14:23justin_smithit uses an edn data structure to describe a data model, and that gets stored / retrieved as data in the db itself
14:23gfredericksso doesn't use java.jdbc at all? uses JDBC directly?
14:23justin_smithand schema changes are also reflected in the model table
14:23justin_smiththe implementation uses jdbc for everything
14:24justin_smiththough at one point we considered implementing datomic and mongo support, those are still vapor
14:25borkdudeI thought if there exists a very light weight ORM library written in Java or so, that can be used from Clojure easily
14:25gfredericksoh man I definitely don't want an ORM
14:25justin_smithprobably - we didn't like any of the ones we knew
14:25justin_smithwe didn't want ORM - we wanted MRM (map relational modeling)
14:25borkdudewithout getting stuck with annotation, but just being able to use edn
14:26justin_smithborkdude: yeah, that's what we aimed for - the RM part without stateful object behavior stuff at all
14:27borkdudethe more I thought about it, the more clojure.java.jdbc fit my needs :)
14:28gfredericksI'm working in a few projects that have a lot of CRUD boilerplace
14:28gfrederickswith java.jdbc
14:29gfredericksand java.jdbc's protocols aren't sufficient for all the type conversion we have to do
14:31justin_smithgfredericks: oh, caribou wouldn't help you then - it just uses a small edn subset
14:32gfredericksI almost thought about making a library just for specifying conversions
14:32gfrederickstypes and keys
14:32gfredericksmaybe prismatic/schema would be sufficient for that
14:32gfredericksor at least could be an implementation
14:33gfredericksI think using camel-snake-kebab and just blindly converting everything is pretty gross
14:34dhardisonwhat's the best way to debug a clojurescript application
14:35dhardisonright now i'm compiling and running and fumbling in the dark
14:35justin_smithdhardison: I find figwheel helps a lot, also cljs.test works
14:35justin_smithdhardison: and definitely use the chrome inspector / console if you are not yet
14:36justin_smithit has breakpoints, stack inspection, local inspection, etc.
14:42dhardisonjustin_smith: hmm i'd love to use devtools but does it support looking into variables?
14:42justin_smithdhardison: in my experience yes, it shows local variables, and namespace level defs
14:42justin_smiththough you do have to figure out the "munging" to get the js version of the thing you want
14:43justin_smithbut that's where the figwheel repl also helps - it's a cljs repl
14:43justin_smithas opposed to the console js repl
16:00lalopsDirect download links/forum attatchments SEO ANALYZER SCRIPT: /AMSG FREE SEO ANALYZER SCRIPT DOWNLOAD ATTATCHMENT FOUND: http://www.websiteadverts.org/forum/showthread.php?tid=17 WEBSITE WORTH CALCULATOR SCRIPT: http://www.websiteadverts.org/forum/showthread.php?tid=16
16:38noncomif i pass, say, a clojure {} into a java method that accepts a HashMap and the java code modifies the {}, that breaks the immutability, right?
16:38noncomi mean, it is no longer done through STM ?
16:39justin_smithnoncom: how would it modify the {}
16:39justin_smithSTM cannot modify {}
16:39noncomjustin_smith: isn't {} a HashMap ?
16:39justin_smith,(type {})
16:39clojurebotclojure.lang.PersistentArrayMap
16:39noncomomg
16:39noncomhow can i be so lame..
16:39justin_smith,(type (java.util.HashMap.))
16:39clojurebotjava.util.HashMap
16:40noncomright, right, my daily dose of stupidity :D
16:40uptowni'm still on an hourly dose personally
16:40justin_smithnoncom: on the other hand (instance? java.util.Map {})
16:40justin_smith,(instance? java.util.Map {})
16:40clojurebottrue
16:40justin_smith,(instance? java.util.Map (java.util.HashMap.))
16:40clojurebottrue
16:41noncom(.add {} 1 1)
16:41noncom,(.add {} 1 1)
16:41clojurebot#error {\n :cause "No matching method found: add for class clojure.lang.PersistentArrayMap"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: add for class clojure.lang.PersistentArrayMap"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]\n [clojure.lan...
16:41justin_smith,(.add (java.util.HashMap.) 1 1)
16:41clojurebot#error {\n :cause "No matching method found: add for class java.util.HashMap"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: add for class java.util.HashMap"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]\n [clojure.lang.Reflector invokeInstanceMe...
16:41justin_smith,(.put (java.util.HashMap.) 1 1)
16:41clojurebotnil
16:41noncom,(.put {} 1 1)
16:41clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.UnsupportedOperationException\n :message nil\n :at [clojure.lang.APersistentMap put "APersistentMap.java" 374]}]\n :trace\n [[clojure.lang.APersistentMap put "APersistentMap.java" 374]\n [sun.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2]\n [sun.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.jav...
16:41justin_smithunsupported operation :)
16:41noncomah, unsupported op
16:42noncomcool! :)
16:42noncomso it gives the guarantee...
16:42justin_smithI mean you could use reflection and get at the internals and mutate - but that's tricky, and you can break most anything in the jvm that way if determined to :)
16:43justin_smith,(java.util.HashMap. {:a 0})
16:43clojurebot{:a 0}
16:44justin_smith,(.get (java.util.HashMap. {:a 0}) :a)
16:44clojurebot0
16:44justin_smithif you really need the mutable thing, that is very easy to arrange
16:45justin_smith,(.get (doto (java.util.HashMap. {:a 0}) (.put :b 1)) :b)
16:45clojurebot1
16:47noncomi see!
16:47noncomactually in this current place i am concerned with making the user unable to mutate
16:47justin_smith,(into {} (doto (java.util.HashMap.) (.put :a 0) (.put :b 1)))
16:47clojurebot{:b 1, :a 0}
16:47justin_smithcool
16:48noncombut your last example is good to remember also when i need it
16:59borkdudeClojure related blog post is now in top 10 on Hacker News
17:00justin_smithborkdude: your post about boot?
17:00borkdudeyeah :)
17:00justin_smithcongrats
17:00borkdudetnx
17:14dhardisoni'm running (def x (atom {:d 2})) -- and then (get x :d) and it's returning nil -- any ideas
17:14Bronsa,(def x (atom {:d 42}))
17:14dhardisoni also tried (get (deref x) :d)
17:14Bronsa,x
17:14clojurebot#'sandbox/x
17:14clojurebot#object[clojure.lang.Atom 0x66862bb9 {:status :ready, :val {:d 42}}]
17:14Bronsa,(class x)
17:14clojurebotclojure.lang.Atom
17:14Bronsa,(class @x)
17:14clojurebotclojure.lang.PersistentArrayMap
17:15Bronsa,(get @x :d)
17:15clojurebot42
17:15dhardisonah
17:15dhardisonwhat does @ symbol do
17:15justin_smith,'@x
17:15clojurebot(clojure.core/deref x)
17:15Bronsa,`@x
17:15clojurebot(clojure.core/deref sandbox/x)
17:15Bronsadamn you justin_smith !
17:15justin_smithhaha
17:19noncomdhardison: @x is a shortcut for (deref x) and it gets what is "inside" the atom. in your case, that's {:d 2}
17:20justin_smithand also, get works with like - anything
17:20justin_smith,(get nil :a)
17:20clojurebotnil
17:20justin_smith,(get Double/NaN :a)
17:20Bronsa,(get 42 23 37)
17:20clojurebotnil
17:20clojurebot37
17:20amalloydhardison: more than a specific answer to your question about @, note the general technique justin_smith just showed you: if you're not sure what some shorthand means, just put a quote in front of it and see how it expands
17:20dhardisoni see - i was trying it out on tryclj.com but it was giving me an error
17:21dhardisonthanks amalloy
17:21noncomyes, get is sorta fail-safe, so you just get nil instead of a NullPointerException or something. that's often the case with clojure
17:29thedoodPLWhat is the easiest way to interact with a rest service (get and post stuff) in clojure?
17:31thedoodPLis there any lib that combines clj-http and a json lib?
17:43dhardisonso, if i dereference something from an atom, i cannot update the data directly, can i? e.g. (def x (atom {:d 1})) -- and then (assoc @x :d 2)
17:45dhardisoni'll have to do a reset!
17:51oddcullydanlarkin: swap!
17:51oddcullyerm
17:51oddcullydhardison: ^^
17:53dhardisonoddcully: i'm passing in the atom into a function -- will that still work
17:53dhardisonlooks like that it might be setting it to null
17:55oddcully,(def a (atom {}))
17:55clojurebot#'sandbox/a
17:55oddcully,((fn [x] (swap! x assoc :x 42)) a)
17:55clojurebot{:x 42}
17:55oddcully,(deref a)
17:55clojurebot{:x 42}
17:58dhardisonoh, i tried assoc @x :x 42 --- that's my mistake thanks
17:59amalloydhardison: remember, all an atom is, is a mutable pointer to a value that, like most things in clojure, is immutable. once you derefence it, you're left with an immutable value that knows nothing about the atom it "came from"
19:09Atlas_darklyhello
19:24TEttinger,"\u0000hey!\u0000\is this nul terminated?"
19:24clojurebot#<RuntimeException java.lang.RuntimeException: Unsupported escape character: \i>
19:24TEttinger,"\u0000hey!\u0000is this nul terminated?"
19:24clojurebot"
19:24TEttingerwoah
19:28Atlas_darklywut
19:36TEttinger,(count "\u0000hey!\u0000is this nul terminated?")
19:36clojurebot29
19:36TEttingerweird
19:36TimMcMaybe an IRC thing.
19:40Atlas_darklyyo
19:43TimMc&"\u0000"
19:43lazybot⇒ "
19:43TimMcfoobar
19:44TimMchmm, can't type a NUL in irssi
20:17creeseDoes the core lib have anything that format a string using values from a map?
21:05gfrederickscreese: no but I wrote such a thing
21:06gfrederickscreese: https://github.com/gfredericks/like-format-but-with-named-args
21:43ToBeReplacedcreese: gfredericks: org.clojure/core.incubator gives clojure.core.strint
21:44gfredericksyep
21:45Atlas_darklyMadmao was better
22:06StarBreakerAtlas_darkly: :)
22:07Atlas_darklyHow do you tag someone in a comment like that? (New to IRC
22:07Atlas_darkly)
22:09StarBreakerDepends on the client you use, but generally it works when you type the beginning of the nick and hit tab
22:10Atlas_darklythanks
22:11StarBreakernp
22:16gniquilclojure noob here, but which text editor should I use. I am most familiar with Sublime but it seems there's nothing good for Sublime3. And I also use Vim a lot. Any suggestions? Oh and Vundle or Pathogen?
22:21amalloygniquil: use the one you're familiar with. i'm fairly sure there are people who use sublime text, although it is sorta last on my list of "clojure editors to recommend"
22:21amalloyif you're also comfortable with vim i'd recommend that over ST
22:22gniquilI am mostly... been using it for 5 years prior, but haven't been my main editor for last 1
22:22gniquilbut then I found these pathogen and vundle debate
22:22gniquilthe quote complete thing really bugs me in Sublime text
22:23gniquiland no repl integration (at least haven't found anything yet)
22:43kristofPeople don't use emacs anymore?
22:44tbaldridgesure we do. About 50% of Clojure devs use Emacs
22:44tbaldridgeThe rest of us use vi, or Cursive, or something else
22:44blkcati'm not even an emacs fan and i still use emacs when working with clojure
22:44kristofcurious why amalloy didn't mention it then :(
22:44gfrederickshe's overcompensating
22:44kristofoh good
22:45amalloykristof: of course people use emacs. but i was being asked by a vim user
22:45amalloyand recommending that he use emacs was wrong
22:45kristofamalloy: I didn't read that part of his question, I'm sorry
22:45tbaldridgeThat being said, I used to use emacs, but don't care for it anymore.
22:45kristoftbaldridge: Oh that's interesting. All the videos I've ever seen you in use emacs.
22:46tbaldridgeYep, I switched about a year ago, almost all my vids on pivotshare use Cursive
22:47tbaldridgeit's really hard to beat a custom tuned IDE. General use, customizable editors are great, but if all I do is program clojure, something that targets that directly is often much better.
22:47tbaldridgeAt least that's been my experience with Cursive, PyCharm, and Visual Studio (for C#)
22:48kristoftbaldridge: I used Intellij a lot back when I was using java and liked it a fair bit, so I'm glad to see that Cursive builds on that