2014-08-26
| 00:00 | justin_smith | and you can keep adding or adjusting at the end of that ->> thread to narrow down the data you are looking for |
| 00:05 | justin_smith | also the magic first / second - the first is to get just one of the contacts, the second is to get the :raw |
| 00:05 | justin_smith | since it was a [] instead of {} |
| 00:06 | sarcher | That makes sense. |
| 00:06 | sarcher | I'm going to have to play around with this a bit and see what I can come up with. |
| 00:06 | sarcher | it's a very different way of thinking about things haha |
| 00:06 | sarcher | thanks again for the help! |
| 00:06 | justin_smith | np |
| 00:07 | justin_smith | the general pattern with what data.xml returns is to filter for the right :tag then probably grab the :content |
| 00:07 | justin_smith | you'll see yourself doing that over and over |
| 00:08 | danielcompton | Does leiningen check for snapshots every time you run it? |
| 00:10 | justin_smith | https://raw.githubusercontent.com/technomancy/leiningen/master/sample.project.clj looks like you can set that explicitly |
| 00:11 | justin_smith | danielcompton: link to the relevant line https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L90 |
| 00:12 | danielcompton | justin_smith: thanks! |
| 00:13 | danielcompton | which is the default? |
| 00:13 | justin_smith | danielcompton: looking for that now |
| 00:15 | justin_smith | https://github.com/technomancy/leiningen/blob/ad65195f40c2a1eeffd31401942cd8111c5de7ff/src/leiningen/deps.clj#L111 once every 24 hours |
| 00:15 | justin_smith | finally found it |
| 00:15 | sm0ke | if find doing this very often (if x (f y) y) can this be expressed any better/shorter? |
| 00:15 | danielcompton | ahaha https://github.com/technomancy/leiningen/blob/2cfca444fe37135637a4efbe9f004d4ce5fe51c7/leiningen-core/src/leiningen/core/main.clj#L13 |
| 00:16 | justin_smith | rofl |
| 00:16 | justin_smith | nice to know it is friendly to the germans |
| 00:16 | sm0ke | leiningen was a german |
| 00:16 | danielcompton | justin_smith: where does it take :update? |
| 00:16 | justin_smith | see my link to project.clj above |
| 00:16 | justin_smith | it is the sample project.clj, it shows the syntax / where the key is expected |
| 00:17 | danielcompton | justin_smith: I mean where in deps.clj does :update change things? |
| 00:17 | danielcompton | looking at deps.clj I can't see :update at all |
| 00:17 | technomancy | danielcompton: use `lein -U ...` |
| 00:18 | danielcompton | technomancy: where does https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L90 take effect? |
| 00:18 | justin_smith | danielcompton: I bet it happens in classpath/resolve-dependencies |
| 00:18 | technomancy | inside pomegranate/aether |
| 00:18 | danielcompton | ah, it all becomes clear |
| 00:18 | danielcompton | er |
| 00:19 | danielcompton | thanks! |
| 00:19 | justin_smith | danielcompton: https://github.com/technomancy/leiningen/blob/ad65195f40c2a1eeffd31401942cd8111c5de7ff/leiningen-core/src/leiningen/core/classpath.clj#L122 |
| 00:19 | justin_smith | yup, I was right |
| 00:19 | justin_smith | (or close enough to get real close :)) |
| 00:21 | danielcompton | (inc justin_smith) |
| 00:21 | lazybot | ⇒ 67 |
| 00:21 | danielcompton | (inc technomancy) |
| 00:21 | lazybot | ⇒ 132 |
| 00:21 | danielcompton | (dec so) |
| 00:21 | lazybot | ⇒ -33 |
| 00:24 | justin_smith | $karma karma |
| 00:24 | lazybot | karma has karma 1. |
| 00:24 | catern | (dec karma) |
| 00:24 | lazybot | ⇒ 0 |
| 00:24 | catern | all is in balance |
| 00:24 | justin_smith | $karma karma karma karma karma chameleon |
| 00:24 | lazybot | karma has karma 0. |
| 00:24 | justin_smith | :P |
| 00:51 | sm0ke | core.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:54 | rhg135 | justin_smith: now it's in my head, damn it :P |
| 00:55 | pmonks | G’day everyone, potentially dumb n00b question here… |
| 00:55 | pmonks | I’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:56 | pmonks | I 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:56 | pmonks | The type is used throughout the API, and manually translating everywhere (while technically possible) sounds like a lot of donkey work. |
| 00:56 | rhg135 | Implicit casing yikes |
| 00:57 | pmonks | Yah that was my reaction. :D |
| 00:57 | sm0ke | ##(bean (java.util.Date.)) |
| 00:57 | lazybot | ⇒ {:seconds 14, :date 26, :class java.util.Date, :minutes 57, :hours 4, :year 114, :timezoneOffset 0, :month 7, :day 2, :time 1409029034220} |
| 00:58 | pmonks | Thing 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:02 | rhg135 | I usually have a function, usually a map, to convert it at every at user interaction point |
| 01:03 | pmonks | And you then call that function internally before interoping with Java, or simply let users of the API choose to use it or not? |
| 01:03 | rhg135 | Internally |
| 01:05 | pmonks | hmmm…….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:06 | pmonks | (not that I’m wrapping all of them up front…) |
| 01:06 | rhg135 | Hmm |
| 01:06 | pmonks | I 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:07 | pmonks | Particularly since it’s only a subset of that API that’s the “80% sweet spot” for callers. |
| 01:07 | pmonks | Well thanks @rhg135 - you answered my question! |
| 01:08 | rhg135 | Np |
| 01:08 | pmonks | I 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:10 | rhg135 | Lol |
| 01:11 | TEttinger | I haven't learned all of Scala's implicit stuff, but all I can tell is it's complicated |
| 01:14 | rhg135 | Reminds me of c++ |
| 01:15 | rhg135 | Trying to fix c/java |
| 01:15 | sm0ke | its stupid |
| 01:15 | sm0ke | and dangerous |
| 01:15 | rhg135 | Very |
| 01:15 | sm0ke | they admit that it wasa bad design choice |
| 01:17 | sm0ke | i think most of the scala dev abstain from using implicits, they prefer to do conversion manually where required |
| 01:17 | TEttinger | I don't even know how implicit really works, I used it to imitate extension methods in C# |
| 01:19 | TEttinger | I'm wondering if there's some way to get idiomatic clojure closer to java speed |
| 01:19 | sm0ke | how is that realted to implicit conversion? |
| 01:20 | TEttinger | sm0ke, implicit has multiple meanings in scala |
| 01:20 | rhg135 | Don't think there is |
| 01:20 | TEttinger | and the clojure comment is because I'd really prefer to use clojure over scala |
| 01:20 | rhg135 | Java is always lower level |
| 01:20 | TEttinger | but scala's performance is much better |
| 01:23 | sm0ke | better than java? |
| 01:23 | TEttinger | no, than clojure |
| 01:23 | sm0ke | idimomatic scala ? |
| 01:24 | TEttinger | not sure what that really is. I haven't really needed to optimize my scala but desperately needed to for clojure |
| 01:24 | TEttinger | both soft-real time, JVM games using the same lib, libgdx |
| 01:24 | sm0ke | http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=clojure&lang2=scala&data=u64q |
| 01:25 | TEttinger | sm0ke, I don't think microbenchmarks of optimized code are the best reference here |
| 01:26 | TEttinger | yeah, uh I do not consider this idiomatic clojure http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=clojure&id=1 |
| 01:26 | sm0ke | TEttinger: for that libgdx comment, it seems absurd |
| 01:26 | sm0ke | doesnt it uses native libs under the hood? |
| 01:27 | sm0ke | neither is the scala port |
| 01:28 | sm0ke | http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=scala&id=1 |
| 01:28 | TEttinger | yes, 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:28 | TEttinger | err |
| 01:28 | TEttinger | profile |
| 01:29 | TEttinger | and that scala looks fairly reasonable, but I do not see definterface in most clojure code |
| 01:30 | TEttinger | and you have stuff like this in the clojure, ^{:unsynchronized-mutable true :tag double} x |
| 01:30 | sm0ke | :p |
| 01:30 | pmonks | “Moore’s Law will make all this moot anyway. What’s that you say? It’s been rescinded?? DOH!!!” |
| 01:30 | sm0ke | immutability is the agenda remember? |
| 01:31 | sm0ke | TEttinger: what kind of glue code are you writing in clojure thats so slow? |
| 01:31 | sm0ke | even high end games use something like lua for similar purpose |
| 01:31 | sm0ke | i dont really see how the microssec diff between clojure and scala is critical here |
| 01:31 | TEttinger | glue code? I didn't write any of it, like I said the issue was with logic code |
| 01:32 | TEttinger | and more importantly, the issue was with how hard it was to optimize the clojure vs. scala |
| 01:32 | sm0ke | my point is, either you write it in C or dont write it at all |
| 01:33 | TEttinger | ugh. I'm not writing games that need extreme 3d performance, both of these are small 2d games |
| 01:33 | sm0ke | i am totally agreeing with clojure being harder to profile and slower than scala |
| 01:34 | sm0ke | so your game is needs like what 6000 fps? |
| 01:34 | TEttinger | it was getting closer to 15 |
| 01:34 | TEttinger | in clojure |
| 01:34 | sm0ke | for a 60 fps game you get, ###(/ 1000000 60) ; millis for evey frame |
| 01:34 | lazybot | ⇒ #<sandbox5671$eval16962$fn__16963 sandbox5671$eval16962$fn__16963@23827d2a> |
| 01:34 | TEttinger | the bigger problems were with input lag |
| 01:34 | sm0ke | ugh ##(/ 1000000 60) |
| 01:34 | lazybot | ⇒ 50000/3 |
| 01:35 | sm0ke | lol |
| 01:35 | TEttinger | ,(/ 1000.0 60) |
| 01:35 | clojurebot | 16.666666666666668 |
| 01:35 | TEttinger | you're doing microseconds I think |
| 01:36 | sm0ke | yep so even if you loose like 3 millis to clojure, you have 95% of same time |
| 01:36 | TEttinger | I'm just saying my experience writing the game |
| 01:36 | TEttinger | I spent personally about half the time on the game trying to optimize it |
| 01:37 | TEttinger | stuff like ztellman's primitive-math helped |
| 01:37 | sm0ke | TEttinger: i may be plain wrong, but it think you would be equally disappointed if you port it entirely to scala |
| 01:38 | TEttinger | oh, I scrapped the game and started a different one. it is faster in scala, but does different stuff |
| 01:38 | ztellman | sm0ke: disagree, a lot of games is math, and Clojure can disappoint you on that count |
| 01:38 | ztellman | I had to write a custom vector math library for http://ideolalia.com/creating-a-simple-game-in-clojure/ |
| 01:39 | sm0ke | is scala that much faster in math? my original point was to write heavy stuff in C |
| 01:39 | ztellman | things have progressed since then, but using the typical numerical stack is more or less comparable |
| 01:43 | TEttinger | well 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:44 | sm0ke | i 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:44 | TEttinger | and I had a major part of the render loop use an array of Images |
| 01:44 | TEttinger | sm0ke, oh, I don't think so either, I think I wrote better code this time |
| 01:45 | TEttinger | but it was easier to write fast code I think |
| 01:45 | sm0ke | TEttinger: you gave Scala the nicest punchline ever "Scala makes it easier to write fast code" |
| 01:45 | sm0ke | :D |
| 01:45 | TEttinger | well compared to java yes |
| 01:46 | TEttinger | I just wonder about stuff like oxcart |
| 01:47 | sm0ke | nah |
| 01:47 | sm0ke | wont work for you, you need low level stuff |
| 01:48 | sm0ke | i dont thing oxcart can make any difference to math operations being slow |
| 01:48 | sm0ke | imho |
| 01:50 | TEttinger | it possibly could, if it can compile it down to primitive math |
| 01:50 | TEttinger | arrdem: I like this commit message https://github.com/oxlang/oxcart/blob/953187d447ee70168105f48f5ed5d666b7d3e187/src/bench/clojure/test/vars.clj |
| 01:52 | sm0ke | hurm interesting |
| 01:53 | sm0ke | i am not sure how defining same `+` operations 500 times is helping though |
| 01:54 | TEttinger | it's a test |
| 01:58 | sm0ke | oxcart is exciting work though |
| 02:28 | bars0 | Hi 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:33 | Kneiva | bars0: I just read this (4 years old post) which is related I think: http://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure |
| 02:35 | bars0 | Lisphttp://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure |
| 02:35 | bars0 | Kneiva: ok, thanks, I'll read this |
| 02:39 | arrdem | TEttinger: lol |
| 02:40 | arrdem | TEttinger: yeah... that "benchmark" is me being as mean as I can imagine how to be comparing Oxcart vs. clojure.core |
| 02:43 | arrdem | totally open to ideas for other test programs |
| 03:34 | TEttinger | $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:34 | lazybot | Message saved. |
| 03:41 | clgv | TEttinger: what did you write? |
| 03:52 | TEttinger | clgv: 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:53 | TEttinger | I 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:53 | lvh | TEttinger: huh; so the issue was it was too slow? |
| 03:53 | lvh | TEttinger: I'm interested in writing some simultaneous turn based games |
| 03:53 | TEttinger | lvh, I think I could manage to get it to be faster these days |
| 03:54 | lvh | performance not as big a deal there :) |
| 03:54 | lvh | more of a deadline scheduler style thing ;) |
| 03:55 | clgv | TEttinger: ah interesting |
| 03:56 | TEttinger | so 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:56 | clgv | I use some semi-immutable datastructures to get java performance in an algorithm |
| 03:57 | TEttinger | IKVM doesn't work well on mono, at least any newer versions |
| 03:57 | TEttinger | so I was stuck with windows only and slow (IKVM turned out to have major performance issues) |
| 03:58 | TEttinger | I 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:58 | clgv | and then you did a scala implementation? |
| 03:58 | clgv | Java lambdas do not close of the used variables? |
| 03:59 | TEttinger | so 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:59 | clgv | or values of the variables... |
| 03:59 | TEttinger | clgv, you can't change outer state |
| 03:59 | TEttinger | in lambdas in java 8 |
| 03:59 | clgv | TEttinger: for referenz types? |
| 04:00 | TEttinger | it's a restriction on lambdas in general |
| 04:02 | clgv | TEttinger: 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:04 | clgv | I guess you meant Java lambdas do only close over "final" local variables? |
| 04:05 | TEttinger | clgv, 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:10 | SagiCZ1 | hi, can i attach metadata to a function from within the function? thus aquiring something akin to regular stateful object? |
| 04:10 | TEttinger | clgv, I encountered this same issue http://stackoverflow.com/questions/17204279/does-java-8-support-closures?rq=1 |
| 04:11 | TEttinger | (doc meta) |
| 04:11 | clojurebot | "([obj]); Returns the metadata of obj, returns nil if there is no metadata." |
| 04:11 | TEttinger | (doc with-meta) |
| 04:11 | clojurebot | "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata." |
| 04:12 | TEttinger | it seems that it wouldn't be the same reference, SagiCZ1 |
| 04:12 | TEttinger | ,(let [a {:a 1 :b 2}] (= a a)) |
| 04:12 | clojurebot | true |
| 04:12 | TEttinger | ,(let [a {:a 1 :b 2} b (with-meta a {:blah true})] (= a b)) |
| 04:12 | clojurebot | true |
| 04:12 | TEttinger | huh |
| 04:12 | TEttinger | maybe... |
| 04:14 | clgv | SagiCZ1: what's your exact use case? you seem to head into a strange direction |
| 04:14 | clgv | TEttinger: they are equal, thats the point of metadata - but the objects are not identical |
| 04:15 | TEttinger | ,(let [a {:a 1 :b 2} b (with-meta a {:blah true})] (identical? a b)) |
| 04:15 | clojurebot | false |
| 04:16 | clgv | SagiCZ1: if you want function local data that can be mutated, then just close over an atom |
| 04:19 | clgv | ,(let [create-counter (fn [] (let [cnt (atom 0)] (fn [] (swap! cnt inc))), counter (create-counter)] (repeatedly 10 counter)) |
| 04:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 04:19 | dawkirst | asked this yesterday too, but just want to get a varied opinion: Programming Clojure or Clojure Programming for a newcomer to Clojure and FP? |
| 04:19 | clgv | ,(let [create-counter (fn [] (let [cnt (atom 0)] (fn [] (swap! cnt inc)))), counter (create-counter)] (repeatedly 10 counter)) |
| 04:19 | clojurebot | (1 2 3 4 5 ...) |
| 04:20 | clgv | dawkirst: depends on what style of writing you like |
| 04:20 | dawkirst | clgv: how do the styles differ? |
| 04:20 | rhg135 | Do you even need a book with a repl? |
| 04:21 | clgv | dawkirst: "Programming Clojure" (2nd edition) is more like "these are the facts" and imho "Clojure Programming" is more narrative |
| 04:21 | rhg135 | They're great but repls are awesome for learning |
| 04:21 | clgv | rhg135: yes, I'd recommend one for every newcommer. the repl is an awesome feature to try out the book example |
| 04:21 | dawkirst | clgv: narrative in the sense that they explain underlying rationales more? |
| 04:22 | dawkirst | rhg135: I guess not, but at the moment I'm just floating around in the ether: I need a bit of theoretical grounding |
| 04:22 | rhg135 | Clgv, they do go well together |
| 04:22 | clgv | dawkirst: no, not necessarily. I wanted to describe the wrinting style by that |
| 04:22 | dawkirst | clgv: ok |
| 04:22 | clgv | dawkirst: afaik they both have example chapters |
| 04:22 | clgv | dawkirst: just read those and decide based on that |
| 04:23 | dawkirst | clgv: that's probably not a bad idea, thanks |
| 04:23 | dawkirst | rhg135: thoughts on Light Table as a REPL? Is it permissible? |
| 04:23 | clgv | dawkirst: personally I read "Programming Clojure" (1st edition) - the other one didnt exist at that time ;) |
| 04:23 | rhg135 | It's incredible |
| 04:24 | rhg135 | Especially for cljs |
| 04:24 | clgv | dawkirst: Light Table as a repl for learning should work pretty well |
| 04:24 | dawkirst | rhg135: awesome :) I think so too. |
| 04:25 | rhg135 | Anyway it's 3am here, I should look at the clock more often lol |
| 04:26 | rhg135 | Piece. |
| 04:26 | rhg135 | Grr |
| 04:26 | rhg135 | Peace** |
| 04:26 | clgv | good sleep ;) |
| 04:27 | clgv | it's 10:26 am over ehre |
| 04:34 | clgv | adding to the book topic: did anyone read the Joy of Clojure Second Edition and can comment on the changes? |
| 04:40 | SagiCZ1 | clgv: thanks for the answer earlier.. i will try it with the atom |
| 04:42 | clgv | SagiCZ1: maybe you should describe your problem, anyway? I was just guessing what you are trying to achieve ;) |
| 05:06 | lvh | hm |
| 05:07 | lvh | I'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:14 | clgv | lvh: 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:14 | clgv | delete the "?" ;) |
| 05:15 | clgv | maybe "myproto" is misleading, imagin "myns" in the above example |
| 05:18 | clgv | lvh: similar to what is done here https://github.com/ztellman/primitive-math/blob/master/src/primitive_math.clj |
| 05:20 | lvh | clgv: oh, durr; that makes sense |
| 05:20 | lvh | clgv: 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:23 | clgv | lvh: if you have better verbs, you should definitely use those. but you can't always avoid collision ;) |
| 05:24 | lvh | clgv: yeah, absolutely |
| 05:24 | lvh | CompilerException 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:25 | lvh | oh... don't have two jvms up |
| 05:26 | lvh | I couldn't figure out why I was seeing stale code in my repl :) |
| 05:26 | clgv | yeah, for development a switch "always compile the clojure code and do not dare to load *.class files" would be nice sometimes |
| 05:36 | lvh | clgv: Hm. That wasn't it, though: https://gist.github.com/lvh/949692f88bf1634a967d |
| 05:57 | noniwoo | hi. why this one gives me original vector without 19? (replace {0 19} [1 2 3 4 5]) |
| 06:02 | clgv | lvh: you forgot about the "this" pointer |
| 06:02 | lvh | clgv: Just adding "this" in front of everything gives me a different exception though |
| 06:02 | clgv | lvh: it needs to be in the argument list for protocols, reify and deftype |
| 06:03 | mpenet | noniwoo: it takes the key as value to be replaced in the vector |
| 06:03 | mpenet | ,(replace {0 19} [0 0 2 3 4 5]) |
| 06:03 | clojurebot | [19 19 2 3 4 ...] |
| 06:03 | lvh | Can't define method not in interfaces: create_BANG_ |
| 06:03 | lvh | clgv: (goes away without this, leading me to believe that it's convinced that method with that arity doesn't exist) |
| 06:04 | clgv | lvh: do you have the first param for "this" in the protcol and the reify? |
| 06:04 | lvh | clgv: Nope, just the reify |
| 06:04 | lvh | clgv: it should be in both? |
| 06:04 | clgv | lvh: yes |
| 06:04 | lvh | clgv: I don't understand why; I don't actually care about the "this" |
| 06:05 | clgv | lvh: for deftypes you sometimes do care |
| 06:05 | clgv | lvh: you can return the object itself without modification via "this" |
| 06:05 | lvh | hm, okay |
| 06:05 | noniwoo | mpenet: oh, I thought it is position. thanks |
| 06:06 | lvh | clgv: but if I'm writing code like mem-store that doesn't care, that doesn't mean I'm doing something wrong? |
| 06:07 | clgv | lvh: 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:08 | lvh | clgv: Aha; so maybe I want proxy? :-) |
| 06:08 | clgv | ah right, and definterface is an exception as well |
| 06:08 | clgv | lvh: no not really if reify does what you want |
| 06:09 | clgv | lvh: you just want to do (reify Store (create! [_, key, value] ...) ...) |
| 06:09 | lvh | clgv: Okay, thanks :) |
| 06:11 | clgv | lvh: in the defprotocol you probably want (create! [store, key, value]) for documentation purposes |
| 06:12 | lvh | clgv: right; maybe I should come up with a different name for that local in mem-store |
| 06:12 | lvh | since this != store :) |
| 06:12 | lvh | (store being an atom there) |
| 06:13 | clgv | lvh: yeah, I just meant that you dont use "this" or "_" there but a name associated with that protocol |
| 06:13 | lvh | right :) |
| 06:13 | lvh | thanks! |
| 06:14 | clgv | anytime |
| 06:14 | lvh | I'm going to replace "key" and "value" with more use-case-specific terms as well |
| 06:16 | amitayh | ? |
| 06:17 | dawkirst | what does #'some-symbol mean? |
| 06:18 | lvh | dawkirst: that's a var quote |
| 06:18 | clgv | dawkirst: reference to the variable and not the value of the symbol |
| 06:18 | lvh | dawkirst: #'sym == (val sym) |
| 06:18 | clgv | ,(meta #'map) |
| 06:18 | clojurebot | {:ns #<Namespace clojure.core>, :name map, :added "1.0", :file "clojure/core.clj", :static true, ...} |
| 06:18 | clgv | ,(meta map) |
| 06:18 | clojurebot | nil |
| 06:18 | clgv | ,(map type [map, #'map]) |
| 06:18 | clojurebot | (clojure.core$map clojure.lang.Var) |
| 06:19 | dawkirst | awesome, thanks! |
| 06:22 | SagiCZ1 | what type is lazy seq? seq or list? |
| 06:23 | SagiCZ1 | ,(map identity (drop 5 (range 10))) |
| 06:23 | clojurebot | (5 6 7 8 9) |
| 06:24 | SagiCZ1 | ,(type (map identity (drop 5 (range 10)))) |
| 06:24 | clojurebot | clojure.lang.LazySeq |
| 06:24 | SagiCZ1 | ,(list? (map identity (drop 5 (range 10)))) |
| 06:24 | clojurebot | false |
| 06:24 | SagiCZ1 | why is it printed as list when its not a list |
| 06:24 | TEttinger | ,(seq? (map identity (drop 5 (range 10)))) |
| 06:24 | clojurebot | true |
| 06:24 | TEttinger | because seqs and lists print the same |
| 06:25 | clgv | SagiCZ1: it is sequential - why do you ask? |
| 06:25 | SagiCZ1 | ,(seq? '(1 2 3)) |
| 06:25 | clojurebot | true |
| 06:25 | clgv | ,(sequential? (iterate inc 0)) |
| 06:25 | clojurebot | true |
| 06:25 | SagiCZ1 | i have this expression.. i need it to return [[coll1] [coll2]].. how do i simplify it? |
| 06:25 | SagiCZ1 | (vector (vec <some-non-vec-coll>)) (vec <some-non-vec-coll>))) |
| 06:26 | clgv | mapv + vec |
| 06:26 | SagiCZ1 | (doc mapv) |
| 06:26 | clojurebot | "([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:26 | clgv | ,(mapv vec (parition-all 2 (range 10)) |
| 06:26 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 06:26 | clgv | ,(mapv vec (parition-all 2 (range 10))) |
| 06:26 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: parition-all in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 06:26 | clgv | ,(mapv vec (partition-all 2 (range 10))) |
| 06:26 | clojurebot | [[0 1] [2 3] [4 5] [6 7] [8 9]] |
| 06:28 | SagiCZ1 | this doesnt work (mapv vec (drop-last x coll) (take-last x coll)) |
| 06:29 | TEttinger | clgv showed a way, SagiCZ1 |
| 06:29 | TEttinger | replace (range 10) with your coll |
| 06:29 | SagiCZ1 | but i dont want partition |
| 06:30 | TEttinger | what is your input like? |
| 06:30 | SagiCZ1 | 1 [:a :b :c :d] ==> [[:a] [:b :c :d]] |
| 06:30 | SagiCZ1 | i am reimplementing split |
| 06:32 | SagiCZ1 | this works too: (mapv vec (list (drop-last x coll) (take-last x coll))) |
| 06:32 | TEttinger | ,(let [splitter 1 coll [:a :b :c :d] ] (mapv vec [(take splitter coll)(drop splitter coll)])) |
| 06:32 | clojurebot | [[:a] [:b :c :d]] |
| 06:33 | TEttinger | ,(let [splitter 2 coll [:a :b :c :d] ] (mapv vec [(take splitter coll)(drop splitter coll)])) |
| 06:33 | clojurebot | [[:a :b] [:c :d]] |
| 06:33 | SagiCZ1 | ok |
| 06:33 | SagiCZ1 | thank you |
| 06:34 | TEttinger | no prob |
| 06:35 | SagiCZ1 | ,(= [[:a :b][:c :d]] ((:a :b)(:c :d))) |
| 06:35 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 06:36 | SagiCZ1 | ,(= [[:a :b][:c :d]] '((:a :b) (:c :d)) ) |
| 06:36 | clojurebot | true |
| 06:36 | TEttinger | need to quote the lists |
| 06:36 | TEttinger | you got it |
| 06:37 | SagiCZ1 | yeah ok.. so i actually didnt need the vectors.. i forgot that = checks the contents.. well nevermind it was an exercise :) |
| 07:11 | martinklepsch | is there a subset? for maps where (subset? {:a 1} {:b 2 :a 1}) would be true? |
| 07:16 | clgv | martinklepsch: no but you can build it via select-keys, keys and = |
| 07:16 | clgv | ,(defn subset? [sub, super] (= sub (select-keys super (keys sub)))) |
| 07:16 | clojurebot | #'sandbox/subset? |
| 07:16 | clgv | ,(subset? {:a 1} {:b 2 :a 1}) |
| 07:16 | clojurebot | true |
| 07:17 | clgv | ,(subset? {:a 1} {:b 2 :a 5}) |
| 07:17 | clojurebot | false |
| 07:17 | clgv | ,(subset? {:a 1 :c 9} {:b 2 :a 1}) |
| 07:17 | clojurebot | false |
| 07:17 | martinklepsch | clgv: 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:18 | clgv | martinklepsch: 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:21 | martinklepsch | clgv: ok, thanks :) |
| 07:21 | martinklepsch | once you see the solution it always seems so obvious |
| 07:26 | clgv | martinklepsch: in this case the solution was to turn around the question: >how do I get a "subset" of a hashmap in clojure?< |
| 07:26 | martinklepsch | clgv: (= super (merge super sub)) — am I overseeing something or is this also a solution? |
| 07:26 | clgv | martinklepsch: schould be yes |
| 07:27 | clgv | martinklepsch: but here, the order of the maps is important. "sub" must be in second position such that it overrides the values in "super" |
| 07:27 | martinklepsch | yup |
| 09:14 | tsdh | Hi. 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:15 | clgv | tsdh: why? |
| 09:16 | clgv | tsdh: whatever you want to do sounds pretty complicated |
| 09:17 | clgv | ,(let [f (with-meta #(inc %) {:awesome true})] (meta f)) |
| 09:17 | clojurebot | {:awesome true} |
| 09:17 | tsdh | clgv: 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:17 | clgv | tsdh: you might need to move back to `let` if letfn wont let you do that |
| 09:18 | tsdh | clgv: let+fn won't do the trick because the individual functions may call each other. |
| 09:18 | clgv | ,(letfn [(^:awesome f [x] (inc x))] (meta f)) |
| 09:18 | clojurebot | nil |
| 09:18 | tsdh | clgv: I.e., they may be mutual recursive. |
| 09:18 | gfredericks | does anybody know why it would ever be helpful to `ln -s src/data_readers.clj data_readers.clj`? |
| 09:18 | clgv | ,(letfn [(f {:awesome true} [x] (inc x))] (meta f)) |
| 09:18 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Parameter declaration {:awesome true} should be a vector, compiling:(NO_SOURCE_PATH:0:0)> |
| 09:18 | tsdh | clgv: Yeah, that's what I tried, too. |
| 09:19 | clgv | tsdh: yeah but it's the wrong one anyway. that metadata is likely lost after compilation |
| 09:19 | tsdh | clgv: I only need it during macro expansion time. |
| 09:19 | clgv | tsdh: well then you have it on the symbol `f` in the above example |
| 09:20 | tsdh | clgv: But (identical? 'foo 'foo) ;=> nil |
| 09:20 | tsdh | clgv: Ah, not nil but false. |
| 09:20 | clgv | ,(-> "(^:awesome f [x] (inc x))" read-string first meta) |
| 09:20 | clojurebot | {:awesome true} |
| 09:23 | tsdh | clgv: 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:45 | justin_smith | lvh: get is based on an interface that you can implement |
| 09:45 | lvh | justin_smith: Oh, cool. |
| 09:45 | justin_smith | (regarding some scrollback) |
| 09:46 | justin_smith | most 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:47 | justin_smith | I 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:48 | justin_smith | I think that for get you need ILookup (and maybe IAssociative too?) |
| 09:48 | martinklepsch | I 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:50 | justin_smith | martinklepsch: it seems like all this would be much simpler with a proper database |
| 09:50 | justin_smith | not to say you can't do 4gb immutible datastructures |
| 09:54 | gfredericks | martinklepsch: it doesn't sound like a use case for state |
| 09:54 | gfredericks | but that's hard to evaluate without knowing your application architecture |
| 09:55 | lvh | are test names typically CamelCase or lispy-case? |
| 09:55 | lvh | (I appear to be seeing both) |
| 09:56 | gfredericks | names of tests? |
| 09:56 | gfredericks | like (deftest ILikeCamels ...)? |
| 09:56 | gfredericks | I've never seen that |
| 09:56 | justin_smith | CamelCase 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:56 | martinklepsch | justin_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:58 | justin_smith | martinklepsch: 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:03 | martinklepsch | the information about mutations isn't very important I to be able to manage how much data is loaded/load more |
| 10:04 | milos_cohagen | i'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:06 | justin_smith | martinklepsch: 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:08 | justin_smith | martinklepsch: consider that a global atom can be used to parallelize in one way, while local / recursive bindings parallelize in another way entirely |
| 10:10 | martinklepsch | justin_smith: I don't really know what you mean by recursive binding |
| 10:11 | martinklepsch | can you maybe point me to an example? |
| 10:12 | justin_smith | martinklepsch: think along the lines of a reduce on a line-seq |
| 10:12 | justin_smith | though you wouldn't be doing that, I am sure |
| 10:13 | justin_smith | reduce 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:17 | justin_smith | (reduce (fn [m w] (update-in m [w] (fnil inc 0))) {} (line-seq (clojure.java.io/reader (.getBytes "hello\nworld")))) |
| 10:17 | justin_smith | ,(reduce (fn [m w] (update-in m [w] (fnil inc 0))) {} (line-seq (clojure.java.io/reader (.getBytes "hello\nworld")))) |
| 10:17 | clojurebot | {"world" 1, "hello" 1} |
| 10:21 | bulters | g'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:22 | bulters | which - considering how the rest of clojure is designed - doesn't ring too well with me :P |
| 10:23 | justin_smith | it's something called destreucture, which is called by fn and let |
| 10:23 | justin_smith | *destructure |
| 10:24 | justin_smith | https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4160 source is here |
| 10:24 | bulters | that's one helluva function |
| 10:24 | bulters | just found it :P |
| 10:25 | justin_smith | so that is called, inside the let macro |
| 10:25 | justin_smith | and also gets invoked eventually in the expansion of fn (though that is less clear to be sure) |
| 10:28 | bulters | justin_smith: probably the reason i didn't find it "in fn" |
| 10:28 | bulters | didn't think of looking into let, hindsight: much easier to find |
| 10:29 | justin_smith | or loop even :) |
| 10:29 | bulters | true, though I don't really use loop that often :P |
| 10:29 | bulters | so that would have been my last guess so to say |
| 10:30 | justin_smith | to be fair, "destructure" should have been the first thing to search for - it is the most intuitive name :) |
| 10:32 | bulters | just to show of my inexperience: I didn't actually think it was a 'dedicated function'; more like some magical construct I overlooked somewhere |
| 10:32 | justin_smith | in clojure a magical construct will often be a function |
| 10:32 | bulters | TIL! |
| 10:33 | justin_smith | the set of special forms is pretty short, after that you have functions and macros |
| 10:33 | justin_smith | *(and reader macros...) |
| 10:35 | bulters | but let is mentioned as a special form... still it's also implemented as a macro in core.clj |
| 10:35 | justin_smith | let* is the true special form |
| 10:35 | bulters | ah |
| 10:35 | justin_smith | let is a macro wrapping it |
| 10:36 | justin_smith | (and that macro gets a :special-form metadata...) |
| 10:36 | justin_smith | similar to fn and fn* |
| 10:36 | scriptor | it's a fairly simple macro, too |
| 10:37 | justin_smith | basically all it does is implement the destructuring before let* is invoked |
| 10:37 | scriptor | all it does is destructure the bindings you pass and then call let* |
| 10:37 | justin_smith | right |
| 10:37 | justin_smith | which brings this all full circle |
| 10:37 | bulters | I love this sh*t |
| 10:38 | scriptor | destructure, on the other hand, is a bit more hairy :) |
| 10:38 | scriptor | http://clojuredocs.org/clojure_core/clojure.core/destructure |
| 10:38 | justin_smith | yup |
| 10:39 | bulters | scriptor: I'm blankly staring at it right now... |
| 10:40 | bulters | but it's really nice to see that magic is just functions all the way down :P |
| 10:40 | justin_smith | mostly - until you hit java and / or directly generated byte code... |
| 11:05 | sdegutis | What's a good project management online service that lets me organize and categorize tasks and put estimates on them? |
| 11:06 | cbp | a jira server |
| 11:06 | sdegutis | Is that a bad thing? |
| 11:06 | sdegutis | Why run? |
| 11:08 | ephemeron | sdegutis: For generic tasks/management? Many people seem to like Trello, or Asana. |
| 11:08 | sdegutis | Thanks. |
| 11:08 | ephemeron | Other people would just look at you sternly and whisper "orgmode". |
| 11:19 | michaniskin | cemerick: 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:30 | cemerick | michaniskin: 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:30 | michaniskin | cemerick: i'd be tagging onto the :eval op, i guess? |
| 11:31 | cemerick | michaniskin: 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:32 | cemerick | If "jobs" == arbitrary futures, etc., then that's way more subtle. |
| 11:32 | michaniskin | cemerick: the jobs themselves add their completion status to a queue, it's just a matter of doseq prn on the queue |
| 11:33 | michaniskin | the middleware wouldn't need to know anything about the jobs themselves |
| 11:33 | michaniskin | just check the queue any time something is evaled |
| 11:33 | michaniskin | and print the contents and empty it |
| 11:33 | michaniskin | like a flash message, kinda |
| 11:33 | cemerick | Even better, then. I thought you wanted to analyze the :code sent for eval to identify jobs being started, etc |
| 11:34 | michaniskin | processes can add messages to the flash queue, and they're popped and printed any time the prompt is printed |
| 11:34 | cemerick | So, yes, you can use :eval ops passing by as a trigger. |
| 11:34 | michaniskin | is there a key in the message for stderr or stdout? |
| 11:34 | cemerick | Might be nicer to just poll every N seconds, just so you aren't evaling stupid stuff to know when a job finishes tho. |
| 11:34 | csd_ | 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:35 | azizur | hello everyone is there anyone from http-kit.org on there? |
| 11:35 | michaniskin | cemerick: the job control is working nicely without middleware, but the notification of completed jobs is being printed async, which is a pain |
| 11:35 | michaniskin | i just need to be notified when the prompt is being printed i guess |
| 11:36 | cemerick | michaniskin: 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:36 | cemerick | Prompt stuff is strictly a client-side tooling concern |
| 11:36 | cemerick | Some tools don't have prompts. |
| 11:36 | michaniskin | so i can write to *err* in my middleware? |
| 11:38 | michaniskin | ok i now compute some code :) |
| 11:38 | michaniskin | thanks cemerick! |
| 11:39 | cemerick | michaniskin: Yeah, sessions are just maps of vars -> bindings; deref and be merry |
| 11:40 | cemerick | #'clojure.tools.nrepl.middleware.session/session, or whatever |
| 11:40 | cemerick | sessions* |
| 11:42 | TimMc | csd_: Something like (apply merge-with set/union (map hash-map vec-keys set-vals)) |
| 11:43 | csd_ | TimMc: thank you! |
| 11:45 | TimMc | &(apply merge-with clojure.set/union (map hash-map [:a :c :d :c] [#{1} #{2} #{3} #{4}])) |
| 11:45 | lazybot | ⇒ {:a #{1}, :c #{2 4}, :d #{3}} |
| 11:55 | azizur | is it possible to write a fully non-blocking application with http-kit and luminus framework? |
| 11:56 | gtrak | azizur: pedestal is made for this |
| 11:56 | virmundi | azizur: I don’t know about liuminus, but have you looked at Pulsar (https://github.com/puniverse/pulsar) |
| 11:56 | gtrak | compojure/ring don't give you as much flexibility |
| 11:57 | virmundi | the nice thing about pulsar is that Parallel Universe is trying to make a ring adapter for it. |
| 11:57 | ohpauleez | +1 for Pedestal :) |
| 11:58 | justin_smith | pulsar also tries to replace core.async, right? |
| 11:59 | virmundi | kinda, it complementary with an Actor model |
| 11:59 | doctorm | Can 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:59 | doctorm | third party libs* that is |
| 11:59 | justin_smith | doctorm: core.trace is really useful for that |
| 11:59 | gtrak | doctorm: conveniently you can eval in any namespace, I redefine things often. |
| 12:00 | doctorm | justin_smith: thanks, I’ll check it out |
| 12:00 | gtrak | directly from a cider jar buffer |
| 12:00 | gtrak | though it throws an error about saving read-only files or somesuch :-) |
| 12:00 | justin_smith | doctorm: also, if you need a finer level of granularity than function arg and return values, you can redefine things as gtrak says |
| 12:01 | langmartin | I'm doing it right now! |
| 12:01 | justin_smith | gtrak: well, directly from any repl, no need to drag cider into that :) |
| 12:01 | gtrak | in principle, yea, that's just how I happen to do it |
| 12:02 | doctorm | I’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:02 | justin_smith | doctorm: 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:02 | gtrak | (in-ns 'that-ns), (def blah __) |
| 12:02 | gtrak | it's convenient to have the existing source handy |
| 12:02 | doctorm | Alright, thank you, I’ll experiment for a bit |
| 12:02 | justin_smith | doctorm: or you can do as gtrak says if you want to simply redefine the functions in that ns |
| 12:03 | justin_smith | gtrak: with clojure you always have the existing source |
| 12:03 | justin_smith | ,(doc source) |
| 12:03 | clojurebot | "([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:04 | justin_smith | doctorm: oh man, why did I call it core.trace? it's tools.trace https://github.com/clojure/tools.trace |
| 12:04 | doctorm | justin_smith: I figured you meant that, found it thanks :) |
| 12:04 | justin_smith | the functions you want are trace-ns and trace-vars |
| 12:08 | Pupeno | At 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:08 | TimMc | trace-ns may or may not still have a bug where it tries to trace things like (def foo {}) |
| 12:08 | arrdem | emacs, light table and sublime text could all fit the bill... |
| 12:08 | arrdem | Atom maybe |
| 12:08 | justin_smith | intellij idea + cursive |
| 12:09 | Bronsa | cursive++ |
| 12:09 | Pupeno | light table |
| 12:09 | Pupeno | That's. |
| 12:14 | imanc | is cursive a jetbrains product? |
| 12:14 | justin_smith | https://cursiveclojure.com/ |
| 12:15 | sdegutis | I think I'm settling on using Trello. |
| 12:16 | justin_smith | imanc: 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:16 | pmonks | +1 to Trello - it’s great |
| 12:18 | stuartsierra | azizur: 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:18 | Pupeno | Yes, it's a third party plugin for Jetbrains, free for now. |
| 12:20 | doctorm | I’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:20 | justin_smith | doctorm: can you paste the code that provoked that error? |
| 12:21 | TimMc | ~paste |
| 12:21 | clojurebot | paste is not gist.github.com |
| 12:21 | TimMc | Thanks, clojurebot. |
| 12:21 | TimMc | ~paste |
| 12:21 | clojurebot | paste is not gist.github.com |
| 12:21 | justin_smith | doctorm: refheap.com is good for pasting |
| 12:21 | TimMc | clojurebot: forget paste |is| not gist.github.com |
| 12:21 | clojurebot | I forgot that paste is not gist.github.com |
| 12:21 | doctorm | justin_smith: sure, it’s a little weird because it’s in a migration file with drift, but I will |
| 12:21 | TimMc | clojurebot: forget paste |is not| gist.github.com |
| 12:21 | clojurebot | I forgot that paste is not gist.github.com |
| 12:22 | justin_smith | doctorm: 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:22 | doctorm | https://www.refheap.com/89490 |
| 12:22 | justin_smith | but with some context we can see the issue |
| 12:22 | justin_smith | doctorm: defn needs a vector |
| 12:22 | doctorm | ah of course it does, thanks |
| 12:23 | justin_smith | parameter declaration must come before the body |
| 12:23 | justin_smith | also, down needs a parameter vector |
| 12:23 | justin_smith | it can be an empty vector if it takes no args |
| 12:26 | doctorm | Interestingly, trace-var causes a NullPointerException to be thrown once I fix the function vector problem |
| 12:29 | csd_ | Is it possible to represent an empty vector [] as a different arity than [1 2 ...] either using destructuring or otherwise? |
| 12:29 | justin_smith | csd_: wat |
| 12:30 | llasram | csd_: Yeah, gonna need a bit more there :-) |
| 12:30 | justin_smith | vectors don't have arities, and I have no idea what you mean by [1 2 ...] |
| 12:31 | csd_ | 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:31 | csd_ | hope that makes sense |
| 12:31 | justin_smith | csd_: destructuring is not pattern matching |
| 12:31 | llasram | csd_: You can either `apply` the vector, or use pattern matching via core.match |
| 12:32 | csd_ | how would i do this using apply |
| 12:32 | mdeboard | arity dispatch is pattern matching, kinda |
| 12:32 | mdeboard | (apply foo []) |
| 12:32 | llasram | csd_: Er, I meant `apply` a function to the vector |
| 12:32 | justin_smith | mdeboard: but he wants dispatch on the content of a vector |
| 12:33 | mdeboard | o |
| 12:33 | mdeboard | use erlang |
| 12:33 | mdeboard | problem solved |
| 12:33 | llasram | csd_: Which will dispatch based on the number of elements in the vector |
| 12:33 | csd_ | oh i get you |
| 12:35 | martinklepsch | I 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:36 | martinklepsch | (it returns nil to be precise) |
| 12:36 | hiredman | (doc group-by) |
| 12:36 | clojurebot | "([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:37 | llasram | ,(->> (concat (range 10) (range 5)) (frequencies) (filter (comp pos? dec val))) |
| 12:37 | clojurebot | ([0 2] [1 2] [4 2] [3 2] [2 2]) |
| 12:37 | justin_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:37 | clojurebot | [#{0 1 4 3 2} #{1 2}] |
| 12:38 | milos_cohagen | martinklepsch: use the set as predicate on list after you create the set? |
| 12:38 | hiredman | guys, group-by |
| 12:39 | justin_smith | oh yeah, the keys give you the set, the vals tell you how many times each came up |
| 12:39 | justin_smith | but why not just frequencies? |
| 12:39 | dnolen_ | thheller: ping |
| 12:41 | hiredman | justin_smith: sure frequencies too, all that other stuff is ridiculous |
| 12:41 | llasram | ,((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:41 | clojurebot | (1 2 1) |
| 12:41 | llasram | That one's lazy! |
| 12:41 | llasram | Er |
| 12:41 | llasram | Or would have been if I'd remembered the `lazy-seq` |
| 12:41 | hiredman | hah |
| 12:44 | martinklepsch | justin_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:46 | justin_smith | I think? I'm often unsuer about *print-length* and related stuff |
| 12:49 | martinklepsch | hm. just set it to false and still get #{...} — it's not a map literal right? |
| 12:50 | Bronsa | martinklepsch: try to set *print-level* to nil |
| 12:51 | martinklepsch | Bronsa: I tried false and nil |
| 12:52 | justin_smith | martinklepsch: and it definitely isn't just ##'#{...} ? |
| 12:52 | lazybot | ⇒ #{...} |
| 12:52 | Bronsa | martinklepsch: *print-level*, not *print-length* |
| 12:53 | TimMc | ,[*print-level* *print-length*] |
| 12:53 | clojurebot | [10 5] |
| 12:53 | TimMc | &[*print-level* *print-length*] |
| 12:53 | lazybot | ⇒ [nil nil] |
| 12:54 | alandipert | Raynes, is there a quick way with conc to stream a processes's err to out? trying to drive/see rsync stderr |
| 12:54 | alandipert | *conch that is |
| 12:55 | alandipert | (i tried (proc ... {:err *out*}) to apparent effect |
| 12:59 | martinklepsch | Bronsa: 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:01 | dnolen_ | sritchie: ping |
| 13:01 | sritchie | hey |
| 13:01 | dnolen_ | sritchie: http://dev.clojure.org/jira/browse/CLJS-839 |
| 13:01 | dnolen_ | attached a possible patch, if you could test that would be awesome |
| 13:02 | sritchie | dnolen_: I was actually about to fix my issue by upgrading beyond 2261 |
| 13:02 | dnolen_ | sritchie: the patch simply keeps Math.imul polyfill out of advanced compilation hopefully that's all that's needed |
| 13:02 | sritchie | it looks like you added the shim imul implementation after the version I’d been using |
| 13:02 | dnolen_ | sritchie: ah yeah, there was *another* Safari imul bug that we addressed too |
| 13:02 | dnolen_ | thheller: also ^ |
| 13:02 | sritchie | :) |
| 13:03 | Raynes | alandipert: I thought that was a thing you can do, but it doesn't look like it. |
| 13:03 | Raynes | Certainly a patch I'd take. Otherwise, you can always pass the :verbose option to get back a map with both types of output. |
| 13:05 | schmee | dnolen_: 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:06 | dnolen_ | schmee: it errors out if you there's not a corresponding match, precise exhaustiveness doesn't mean much in a dynamically typed context |
| 13:06 | schmee | dnolen_: yeah, I figured as much |
| 13:07 | schmee | but computing reachability should be possible, in some sense at least? |
| 13:07 | dnolen_ | schmee: I don't see how that's possible except for trivial cases |
| 13:08 | dnolen_ | schmee: and those will get picked up by Google Closure anyhow |
| 13:09 | schmee | dnolen_: aight! |
| 13:09 | schmee | thanks for your great work and presentations btw, really inspiring! |
| 13:10 | dnolen_ | schmee: your welcome and thank you for saying so. |
| 13:10 | mdeboard | please, you'll embarass him |
| 13:11 | schmee | imo people spend to much time calling out stuff they don't like instead of the stuff they actually like |
| 13:11 | schmee | credit where credit is due! :) |
| 13:12 | mdeboard | he's doing it all for the nookie |
| 13:12 | alandipert | Raynes, thanks i may |
| 13:12 | Raynes | alandipert: I'm super shocked I never implemented that functionality, fwiw. |
| 13:13 | Raynes | Surprised that I didn't need it myself |
| 13:13 | hlprmnky | dnolen_ : hear, hear! Your recent talk gave me the grasp of core.async I needed to tackle a fun little project at work. |
| 13:13 | dnolen_ | hlprmnky: cool! |
| 13:14 | hlprmnky | my first actual soup-to-nuts Clojure “app”, actually, as opposed to maintenance and extension on someone else’s work. Feels good, man. |
| 13:28 | jakecraige | Are 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:29 | jakecraige | or should i be using some sort of web framework for clojure |
| 13:30 | technomancy | jakecraige: https://github.com/technomancy/syme is a small nontrivial sample app you could read for guidance/samples |
| 13:33 | jakecraige | technomancy: thanks, I'll check it out |
| 13:33 | technomancy | in 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:41 | technomancy | |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:45 | TimMc | Augh, what. |
| 13:45 | TimMc | OK, 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:46 | TimMc | This obviously breaks various lein tasks that try to fetch the nonexistent version. |
| 13:47 | TimMc | I've used :exclusions on my lib (project #1), but project #2 depends on #1 and keeps trying to fetch Clojure 1.4.+. :-( |
| 13:47 | TimMc | Is there some way to stop this madness? |
| 13:48 | technomancy | TimMc: exclusions in #2 don't work? |
| 13:49 | TimMc | Oh, I need both? |
| 13:49 | technomancy | TimMc: not sure; worth trying though |
| 13:51 | TimMc | OK, in retrospect that makes sense, in a certain twisted way. |
| 13:51 | TimMc | Works, thanks. |
| 13:51 | technomancy | cool |
| 13:51 | TimMc | Now I'm back to my original error. Whee. |
| 13:53 | hiredman | http://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:54 | llasram | buuuurn |
| 13:55 | llasram | Actually -- manually setting `:inline` metadata totally works. It's just `definline` which is insane for no reason |
| 13:55 | hiredman | also, "updates are racy, but access is controlled" |
| 13:56 | llasram | Yeah. It's too bad the JVM doesn't have some sort of support for local per-thread mutable state |
| 13:56 | amalloy | hiredman: sounds like the paywall page for a premium cable channel |
| 13:57 | technomancy | bahaha |
| 13:57 | hiredman | hah |
| 13:59 | Bronsa | hiredman: if you won't, I will (leaving aside the sarcastic tone) I wouldn't be happy with vswap! being a macro |
| 14:00 | hiredman | Bronsa: it would be interesting to see how swap! would perform if inlined (get rid of the use of apply) |
| 14:02 | Bronsa | hiredman: can apply really be a bottleneck? |
| 14:02 | hiredman | I have no idea |
| 14:02 | hiredman | I have a vague notion that apply is really slow |
| 14:02 | amalloy | Bronsa: yes, it could be |
| 14:02 | amalloy | mostly because you have to build an argseq, not because apply itself is slow |
| 14:03 | amalloy | although a fair number of my uses of swap! aren't inlinable, with stuff like (update-in my-app [:state] swap! assoc :done true) |
| 14:03 | hiredman | alex's "benchmark" there doesn't show a huge difference, but then again it is using dotimes |
| 14:04 | TimMc | criterium or nothing |
| 14:04 | amalloy | speaking of core not using criterium, do they use lein yet, these days? |
| 14:04 | TimMc | technomancy: I guess this means that every project needs to document its exclusions. :-( |
| 14:04 | Bronsa | amalloy: ah, that might make sense |
| 14:05 | hiredman | a lot of contrib has a project.clj checked in |
| 14:05 | technomancy | TimMc: every project that transitively includes brokenness, sure |
| 14:05 | TimMc | blerg |
| 14:05 | technomancy | it's pretty rare to come across version ranges these days |
| 14:06 | amalloy | yeah, but it's not "official", right. they all have to use a pom for releases and so on |
| 14:06 | Bronsa | yes |
| 14:06 | Bronsa | hudson uses the pom.xml |
| 14:06 | amalloy | technomancy: 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:06 | amalloy | they can't process the exclusion for it because it's not a real thing |
| 14:06 | technomancy | amalloy: yeah, but version ranges are a lot more common |
| 14:06 | technomancy | and are worked around the same way |
| 14:07 | amalloy | well so what? they won't cause the problem TimMc has |
| 14:07 | amalloy | you can just fight a version range by adding one of your own on a specific version |
| 14:07 | technomancy | amalloy: adding your own version range? |
| 14:07 | amalloy | [org.clojure/clojure "[1.6.0]") |
| 14:07 | technomancy | that works for applications but is a bad idea for libraries |
| 14:07 | amalloy | sure |
| 14:08 | amalloy | but the solution you proposed doesn't really work for libraries either. he has to exclude it in his app |
| 14:08 | amalloy | or else it sneaks in transitively |
| 14:10 | technomancy | gotcha, yeah |
| 14:10 | technomancy | the real solution is to report it as a bug upstream and squash it |
| 14:11 | TimMc | I've already opened a ticket for it, yeah. https://github.com/ReactiveX/RxClojure/issues/2 |
| 14:11 | amalloy | "bug: uses gradle" |
| 14:11 | technomancy | be the change you want to see in the world |
| 14:12 | amalloy | TimMc: "occasionally"? i can't imagine why it wouldn't be every time |
| 14:13 | technomancy | amalloy: it might be that ranges have the same daily caching logic as snapshots |
| 14:13 | technomancy | and failures are cached, which is almost always the wrong thing, but could accidentally be helpful in this situation |
| 14:15 | TimMc | That's my best guess, although it will also happen multiple times in the same day (sometimes.) |
| 14:15 | joshuafcole | Why does the transitive dependency happen in the first place? Are there cases where that is a useful behavior? |
| 14:16 | technomancy | joshuafcole: sure, like ... every time there's not a version range, basically? |
| 14:18 | joshuafcole | Sorry, 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:19 | technomancy | oh, yeah I'm not sure about that |
| 14:19 | tac | Does Clojure merely require the JRE? (and not the JDK?) |
| 14:19 | technomancy | we get a whole bunch of behaviour from aether that is 95% golden, and there is the occasional questionable decision thrown in. |
| 14:20 | technomancy | they'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:20 | technomancy | tac: correct |
| 14:21 | seangrove | technomancy: I've been looking at Mirage and Halvm for fun recently - have you found OCaml's type system to be useful at all? |
| 14:21 | joshuafcole | Ah 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:21 | technomancy | seangrove: yeah, it is wonderful. |
| 14:22 | csd_ | How do I easily convert from hash-set (#{1} #{2} #{3}) to list (1 2 3) ? |
| 14:23 | amalloy | apply concat |
| 14:23 | seangrove | ,(apply concat (hash-set #{1} #{3} #{2})) |
| 14:23 | clojurebot | (3 2 1) |
| 14:24 | seangrove | As per amalloy's frighteningly quick suggestion |
| 14:24 | amalloy | frighteningly quick is at least like twice as fast. that took almost a minute |
| 14:25 | csd_ | 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:25 | joshuafcole | Frighteningly quick is at least 30 seconds. |
| 14:25 | joshuafcole | noted |
| 14:27 | imanc | newb question, but why doesn't that result in '(#{1} #{2} #{3}) ? |
| 14:27 | amalloy | imanc: it's the difference between apply concat vs just concat |
| 14:27 | technomancy | seangrove: 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:27 | technomancy | seangrove: 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:28 | seangrove | technomancy: 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:28 | tac | technomancy: 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:28 | technomancy | tac: 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:29 | technomancy | also ocaml is super easy to pick up if you know clojure |
| 14:29 | technomancy | you can be relatively productive in a week |
| 14:29 | turbofail | clearly we need a hybrid of the two. clojaml |
| 14:29 | technomancy | as long as you're willing to just spam your code with moar parens when you can't figure out the precedence rules |
| 14:29 | justin_smith | csd_: 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:29 | seangrove | That was definitely one of the bigger annoyances, I mised sexp's |
| 14:29 | lazybot | ⇒ ((1 2 3 4) (1 2 3 4) (1 2 3 4) ([1 2] [3 4])) |
| 14:30 | technomancy | seangrove: yeah, but I was surprised that I didn't miss macros. just the regularity and predictability. |
| 14:30 | tac | the one and only thing that keeps me from seriously looking into ocaml is that silly GIL |
| 14:31 | tac | it sounds like they are working to fix that, though |
| 14:31 | technomancy | tac: I find that just makes it complementary to Clojure. |
| 14:31 | justin_smith | my ocaml variant idea is ocalm - it's the lazy ocaml |
| 14:31 | turbofail | huh. why would ocaml need a GIL? |
| 14:31 | seangrove | tac: Which language are you comparing it to? |
| 14:31 | technomancy | if 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:31 | technomancy | turbofail: for the GC |
| 14:31 | turbofail | do they use reference counting or something? |
| 14:31 | tac | turbofail: probably multithreaded programming just wasn't a priority |
| 14:31 | Bronsa | when 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:32 | tac | seangrove: I use mostly Haskell and Python. |
| 14:32 | justin_smith | and backporting concurrency to something not designed with concurrency in mind is usually a huge PITA |
| 14:32 | technomancy | actual concurrent production GC is incredibly difficult to do well. afaik it's only been implemented 5 times or so total. |
| 14:32 | tac | Trying to get clojure installed and running atm so I can go visit a Clojure meetup in town tomorrow night |
| 14:32 | justin_smith | tac: don't install clojure -install lein |
| 14:32 | tac | I'm slowly learning this |
| 14:33 | technomancy | like, in the entire world. |
| 14:33 | tac | I installed lein (not sure what it's for), and did a ./lein new hello |
| 14:33 | justin_smith | tac: lein is the build tool and dependency manager. One of the dependencies it handles is clojure itself |
| 14:33 | tac | oh, and I can apparently run it |
| 14:33 | tac | neat |
| 14:33 | tac | is lein a clojure thing, then? |
| 14:34 | justin_smith | yes, and it's one of the best things about clojure IMHO |
| 14:34 | turbofail | there's still a big difference between a not-quite-concurrent GC and a language runtime with a GIL |
| 14:35 | tac | why is it annotated -main instead of main? |
| 14:35 | justin_smith | tac: that's how gen-class works |
| 14:35 | justin_smith | -foo is the method foo |
| 14:35 | tac | ah |
| 14:35 | justin_smith | main needs to be a method |
| 14:35 | amalloy | tac: because main is a special case of gen-classing, which uses - as a prefix to say "this should be a generated method" |
| 14:36 | tac | and there's no compile cycle in clojure (by default)? |
| 14:36 | tac | I just run my project with lein? |
| 14:36 | justin_smith | tac: every clojure statement is compiled when evaluated |
| 14:36 | justin_smith | there is the possibility of doing an uberjar / jar package - but that's more about packaging than compiling usually |
| 14:37 | amalloy | tac: 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:37 | justin_smith | unless you use :aot - but :aot is very unpopular and a huge source of bugs |
| 14:37 | tac | gotcha. 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:37 | tac | amalloy: how do you launch the repl then? |
| 14:37 | justin_smith | tac: so you can run your code on the prod server without installing anything but a jvm on the other end |
| 14:38 | amalloy | well, really i do it from emacs, with lein jack-in |
| 14:38 | technomancy | justin_smith: AOT during development, specifically |
| 14:38 | amalloy | but you can use lein repl if you aren't ready to figure out editor tooling |
| 14:38 | justin_smith | technomancy: sure - but even in production how often is it really useful? |
| 14:38 | technomancy | justin_smith: depends on whether you care about startup time |
| 14:38 | tac | ah, lein repl does the trick |
| 14:39 | tac | I 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:39 | technomancy | justin_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:39 | justin_smith | tac: 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:40 | justin_smith | technomancy: good point, I usually use "lein do check test" for that |
| 14:40 | celwell | Should I use buddy or friend for my authentication needs? |
| 14:40 | justin_smith | that's "lein do check, test" of course |
| 14:40 | technomancy | justin_smith: IMO `lein compile :all` is better than check unless you're hypersensitive to reflection. |
| 14:41 | justin_smith | technomancy: what's the improvement? |
| 14:42 | technomancy | justin_smith: less noisy, speeds up boot |
| 14:42 | technomancy | it's minor though |
| 14:43 | amalloy | celwell: i've never heard of buddy. it sounds like it must be based on friend |
| 14:43 | tadni | Hrm, cider doesn't seem to be opening an nrepl conncetion. |
| 14:43 | turbofail | hm. http://www.ocamljava.org/ is a thing |
| 14:43 | technomancy | I'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:44 | technomancy | it would be better expressed as a composition of existing tasks |
| 14:44 | celwell | amalloy: I think it's relatively new https://github.com/niwibe/buddy |
| 14:44 | technomancy | turbofail: wow |
| 14:45 | technomancy | wait, both implementations are made by different people named Xavier? |
| 14:45 | technomancy | weird |
| 14:45 | turbofail | if it actually works it seems like it'd be a great replacement for scala |
| 14:45 | justin_smith | turbofail: my thoughts exactly |
| 14:49 | turbofail | hm. looks like it still needs some work |
| 14:49 | turbofail | still interesting though |
| 14:51 | technomancy | similar to erjang |
| 14:51 | technomancy | it's pretty amazing how much progress that project was able to make as a one-man-show |
| 14:51 | technomancy | especially compared to jruby, which basically didn't get close until it had corporate backing |
| 14:51 | drguildo | does anybody have any advice for debugging a process that hangs? |
| 14:54 | aperiodic | drguildo: check to make sure all your loop/recurs terminate |
| 14:54 | aperiodic | that's usually the problem if the process sits there spinning without blowing stack |
| 14:54 | drguildo | aperiodic, there are none |
| 14:54 | mdrogalis | drguildo: Check out jstack |
| 14:55 | mdrogalis | You can see what a running pid is up to |
| 14:56 | drguildo | mdrogalis, thanks |
| 14:56 | tac | I saw on a video the other day that 'nil' signals the end of an iterator |
| 14:56 | mdrogalis | drguildo: Np |
| 14:56 | tac | Just to be sure, that means you can't have nils present anywhere in your iterator stream, right? |
| 14:57 | tac | (unless you box them somehow) |
| 14:57 | turbofail | iterators? we don't really do iterators in this part of town |
| 14:58 | tac | whatever the proper name for them is |
| 14:58 | tac | seq's |
| 14:58 | turbofail | you can have a nil in a seq just fine |
| 14:58 | mdrogalis | tac: Need a little more context. Maybe you're thinking of something with core.async? |
| 14:58 | turbofail | (take 10 (repeat nil)) |
| 14:58 | tac | oh, is it that if the tail of a seq is nil, then the sequence is over? |
| 14:59 | turbofail | yeah, either nil or the empty sequence '() |
| 14:59 | tac | gotcha |
| 14:59 | turbofail | usually you query for that using empty? |
| 14:59 | mdrogalis | tac: I think you saw something pretty specific that doesn't extend to a larger context. |
| 15:00 | tac | I think it was Rich Hickey for Lisp Programmers |
| 15:00 | mdrogalis | Eh, that guy doesnt know what he's talking about. |
| 15:00 | schmee | how do I implement a custom `println` for a record? |
| 15:00 | mdrogalis | Kidding. 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:01 | tac | ,(1 . 2) |
| 15:01 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: . in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:01 | tac | Does Clojure not have dotted cells like in some lisps? |
| 15:01 | turbofail | nope |
| 15:01 | technomancy | tac: correct |
| 15:01 | turbofail | good riddance if you ask me |
| 15:02 | tac | I agree |
| 15:02 | tac | Does the tail always have to be a list, then? |
| 15:02 | dnolen_ | tac: a seq |
| 15:02 | tac | gotcha |
| 15:02 | dnolen_ | or nil |
| 15:02 | technomancy | unlike CL, the empty list is distinct from nil |
| 15:02 | technomancy | but they are related in ways that are somewhat surprising |
| 15:03 | technomancy | ,(seq ()) ; kind of makes no sense, but there you have it |
| 15:03 | clojurebot | nil |
| 15:03 | tac | seq there is just doing a coercion? |
| 15:03 | tac | from the empty list to a sequence? |
| 15:03 | technomancy | I'm not sure what it's doing =) |
| 15:04 | technomancy | nil is not a sequence |
| 15:04 | tac | well, it's Java's null |
| 15:04 | tac | so it's whatever type you want |
| 15:04 | technomancy | anyway all that to say there are some behaviours that are simply arbitrary that you have to memorize |
| 15:05 | TimMc | ~seqs and colls |
| 15:05 | clojurebot | seqs and colls is http://www.brainonfire.net/files/seqs-and-colls/main.html |
| 15:05 | tac | gotcha |
| 15:05 | technomancy | yeah, that's a good guide |
| 15:05 | tac | Out of curiosity, does anyone here go to the Chicago Clojure meetup? |
| 15:06 | turbofail | hm. i don't think i've ever bothered memorizing that |
| 15:07 | technomancy | turbofail: not necessarily all the charts there, but the (seq? (seq ())) ; -> false weirdness at least |
| 15:08 | turbofail | i didn't know that one either. it's never come up |
| 15:08 | turbofail | i don't think i typically call seq at all really |
| 15:08 | technomancy | you see seq used as a predicate for non-emptiness a lot in the wild IME |
| 15:08 | turbofail | hm |
| 15:08 | technomancy | the official style guide even says to prefer it to (not (empty? ...)) |
| 15:08 | turbofail | i always use not-empty for that |
| 15:08 | technomancy | (which I think is silly, but hey) |
| 15:09 | joshuafcole | I 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:10 | technomancy | turbofail: hm; actually I'm not seeing it on the wiki, but I know Rich has said it several times. |
| 15:10 | stuartsierra | joshuafcole: nil is a sequence terminator |
| 15:11 | technomancy | joshuafcole: I think the simplest way of explaining it is that map, etc simply accept anything you can safely pass to seq |
| 15:11 | turbofail | though not-empty basically just delegates to seq |
| 15:11 | turbofail | lol |
| 15:11 | stuartsierra | technomancy: It's in the docstring for `empty?` :) |
| 15:12 | joshuafcole | Interesting, gotcha |
| 15:12 | technomancy | stuartsierra: hah, there you go. oddly enough not in the doc for not-empty though. |
| 15:12 | technomancy | http://p.hagelb.org/mystery.gif |
| 15:12 | tac | the binding keyword creates dynamically-scoped variables. is that right? |
| 15:13 | technomancy | tac: no, it doesn't create them |
| 15:13 | technomancy | it just binds them to new values |
| 15:17 | tac | oh hm |
| 15:17 | tac | so binding mutates a global variable, and then when the scope ends, it mutates it back? |
| 15:17 | technomancy | vars are mostly created by def and the macros that expand to them |
| 15:18 | tac | s/global/thread-local |
| 15:18 | technomancy | technically it's just pushing a new value onto a stack, bit it's similar to mutation. |
| 15:18 | technomancy | *but |
| 15:18 | tac | right right |
| 15:19 | tac | so operationally, they work like implicit parameters that get threaded through your function calls |
| 15:19 | technomancy | vars 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:19 | technomancy | yup |
| 15:19 | tac | I guess that's a lot like the reader monad |
| 15:20 | stuartsierra | The effect of `binding` isn't global, though, it's local to a thread. |
| 15:20 | tac | yeah |
| 15:20 | virmundi | where 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:21 | tac | if it were global, you'd have some janky semantics because of the changing values |
| 15:22 | tac | the docs mention a clj command line tool |
| 15:22 | tac | if i'm using lein, I just ignore clj.. right? |
| 15:22 | turbofail | it's basicallly just running `java -cp clojure-x.x.jar clojure.main' |
| 15:23 | tac | I'm not even sure where lein puts the clojure jar |
| 15:23 | stuartsierra | tac: What docs? There's no "official" clj command-line executable. |
| 15:23 | justin_smith | tac: under ~/.m2 |
| 15:24 | tac | http://java.ociweb.com/mark/clojure/article.html |
| 15:24 | tac | you can CTRL+f for the clj instance I'm referring to |
| 15:24 | tac | "$ clj vars.clj |
| 15:24 | tac | " |
| 15:25 | tac | oh, and I'm hopping around, so many it was defined earlier and I missed it |
| 15:25 | justin_smith | "use the shell script for executing Clojure files described earlier" |
| 15:25 | tac | How are sets typically implemented? |
| 15:26 | turbofail | http://en.wikipedia.org/wiki/Hash_array_mapped_trie |
| 15:27 | stuartsierra | justin_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:27 | tac | very likely, probably! |
| 15:28 | tac | So to put something into a set, it needs to be hashable and support equality comparison |
| 15:28 | justin_smith | tac: luckily, all java objects support that |
| 15:28 | justin_smith | and all primitives are trivially coercible to object form |
| 15:30 | will2357 | Hey 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:30 | will2357 | That happens to be fault-tolerant (i.e., can't lose a message due to a handler crash)? |
| 15:31 | SagiCZ1 | how about oracles activeMQ with clojures java interop? |
| 15:32 | tac | justin_smith: I think I'm thinking with my haskell glasses on again, thinking to myself "function objects are incomparable" |
| 15:33 | justin_smith | tac: they aren't ordered, but they can be equal or not (in clojure) |
| 15:33 | SagiCZ1 | clgv: are you here by any chance? |
| 15:33 | justin_smith | ,(= rand #(rand)) ; tac |
| 15:33 | clojurebot | false |
| 15:33 | justin_smith | ,(= rand rand) ; tac |
| 15:33 | clojurebot | true |
| 15:34 | justin_smith | ,(hash rand) |
| 15:34 | clojurebot | 2416519 |
| 15:35 | justin_smith | ,(isa? (class rand) Object) |
| 15:35 | clojurebot | true |
| 15:35 | tac | but |
| 15:35 | tac | ,(= rand (fn [] (rand))) |
| 15:35 | clojurebot | false |
| 15:36 | justin_smith | yes, it is a weak equality |
| 15:36 | justin_smith | and #(rand) is just a fancy way of saying what you did above |
| 15:37 | justin_smith | or maybe we could call it a conservative equality, that misses many chances to label equivalent objects as equal |
| 15:37 | justin_smith | ,(= #(rand) #(rand)) |
| 15:37 | clojurebot | false |
| 15:38 | tac | sets, arrays, lists, and maps are all immutable, right? |
| 15:38 | justin_smith | arrays are mutible |
| 15:38 | justin_smith | vectors are immutible |
| 15:38 | tac | gotcha |
| 15:39 | tac | can vectors change length? Or is it just their cells can be repointed at other things? |
| 15:39 | justin_smith | they can't change, they are immutible |
| 15:40 | tac | err |
| 15:40 | tac | hmm |
| 15:40 | tac | I didn't read that carefully enough |
| 15:40 | justin_smith | though you can create a new one that appends to an old one efficiently |
| 15:40 | justin_smith | arrays cannot change length either |
| 15:40 | schmee | when implementing a protocol on a record, can the functions in the protocol call each other? |
| 15:40 | schmee | I'm getting some errors and I'm not sure if that's the issue, or something else... |
| 15:41 | justin_smith | tac: and yeah, cells in an array can be reassigned |
| 15:42 | tac | [a b c] is array syntax right? |
| 15:42 | tac | and (a b c) is.... vector? |
| 15:42 | justin_smith | no |
| 15:42 | justin_smith | [a b c] is a vector |
| 15:42 | justin_smith | (a b c) is calling a on the args b and c |
| 15:42 | justin_smith | '(a b c) is a list literal |
| 15:43 | justin_smith | there is no literal notation for arrays, they are an underlying jvm construct |
| 15:43 | tac | ahh ok |
| 15:43 | tac | so they are less "blessed" in clojure, right? |
| 15:43 | justin_smith | ,((juxt identity type) (into-array [1 2 3])) |
| 15:43 | clojurebot | [#<Long[] [Ljava.lang.Long;@17e1dd2> [Ljava.lang.Long;] |
| 15:45 | justin_smith | tac: right - they are one of the primitive things defined by the jvm, and they underly other types |
| 16:00 | stuartsierra | tac: Clojure tests equality by value for immutable data structures and by identity for everything else, which includes most Java objects. |
| 16:00 | tac | I figured that's probably how it worked |
| 16:00 | tac | although functions are immutable ;P |
| 16:02 | stuartsierra | Yes but (compiled) functions are not data structures as far as Clojure is concerned. |
| 16:03 | technomancy | stuartsierra: I don't think that's accurate re "most Java objects" |
| 16:03 | technomancy | stuartsierra: sadly = will return true for two different HashMaps |
| 16:04 | turbofail | really? |
| 16:04 | turbofail | oh right it dispatches to the equalTo method if it has one |
| 16:04 | technomancy | ,(let [a (doto (HashMap.) (.put "a" "a")), b (doto (HashMap.) (.put "a" "a"))] (= a b)) ; oops |
| 16:04 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: HashMap, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:04 | technomancy | aw come on |
| 16:05 | technomancy | ,(let [a (doto (HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (= a b)) ; oops |
| 16:05 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: HashMap, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:05 | technomancy | ,(let [a (doto (java.util.HashMap.) (.put "a" "a")), b (doto (java.util.HashMap.) (.put "a" "a"))] (= a b)) ; oops |
| 16:05 | clojurebot | true |
| 16:05 | technomancy | third time's the charm |
| 16:05 | technomancy | anyway, clojure.core/= is not to be trusted with arbitrary java objects |
| 16:05 | stuartsierra | Yes, technomancy is right. Clojure's = falls back to Java Object.equals, which can be fishy. |
| 16:05 | tac | is the / to denote a namespace? |
| 16:07 | technomancy | yeah |
| 16:07 | tww | newbie 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:07 | tac | eval is only one-letter off from evil |
| 16:08 | tac | At least, that's what I've been trained to think ;) |
| 16:08 | technomancy | ,(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:08 | clojurebot | technomancy: Gabh mo leithscéal? |
| 16:08 | technomancy | oh, does the bot block try/catch? boo. |
| 16:10 | amalloy_ | technomancy: well, blocks catch |
| 16:10 | amalloy | and finally, i guess, right? so catch is allowed but not if you use it for anything |
| 16:10 | amalloy | ,(try 1 (finally 2)) |
| 16:10 | clojurebot | amalloy: Titim gan éirí ort. |
| 16:11 | technomancy | ,(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:11 | clojurebot | #<SecurityException java.lang.SecurityException: no threads please> |
| 16:11 | technomancy | drat |
| 16:12 | amalloy | tww: 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:14 | amalloy | ,(try 1) |
| 16:14 | clojurebot | 1 |
| 16:14 | tww | amalloy: thanks. i do have a sane list of lists for my hash-map |
| 16:15 | tww | amalloy_: i appreciate the help |
| 16:24 | schmee | is it possible to use loop/recur when implementing protocols? |
| 16:25 | razum2um | can I conditionally require some code like (ns some (if cond (:require [lib])))) ? |
| 16:26 | joegallo | razum2um: require is available at runtime |
| 16:26 | gfredericks | razum2um: you can do (ns some) (if cond (require '[lib])) |
| 16:26 | joegallo | so, outside of the ns form |
| 16:27 | razum2um | ok, thanks |
| 16:36 | virmundi | justin_smith: is there a short way to conditionally add a key/value to a map if the value is not nil? |
| 16:39 | virmundi | justin_smith: the best I can figure is (merge {…} (if (cond?) {..})) |
| 16:41 | mpenet | ,(doc update-in) |
| 16:41 | clojurebot | "([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:45 | gfredericks | ,(defn assoc-when [m k v] (cond-> m v (assoc k v))) |
| 16:45 | clojurebot | #'sandbox/assoc-when |
| 17:11 | pvinis | i set up a project with lein. |
| 17:11 | pvinis | hi |
| 17:11 | pvinis | i set up a project with lein. |
| 17:11 | justin_smith | congratulations |
| 17:11 | pvinis | i set up a project with lein. |
| 17:12 | pvinis | i set up a project with lein. |
| 17:12 | pvinis | i set up a project with lein. |
| 17:13 | pvinis | i 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:13 | pvinis | is this interactive adding of people possible? |
| 17:13 | justin_smith | pvinis: sure, using an atom for example |
| 17:15 | justin_smith | ,(do (def people (atom [])) (defn add-person [name age] (swap! people conj {:age age :name name})) (add-person "guy" 30) @people) |
| 17:15 | clojurebot | [{:age 30, :name "guy"}] |
| 17:15 | justin_smith | ,(add-person "doll" 42) |
| 17:15 | clojurebot | [{:age 30, :name "guy"} {:age 42, :name "doll"}] |
| 17:15 | justin_smith | pvinis: maybe something like the above |
| 17:16 | aperiodic | pvinis: if you're asking about how to get the input then you probably want to look at ##(doc read-line) |
| 17:16 | lazybot | ⇒ "([]); Reads the next line from stream that is the current value of *in* ." |
| 17:16 | pvinis | aha. i will try that. thanks justin_smith |
| 17:16 | gtrak | what's the difference between clj-oauth vs oauth-clj? |
| 17:17 | pvinis | aperiodic: i probably need to get the input as well. ill check it. thanks |
| 17:18 | justin_smith | one gotcha: with print, you will also need to call (flush) if you want a prompt to show up without a newline |
| 17:19 | technomancy | gtrak: M-t+ |
| 17:19 | technomancy | ? |
| 17:19 | gtrak | there are two libs that do basically the same thing afaict, clj-oauth is more relied-on in clojuresphere. |
| 17:25 | pvinis | can i get a repl when i do lein run? like get a repl as my main loop of the app? |
| 17:27 | justin_smith | pvinis: lein repl |
| 17:27 | technomancy | pvinis: check out the tools.nrepl repo if you want a repl server embedded in your actual main |
| 17:27 | justin_smith | or use clojure.tools.nrepl |
| 17:28 | pvinis | cool. thanks |
| 17:28 | justin_smith | https://github.com/clojure/tools.nrepl |
| 17:29 | pvinis | im trying to learn clojure by making an app. its interesting, but can be a bit confusing |
| 17:29 | arohner | woohoo: "java(5182,0x1297e6000) malloc: *** error for object 0x8280400: pointer being freed was not allocated" |
| 17:29 | justin_smith | woah |
| 17:29 | justin_smith | arohner: did you call a private method somewhere to make that happen? |
| 17:29 | justin_smith | if not, congrats! |
| 17:29 | justin_smith | if so, that's cheating |
| 17:29 | arohner | justin_smith: nope. Playing NIO & byte buffers |
| 17:31 | pvinis | thats 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:31 | pvinis | too much unknown stuff early on |
| 17:32 | amalloy | justin_smith: sounds more like a native method than a private method |
| 17:32 | technomancy | pvinis: 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:32 | justin_smith | pvinis: yeah, the depth of the stack by the time an error is found is definitely not a n00b friendly aspect of clojure |
| 17:32 | amalloy | i've certainly gotten jvm segfaults as a result of native code i edited |
| 17:32 | technomancy | pvinis: don't underestimate the power of having interactive access plus immutable data structures that you can copy/paste |
| 17:33 | technomancy | pvinis: on that note, tools.trace can be really helpful too. |
| 17:34 | pvinis | i saw that there is a c compiler for clojure. is there a "native" c lisp? |
| 17:34 | pvinis | ill check out tools.trace |
| 17:35 | schmee | pvinis: 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:10 | danielcompton | is it possible to explore dependency jars in emacs like you can from IntelliJ? |
| 18:11 | technomancy | danielcompton: M-. works from cider sessions to do this, yeah |
| 18:11 | technomancy | you can even edit them if you're insane |
| 18:11 | danielcompton | woah this is awesome |
| 18:14 | danielcompton | technomancy: which symobls does it show? |
| 18:14 | danielcompton | it doesn't seem to be all of the ones required in my namespace? |
| 18:16 | danielcompton | if I `use` a library it shows it as a var, if I require it then I can't see the prefixed namespace/symbol |
| 18:16 | technomancy | not sure what you mean; it's always worked for me |
| 18:18 | danielcompton | In my :require I have [plumbing.core :refer [dissoc-in]]. I can M-. and see dissoc-in, but no other vars from plumbing.core |
| 18:18 | technomancy | oh, sure |
| 18:19 | danielcompton | is that expected/is there any way to M-. on a namespace? |
| 18:20 | amalloy | danielcompton: M-. only lets you look up vars which are valid in the current ns |
| 18:21 | danielcompton | amalloy: isn't plumbing.core/assoc-when a valid var in a ns? |
| 18:21 | amalloy | in the *current* ns. you only referred dissoc-in |
| 18:22 | technomancy | danielcompton: if you fully-qualify the var, M-. will work. |
| 18:23 | danielcompton | can you explain what you mean when you say fully-qualify? |
| 18:23 | amalloy | danielcompton: type the following: plumbing.core/assoc-when |
| 18:23 | amalloy | and then press M-. while pointing at it |
| 18:24 | danielcompton | oh wow, I was only running it from the minibuffer, I thought I could only pick vars that were in the minibuffer selection list |
| 18:25 | danielcompton | *movie voice* Cider: This changes everything, again. |
| 18:27 | justin_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:27 | justin_smith | rated nc-17 |
| 18:28 | justin_smith | *users |
| 18:29 | danielcompton | contains intense themes, aerial battle sequences and strong language |
| 18:29 | technomancy | fact: aerial battle sequences are the best battle sequences. |
| 18:30 | mdeboard | The Little Mermaid had a really great one |
| 18:31 | mdeboard | Aerial was all like, "No, evil queen octopus lady!" then shoots her voice at her |
| 18:31 | mdeboard | Really great Aerial battle |
| 18:31 | Wild_Cat | technomancy: the entirety of Macross Plus shows that statement to be absolutely correct. |
| 18:32 | justin_smith | Wild_Cat: I am disappointed that you did not attempt a macro themed pun |
| 18:32 | technomancy | >_< |
| 18:32 | Wild_Cat | justin_smith: I'm still a Clojure noob. :p |
| 18:36 | justin_smith | (defmacross valkyrie [] ...) |
| 18:46 | danielcompton | mdeboard: just got that, I was thinking for a while how you have an aerial battle underwater |
| 18:47 | mdeboard | danielcompton: :P |
| 18:54 | mdeboard | If I'm reading the source right, nrepl clients handle creation of nrepl server instances? |
| 18:57 | justin_smith | mdeboard: huh? you use clojure.tools.nrepl.server/start-server to start listening to connections |
| 18:57 | justin_smith | the client doesn't make new instances |
| 18:57 | justin_smith | do you mean sessions? |
| 18:57 | elben | Anyone 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:00 | mdeboard | justin_smith: No, I'm looking at https://github.com/technomancy/leiningen/blob/master/src/leiningen/repl.clj#L243-L246 |
| 19:01 | mdeboard | and the `lein repl' command itself |
| 19:01 | justin_smith | lein creates the server and also attaches a client for the user to interact with |
| 19:02 | justin_smith | that's not the same as a client being in charge of creating server instances |
| 19:02 | justin_smith | you can start-server without ever spawing a client |
| 19:03 | justin_smith | or maybe I am misunderstanding you |
| 19:17 | mdeboard | justin_smith: No, I think you're udnerstanding me ok. I'm just trying to internalize how it works. |
| 19:17 | mdeboard | so I'm probably not saying what I mean |
| 19:18 | justin_smith | so, the code you linked to invokes reply |
| 19:18 | justin_smith | reply in turn invokes nrepl |
| 19:18 | justin_smith | you can use nrepl to create a client or a server within your process - leiningen happens to do both (but via reply) |
| 19:20 | nhanH | Is "lein repl" supposed to ignore the user-wide profiles in ~/.lein/profiles.clj ? |
| 19:20 | justin_smith | no, those should get merged into your settings |
| 19:22 | nhanH | so, 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:22 | justin_smith | can you paste your profiles.clj and describe the symptom (what you expect, and what you get instead) |
| 19:23 | justin_smith | paste in a site like refheap.com that is, of course |
| 19:23 | nhanH | I 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:24 | nhanH | but if the profiles.clj is only in ~/.lein, then I can't |
| 19:24 | nhanH | http://pastebin.com/J764GanH the profiles.clj file |
| 19:25 | justin_smith | does your project.clj have an :env key that would override that maybe? |
| 19:26 | nhanH | here http://pastebin.com/chuCzjuS |
| 19:26 | nhanH | I don't think there is anything to override |
| 19:27 | nhanH | so I'm using lein-environ to generate .lein-env to be used by environ |
| 19:27 | nhanH | that file has an empty map if I don't have a profiles.clj under my project folder |
| 19:27 | justin_smith | yeah, that should be working |
| 19:29 | nhanH | any suggestion? |
| 19:29 | justin_smith | nhanH: actually - looking at the environ docs, environ does not get the bindings from lein |
| 19:30 | nhanH | "lein test" work properly with the user-wide profiles though |
| 19:30 | nhanH | wait actually hmm |
| 19:30 | nhanH | let me see |
| 19:30 | justin_smith | I 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:32 | nhanH | hmm, I just checked, and apparently "lein test" does run and get the main profiles.clj properly |
| 19:32 | nhanH | so environ can get the bindings from lein |
| 19:32 | nhanH | it just doesn't do it for the repl |
| 19:44 | jds_ | 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:00 | sritchie | anyone know the API call to query clojars for a project’s most recent version? |
| 20:44 | danielcompton | Microsoft sharing the love for immutable objects http://www.freepatentsonline.com/y2014/0196008.html |
| 20:48 | nullptr | danielcompton: microsoft has an immutable collections impl for .net http://msdn.microsoft.com/en-us/library/dn385366(v=vs.110).aspx |
| 20:53 | razum2um1 | why does lein uberjat complains about Don't know how to create ISeq from: java.util.regex.Pattern though in docs it's possible? |
| 20:53 | razum2um1 | btw, how to compile :all except one ns |
| 20:55 | danielcompton | nullptr: and it looks like they have a patent for it too |
| 21:05 | celwell | Hello, 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:07 | danielcompton | ,(clojure.string/escape sql-value {\' "\'" \" "\""}) |
| 21:07 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \'> |
| 21:14 | bluesnow | Hi, I'm confused about the difference between (repeatedly 10 (partial rand-int 50)) and (repeatedly 10 (fn [] (rand-int 50))) |
| 21:15 | bluesnow | The 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:15 | danielcompton | ,(doc rand-int) |
| 21:15 | clojurebot | "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)." |
| 21:16 | celwell | danielcompton: so, Unsupported escape character, is actually a different error than the one I got, but any ideas |
| 21:17 | bluesnow | danielcompton: Uh, I still don't see it. For example, when I do (rand-int 10 50), I get an ArityException |
| 21:18 | bluesnow | so why is the book using partial in the expression, instead of just fn? |
| 21:18 | aperiodic | ,((partial rand-int 50)) |
| 21:18 | clojurebot | 15 |
| 21:19 | bluesnow | Ah I see. So they just use partial to define the function instead of using fn, since the function definition using partial is shorter.. |
| 21:19 | danielcompton | bluesnow: I'm not quite sure how to describe the difference between the two, they both return a function |
| 21:19 | danielcompton | bluesnow: but partial curries the arguments (I think) |
| 21:19 | bluesnow | danielcompton: Right. But in the case of the repeatedly + partial/fn rand int expression, it's the same, right? |
| 21:20 | bluesnow | because rand-int only takes one arg anyway |
| 21:20 | bluesnow | so there's nothing to curry / no extra argument that can be passed |
| 21:20 | danielcompton | partial returns a function taking a variable number of arguments. So the result is the same but they're not the same function |
| 21:20 | bluesnow | danielcompton: Right. |
| 21:20 | bluesnow | Ok, I get that. |
| 21:21 | bluesnow | Thanks, 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:25 | danielcompton | bluesnow: I would say it's to show different ways of doing the same thing? |
| 21:26 | danielcompton | good question |
| 21:27 | bluesnow | danielcompton: 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:39 | irctc | hey hey |
| 21:40 | irctc | how do i get UserDefinedFileAttributeView to work from clojure (noob here) |
| 21:40 | irctc | is 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:43 | TEttinger | irctc, well to start you'd probably want to import some of those long java names |
| 21:43 | TEttinger | save some typing |
| 21:44 | irctc | i think i don't know how to do this: UserDefinedFileAttributeView.class in clojure |
| 21:44 | TEttinger | uh, is it a class defined inside another class? |
| 21:44 | irctc | it's an interface |
| 21:45 | TEttinger | oh ok, so you need to get the Class from that? |
| 21:46 | irctc | here's the java: UserDefinedFileAttributeView view = file.getFileAttributeView(UserDefinedFileAttributeView.class); |
| 21:47 | TEttinger | well I think you can still do (.class UserDefinedFileAttributeView), not sure -- I deal with interfaces rarely |
| 21:49 | irctc | yeah can't get that to work |
| 21:49 | irctc | figured i would try asking for help |
| 21:51 | irctc | looks like it's just (class xyz) vs (.class xyz) |
| 21:54 | TEttinger | irctc, (class java...blahView) gives me java.lang.Class , which I don't think is what you want |
| 21:55 | TimMc | (dec AOT) |
| 21:55 | TEttinger | try entering just: java.nio.file.attribute.UserDefinedFileAttributeView |
| 21:55 | TEttinger | lazybot is out |
| 21:55 | TimMc | :-( |
| 21:56 | TimMc | How am I supposed to formally register diapproval, then? |
| 21:56 | TEttinger | irctc: using java.nio.file.attribute.UserDefinedFileAttributeView without parentheses should be the actual class |
| 22:01 | irctc | that got me farther along thx |
| 22:11 | Lanny | spectral == know-nothing nigger |
| 22:12 | TimMc | plonk |
| 22:18 | beamso | i'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:34 | celwell | How 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:42 | beamso | celwell: {\' "\\'" \" "\""} ? |
| 23:43 | celwell | beamso: thank you. |
| 23:44 | beamso | try calling str on the output to test it |
| 23:44 | beamso | i didn't test escaping '"' |
| 23:48 | celwell | beamso: Yeah, that doesn't work for '"', but I got it to work with this: {\' "\\'" \" "\\\""} |
| 23:50 | amalloy | yikes, celwell, automatically escaping sql strings is playing with fire |
| 23:50 | amalloy | are you sure you can't use parameterized queries with fixed sql? |
| 23:50 | celwell | amalloy: I wish I could do what I need with just clojure.java.jdbc |
| 23:51 | celwell | amalloy: I need to wrap values in AES_ENCRYPT() |
| 23:52 | celwell | I would probably have to back out of jdbc completely if I wanted to still use java's parameterization |
| 23:53 | danielcompton | Emacs plugins: http://3.bp.blogspot.com/-WtKPYcpHxh8/UcdueZEQYpI/AAAAAAAAAJc/3-muBcjfBUk/s1600/world+war+z+4.jpg |
| 23:54 | celwell | Hmm... now that I think about it, maybe I can just construct the INSERT string and put AES_ENCRYPT(?), AES_ENCRYPT(?), etc. |
| 23:54 | talios | danielcompton - looks like an eclipse plugin to me. |