#clojure logs

2014-08-26

00:00justin_smithand you can keep adding or adjusting at the end of that ->> thread to narrow down the data you are looking for
00:05justin_smithalso the magic first / second - the first is to get just one of the contacts, the second is to get the :raw
00:05justin_smithsince it was a [] instead of {}
00:06sarcherThat makes sense.
00:06sarcherI'm going to have to play around with this a bit and see what I can come up with.
00:06sarcherit's a very different way of thinking about things haha
00:06sarcherthanks again for the help!
00:06justin_smithnp
00:07justin_smiththe general pattern with what data.xml returns is to filter for the right :tag then probably grab the :content
00:07justin_smithyou'll see yourself doing that over and over
00:08danielcomptonDoes leiningen check for snapshots every time you run it?
00:10justin_smithhttps://raw.githubusercontent.com/technomancy/leiningen/master/sample.project.clj looks like you can set that explicitly
00:11justin_smithdanielcompton: link to the relevant line https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L90
00:12danielcomptonjustin_smith: thanks!
00:13danielcomptonwhich is the default?
00:13justin_smithdanielcompton: looking for that now
00:15justin_smithhttps://github.com/technomancy/leiningen/blob/ad65195f40c2a1eeffd31401942cd8111c5de7ff/src/leiningen/deps.clj#L111 once every 24 hours
00:15justin_smithfinally found it
00:15sm0keif find doing this very often (if x (f y) y) can this be expressed any better/shorter?
00:15danielcomptonahaha https://github.com/technomancy/leiningen/blob/2cfca444fe37135637a4efbe9f004d4ce5fe51c7/leiningen-core/src/leiningen/core/main.clj#L13
00:16justin_smithrofl
00:16justin_smithnice to know it is friendly to the germans
00:16sm0keleiningen was a german
00:16danielcomptonjustin_smith: where does it take :update?
00:16justin_smithsee my link to project.clj above
00:16justin_smithit is the sample project.clj, it shows the syntax / where the key is expected
00:17danielcomptonjustin_smith: I mean where in deps.clj does :update change things?
00:17danielcomptonlooking at deps.clj I can't see :update at all
00:17technomancydanielcompton: use `lein -U ...`
00:18danielcomptontechnomancy: where does https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L90 take effect?
00:18justin_smithdanielcompton: I bet it happens in classpath/resolve-dependencies
00:18technomancyinside pomegranate/aether
00:18danielcomptonah, it all becomes clear
00:18danielcomptoner
00:19danielcomptonthanks!
00:19justin_smithdanielcompton: https://github.com/technomancy/leiningen/blob/ad65195f40c2a1eeffd31401942cd8111c5de7ff/leiningen-core/src/leiningen/core/classpath.clj#L122
00:19justin_smithyup, I was right
00:19justin_smith(or close enough to get real close :))
00:21danielcompton(inc justin_smith)
00:21lazybot⇒ 67
00:21danielcompton(inc technomancy)
00:21lazybot⇒ 132
00:21danielcompton(dec so)
00:21lazybot⇒ -33
00:24justin_smith$karma karma
00:24lazybotkarma has karma 1.
00:24catern(dec karma)
00:24lazybot⇒ 0
00:24caternall is in balance
00:24justin_smith$karma karma karma karma karma chameleon
00:24lazybotkarma has karma 0.
00:24justin_smith:P
00:51sm0kecore.async is like a playground right now, i hope some of these days the devs make a 0.1.x release with limitled stable features as people are already beginning to use it
00:54rhg135justin_smith: now it's in my head, damn it :P
00:55pmonksG’day everyone, potentially dumb n00b question here…
00:55pmonksI’m working on wrapping a Java API in idiomatic Clojure, and one ubiquitous type in that API I feel is best represnted by keywords on the Clojure side.
00:56pmonksI can manually translate between instances of this class and keywords, but is there a way to tell Clojure how to do the type conversions, and then just handle them wherever needed?
00:56pmonksThe type is used throughout the API, and manually translating everywhere (while technically possible) sounds like a lot of donkey work.
00:56rhg135Implicit casing yikes
00:57pmonksYah that was my reaction. :D
00:57sm0ke##(bean (java.util.Date.))
00:57lazybot⇒ {:seconds 14, :date 26, :class java.util.Date, :minutes 57, :hours 4, :year 114, :timezoneOffset 0, :month 7, :day 2, :time 1409029034220}
00:58pmonksThing is, this type maps beautifully to keywords (though it’s not symetrical - while all instances of the class can be mapped to keywords, the reverse isn’t true).
01:02rhg135I usually have a function, usually a map, to convert it at every at user interaction point
01:03pmonksAnd you then call that function internally before interoping with Java, or simply let users of the API choose to use it or not?
01:03rhg135Internally
01:05pmonkshmmm…….in the Java API I’m wrapping there are approximately 215 classes that use this particularly type, many of which offer numerous methods that have it somewhere...
01:06pmonks(not that I’m wrapping all of them up front…)
01:06rhg135Hmm
01:06pmonksI guess I have to do work to nicely wrap all that garbage anyway - might as well add in conversion calls as a nice convenience. ;-)
01:07pmonksParticularly since it’s only a subset of that API that’s the “80% sweet spot” for callers.
01:07pmonksWell thanks @rhg135 - you answered my question!
01:08rhg135Np
01:08pmonksI was wondering for a minute if Clojure might have opened the Pandora’s Box of Scala-style implicits (which seem like a capital-N nightmare).
01:10rhg135Lol
01:11TEttingerI haven't learned all of Scala's implicit stuff, but all I can tell is it's complicated
01:14rhg135Reminds me of c++
01:15rhg135Trying to fix c/java
01:15sm0keits stupid
01:15sm0keand dangerous
01:15rhg135Very
01:15sm0kethey admit that it wasa bad design choice
01:17sm0kei think most of the scala dev abstain from using implicits, they prefer to do conversion manually where required
01:17TEttingerI don't even know how implicit really works, I used it to imitate extension methods in C#
01:19TEttingerI'm wondering if there's some way to get idiomatic clojure closer to java speed
01:19sm0kehow is that realted to implicit conversion?
01:20TEttingersm0ke, implicit has multiple meanings in scala
01:20rhg135Don't think there is
01:20TEttingerand the clojure comment is because I'd really prefer to use clojure over scala
01:20rhg135Java is always lower level
01:20TEttingerbut scala's performance is much better
01:23sm0kebetter than java?
01:23TEttingerno, than clojure
01:23sm0keidimomatic scala ?
01:24TEttingernot sure what that really is. I haven't really needed to optimize my scala but desperately needed to for clojure
01:24TEttingerboth soft-real time, JVM games using the same lib, libgdx
01:24sm0kehttp://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=clojure&lang2=scala&data=u64q
01:25TEttingersm0ke, I don't think microbenchmarks of optimized code are the best reference here
01:26TEttingeryeah, uh I do not consider this idiomatic clojure http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=clojure&id=1
01:26sm0keTEttinger: for that libgdx comment, it seems absurd
01:26sm0kedoesnt it uses native libs under the hood?
01:27sm0keneither is the scala port
01:28sm0kehttp://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=scala&id=1
01:28TEttingeryes, the problems weren't in graphics (the same needs, approximately, for both), but in logic. I may have been doing substantially more logic in clojure, but it was just plain hard to debug
01:28TEttingererr
01:28TEttingerprofile
01:29TEttingerand that scala looks fairly reasonable, but I do not see definterface in most clojure code
01:30TEttingerand you have stuff like this in the clojure, ^{:unsynchronized-mutable true :tag double} x
01:30sm0ke:p
01:30pmonks“Moore’s Law will make all this moot anyway. What’s that you say? It’s been rescinded?? DOH!!!”
01:30sm0keimmutability is the agenda remember?
01:31sm0keTEttinger: what kind of glue code are you writing in clojure thats so slow?
01:31sm0keeven high end games use something like lua for similar purpose
01:31sm0kei dont really see how the microssec diff between clojure and scala is critical here
01:31TEttingerglue code? I didn't write any of it, like I said the issue was with logic code
01:32TEttingerand more importantly, the issue was with how hard it was to optimize the clojure vs. scala
01:32sm0kemy point is, either you write it in C or dont write it at all
01:33TEttingerugh. I'm not writing games that need extreme 3d performance, both of these are small 2d games
01:33sm0kei am totally agreeing with clojure being harder to profile and slower than scala
01:34sm0keso your game is needs like what 6000 fps?
01:34TEttingerit was getting closer to 15
01:34TEttingerin clojure
01:34sm0kefor a 60 fps game you get, ###(/ 1000000 60) ; millis for evey frame
01:34lazybot⇒ #<sandbox5671$eval16962$fn__16963 sandbox5671$eval16962$fn__16963@23827d2a>
01:34TEttingerthe bigger problems were with input lag
01:34sm0keugh ##(/ 1000000 60)
01:34lazybot⇒ 50000/3
01:35sm0kelol
01:35TEttinger,(/ 1000.0 60)
01:35clojurebot16.666666666666668
01:35TEttingeryou're doing microseconds I think
01:36sm0keyep so even if you loose like 3 millis to clojure, you have 95% of same time
01:36TEttingerI'm just saying my experience writing the game
01:36TEttingerI spent personally about half the time on the game trying to optimize it
01:37TEttingerstuff like ztellman's primitive-math helped
01:37sm0keTEttinger: i may be plain wrong, but it think you would be equally disappointed if you port it entirely to scala
01:38TEttingeroh, I scrapped the game and started a different one. it is faster in scala, but does different stuff
01:38ztellmansm0ke: disagree, a lot of games is math, and Clojure can disappoint you on that count
01:38ztellmanI had to write a custom vector math library for http://ideolalia.com/creating-a-simple-game-in-clojure/
01:39sm0keis scala that much faster in math? my original point was to write heavy stuff in C
01:39ztellmanthings have progressed since then, but using the typical numerical stack is more or less comparable
01:43TEttingerwell I used a lot of native arrays in clojure, which I don't consider idiomatic at all and it didn't feel easy. I eventually rewrote most of the game in the higher-level lib play-clj (which itself wraps what I was using before, libgdx), and the game surprisingly had better performance. it turned out primitive object arrays are not fast at all and collections are better for objects
01:44sm0kei personally think clojure is horribly slow, but i still dont buy it that moving same code to scala got you to 60 fps from 15
01:44TEttingerand I had a major part of the render loop use an array of Images
01:44TEttingersm0ke, oh, I don't think so either, I think I wrote better code this time
01:45TEttingerbut it was easier to write fast code I think
01:45sm0keTEttinger: you gave Scala the nicest punchline ever "Scala makes it easier to write fast code"
01:45sm0ke:D
01:45TEttingerwell compared to java yes
01:46TEttingerI just wonder about stuff like oxcart
01:47sm0kenah
01:47sm0kewont work for you, you need low level stuff
01:48sm0kei dont thing oxcart can make any difference to math operations being slow
01:48sm0keimho
01:50TEttingerit possibly could, if it can compile it down to primitive math
01:50TEttingerarrdem: I like this commit message https://github.com/oxlang/oxcart/blob/953187d447ee70168105f48f5ed5d666b7d3e187/src/bench/clojure/test/vars.clj
01:52sm0kehurm interesting
01:53sm0kei am not sure how defining same `+` operations 500 times is helping though
01:54TEttingerit's a test
01:58sm0keoxcart is exciting work though
02:28bars0Hi all! Is there some clojure channel for newbies? If not: could someone point me to the documentation/blog how to build functins with required/default/optional parematers in clojure way. This is what I've wrote, but I know this is wrong: http://pastebin.com/AR7XgkWK
02:33Kneivabars0: I just read this (4 years old post) which is related I think: http://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure
02:35bars0Lisphttp://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure
02:35bars0Kneiva: ok, thanks, I'll read this
02:39arrdemTEttinger: lol
02:40arrdemTEttinger: yeah... that "benchmark" is me being as mean as I can imagine how to be comparing Oxcart vs. clojure.core
02:43arrdemtotally open to ideas for other test programs
03:34TEttinger$mail sm0ke having thought about it, most of my performance improvements in the Scala code would be just as applicable in Clojure. I may write my next game with Clojure if this works...
03:34lazybotMessage saved.
03:41clgvTEttinger: what did you write?
03:52TEttingerclgv: I wrote part of a roguelike dungeon-crawly game in clojure a while ago. I got tired of the constant optimizing I needed to do to get multiple monsters to act as soon as the player pressed a button, and I eventually stopped working on that one for unrelated reasons (the design wasn't very clear from the start).
03:53TEttingerI later started making my own art using a C# program that parsed voxel models (bindings existed for C# and C, not anything JVM), and that parser got out of hand and turned into a demo, then a game
03:53lvhTEttinger: huh; so the issue was it was too slow?
03:53lvhTEttinger: I'm interested in writing some simultaneous turn based games
03:53TEttingerlvh, I think I could manage to get it to be faster these days
03:54lvhperformance not as big a deal there :)
03:54lvhmore of a deadline scheduler style thing ;)
03:55clgvTEttinger: ah interesting
03:56TEttingerso that C# demo used some very clojuresque featurers. it used a bit of higher-order functions, and I used a future-like use of threads to offload the slow pathfinding code onto another core. but it also used IKVM so I could use the java lib, libgdx, that I was used to, and have it work from C# where I already had a codebase form the voxel renderer
03:56clgvI use some semi-immutable datastructures to get java performance in an algorithm
03:57TEttingerIKVM doesn't work well on mono, at least any newer versions
03:57TEttingerso I was stuck with windows only and slow (IKVM turned out to have major performance issues)
03:58TEttingerI tried to port to Java 8, but lambdas are no substitute for real HOFs. they aren't actually closures, so I couldn't use them in the same way as in C#
03:58clgvand then you did a scala implementation?
03:58clgvJava lambdas do not close of the used variables?
03:59TEttingerso I stuck to Scala, and found that it was a simple port (similar features in scala and C#), and without IKVM was much faster
03:59clgvor values of the variables...
03:59TEttingerclgv, you can't change outer state
03:59TEttingerin lambdas in java 8
03:59clgvTEttinger: for referenz types?
04:00TEttingerit's a restriction on lambdas in general
04:02clgvTEttinger: can you be more precise on "can't change outer state"? I mean if I close over a double value, I know that I wont see any change in the variable that held the value outside the lamda
04:04clgvI guess you meant Java lambdas do only close over "final" local variables?
04:05TEttingerclgv, I will try to find an article explaining the issue, but in my C# code I could have a method of ClassA that changes a static public member of ClassA be passed somewhere else, be called in a method of ClassB, and it would change ClassA. not so in Java
04:10SagiCZ1hi, can i attach metadata to a function from within the function? thus aquiring something akin to regular stateful object?
04:10TEttingerclgv, I encountered this same issue http://stackoverflow.com/questions/17204279/does-java-8-support-closures?rq=1
04:11TEttinger(doc meta)
04:11clojurebot"([obj]); Returns the metadata of obj, returns nil if there is no metadata."
04:11TEttinger(doc with-meta)
04:11clojurebot"([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."
04:12TEttingerit seems that it wouldn't be the same reference, SagiCZ1
04:12TEttinger,(let [a {:a 1 :b 2}] (= a a))
04:12clojurebottrue
04:12TEttinger,(let [a {:a 1 :b 2} b (with-meta a {:blah true})] (= a b))
04:12clojurebottrue
04:12TEttingerhuh
04:12TEttingermaybe...
04:14clgvSagiCZ1: what's your exact use case? you seem to head into a strange direction
04:14clgvTEttinger: they are equal, thats the point of metadata - but the objects are not identical
04:15TEttinger,(let [a {:a 1 :b 2} b (with-meta a {:blah true})] (identical? a b))
04:15clojurebotfalse
04:16clgvSagiCZ1: if you want function local data that can be mutated, then just close over an atom
04:19clgv,(let [create-counter (fn [] (let [cnt (atom 0)] (fn [] (swap! cnt inc))), counter (create-counter)] (repeatedly 10 counter))
04:19clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
04:19dawkirstasked this yesterday too, but just want to get a varied opinion: Programming Clojure or Clojure Programming for a newcomer to Clojure and FP?
04:19clgv,(let [create-counter (fn [] (let [cnt (atom 0)] (fn [] (swap! cnt inc)))), counter (create-counter)] (repeatedly 10 counter))
04:19clojurebot(1 2 3 4 5 ...)
04:20clgvdawkirst: depends on what style of writing you like
04:20dawkirstclgv: how do the styles differ?
04:20rhg135Do you even need a book with a repl?
04:21clgvdawkirst: "Programming Clojure" (2nd edition) is more like "these are the facts" and imho "Clojure Programming" is more narrative
04:21rhg135They're great but repls are awesome for learning
04:21clgvrhg135: yes, I'd recommend one for every newcommer. the repl is an awesome feature to try out the book example
04:21dawkirstclgv: narrative in the sense that they explain underlying rationales more?
04:22dawkirstrhg135: I guess not, but at the moment I'm just floating around in the ether: I need a bit of theoretical grounding
04:22rhg135Clgv, they do go well together
04:22clgvdawkirst: no, not necessarily. I wanted to describe the wrinting style by that
04:22dawkirstclgv: ok
04:22clgvdawkirst: afaik they both have example chapters
04:22clgvdawkirst: just read those and decide based on that
04:23dawkirstclgv: that's probably not a bad idea, thanks
04:23dawkirstrhg135: thoughts on Light Table as a REPL? Is it permissible?
04:23clgvdawkirst: personally I read "Programming Clojure" (1st edition) - the other one didnt exist at that time ;)
04:23rhg135It's incredible
04:24rhg135Especially for cljs
04:24clgvdawkirst: Light Table as a repl for learning should work pretty well
04:24dawkirstrhg135: awesome :) I think so too.
04:25rhg135Anyway it's 3am here, I should look at the clock more often lol
04:26rhg135Piece.
04:26rhg135Grr
04:26rhg135Peace**
04:26clgvgood sleep ;)
04:27clgvit's 10:26 am over ehre
04:34clgvadding to the book topic: did anyone read the Joy of Clojure Second Edition and can comment on the changes?
04:40SagiCZ1clgv: thanks for the answer earlier.. i will try it with the atom
04:42clgvSagiCZ1: maybe you should describe your problem, anyway? I was just guessing what you are trying to achieve ;)
05:06lvhhm
05:07lvhI'm writing a protocol for a simple kv store. is shadowing "get" ok? the error message seems to imply regular get will stop working (which makes sense, I guess; the existing get doesn't use protocols probably, and it's not like I'm extending the protocol for an exisitng type)
05:14clgvlvh: what you should do is the following? in the implementing namespace use (:refer-clojure :exclude [get]) and in namespaces where you want to use it, you shoud use an alias, e.g. myproto, and refer to the method like (myproto/get ...)
05:14clgvdelete the "?" ;)
05:15clgvmaybe "myproto" is misleading, imagin "myns" in the above example
05:18clgvlvh: similar to what is done here https://github.com/ztellman/primitive-math/blob/master/src/primitive_math.clj
05:20lvhclgv: oh, durr; that makes sense
05:20lvhclgv: I actually replaced it with create/retrieve, which is marginally better because create implies that overwriting an existing key is an error (and it is)
05:23clgvlvh: if you have better verbs, you should definitely use those. but you can't always avoid collision ;)
05:24lvhclgv: yeah, absolutely
05:24lvhCompilerException java.lang.IllegalArgumentException: No single method: retrieve of interface: icecap.storage.core.Store found for function: retrieve of protocol: Store, compiling:(/private/var/folders/dd/lh02zlnn1hg7cgs85w8qq6c00000gn/T/form-init939129485929514517.clj:1:1)
05:25lvhoh... don't have two jvms up
05:26lvhI couldn't figure out why I was seeing stale code in my repl :)
05:26clgvyeah, for development a switch "always compile the clojure code and do not dare to load *.class files" would be nice sometimes
05:36lvhclgv: Hm. That wasn't it, though: https://gist.github.com/lvh/949692f88bf1634a967d
05:57noniwoohi. why this one gives me original vector without 19? (replace {0 19} [1 2 3 4 5])
06:02clgvlvh: you forgot about the "this" pointer
06:02lvhclgv: Just adding "this" in front of everything gives me a different exception though
06:02clgvlvh: it needs to be in the argument list for protocols, reify and deftype
06:03mpenetnoniwoo: it takes the key as value to be replaced in the vector
06:03mpenet,(replace {0 19} [0 0 2 3 4 5])
06:03clojurebot[19 19 2 3 4 ...]
06:03lvh Can't define method not in interfaces: create_BANG_
06:03lvhclgv: (goes away without this, leading me to believe that it's convinced that method with that arity doesn't exist)
06:04clgvlvh: do you have the first param for "this" in the protcol and the reify?
06:04lvhclgv: Nope, just the reify
06:04lvhclgv: it should be in both?
06:04clgvlvh: yes
06:04lvhclgv: I don't understand why; I don't actually care about the "this"
06:05clgvlvh: for deftypes you sometimes do care
06:05clgvlvh: you can return the object itself without modification via "this"
06:05lvhhm, okay
06:05noniwoompenet: oh, I thought it is position. thanks
06:06lvhclgv: but if I'm writing code like mem-store that doesn't care, that doesn't mean I'm doing something wrong?
06:07clgvlvh: it's the contract of defprotocol and the others that you include that param. proxy is an exception from that with implicit definition of "this"
06:08lvhclgv: Aha; so maybe I want proxy? :-)
06:08clgvah right, and definterface is an exception as well
06:08clgvlvh: no not really if reify does what you want
06:09clgvlvh: you just want to do (reify Store (create! [_, key, value] ...) ...)
06:09lvhclgv: Okay, thanks :)
06:11clgvlvh: in the defprotocol you probably want (create! [store, key, value]) for documentation purposes
06:12lvhclgv: right; maybe I should come up with a different name for that local in mem-store
06:12lvhsince this != store :)
06:12lvh(store being an atom there)
06:13clgvlvh: yeah, I just meant that you dont use "this" or "_" there but a name associated with that protocol
06:13lvhright :)
06:13lvhthanks!
06:14clgvanytime
06:14lvhI'm going to replace "key" and "value" with more use-case-specific terms as well
06:16amitayh?
06:17dawkirstwhat does #'some-symbol mean?
06:18lvhdawkirst: that's a var quote
06:18clgvdawkirst: reference to the variable and not the value of the symbol
06:18lvhdawkirst: #'sym == (val sym)
06:18clgv,(meta #'map)
06:18clojurebot{:ns #<Namespace clojure.core>, :name map, :added "1.0", :file "clojure/core.clj", :static true, ...}
06:18clgv,(meta map)
06:18clojurebotnil
06:18clgv,(map type [map, #'map])
06:18clojurebot(clojure.core$map clojure.lang.Var)
06:19dawkirstawesome, thanks!
06:22SagiCZ1what type is lazy seq? seq or list?
06:23SagiCZ1,(map identity (drop 5 (range 10)))
06:23clojurebot(5 6 7 8 9)
06:24SagiCZ1,(type (map identity (drop 5 (range 10))))
06:24clojurebotclojure.lang.LazySeq
06:24SagiCZ1,(list? (map identity (drop 5 (range 10))))
06:24clojurebotfalse
06:24SagiCZ1why is it printed as list when its not a list
06:24TEttinger,(seq? (map identity (drop 5 (range 10))))
06:24clojurebottrue
06:24TEttingerbecause seqs and lists print the same
06:25clgvSagiCZ1: it is sequential - why do you ask?
06:25SagiCZ1,(seq? '(1 2 3))
06:25clojurebottrue
06:25clgv,(sequential? (iterate inc 0))
06:25clojurebottrue
06:25SagiCZ1i have this expression.. i need it to return [[coll1] [coll2]].. how do i simplify it?
06:25SagiCZ1(vector (vec <some-non-vec-coll>)) (vec <some-non-vec-coll>)))
06:26clgvmapv + vec
06:26SagiCZ1(doc mapv)
06:26clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
06:26clgv,(mapv vec (parition-all 2 (range 10))
06:26clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
06:26clgv,(mapv vec (parition-all 2 (range 10)))
06:26clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: parition-all in this context, compiling:(NO_SOURCE_PATH:0:0)>
06:26clgv,(mapv vec (partition-all 2 (range 10)))
06:26clojurebot[[0 1] [2 3] [4 5] [6 7] [8 9]]
06:28SagiCZ1this doesnt work (mapv vec (drop-last x coll) (take-last x coll))
06:29TEttingerclgv showed a way, SagiCZ1
06:29TEttingerreplace (range 10) with your coll
06:29SagiCZ1but i dont want partition
06:30TEttingerwhat is your input like?
06:30SagiCZ1 1 [:a :b :c :d] ==> [[:a] [:b :c :d]]
06:30SagiCZ1i am reimplementing split
06:32SagiCZ1this works too: (mapv vec (list (drop-last x coll) (take-last x coll)))
06:32TEttinger,(let [splitter 1 coll [:a :b :c :d] ] (mapv vec [(take splitter coll)(drop splitter coll)]))
06:32clojurebot[[:a] [:b :c :d]]
06:33TEttinger,(let [splitter 2 coll [:a :b :c :d] ] (mapv vec [(take splitter coll)(drop splitter coll)]))
06:33clojurebot[[:a :b] [:c :d]]
06:33SagiCZ1ok
06:33SagiCZ1thank you
06:34TEttingerno prob
06:35SagiCZ1,(= [[:a :b][:c :d]] ((:a :b)(:c :d)))
06:35clojurebot#<NullPointerException java.lang.NullPointerException>
06:36SagiCZ1,(= [[:a :b][:c :d]] '((:a :b) (:c :d)) )
06:36clojurebottrue
06:36TEttingerneed to quote the lists
06:36TEttingeryou got it
06:37SagiCZ1yeah ok.. so i actually didnt need the vectors.. i forgot that = checks the contents.. well nevermind it was an exercise :)
07:11martinklepschis there a subset? for maps where (subset? {:a 1} {:b 2 :a 1}) would be true?
07:16clgvmartinklepsch: no but you can build it via select-keys, keys and =
07:16clgv,(defn subset? [sub, super] (= sub (select-keys super (keys sub))))
07:16clojurebot#'sandbox/subset?
07:16clgv,(subset? {:a 1} {:b 2 :a 1})
07:16clojurebottrue
07:17clgv,(subset? {:a 1} {:b 2 :a 5})
07:17clojurebotfalse
07:17clgv,(subset? {:a 1 :c 9} {:b 2 :a 1})
07:17clojurebotfalse
07:17martinklepschclgv: ah, that sounds good. I was going to do some: for each mapentry in the subset check if it exists in the other map
07:18clgvmartinklepsch: that's a highlevel implementation above. in case this happens to be a bottleneck you might change to something low level via reduce or loop/recur
07:21martinklepschclgv: ok, thanks :)
07:21martinklepschonce you see the solution it always seems so obvious
07:26clgvmartinklepsch: in this case the solution was to turn around the question: >how do I get a "subset" of a hashmap in clojure?<
07:26martinklepschclgv: (= super (merge super sub)) — am I overseeing something or is this also a solution?
07:26clgvmartinklepsch: schould be yes
07:27clgvmartinklepsch: but here, the order of the maps is important. "sub" must be in second position such that it overrides the values in "super"
07:27martinklepschyup
09:14tsdhHi. Is it possible to attach metadata to letfn-bound functions? Or well, it is, but is there a way to access it from the letfn's other fndecls and its body?
09:15clgvtsdh: why?
09:16clgvtsdh: whatever you want to do sounds pretty complicated
09:17clgv,(let [f (with-meta #(inc %) {:awesome true})] (meta f))
09:17clojurebot{:awesome true}
09:17tsdhclgv: I have a macro that expands into a letfn form, and I'd like to annotate the functions with some metadata for implementing black magic. ;-)
09:17clgvtsdh: you might need to move back to `let` if letfn wont let you do that
09:18tsdhclgv: let+fn won't do the trick because the individual functions may call each other.
09:18clgv,(letfn [(^:awesome f [x] (inc x))] (meta f))
09:18clojurebotnil
09:18tsdhclgv: I.e., they may be mutual recursive.
09:18gfredericksdoes anybody know why it would ever be helpful to `ln -s src/data_readers.clj data_readers.clj`?
09:18clgv,(letfn [(f {:awesome true} [x] (inc x))] (meta f))
09:18clojurebot#<CompilerException java.lang.IllegalArgumentException: Parameter declaration {:awesome true} should be a vector, compiling:(NO_SOURCE_PATH:0:0)>
09:18tsdhclgv: Yeah, that's what I tried, too.
09:19clgvtsdh: yeah but it's the wrong one anyway. that metadata is likely lost after compilation
09:19tsdhclgv: I only need it during macro expansion time.
09:19clgvtsdh: well then you have it on the symbol `f` in the above example
09:20tsdhclgv: But (identical? 'foo 'foo) ;=> nil
09:20tsdhclgv: Ah, not nil but false.
09:20clgv,(-> "(^:awesome f [x] (inc x))" read-string first meta)
09:20clojurebot{:awesome true}
09:23tsdhclgv: Hm, thinking about it, I could pass along a set of function names (with metadata), so (this-set 'f) would return the symbol f with the metadata...
09:45justin_smithlvh: get is based on an interface that you can implement
09:45lvhjustin_smith: Oh, cool.
09:45justin_smith(regarding some scrollback)
09:46justin_smithmost of the core of clojure is programmed in terms of interfaces rather than classes, so you can use the core functions on your own datatypes as long as they implement the appropriate interfaces
09:47justin_smithI don't know of an authoritative doc about what those interfaces are - but they are all in one place as protocols in cljs https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L201
09:48justin_smithI think that for get you need ILookup (and maybe IAssociative too?)
09:48martinklepschI want to load 4gb of maps into memory and filter/query/transform them. Is an atom appropriate if I want to later-add data?
09:50justin_smithmartinklepsch: it seems like all this would be much simpler with a proper database
09:50justin_smithnot to say you can't do 4gb immutible datastructures
09:54gfredericksmartinklepsch: it doesn't sound like a use case for state
09:54gfredericksbut that's hard to evaluate without knowing your application architecture
09:55lvhare test names typically CamelCase or lispy-case?
09:55lvh(I appear to be seeing both)
09:56gfredericksnames of tests?
09:56gfrederickslike (deftest ILikeCamels ...)?
09:56gfredericksI've never seen that
09:56justin_smithCamelCase is for things that are directly created on a jvm level (protocols become interfaces, records / deftypes become classes, etc.) it should be avoided otherwise
09:56martinklepschjustin_smith: the querying I want to do would require a complex database setups (compared to reading just from files on disk) and so I thought it's fine to just run map/filter etc on one big data structure
09:58justin_smithmartinklepsch: OK, if the structure is not uniform enough for a db to make sense than don't use one, it just seemed like "controlled mutation? huge dataset? why isn't this a db?"
10:03martinklepschthe information about mutations isn't very important I to be able to manage how much data is loaded/load more
10:04milos_cohageni've been haunted the past couple of weeks ever since i spent a day trying to understand implementing foldl in terms of foldr in haskell. thoughts of comparing clojure's lazy-seqs versus haskell's lazy evaluation. need to focus on my day job writing js!
10:06justin_smithmartinklepsch: yeah, you can do that via a global atom in a def, or via args to a recursive function, or the carried state argument of a reduce...
10:08justin_smithmartinklepsch: consider that a global atom can be used to parallelize in one way, while local / recursive bindings parallelize in another way entirely
10:10martinklepschjustin_smith: I don't really know what you mean by recursive binding
10:11martinklepschcan you maybe point me to an example?
10:12justin_smithmartinklepsch: think along the lines of a reduce on a line-seq
10:12justin_smiththough you wouldn't be doing that, I am sure
10:13justin_smithreduce on a line seq is an alternative to slurping the whole text document, and in some cases lets you get the same work done with less resource usage
10:17justin_smith(reduce (fn [m w] (update-in m [w] (fnil inc 0))) {} (line-seq (clojure.java.io/reader (.getBytes "hello\nworld"))))
10:17justin_smith,(reduce (fn [m w] (update-in m [w] (fnil inc 0))) {} (line-seq (clojure.java.io/reader (.getBytes "hello\nworld"))))
10:17clojurebot{"world" 1, "hello" 1}
10:21bultersg'day all! Can someone here perhaps shed some light on how [{:keys [...]}] destructuring actually works? It seems a bit like a magical built in to be
10:22bulterswhich - considering how the rest of clojure is designed - doesn't ring too well with me :P
10:23justin_smithit's something called destreucture, which is called by fn and let
10:23justin_smith*destructure
10:24justin_smithhttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4160 source is here
10:24bultersthat's one helluva function
10:24bultersjust found it :P
10:25justin_smithso that is called, inside the let macro
10:25justin_smithand also gets invoked eventually in the expansion of fn (though that is less clear to be sure)
10:28bultersjustin_smith: probably the reason i didn't find it "in fn"
10:28bultersdidn't think of looking into let, hindsight: much easier to find
10:29justin_smithor loop even :)
10:29bulterstrue, though I don't really use loop that often :P
10:29bultersso that would have been my last guess so to say
10:30justin_smithto be fair, "destructure" should have been the first thing to search for - it is the most intuitive name :)
10:32bultersjust to show of my inexperience: I didn't actually think it was a 'dedicated function'; more like some magical construct I overlooked somewhere
10:32justin_smithin clojure a magical construct will often be a function
10:32bultersTIL!
10:33justin_smiththe set of special forms is pretty short, after that you have functions and macros
10:33justin_smith*(and reader macros...)
10:35bultersbut let is mentioned as a special form... still it's also implemented as a macro in core.clj
10:35justin_smithlet* is the true special form
10:35bultersah
10:35justin_smithlet is a macro wrapping it
10:36justin_smith(and that macro gets a :special-form metadata...)
10:36justin_smithsimilar to fn and fn*
10:36scriptorit's a fairly simple macro, too
10:37justin_smithbasically all it does is implement the destructuring before let* is invoked
10:37scriptorall it does is destructure the bindings you pass and then call let*
10:37justin_smithright
10:37justin_smithwhich brings this all full circle
10:37bultersI love this sh*t
10:38scriptordestructure, on the other hand, is a bit more hairy :)
10:38scriptorhttp://clojuredocs.org/clojure_core/clojure.core/destructure
10:38justin_smithyup
10:39bultersscriptor: I'm blankly staring at it right now...
10:40bultersbut it's really nice to see that magic is just functions all the way down :P
10:40justin_smithmostly - until you hit java and / or directly generated byte code...
11:05sdegutisWhat's a good project management online service that lets me organize and categorize tasks and put estimates on them?
11:06cbpa jira server
11:06sdegutisIs that a bad thing?
11:06sdegutisWhy run?
11:08ephemeronsdegutis: For generic tasks/management? Many people seem to like Trello, or Asana.
11:08sdegutisThanks.
11:08ephemeronOther people would just look at you sternly and whisper "orgmode".
11:19michaniskincemerick: do you know of any nrepl middleware example that adds things to stderr? i'm working on a job control thing, and i'd like to be able to notify the user about completed background jobs when the prompt is printed, like bash does
11:30cemerickmichaniskin: not off the top of my head, but that should be straightforward. A broadcast to all sessions would be way easier than trying to confine the messages to only the session that started the job(s), certainly.
11:30michaniskincemerick: i'd be tagging onto the :eval op, i guess?
11:31cemerickmichaniskin: sounds complicated. These jobs presumably have many ways to report status/progress/completion? If so, adding an implementation that spams all connected nREPL sessions should be simple.
11:32cemerickIf "jobs" == arbitrary futures, etc., then that's way more subtle.
11:32michaniskincemerick: the jobs themselves add their completion status to a queue, it's just a matter of doseq prn on the queue
11:33michaniskinthe middleware wouldn't need to know anything about the jobs themselves
11:33michaniskinjust check the queue any time something is evaled
11:33michaniskinand print the contents and empty it
11:33michaniskinlike a flash message, kinda
11:33cemerickEven better, then. I thought you wanted to analyze the :code sent for eval to identify jobs being started, etc
11:34michaniskinprocesses can add messages to the flash queue, and they're popped and printed any time the prompt is printed
11:34cemerickSo, yes, you can use :eval ops passing by as a trigger.
11:34michaniskinis there a key in the message for stderr or stdout?
11:34cemerickMight be nicer to just poll every N seconds, just so you aren't evaling stupid stuff to know when a job finishes tho.
11:34csd_What is the easiest way to take a seq of vector in the form of [-1] [0] [1] ... and a seq of related sets in the form #{-2} #{-1} #{0} and to create a map with the vectors as keys, the sets as values, and the understanding that if a key already exists that the additional value be joined to an existing set?
11:35azizurhello everyone is there anyone from http-kit.org on there?
11:35michaniskincemerick: the job control is working nicely without middleware, but the notification of completed jobs is being printed async, which is a pain
11:35michaniskini just need to be notified when the prompt is being printed i guess
11:36cemerickmichaniskin: no, write to the writer in each session mapped to #'*err* https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/session.clj#L121
11:36cemerickPrompt stuff is strictly a client-side tooling concern
11:36cemerickSome tools don't have prompts.
11:36michaniskinso i can write to *err* in my middleware?
11:38michaniskinok i now compute some code :)
11:38michaniskinthanks cemerick!
11:39cemerickmichaniskin: Yeah, sessions are just maps of vars -> bindings; deref and be merry
11:40cemerick#'clojure.tools.nrepl.middleware.session/session, or whatever
11:40cemericksessions*
11:42TimMccsd_: Something like (apply merge-with set/union (map hash-map vec-keys set-vals))
11:43csd_TimMc: thank you!
11:45TimMc&(apply merge-with clojure.set/union (map hash-map [:a :c :d :c] [#{1} #{2} #{3} #{4}]))
11:45lazybot⇒ {:a #{1}, :c #{2 4}, :d #{3}}
11:55azizuris it possible to write a fully non-blocking application with http-kit and luminus framework?
11:56gtrakazizur: pedestal is made for this
11:56virmundiazizur: I don’t know about liuminus, but have you looked at Pulsar (https://github.com/puniverse/pulsar)
11:56gtrakcompojure/ring don't give you as much flexibility
11:57virmundithe nice thing about pulsar is that Parallel Universe is trying to make a ring adapter for it.
11:57ohpauleez+1 for Pedestal :)
11:58justin_smithpulsar also tries to replace core.async, right?
11:59virmundikinda, it complementary with an Actor model
11:59doctormCan someone recommend an article on debugging in Clojure? Mainly I’m interested in the best way to get some insight into what third party programs are doing
11:59doctormthird party libs* that is
11:59justin_smithdoctorm: core.trace is really useful for that
11:59gtrakdoctorm: conveniently you can eval in any namespace, I redefine things often.
12:00doctormjustin_smith: thanks, I’ll check it out
12:00gtrakdirectly from a cider jar buffer
12:00gtrakthough it throws an error about saving read-only files or somesuch :-)
12:00justin_smithdoctorm: also, if you need a finer level of granularity than function arg and return values, you can redefine things as gtrak says
12:01langmartinI'm doing it right now!
12:01justin_smithgtrak: well, directly from any repl, no need to drag cider into that :)
12:01gtrakin principle, yea, that's just how I happen to do it
12:02doctormI’m new, what do you mean by redefine? Like, if I want to get a tracer into a library I’m using so I can watch a value as the function runs, how would I go about it?
12:02justin_smithdoctorm: core.trace is made for that - it has a function to trace every funciton in a given ns, or to trace a specific function
12:02gtrak(in-ns 'that-ns), (def blah __)
12:02gtrakit's convenient to have the existing source handy
12:02doctormAlright, thank you, I’ll experiment for a bit
12:02justin_smithdoctorm: or you can do as gtrak says if you want to simply redefine the functions in that ns
12:03justin_smithgtrak: with clojure you always have the existing source
12:03justin_smith,(doc source)
12:03clojurebot"([n]); Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)"
12:04justin_smithdoctorm: oh man, why did I call it core.trace? it's tools.trace https://github.com/clojure/tools.trace
12:04doctormjustin_smith: I figured you meant that, found it thanks :)
12:04justin_smiththe functions you want are trace-ns and trace-vars
12:08PupenoAt the last Clojure meetup, a lot of people were using a new nice editor on mac, but I forgot its name... what could it be?
12:08TimMctrace-ns may or may not still have a bug where it tries to trace things like (def foo {})
12:08arrdememacs, light table and sublime text could all fit the bill...
12:08arrdemAtom maybe
12:08justin_smithintellij idea + cursive
12:09Bronsacursive++
12:09Pupenolight table
12:09PupenoThat's.
12:14imancis cursive a jetbrains product?
12:14justin_smithhttps://cursiveclojure.com/
12:15sdegutisI think I'm settling on using Trello.
12:16justin_smithimanc: I think it's a third party plugin, with the aims of eventually being a commercial standalone ide (right now it is a free preview)
12:16pmonks+1 to Trello - it’s great
12:18stuartsierraazizur: It is possible to write fully non-blocking applications in Clojure, but it can be hard to find every possible case of blocking I/O in every third-party dependency. Even Java libraries which claim to be "non-blocking" may sometimes do blocking operations. That's one reason Netflix wrote Hystrix, I believe.
12:18PupenoYes, it's a third party plugin for Jetbrains, free for now.
12:20doctormI’m getting “Parameter declaration trace-vars should be a vector” doing (trace-vars exec-raw), which was the nearly the same error message I was trying to debug. What does that message usually indicate?
12:20justin_smithdoctorm: can you paste the code that provoked that error?
12:21TimMc~paste
12:21clojurebotpaste is not gist.github.com
12:21TimMcThanks, clojurebot.
12:21TimMc~paste
12:21clojurebotpaste is not gist.github.com
12:21justin_smithdoctorm: refheap.com is good for pasting
12:21TimMcclojurebot: forget paste |is| not gist.github.com
12:21clojurebotI forgot that paste is not gist.github.com
12:21doctormjustin_smith: sure, it’s a little weird because it’s in a migration file with drift, but I will
12:21TimMcclojurebot: forget paste |is not| gist.github.com
12:21clojurebotI forgot that paste is not gist.github.com
12:22justin_smithdoctorm: that error means that it thinks the call to trace-vars should have been the parameter declaration for an fn (or maybe a binding form for a loop)
12:22doctormhttps://www.refheap.com/89490
12:22justin_smithbut with some context we can see the issue
12:22justin_smithdoctorm: defn needs a vector
12:22doctormah of course it does, thanks
12:23justin_smithparameter declaration must come before the body
12:23justin_smithalso, down needs a parameter vector
12:23justin_smithit can be an empty vector if it takes no args
12:26doctormInterestingly, trace-var causes a NullPointerException to be thrown once I fix the function vector problem
12:29csd_Is it possible to represent an empty vector [] as a different arity than [1 2 ...] either using destructuring or otherwise?
12:29justin_smithcsd_: wat
12:30llasramcsd_: Yeah, gonna need a bit more there :-)
12:30justin_smithvectors don't have arities, and I have no idea what you mean by [1 2 ...]
12:31csd_I want to write a multi-variadic function where if I pass [] then the function just returns an empty [], but if the vector has values it evaluates the vector. I just want to write this in the multivariadic idiom
12:31csd_hope that makes sense
12:31justin_smithcsd_: destructuring is not pattern matching
12:31llasramcsd_: You can either `apply` the vector, or use pattern matching via core.match
12:32csd_how would i do this using apply
12:32mdeboardarity dispatch is pattern matching, kinda
12:32mdeboard(apply foo [])
12:32llasramcsd_: Er, I meant `apply` a function to the vector
12:32justin_smithmdeboard: but he wants dispatch on the content of a vector
12:33mdeboardo
12:33mdeboarduse erlang
12:33mdeboardproblem solved
12:33llasramcsd_: Which will dispatch based on the number of elements in the vector
12:33csd_oh i get you
12:35martinklepschI have a list that contains a few elements less when making it into a set. I'd like to know the duplicates but a function like dups [see link] doesn't return anything: http://stackoverflow.com/questions/8056645/returning-duplicates-in-a-sequence
12:36martinklepsch(it returns nil to be precise)
12:36hiredman(doc group-by)
12:36clojurebot"([f coll]); Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."
12:37llasram,(->> (concat (range 10) (range 5)) (frequencies) (filter (comp pos? dec val)))
12:37clojurebot([0 2] [1 2] [4 2] [3 2] [2 2])
12:37justin_smith,(reduce (fn [[found dups] e] (if (contains? found e) [found (conj dups e)] [(conj found e) dups])) [#{} #{}] [0 1 2 1 2 1 3 4])
12:37clojurebot[#{0 1 4 3 2} #{1 2}]
12:38milos_cohagenmartinklepsch: use the set as predicate on list after you create the set?
12:38hiredmanguys, group-by
12:39justin_smithoh yeah, the keys give you the set, the vals tell you how many times each came up
12:39justin_smithbut why not just frequencies?
12:39dnolen_thheller: ping
12:41hiredmanjustin_smith: sure frequencies too, all that other stuff is ridiculous
12:41llasram,((fn step ([coll] (step #{} coll)) ([seen? coll] (when-let [[x & coll] (seq coll)] (if (seen? x) (cons x (step seen? coll)) (step (conj seen? x) coll))))) [0 1 2 1 2 1 3 4])
12:41clojurebot(1 2 1)
12:41llasramThat one's lazy!
12:41llasramEr
12:41llasramOr would have been if I'd remembered the `lazy-seq`
12:41hiredmanhah
12:44martinklepschjustin_smith: using your suggestion the second set (which seems to contain the dupes) is printed as #{...} — could that be related me doing: (set! *print-length* 50)
12:46justin_smithI think? I'm often unsuer about *print-length* and related stuff
12:49martinklepschhm. just set it to false and still get #{...} — it's not a map literal right?
12:50Bronsamartinklepsch: try to set *print-level* to nil
12:51martinklepschBronsa: I tried false and nil
12:52justin_smithmartinklepsch: and it definitely isn't just ##'#{...} ?
12:52lazybot⇒ #{...}
12:52Bronsamartinklepsch: *print-level*, not *print-length*
12:53TimMc,[*print-level* *print-length*]
12:53clojurebot[10 5]
12:53TimMc&[*print-level* *print-length*]
12:53lazybot⇒ [nil nil]
12:54alandipertRaynes, is there a quick way with conc to stream a processes's err to out? trying to drive/see rsync stderr
12:54alandipert*conch that is
12:55alandipert(i tried (proc ... {:err *out*}) to apparent effect
12:59martinklepschBronsa: oh, sorry. print-level set to nil didn't change it. It works fine for a seq like [1 1 2 3 4 4 5] but with my 12000 elem seq it doesn't
13:01dnolen_sritchie: ping
13:01sritchiehey
13:01dnolen_sritchie: http://dev.clojure.org/jira/browse/CLJS-839
13:01dnolen_attached a possible patch, if you could test that would be awesome
13:02sritchiednolen_: I was actually about to fix my issue by upgrading beyond 2261
13:02dnolen_sritchie: the patch simply keeps Math.imul polyfill out of advanced compilation hopefully that's all that's needed
13:02sritchieit looks like you added the shim imul implementation after the version I’d been using
13:02dnolen_sritchie: ah yeah, there was *another* Safari imul bug that we addressed too
13:02dnolen_thheller: also ^
13:02sritchie:)
13:03Raynesalandipert: I thought that was a thing you can do, but it doesn't look like it.
13:03RaynesCertainly a patch I'd take. Otherwise, you can always pass the :verbose option to get back a map with both types of output.
13:05schmeednolen_: hey, I was looking at core.match today, and I was wondering if it contains any form of exhaustiveness or reachability checking of the patterns?
13:06dnolen_schmee: it errors out if you there's not a corresponding match, precise exhaustiveness doesn't mean much in a dynamically typed context
13:06schmeednolen_: yeah, I figured as much
13:07schmeebut computing reachability should be possible, in some sense at least?
13:07dnolen_schmee: I don't see how that's possible except for trivial cases
13:08dnolen_schmee: and those will get picked up by Google Closure anyhow
13:09schmeednolen_: aight!
13:09schmeethanks for your great work and presentations btw, really inspiring!
13:10dnolen_schmee: your welcome and thank you for saying so.
13:10mdeboardplease, you'll embarass him
13:11schmeeimo people spend to much time calling out stuff they don't like instead of the stuff they actually like
13:11schmeecredit where credit is due! :)
13:12mdeboardhe's doing it all for the nookie
13:12alandipertRaynes, thanks i may
13:12Raynesalandipert: I'm super shocked I never implemented that functionality, fwiw.
13:13RaynesSurprised that I didn't need it myself
13:13hlprmnkydnolen_ : hear, hear! Your recent talk gave me the grasp of core.async I needed to tackle a fun little project at work.
13:13dnolen_hlprmnky: cool!
13:14hlprmnkymy first actual soup-to-nuts Clojure “app”, actually, as opposed to maintenance and extension on someone else’s work. Feels good, man.
13:28jakecraigeAre there any good blog posts on stucturing a web app written in clojure? Just getting the handler file is a start but I'm not sure what other folders I might need. I guess a good example app would be nice as well
13:29jakecraigeor should i be using some sort of web framework for clojure
13:30technomancyjakecraige: https://github.com/technomancy/syme is a small nontrivial sample app you could read for guidance/samples
13:33jakecraigetechnomancy: thanks, I'll check it out
13:33technomancyin particular I would recommend using the strategy there for DB migrations
13:39|xk05|on 'lein repl' in a terminal, i get Exception in thread "nREPL-worker-0" java.lang.NoSuchMethodError: clojure.tools.nrepl.StdOutBuffer.length()I
13:41technomancy|xk05|: yeah, this is a known bug; need to work inside a project or fall back to 2.4.2 until 2.4.4 is released
13:41|xk05|technomancy, ok
13:45TimMcAugh, what.
13:45TimMcOK, so I have a project depending on rxjava-clojure, which has a dependency on org.clojure/clojure "1.4.+", which is some Gradle nonsense.
13:46TimMcThis obviously breaks various lein tasks that try to fetch the nonexistent version.
13:47TimMcI've used :exclusions on my lib (project #1), but project #2 depends on #1 and keeps trying to fetch Clojure 1.4.+. :-(
13:47TimMcIs there some way to stop this madness?
13:48technomancyTimMc: exclusions in #2 don't work?
13:49TimMcOh, I need both?
13:49technomancyTimMc: not sure; worth trying though
13:51TimMcOK, in retrospect that makes sense, in a certain twisted way.
13:51TimMcWorks, thanks.
13:51technomancycool
13:51TimMcNow I'm back to my original error. Whee.
13:53hiredmanhttp://dev.clojure.org/jira/browse/CLJ-1512 I really really want to put a comment on here "if only clojure had some way of defining inlinable functions..." but I won't
13:54llasrambuuuurn
13:55llasramActually -- manually setting `:inline` metadata totally works. It's just `definline` which is insane for no reason
13:55hiredmanalso, "updates are racy, but access is controlled"
13:56llasramYeah. It's too bad the JVM doesn't have some sort of support for local per-thread mutable state
13:56amalloyhiredman: sounds like the paywall page for a premium cable channel
13:57technomancybahaha
13:57hiredmanhah
13:59Bronsahiredman: if you won't, I will (leaving aside the sarcastic tone) I wouldn't be happy with vswap! being a macro
14:00hiredmanBronsa: it would be interesting to see how swap! would perform if inlined (get rid of the use of apply)
14:02Bronsahiredman: can apply really be a bottleneck?
14:02hiredmanI have no idea
14:02hiredmanI have a vague notion that apply is really slow
14:02amalloyBronsa: yes, it could be
14:02amalloymostly because you have to build an argseq, not because apply itself is slow
14:03amalloyalthough a fair number of my uses of swap! aren't inlinable, with stuff like (update-in my-app [:state] swap! assoc :done true)
14:03hiredmanalex's "benchmark" there doesn't show a huge difference, but then again it is using dotimes
14:04TimMccriterium or nothing
14:04amalloyspeaking of core not using criterium, do they use lein yet, these days?
14:04TimMctechnomancy: I guess this means that every project needs to document its exclusions. :-(
14:04Bronsaamalloy: ah, that might make sense
14:05hiredmana lot of contrib has a project.clj checked in
14:05technomancyTimMc: every project that transitively includes brokenness, sure
14:05TimMcblerg
14:05technomancyit's pretty rare to come across version ranges these days
14:06amalloyyeah, but it's not "official", right. they all have to use a pom for releases and so on
14:06Bronsayes
14:06Bronsahudson uses the pom.xml
14:06amalloytechnomancy: it's not even version ranges that are the problem; it's the totally made-up "1.4.+" syntax that lein/maven can't understand at all
14:06amalloythey can't process the exclusion for it because it's not a real thing
14:06technomancyamalloy: yeah, but version ranges are a lot more common
14:06technomancyand are worked around the same way
14:07amalloywell so what? they won't cause the problem TimMc has
14:07amalloyyou can just fight a version range by adding one of your own on a specific version
14:07technomancyamalloy: adding your own version range?
14:07amalloy[org.clojure/clojure "[1.6.0]")
14:07technomancythat works for applications but is a bad idea for libraries
14:07amalloysure
14:08amalloybut the solution you proposed doesn't really work for libraries either. he has to exclude it in his app
14:08amalloyor else it sneaks in transitively
14:10technomancygotcha, yeah
14:10technomancythe real solution is to report it as a bug upstream and squash it
14:11TimMcI've already opened a ticket for it, yeah. https://github.com/ReactiveX/RxClojure/issues/2
14:11amalloy"bug: uses gradle"
14:11technomancybe the change you want to see in the world
14:12amalloyTimMc: "occasionally"? i can't imagine why it wouldn't be every time
14:13technomancyamalloy: it might be that ranges have the same daily caching logic as snapshots
14:13technomancyand failures are cached, which is almost always the wrong thing, but could accidentally be helpful in this situation
14:15TimMcThat's my best guess, although it will also happen multiple times in the same day (sometimes.)
14:15joshuafcoleWhy does the transitive dependency happen in the first place? Are there cases where that is a useful behavior?
14:16technomancyjoshuafcole: sure, like ... every time there's not a version range, basically?
14:18joshuafcoleSorry, maybe I'm using the wrong terminology (or am misunderstanding the problem). but is sounds like if B depends on A, excluding x from A, and C depends on B, then C gets x as a dep regardless of B's exclusion?
14:19technomancyoh, yeah I'm not sure about that
14:19tacDoes Clojure merely require the JRE? (and not the JDK?)
14:19technomancywe get a whole bunch of behaviour from aether that is 95% golden, and there is the occasional questionable decision thrown in.
14:20technomancythey're rare enough that it's not worth the headache of diverging from their implementation, but they do crop up every once in a while.
14:20technomancytac: correct
14:21seangrovetechnomancy: I've been looking at Mirage and Halvm for fun recently - have you found OCaml's type system to be useful at all?
14:21joshuafcoleAh I see. I'll look into Aether. I'm just trying to examine the turtles beneath my feet now, so if the tower teeters on me later I'll know which direction to move in. :)
14:21technomancyseangrove: yeah, it is wonderful.
14:22csd_How do I easily convert from hash-set (#{1} #{2} #{3}) to list (1 2 3) ?
14:23amalloyapply concat
14:23seangrove,(apply concat (hash-set #{1} #{3} #{2}))
14:23clojurebot(3 2 1)
14:24seangroveAs per amalloy's frighteningly quick suggestion
14:24amalloyfrighteningly quick is at least like twice as fast. that took almost a minute
14:25csd_amalloy: thanks thats useful, but is there a way that shows the behinds the scenes of how to convert the type from one form to the other?
14:25joshuafcoleFrighteningly quick is at least 30 seconds.
14:25joshuafcolenoted
14:27imancnewb question, but why doesn't that result in '(#{1} #{2} #{3}) ?
14:27amalloyimanc: it's the difference between apply concat vs just concat
14:27technomancyseangrove: I was super impressed with ocaml's types; they never got in the way and always pointed me at places where I made actual mistakes.
14:27technomancyseangrove: the one exception (to never getting in the way) was code that dealt with serialization; you do need to do more spoon-feeding there if you're not working against a schema.
14:28seangrovetechnomancy: I've been playing around with Haskell a bit, and I haven't found the types to be a bother really, once I got past the syntax
14:28tactechnomancy: The amazing thing is when you go to refactor typed code. You spend an hour or two fixing type errors, then it mostly just works after it compiles again :D
14:28technomancytac: the codebase I was working on was pretty tiny (under 1kloc) so it's not really representative, but I found that to be mostly true
14:29technomancyalso ocaml is super easy to pick up if you know clojure
14:29technomancyyou can be relatively productive in a week
14:29turbofailclearly we need a hybrid of the two. clojaml
14:29technomancyas long as you're willing to just spam your code with moar parens when you can't figure out the precedence rules
14:29justin_smithcsd_: regarding "behind the scenes", most sequence operations call seq on their arguments ##(map seq [[1 2 3 4] '(1 2 3 4) #{1 2 3 4} {1 2 3 4}])
14:29seangroveThat was definitely one of the bigger annoyances, I mised sexp's
14:29lazybot⇒ ((1 2 3 4) (1 2 3 4) (1 2 3 4) ([1 2] [3 4]))
14:30technomancyseangrove: yeah, but I was surprised that I didn't miss macros. just the regularity and predictability.
14:30tacthe one and only thing that keeps me from seriously looking into ocaml is that silly GIL
14:31tacit sounds like they are working to fix that, though
14:31technomancytac: I find that just makes it complementary to Clojure.
14:31justin_smithmy ocaml variant idea is ocalm - it's the lazy ocaml
14:31turbofailhuh. why would ocaml need a GIL?
14:31seangrovetac: Which language are you comparing it to?
14:31technomancyif you need something big and beefy with concurrency, it's not a great fit for ocaml; if you need something small and lightweight, it's not a great fit for clojure.
14:31technomancyturbofail: for the GC
14:31turbofaildo they use reference counting or something?
14:31tacturbofail: probably multithreaded programming just wasn't a priority
14:31Bronsawhen I first started learning lisp, macros were the thing I was most excited about. Now I find myself trying to avoid using them as much as possible
14:32tacseangrove: I use mostly Haskell and Python.
14:32justin_smithand backporting concurrency to something not designed with concurrency in mind is usually a huge PITA
14:32technomancyactual concurrent production GC is incredibly difficult to do well. afaik it's only been implemented 5 times or so total.
14:32tacTrying to get clojure installed and running atm so I can go visit a Clojure meetup in town tomorrow night
14:32justin_smithtac: don't install clojure -install lein
14:32tacI'm slowly learning this
14:33technomancylike, in the entire world.
14:33tacI installed lein (not sure what it's for), and did a ./lein new hello
14:33justin_smithtac: lein is the build tool and dependency manager. One of the dependencies it handles is clojure itself
14:33tacoh, and I can apparently run it
14:33tacneat
14:33tacis lein a clojure thing, then?
14:34justin_smithyes, and it's one of the best things about clojure IMHO
14:34turbofailthere's still a big difference between a not-quite-concurrent GC and a language runtime with a GIL
14:35tacwhy is it annotated -main instead of main?
14:35justin_smithtac: that's how gen-class works
14:35justin_smith-foo is the method foo
14:35tacah
14:35justin_smithmain needs to be a method
14:35amalloytac: because main is a special case of gen-classing, which uses - as a prefix to say "this should be a generated method"
14:36tacand there's no compile cycle in clojure (by default)?
14:36tacI just run my project with lein?
14:36justin_smithtac: every clojure statement is compiled when evaluated
14:36justin_smiththere is the possibility of doing an uberjar / jar package - but that's more about packaging than compiling usually
14:37amalloytac: i don't actually run with lein very often. either i'm developing, in which case i do everything from the repl; or i'm releasing/deploying, in which case i build a jar
14:37justin_smithunless you use :aot - but :aot is very unpopular and a huge source of bugs
14:37tacgotcha. so you can ship jars to Corporatus, and they don't need to ask any questions about which technology you wrote your middlewarez in
14:37tacamalloy: how do you launch the repl then?
14:37justin_smithtac: so you can run your code on the prod server without installing anything but a jvm on the other end
14:38amalloywell, really i do it from emacs, with lein jack-in
14:38technomancyjustin_smith: AOT during development, specifically
14:38amalloybut you can use lein repl if you aren't ready to figure out editor tooling
14:38justin_smithtechnomancy: sure - but even in production how often is it really useful?
14:38technomancyjustin_smith: depends on whether you care about startup time
14:38tacah, lein repl does the trick
14:39tacI don't think i need to be at a point tomorrow where I'm shipping code. But just knowing basic basic syntax would help me mingle with the Clojure crowd
14:39technomancyjustin_smith: it's also a decent sanity check that everything actually compiles if you haven't bothered to set up a proper ci->deploy pipeline
14:39justin_smithtac: if you had created the project with lein new app hello you could also use "lein run" (though the changes needed to make a "lein new" project runnable are pretty minor too)
14:40justin_smithtechnomancy: good point, I usually use "lein do check test" for that
14:40celwellShould I use buddy or friend for my authentication needs?
14:40justin_smiththat's "lein do check, test" of course
14:40technomancyjustin_smith: IMO `lein compile :all` is better than check unless you're hypersensitive to reflection.
14:41justin_smithtechnomancy: what's the improvement?
14:42technomancyjustin_smith: less noisy, speeds up boot
14:42technomancyit's minor though
14:43amalloycelwell: i've never heard of buddy. it sounds like it must be based on friend
14:43tadniHrm, cider doesn't seem to be opening an nrepl conncetion.
14:43turbofailhm. http://www.ocamljava.org/ is a thing
14:43technomancyI'm not convinced check is worth including as its own task tbh; it's just compiling with warn-on-reflection, and then discarding the class files
14:44technomancyit would be better expressed as a composition of existing tasks
14:44celwellamalloy: I think it's relatively new https://github.com/niwibe/buddy
14:44technomancyturbofail: wow
14:45technomancywait, both implementations are made by different people named Xavier?
14:45technomancyweird
14:45turbofailif it actually works it seems like it'd be a great replacement for scala
14:45justin_smithturbofail: my thoughts exactly
14:49turbofailhm. looks like it still needs some work
14:49turbofailstill interesting though
14:51technomancysimilar to erjang
14:51technomancyit's pretty amazing how much progress that project was able to make as a one-man-show
14:51technomancyespecially compared to jruby, which basically didn't get close until it had corporate backing
14:51drguildodoes anybody have any advice for debugging a process that hangs?
14:54aperiodicdrguildo: check to make sure all your loop/recurs terminate
14:54aperiodicthat's usually the problem if the process sits there spinning without blowing stack
14:54drguildoaperiodic, there are none
14:54mdrogalisdrguildo: Check out jstack
14:55mdrogalisYou can see what a running pid is up to
14:56drguildomdrogalis, thanks
14:56tacI saw on a video the other day that 'nil' signals the end of an iterator
14:56mdrogalisdrguildo: Np
14:56tacJust to be sure, that means you can't have nils present anywhere in your iterator stream, right?
14:57tac(unless you box them somehow)
14:57turbofailiterators? we don't really do iterators in this part of town
14:58tacwhatever the proper name for them is
14:58tacseq's
14:58turbofailyou can have a nil in a seq just fine
14:58mdrogalistac: Need a little more context. Maybe you're thinking of something with core.async?
14:58turbofail(take 10 (repeat nil))
14:58tacoh, is it that if the tail of a seq is nil, then the sequence is over?
14:59turbofailyeah, either nil or the empty sequence '()
14:59tacgotcha
14:59turbofailusually you query for that using empty?
14:59mdrogalistac: I think you saw something pretty specific that doesn't extend to a larger context.
15:00tacI think it was Rich Hickey for Lisp Programmers
15:00mdrogalisEh, that guy doesnt know what he's talking about.
15:00schmeehow do I implement a custom `println` for a record?
15:00mdrogalisKidding. Yeah, not sure what he'd be referencing there.
15:01|xk05|ok, lesson #1, start LightTable in a different terminal tab than the one you will be using lein in
15:01tac,(1 . 2)
15:01clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: . in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:01tacDoes Clojure not have dotted cells like in some lisps?
15:01turbofailnope
15:01technomancytac: correct
15:01turbofailgood riddance if you ask me
15:02tacI agree
15:02tacDoes the tail always have to be a list, then?
15:02dnolen_tac: a seq
15:02tacgotcha
15:02dnolen_or nil
15:02technomancyunlike CL, the empty list is distinct from nil
15:02technomancybut they are related in ways that are somewhat surprising
15:03technomancy,(seq ()) ; kind of makes no sense, but there you have it
15:03clojurebotnil
15:03tacseq there is just doing a coercion?
15:03tacfrom the empty list to a sequence?
15:03technomancyI'm not sure what it's doing =)
15:04technomancynil is not a sequence
15:04tacwell, it's Java's null
15:04tacso it's whatever type you want
15:04technomancyanyway all that to say there are some behaviours that are simply arbitrary that you have to memorize
15:05TimMc~seqs and colls
15:05clojurebotseqs and colls is http://www.brainonfire.net/files/seqs-and-colls/main.html
15:05tacgotcha
15:05technomancyyeah, that's a good guide
15:05tacOut of curiosity, does anyone here go to the Chicago Clojure meetup?
15:06turbofailhm. i don't think i've ever bothered memorizing that
15:07technomancyturbofail: not necessarily all the charts there, but the (seq? (seq ())) ; -> false weirdness at least
15:08turbofaili didn't know that one either. it's never come up
15:08turbofaili don't think i typically call seq at all really
15:08technomancyyou see seq used as a predicate for non-emptiness a lot in the wild IME
15:08turbofailhm
15:08technomancythe official style guide even says to prefer it to (not (empty? ...))
15:08turbofaili always use not-empty for that
15:08technomancy(which I think is silly, but hey)
15:09joshuafcoleI find it interesting that (seq? nil) is false but (map fn nil) is valid. Do you guys know the reasoning behind (seq? nil) being false?
15:10technomancyturbofail: hm; actually I'm not seeing it on the wiki, but I know Rich has said it several times.
15:10stuartsierrajoshuafcole: nil is a sequence terminator
15:11technomancyjoshuafcole: I think the simplest way of explaining it is that map, etc simply accept anything you can safely pass to seq
15:11turbofailthough not-empty basically just delegates to seq
15:11turbofaillol
15:11stuartsierratechnomancy: It's in the docstring for `empty?` :)
15:12joshuafcoleInteresting, gotcha
15:12technomancystuartsierra: hah, there you go. oddly enough not in the doc for not-empty though.
15:12technomancyhttp://p.hagelb.org/mystery.gif
15:12tacthe binding keyword creates dynamically-scoped variables. is that right?
15:13technomancytac: no, it doesn't create them
15:13technomancyit just binds them to new values
15:17tacoh hm
15:17tacso binding mutates a global variable, and then when the scope ends, it mutates it back?
15:17technomancyvars are mostly created by def and the macros that expand to them
15:18tacs/global/thread-local
15:18technomancytechnically it's just pushing a new value onto a stack, bit it's similar to mutation.
15:18technomancy*but
15:18tacright right
15:19tacso operationally, they work like implicit parameters that get threaded through your function calls
15:19technomancyvars are neat... they are deceptively similar to concepts in other languages but have their own semantics which IMO are a lot nicer than what you usually see
15:19technomancyyup
15:19tacI guess that's a lot like the reader monad
15:20stuartsierraThe effect of `binding` isn't global, though, it's local to a thread.
15:20tacyeah
15:20virmundiwhere should I put documentation for a configuration object in a library I'm making like clojure.java.jdbc? Should it go in the read me? I've sprinkled pertinent parts of the configuration at various api points.
15:21tacif it were global, you'd have some janky semantics because of the changing values
15:22tacthe docs mention a clj command line tool
15:22tacif i'm using lein, I just ignore clj.. right?
15:22turbofailit's basicallly just running `java -cp clojure-x.x.jar clojure.main'
15:23tacI'm not even sure where lein puts the clojure jar
15:23stuartsierratac: What docs? There's no "official" clj command-line executable.
15:23justin_smithtac: under ~/.m2
15:24tachttp://java.ociweb.com/mark/clojure/article.html
15:24tacyou can CTRL+f for the clj instance I'm referring to
15:24tac"$ clj vars.clj
15:24tac"
15:25tacoh, and I'm hopping around, so many it was defined earlier and I missed it
15:25justin_smith"use the shell script for executing Clojure files described earlier"
15:25tacHow are sets typically implemented?
15:26turbofailhttp://en.wikipedia.org/wiki/Hash_array_mapped_trie
15:27stuartsierrajustin_smith, tac: there doesn't appear to be any description of a `clj` executable earlier on the page. Maybe a relic of something older.
15:27tacvery likely, probably!
15:28tacSo to put something into a set, it needs to be hashable and support equality comparison
15:28justin_smithtac: luckily, all java objects support that
15:28justin_smithand all primitives are trivially coercible to object form
15:30will2357Hey all, I'm fairly new to Clojure, and I was wondering if anyone has any suggestions for a fault tolerant messaging system/framework for clojure. I've seen Langohr, which runs on RabbitMQ, but as they say it is not an "API for task queues that hides all the AMQP machinery from the developer". Anyone know of a simple API for task queues?
15:30will2357That happens to be fault-tolerant (i.e., can't lose a message due to a handler crash)?
15:31SagiCZ1how about oracles activeMQ with clojures java interop?
15:32tacjustin_smith: I think I'm thinking with my haskell glasses on again, thinking to myself "function objects are incomparable"
15:33justin_smithtac: they aren't ordered, but they can be equal or not (in clojure)
15:33SagiCZ1clgv: are you here by any chance?
15:33justin_smith,(= rand #(rand)) ; tac
15:33clojurebotfalse
15:33justin_smith,(= rand rand) ; tac
15:33clojurebottrue
15:34justin_smith,(hash rand)
15:34clojurebot2416519
15:35justin_smith,(isa? (class rand) Object)
15:35clojurebottrue
15:35tacbut
15:35tac,(= rand (fn [] (rand)))
15:35clojurebotfalse
15:36justin_smithyes, it is a weak equality
15:36justin_smithand #(rand) is just a fancy way of saying what you did above
15:37justin_smithor maybe we could call it a conservative equality, that misses many chances to label equivalent objects as equal
15:37justin_smith,(= #(rand) #(rand))
15:37clojurebotfalse
15:38tacsets, arrays, lists, and maps are all immutable, right?
15:38justin_smitharrays are mutible
15:38justin_smithvectors are immutible
15:38tacgotcha
15:39taccan vectors change length? Or is it just their cells can be repointed at other things?
15:39justin_smiththey can't change, they are immutible
15:40tacerr
15:40tachmm
15:40tacI didn't read that carefully enough
15:40justin_smiththough you can create a new one that appends to an old one efficiently
15:40justin_smitharrays cannot change length either
15:40schmeewhen implementing a protocol on a record, can the functions in the protocol call each other?
15:40schmeeI'm getting some errors and I'm not sure if that's the issue, or something else...
15:41justin_smithtac: and yeah, cells in an array can be reassigned
15:42tac[a b c] is array syntax right?
15:42tacand (a b c) is.... vector?
15:42justin_smithno
15:42justin_smith[a b c] is a vector
15:42justin_smith(a b c) is calling a on the args b and c
15:42justin_smith'(a b c) is a list literal
15:43justin_smiththere is no literal notation for arrays, they are an underlying jvm construct
15:43tacahh ok
15:43tacso they are less "blessed" in clojure, right?
15:43justin_smith,((juxt identity type) (into-array [1 2 3]))
15:43clojurebot[#<Long[] [Ljava.lang.Long;@17e1dd2> [Ljava.lang.Long;]
15:45justin_smithtac: right - they are one of the primitive things defined by the jvm, and they underly other types
16:00stuartsierratac: Clojure tests equality by value for immutable data structures and by identity for everything else, which includes most Java objects.
16:00tacI figured that's probably how it worked
16:00tacalthough functions are immutable ;P
16:02stuartsierraYes but (compiled) functions are not data structures as far as Clojure is concerned.
16:03technomancystuartsierra: I don't think that's accurate re "most Java objects"
16:03technomancystuartsierra: sadly = will return true for two different HashMaps
16:04turbofailreally?
16:04turbofailoh right it dispatches to the equalTo method if it has one
16:04technomancy,(let [a (doto (HashMap.) (.put "a" "a")), b (doto (HashMap.) (.put "a" "a"))] (= a b)) ; oops
16:04clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: HashMap, compiling:(NO_SOURCE_PATH:0:0)>
16:04technomancyaw come on
16:05technomancy,(let [a (doto (HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (= a b)) ; oops
16:05clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: HashMap, compiling:(NO_SOURCE_PATH:0:0)>
16:05technomancy,(let [a (doto (java.util.HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (= a b)) ; oops
16:05clojurebottrue
16:05technomancythird time's the charm
16:05technomancyanyway, clojure.core/= is not to be trusted with arbitrary java objects
16:05stuartsierraYes, technomancy is right. Clojure's = falls back to Java Object.equals, which can be fishy.
16:05tacis the / to denote a namespace?
16:07technomancyyeah
16:07twwnewbie questions: creating a hash-map from a list of key,values. what's the preferred way: (apply hash-map (list :a :apple :b :banana :p :peach)) OR (eval (cons hash-map (list :a :apple :b :banana :p :peach))) OR something else?
16:07taceval is only one-letter off from evil
16:08tacAt least, that's what I've been trained to think ;)
16:08technomancy,(let [a (doto (java.util.HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (try (= a b) (finally (.put a "a" "b")))) ; better yet
16:08clojurebottechnomancy: Gabh mo leithscéal?
16:08technomancyoh, does the bot block try/catch? boo.
16:10amalloy_technomancy: well, blocks catch
16:10amalloyand finally, i guess, right? so catch is allowed but not if you use it for anything
16:10amalloy,(try 1 (finally 2))
16:10clojurebotamalloy: Titim gan éirí ort.
16:11technomancy,(let [a (doto (java.util.HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (future (Thread/sleep 100) (.put a "a" "b")) (= a b)) ; fun times
16:11clojurebot#<SecurityException java.lang.SecurityException: no threads please>
16:11technomancydrat
16:12amalloytww: apply hash-map would be the way to go, although why do you have such a weird list instead of something like [[a apple] [b banana] [c peach]] is a consideration too - usually it's nice if each item in a list represents the same sort of thing
16:14amalloy,(try 1)
16:14clojurebot1
16:14twwamalloy: thanks. i do have a sane list of lists for my hash-map
16:15twwamalloy_: i appreciate the help
16:24schmeeis it possible to use loop/recur when implementing protocols?
16:25razum2umcan I conditionally require some code like (ns some (if cond (:require [lib])))) ?
16:26joegallorazum2um: require is available at runtime
16:26gfredericksrazum2um: you can do (ns some) (if cond (require '[lib]))
16:26joegalloso, outside of the ns form
16:27razum2umok, thanks
16:36virmundijustin_smith: is there a short way to conditionally add a key/value to a map if the value is not nil?
16:39virmundijustin_smith: the best I can figure is (merge {…} (if (cond?) {..}))
16:41mpenet,(doc update-in)
16:41clojurebot"([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."
16:45gfredericks,(defn assoc-when [m k v] (cond-> m v (assoc k v)))
16:45clojurebot#'sandbox/assoc-when
17:11pvinisi set up a project with lein.
17:11pvinishi
17:11pvinisi set up a project with lein.
17:11justin_smithcongratulations
17:11pvinisi set up a project with lein.
17:12pvinisi set up a project with lein.
17:12pvinisi set up a project with lein.
17:13pvinisi want to have a repl and do like (add-person "guy"), and then have the repl ask me, "age?" and i put 30, and then it constructs a record with all info, or just run (add-person {:name "guy" :age 30}).
17:13pvinisis this interactive adding of people possible?
17:13justin_smithpvinis: sure, using an atom for example
17:15justin_smith,(do (def people (atom [])) (defn add-person [name age] (swap! people conj {:age age :name name})) (add-person "guy" 30) @people)
17:15clojurebot[{:age 30, :name "guy"}]
17:15justin_smith,(add-person "doll" 42)
17:15clojurebot[{:age 30, :name "guy"} {:age 42, :name "doll"}]
17:15justin_smithpvinis: maybe something like the above
17:16aperiodicpvinis: if you're asking about how to get the input then you probably want to look at ##(doc read-line)
17:16lazybot⇒ "([]); Reads the next line from stream that is the current value of *in* ."
17:16pvinisaha. i will try that. thanks justin_smith
17:16gtrakwhat's the difference between clj-oauth vs oauth-clj?
17:17pvinisaperiodic: i probably need to get the input as well. ill check it. thanks
17:18justin_smithone gotcha: with print, you will also need to call (flush) if you want a prompt to show up without a newline
17:19technomancygtrak: M-t+
17:19technomancy?
17:19gtrakthere are two libs that do basically the same thing afaict, clj-oauth is more relied-on in clojuresphere.
17:25pviniscan i get a repl when i do lein run? like get a repl as my main loop of the app?
17:27justin_smithpvinis: lein repl
17:27technomancypvinis: check out the tools.nrepl repo if you want a repl server embedded in your actual main
17:27justin_smithor use clojure.tools.nrepl
17:28pviniscool. thanks
17:28justin_smithhttps://github.com/clojure/tools.nrepl
17:29pvinisim trying to learn clojure by making an app. its interesting, but can be a bit confusing
17:29arohnerwoohoo: "java(5182,0x1297e6000) malloc: *** error for object 0x8280400: pointer being freed was not allocated"
17:29justin_smithwoah
17:29justin_smitharohner: did you call a private method somewhere to make that happen?
17:29justin_smithif not, congrats!
17:29justin_smithif so, that's cheating
17:29arohnerjustin_smith: nope. Playing NIO & byte buffers
17:31pvinisthats another thing.. if something is not right and needs debugging, you get a whole sea of seemingly random errors. for a noob, thats too much
17:31pvinistoo much unknown stuff early on
17:32amalloyjustin_smith: sounds more like a native method than a private method
17:32technomancypvinis: yeah, the error messages from clojure are pretty bad. Usually it helps to isolate things where you can call lower-level functions directly from the repl and work your way out to bigger things till you can identify the problem.
17:32justin_smithpvinis: yeah, the depth of the stack by the time an error is found is definitely not a n00b friendly aspect of clojure
17:32amalloyi've certainly gotten jvm segfaults as a result of native code i edited
17:32technomancypvinis: don't underestimate the power of having interactive access plus immutable data structures that you can copy/paste
17:33technomancypvinis: on that note, tools.trace can be really helpful too.
17:34pvinisi saw that there is a c compiler for clojure. is there a "native" c lisp?
17:34pvinisill check out tools.trace
17:35schmeepvinis: the errors were the biggest hurdle for me when starting out with clojure as well... after some time they start to make more sense, but at first it is very frustrating
18:10danielcomptonis it possible to explore dependency jars in emacs like you can from IntelliJ?
18:11technomancydanielcompton: M-. works from cider sessions to do this, yeah
18:11technomancyyou can even edit them if you're insane
18:11danielcomptonwoah this is awesome
18:14danielcomptontechnomancy: which symobls does it show?
18:14danielcomptonit doesn't seem to be all of the ones required in my namespace?
18:16danielcomptonif I `use` a library it shows it as a var, if I require it then I can't see the prefixed namespace/symbol
18:16technomancynot sure what you mean; it's always worked for me
18:18danielcomptonIn my :require I have [plumbing.core :refer [dissoc-in]]. I can M-. and see dissoc-in, but no other vars from plumbing.core
18:18technomancyoh, sure
18:19danielcomptonis that expected/is there any way to M-. on a namespace?
18:20amalloydanielcompton: M-. only lets you look up vars which are valid in the current ns
18:21danielcomptonamalloy: isn't plumbing.core/assoc-when a valid var in a ns?
18:21amalloyin the *current* ns. you only referred dissoc-in
18:22technomancydanielcompton: if you fully-qualify the var, M-. will work.
18:23danielcomptoncan you explain what you mean when you say fully-qualify?
18:23amalloydanielcompton: type the following: plumbing.core/assoc-when
18:23amalloyand then press M-. while pointing at it
18:24danielcomptonoh wow, I was only running it from the minibuffer, I thought I could only pick vars that were in the minibuffer selection list
18:25danielcompton*movie voice* Cider: This changes everything, again.
18:27justin_smith"In a world where stability is only a legend, and new user's are funneled to snapshot versions - one project will change the way you think about clojure, and emacs, forever"
18:27justin_smithrated nc-17
18:28justin_smith*users
18:29danielcomptoncontains intense themes, aerial battle sequences and strong language
18:29technomancyfact: aerial battle sequences are the best battle sequences.
18:30mdeboardThe Little Mermaid had a really great one
18:31mdeboardAerial was all like, "No, evil queen octopus lady!" then shoots her voice at her
18:31mdeboardReally great Aerial battle
18:31Wild_Cattechnomancy: the entirety of Macross Plus shows that statement to be absolutely correct.
18:32justin_smithWild_Cat: I am disappointed that you did not attempt a macro themed pun
18:32technomancy>_<
18:32Wild_Catjustin_smith: I'm still a Clojure noob. :p
18:36justin_smith(defmacross valkyrie [] ...)
18:46danielcomptonmdeboard: just got that, I was thinking for a while how you have an aerial battle underwater
18:47mdeboarddanielcompton: :P
18:54mdeboardIf I'm reading the source right, nrepl clients handle creation of nrepl server instances?
18:57justin_smithmdeboard: huh? you use clojure.tools.nrepl.server/start-server to start listening to connections
18:57justin_smiththe client doesn't make new instances
18:57justin_smithdo you mean sessions?
18:57elbenAnyone find themselves always reaching for core.async/thread instead of jvm threadpools to build N processor, M consumer systems because it’s so easy?
19:00mdeboardjustin_smith: No, I'm looking at https://github.com/technomancy/leiningen/blob/master/src/leiningen/repl.clj#L243-L246
19:01mdeboardand the `lein repl' command itself
19:01justin_smithlein creates the server and also attaches a client for the user to interact with
19:02justin_smiththat's not the same as a client being in charge of creating server instances
19:02justin_smithyou can start-server without ever spawing a client
19:03justin_smithor maybe I am misunderstanding you
19:17mdeboardjustin_smith: No, I think you're udnerstanding me ok. I'm just trying to internalize how it works.
19:17mdeboardso I'm probably not saying what I mean
19:18justin_smithso, the code you linked to invokes reply
19:18justin_smithreply in turn invokes nrepl
19:18justin_smithyou can use nrepl to create a client or a server within your process - leiningen happens to do both (but via reply)
19:20nhanHIs "lein repl" supposed to ignore the user-wide profiles in ~/.lein/profiles.clj ?
19:20justin_smithno, those should get merged into your settings
19:22nhanHso, apparently when I run "lein repl", the user-wide profile is being ignored, do you have any suggestion on how to find out what's wrong?
19:22justin_smithcan you paste your profiles.clj and describe the symptom (what you expect, and what you get instead)
19:23justin_smithpaste in a site like refheap.com that is, of course
19:23nhanHI use environ to read out the setting, to make it short, if I copy the profiles.clj into the project folder, I can call env to get the setting in repl
19:24nhanHbut if the profiles.clj is only in ~/.lein, then I can't
19:24nhanHhttp://pastebin.com/J764GanH the profiles.clj file
19:25justin_smithdoes your project.clj have an :env key that would override that maybe?
19:26nhanHhere http://pastebin.com/chuCzjuS
19:26nhanHI don't think there is anything to override
19:27nhanHso I'm using lein-environ to generate .lein-env to be used by environ
19:27nhanHthat file has an empty map if I don't have a profiles.clj under my project folder
19:27justin_smithyeah, that should be working
19:29nhanHany suggestion?
19:29justin_smithnhanH: actually - looking at the environ docs, environ does not get the bindings from lein
19:30nhanH"lein test" work properly with the user-wide profiles though
19:30nhanHwait actually hmm
19:30nhanHlet me see
19:30justin_smithI think it loads the project.clj itself - and the docs mentions a profiles.clj in your repo, but does not mention anything about getting stuff from your main profiles.clj
19:32nhanHhmm, I just checked, and apparently "lein test" does run and get the main profiles.clj properly
19:32nhanHso environ can get the bindings from lein
19:32nhanHit just doesn't do it for the repl
19:44jds_does anyone here have experience using flambo with apache spark? i'm having some issues trying to use a non-local spark master, i believe related to serialization
20:00sritchieanyone know the API call to query clojars for a project’s most recent version?
20:44danielcomptonMicrosoft sharing the love for immutable objects http://www.freepatentsonline.com/y2014/0196008.html
20:48nullptrdanielcompton: microsoft has an immutable collections impl for .net http://msdn.microsoft.com/en-us/library/dn385366(v=vs.110).aspx
20:53razum2um1why does lein uberjat complains about Don't know how to create ISeq from: java.util.regex.Pattern though in docs it's possible?
20:53razum2um1btw, how to compile :all except one ns
20:55danielcomptonnullptr: and it looks like they have a patent for it too
21:05celwellHello, I can't figure out how to escape a string properly. I can do it fine with certain characters, but quotes and double-quotes are giving me problems. Here is what I have: (clojure.string/escape sql-value {\' "\'" \" "\""})
21:07danielcompton,(clojure.string/escape sql-value {\' "\'" \" "\""})
21:07clojurebot#<RuntimeException java.lang.RuntimeException: Unsupported escape character: \'>
21:14bluesnowHi, I'm confused about the difference between (repeatedly 10 (partial rand-int 50)) and (repeatedly 10 (fn [] (rand-int 50)))
21:15bluesnowThe book Clojure Programming uses the first, but doesn't rand-int only take one argument? So I don't understand the use of partial
21:15danielcompton,(doc rand-int)
21:15clojurebot"([n]); Returns a random integer between 0 (inclusive) and n (exclusive)."
21:16celwelldanielcompton: so, Unsupported escape character, is actually a different error than the one I got, but any ideas
21:17bluesnowdanielcompton: Uh, I still don't see it. For example, when I do (rand-int 10 50), I get an ArityException
21:18bluesnowso why is the book using partial in the expression, instead of just fn?
21:18aperiodic,((partial rand-int 50))
21:18clojurebot15
21:19bluesnowAh I see. So they just use partial to define the function instead of using fn, since the function definition using partial is shorter..
21:19danielcomptonbluesnow: I'm not quite sure how to describe the difference between the two, they both return a function
21:19danielcomptonbluesnow: but partial curries the arguments (I think)
21:19bluesnowdanielcompton: Right. But in the case of the repeatedly + partial/fn rand int expression, it's the same, right?
21:20bluesnowbecause rand-int only takes one arg anyway
21:20bluesnowso there's nothing to curry / no extra argument that can be passed
21:20danielcomptonpartial returns a function taking a variable number of arguments. So the result is the same but they're not the same function
21:20bluesnowdanielcompton: Right.
21:20bluesnowOk, I get that.
21:21bluesnowThanks, was just wondering why they would use partial, since rand-int can only take one argument. So it can't take advantage of any other variable args
21:25danielcomptonbluesnow: I would say it's to show different ways of doing the same thing?
21:26danielcomptongood question
21:27bluesnowdanielcompton: Yeah, probably. It just seemed like a weird use of partial, since I usually associate a use of partial with the need for currying / passing a variable number of args later.
21:39irctchey hey
21:40irctchow do i get UserDefinedFileAttributeView to work from clojure (noob here)
21:40irctcis this close? (java.nio.file.Files/getFileAttributeView (.toPath (java.io.File. "/etc/hosts")) (java.nio.file.attribute.UserDefinedFileAttributeView) (java.nio.file.LinkOption/NOFOLLOW_LINKS))
21:43TEttingerirctc, well to start you'd probably want to import some of those long java names
21:43TEttingersave some typing
21:44irctci think i don't know how to do this: UserDefinedFileAttributeView.class in clojure
21:44TEttingeruh, is it a class defined inside another class?
21:44irctcit's an interface
21:45TEttingeroh ok, so you need to get the Class from that?
21:46irctchere's the java: UserDefinedFileAttributeView view = file.getFileAttributeView(UserDefinedFileAttributeView.class);
21:47TEttingerwell I think you can still do (.class UserDefinedFileAttributeView), not sure -- I deal with interfaces rarely
21:49irctcyeah can't get that to work
21:49irctcfigured i would try asking for help
21:51irctclooks like it's just (class xyz) vs (.class xyz)
21:54TEttingerirctc, (class java...blahView) gives me java.lang.Class , which I don't think is what you want
21:55TimMc(dec AOT)
21:55TEttingertry entering just: java.nio.file.attribute.UserDefinedFileAttributeView
21:55TEttingerlazybot is out
21:55TimMc:-(
21:56TimMcHow am I supposed to formally register diapproval, then?
21:56TEttingerirctc: using java.nio.file.attribute.UserDefinedFileAttributeView without parentheses should be the actual class
22:01irctcthat got me farther along thx
22:11Lannyspectral == know-nothing nigger
22:12TimMcplonk
22:18beamsoi'm attempting to share some validation errors between a parent om form component and child components. is the best way to do this through the central app state or through the state that can be associated with the component through IRenderState?
23:34celwellHow can I escape double-quotes and single-quotes in a string? I have this, but it doesn't work: (clojure.string/escape sql-value {\' "\'" \" "\""})
23:42beamsocelwell: {\' "\\'" \" "\""} ?
23:43celwellbeamso: thank you.
23:44beamsotry calling str on the output to test it
23:44beamsoi didn't test escaping '"'
23:48celwellbeamso: Yeah, that doesn't work for '"', but I got it to work with this: {\' "\\'" \" "\\\""}
23:50amalloyyikes, celwell, automatically escaping sql strings is playing with fire
23:50amalloyare you sure you can't use parameterized queries with fixed sql?
23:50celwellamalloy: I wish I could do what I need with just clojure.java.jdbc
23:51celwellamalloy: I need to wrap values in AES_ENCRYPT()
23:52celwellI would probably have to back out of jdbc completely if I wanted to still use java's parameterization
23:53danielcomptonEmacs plugins: http://3.bp.blogspot.com/-WtKPYcpHxh8/UcdueZEQYpI/AAAAAAAAAJc/3-muBcjfBUk/s1600/world+war+z+4.jpg
23:54celwellHmm... now that I think about it, maybe I can just construct the INSERT string and put AES_ENCRYPT(?), AES_ENCRYPT(?), etc.
23:54taliosdanielcompton - looks like an eclipse plugin to me.