2014-05-14
| 00:01 | amalloy | *shrug* i don't know what you've been asked to build. maybe you're not supposed to care where these objects come from, or a transport layer is something you can bolt on later |
| 00:02 | ddellacosta | amalloy: (offtopic) didn't you say this exact thing yesterday? http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ |
| 00:02 | ddellacosta | that's all, just interesting I thought... |
| 00:03 | amalloy | ddellacosta: i stole it from him |
| 00:03 | ddellacosta | amalloy: well, there ya go |
| 00:04 | numberten | is there a good resource for learning how to quickly compile and test files, ideally something similiar workflow wise to testing .hs files by loading them into ghci? |
| 00:04 | numberten | leiningen seems rather heavy for that.. but maybe that's just because I'm not especially familiar with it? |
| 00:08 | hiredman | numberten: java -jar clojure.jar will start a very bare bones repl |
| 00:08 | quizdr | ddellacosta amalloy that's a nice article. i wish more dev bloggers spoke with insight that transcends the "here's a neat trick I just came up with" variety. |
| 00:08 | hiredman | numberten: java -cp clojure.jar clojure.main --help will print a list of command line options |
| 00:08 | Rosnec | is there a simple way to take two maps, A and B, and for each key that is in both A and B, replace B's key with A's value? |
| 00:08 | numberten | hiredman: alright thanks |
| 00:09 | Rosnec | I know it wouldn't be too hard with reduce, but if there's something designed for that I'd rather use it |
| 00:09 | Rosnec | it should behave something like this: |
| 00:09 | amalloy | (merge b a)? |
| 00:10 | Rosnec | amalloy, no, not merge |
| 00:10 | Rosnec | lemme write an example real quick |
| 00:11 | Rosnec | (replace-keys {:a :a-replacement, :b :b-replacement} {:a 4, :b 5, :c 6}) => {:a-replacement 4, :b-replacement 5, :c 6} |
| 00:11 | Rosnec | it's the keys I'm changing, not the values |
| 00:12 | amalloy | clojure.set/rename-keys |
| 00:12 | Rosnec | amalloy: :D |
| 00:12 | Rosnec | beautiful |
| 00:14 | Rosnec | actually, there's one thing that this doesn't cover in my usage, which might make me resort to writing somethign with reduce |
| 00:14 | Rosnec | I need to keep track of which keys I've successfully replaced |
| 00:15 | Rosnec | because I'm recursing through a bunch of maps, and each time a key from kmap is used, I want to dissoc that key from kmap |
| 00:16 | Rosnec | I suppose I could just check afterwards which keys from kmap exist in map |
| 00:17 | Rosnec | and dissoc them when I recur |
| 00:26 | technomancy | numberten: once you have a repl open, just run (clojure.test/run-tests) or (require 'some.ns :reload) |
| 00:58 | orknob | Is there an archive of this room anywhere? Asking since the room seems to be active outside of my working hours? |
| 00:59 | Jaood | the first result of googling "#clojure log freenode" for me |
| 00:59 | mdeboard | orknob: The channel logsare indexed by google |
| 01:00 | mdeboard | orknob: Also you might want to consider setting up/using an IRC bouncer |
| 01:00 | orknob | @Jaood ah, thanks. I searched for |
| 01:01 | orknob | @Jaood “freenode archives” and came up with http://www.irclog.org/network.php?net=freenode which doesn’t have Clojure |
| 01:01 | orknob | @mdeboard thanks. IRC n00b here. Looking up IRC bouncer. |
| 01:03 | technomancy | also, it's IRC, not twitter =) |
| 01:03 | danielcompton | Why is clojure.string and clojure.set included with Clojure core but not something like https://github.com/clojure/math.numeric-tower |
| 01:03 | technomancy | orknob: ^ |
| 01:03 | technomancy | danielcompton: historical reasons more than anything else |
| 01:04 | danielcompton | technomancy how does it distinguish between them? |
| 01:04 | technomancy | danielcompton: I don't understand the question |
| 01:04 | danielcompton | technomancy how would I know which is included and which is a separate dependency? |
| 01:05 | technomancy | the ones that are included are documented with clojure itself rather than being a separate project |
| 01:08 | danielcompton | Got it |
| 01:15 | dissipate | anyone else having trouble with http://tryclj.com/? |
| 01:16 | cbp` | which troubles? |
| 01:18 | dissipate | cbp`, timing out |
| 01:19 | cbp` | dissipate: you get Execution timed out! ? |
| 01:20 | danielcompton | dissipate working for me |
| 01:20 | dissipate | cbp`, yeah, the ajax calls are timing out |
| 01:22 | dissipate | hmm, working now. |
| 01:22 | dissipate | must have been lagged out |
| 03:38 | mskoud | what does (let [{widgets :body} (<! (http/get url))]... specifically the {widgets :body} mean? |
| 03:40 | sm0ke | how do i integrate junit tests into my lein project/ |
| 03:40 | sm0ke | ?* |
| 03:41 | pyrtsa | mskoud: Given that the right-hand side returns a map m with the key :body, it binds the value (:body m) to `widgets`. |
| 03:42 | mskoud | ok, i see, thanks. |
| 03:42 | pyrtsa | It's just the ordinary use of maps in let bindings. |
| 03:46 | sm0ke | there is a https://github.com/febeling/lein-junit |
| 03:53 | hennry | Hello I put the validation on the clojure code if there is error then it will be handle , its reload with the empty form which i not want , what ever data we filled correctly it will be remain in the form and the error field data delete only |
| 03:58 | martinklepsch | anyone here some experience profiling with timbre? is it possible to profile across multiple namespaces? |
| 04:43 | pbw | Can I use map to create a lazy sequence from two cycles? |
| 04:48 | dissipate | pbw, why not use a 'for' |
| 04:48 | pbw | Forgot to mention these are infinite sequences |
| 04:49 | pbw | Is that implied by "cycle"? |
| 04:49 | dissipate | pbw, http://clojuredocs.org/clojure_core/clojure.core/for |
| 04:50 | pbw | Digesting that now… thanks |
| 04:53 | pbw | I don't know that that will work. I want the map to operate on the corresponding elements of the two (or more) input cycles, not to do nested iterations. |
| 04:53 | dissipate | pbw, (take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y])) |
| 04:54 | dissipate | ;(take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y])) |
| 04:54 | dissipate | ;;(take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y])) |
| 04:56 | dissipate | pbw, not sure exactly what you are trying to do but 'for' will create a lazy sequence from two cycles. :D |
| 04:56 | pbw | Yes, but not in the right order. |
| 04:56 | pbw | (def cycle2 (cycle [true false])) |
| 04:57 | pbw | (def cycle3 (cycle [true true false])) |
| 04:58 | dissipate | pbw, and? |
| 04:58 | pbw | What I want is a cycle that is the logical and of the corresponding elements of the two cycles. |
| 05:00 | pbw | (take 6 (some-map cycle2 cycle3)) => [true false false false true false] |
| 05:08 | dissipate | pbw, hmm, looks like my solution is bad actually. :( |
| 05:09 | pbw | It's because of the nested iteration of for. It gives a cartesian product of the elements of the input sequences, so it couldn't handle an infinite seq. That's what it looks like to me, anyway. |
| 05:12 | pbw | If I try this: (def cycle23 (map and cycle2 cycle3)) |
| 05:12 | pbw | I get Can't take value of a macro |
| 05:13 | jonathanj | #(and %1 %2) |
| 05:14 | pbw | That is accepted, but (take 19 (cycle23)) gives: ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn |
| 05:15 | jonathanj | (take 19 cycle23) |
| 05:15 | jonathanj | i don't think you want to call your sequence |
| 05:16 | pbw | No, I don't! And that works. |
| 05:16 | pbw | (take 10 cycle23) |
| 05:16 | pbw | => (true false false false true false true false false false) |
| 05:16 | jonathanj | it's unfortunate that you can't just use `and` as is |
| 05:17 | pbw | Ok. Next question. Can I extend this so that it will take more than 1 cycles, rather than just two. |
| 05:18 | pbw | It is unfortunate. And that makes it awkward to get my next answer. |
| 05:19 | dissipate | pbw, yep, write a function that returns a lazy seq that takes an arbitrary number of cycles as arguments. |
| 05:20 | jonathanj | can you define an anonymous function that takes &? |
| 05:20 | nathan7 | jumblerg: %& |
| 05:20 | nathan7 | jonathanj* |
| 05:20 | dissipate | jonathanj, yep |
| 05:21 | ssideris | or just (fn [& stuff] ...) |
| 05:21 | nathan7 | (#(identity %&) 1 2 3) = [1 2 3] |
| 05:21 | jonathanj | <3 |
| 05:21 | jonathanj | hrm |
| 05:22 | pbw | Trying to work out what's going on above. |
| 05:22 | dissipate | pbw, set up a multi-arity function the first arity being 2 and the second being arbitrary. |
| 05:22 | jonathanj | #(and %&) doesn't quite do what i expected |
| 05:23 | pbw | No. => ((true true) (false true) (true false) (false true) (true true) (false false) (true true) (false true) (true false) (false true)) |
| 05:23 | jonathanj | i guess that's because it's doing (and [true false]) |
| 05:23 | jonathanj | which is [true false] |
| 05:23 | pbw | Ok |
| 05:24 | pbw | @dissipate - I'll try that if I can't get a simpler thing working |
| 05:25 | jonathanj | i'm not exactly sure how you write this |
| 05:25 | dissipate | jonathanj, right, it actually becomes a single argument that is a vector of all the arguments |
| 05:26 | dissipate | jonathanj, i think if you add an 'apply' it works |
| 05:26 | jonathanj | how do i use the bot? :P |
| 05:26 | jonathanj | ,(apply #(and %&) [true false]) |
| 05:26 | clojurebot | (true false) |
| 05:27 | jonathanj | ,(#(apply and %&) [true false]) |
| 05:27 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:27 | pbw | I've seen that error! |
| 05:28 | dissipate | ,(#(apply and %&) true false) |
| 05:28 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:28 | pbw | I did get the 2 arg version going a while ago, but forgot how I'd done it. ANd I did try apply. |
| 05:28 | ssideris | apply works on normal functions, but and is a macro |
| 05:29 | ssideris | hence the error |
| 05:29 | dissipate | ssideris, i see. crappy. :( so what's the apply for macros? |
| 05:30 | dissipate | http://clojuredocs.org/clojure_contrib/clojure.contrib.apply-macro/apply-macro |
| 05:30 | dissipate | says to never use it. :( |
| 05:30 | jonathanj | well it is weird |
| 05:30 | dissipate | ,(#(apply-macro and %&) true false) |
| 05:30 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: apply-macro in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:30 | jonathanj | almost as weird as (and) being a macro :P |
| 05:31 | emlyn | What about ,(reduce #(and %1 %2) [true false]) |
| 05:31 | emlyn | ,(reduce #(and %1 %2) [true false]) |
| 05:31 | clojurebot | false |
| 05:33 | pbw | It's the unknown number of arguments that is the problem. |
| 05:33 | jonathanj | right, so if you: (defn and-fn [& args] (reduce #(and %1 %2) [true false]) |
| 05:33 | jonathanj | then you can just write: (map and-fn cy1 cy2 cy3 ...) |
| 05:33 | emlyn | ,(reduce #(and %1 %2) [true false true true false]) |
| 05:33 | clojurebot | false |
| 05:33 | pbw | Duh |
| 05:34 | ssideris | pbw: http://clojuredocs.org/clojure_core/clojure.core/every_q |
| 05:34 | leggo | though that won't short circuit |
| 05:35 | jonathanj | leggo: which? the reduce? |
| 05:35 | ssideris | leggo: it stops at the first false it encounters |
| 05:36 | ssideris | look at the source |
| 05:36 | leggo | it does? how? |
| 05:36 | dissipate | http://stackoverflow.com/questions/9218044/in-clojure-how-to-apply-and-to-a-list |
| 05:37 | ssideris | leggo: recurs until it finds a false value |
| 05:37 | dissipate | ,(every? identity '(true false)) |
| 05:37 | clojurebot | false |
| 05:39 | jonathanj | why is `and` a macro? |
| 05:40 | dissipate | jonathanj, good question, i have no idea why |
| 05:40 | CookedGryphon | jonathanj: so that it can short circuit |
| 05:40 | pyrtsa | To avoid evaluating more arguments if the result is already clear. |
| 05:40 | Bronsa | jonathanj: so that (and true (println "foo")) short circutis and doesn't print "foo" |
| 05:41 | jonathanj | i guess that makes sense |
| 05:41 | pbw | (def cyclen (map #(every? identity %&) cycle2 cycle3)) |
| 05:41 | ssideris | Bronsa: that would be the case for or! or can decide to stop early, but the semantics of and don't allow that, right? |
| 05:41 | leggo | ssideris, I must be completely misunderstanding how reduce works then. is it not just a left fold? how would it know when to stop instead of going through all the elements? |
| 05:41 | dissipate | ah, makes sense. yep, short circuiting can only truly be achieved as macro |
| 05:41 | pyrtsa | (and condition (println "foo")) is a poor example, though. One should use (when condition ...) for it. |
| 05:41 | pbw | (take 10 cyclen) => (true false false false true false true false false false) |
| 05:41 | Bronsa | ssideris: durr. |
| 05:41 | dissipate | in other languages like Python, the arguments must be evaluated first, so it's less efficient |
| 05:41 | ssideris | leggo: sorry to have confused you, I was talking about (every?) |
| 05:41 | Bronsa | well s/true/false |
| 05:42 | pyrtsa | But (when (and ...) ...) makes sense. |
| 05:42 | Bronsa | (and false (println "foo")) |
| 05:42 | leggo | ssideris ah ok |
| 05:42 | ssideris | Bronsa: ok, it makes sense like that :-) |
| 05:43 | dissipate | pbw, so it's working? |
| 05:44 | ssideris | so and is a macro in order to be able to look at Bronsa's example, evaluate the first thing (false) and stop without evaluating any of the other s-expressions - (println "foo") in this case |
| 05:44 | pbw | Yes. Thank you all. Btw, does every? short-circuit? |
| 05:45 | pyrtsa | Yes. |
| 05:45 | dissipate | ssideris, yes. in a function the arguments must be evaluated (i believe) |
| 05:45 | pbw | thanks. What does 'identity' do that makes the %& work? |
| 05:46 | dissipate | pbw, it 'unboxes' the arguments from the vector |
| 05:47 | pbw | Like 'apply'? |
| 05:47 | llasram | pbw: %& is part of the reader syntax for shorter anonymous functions |
| 05:47 | sm0ke | i keep getting "java.lang.NoSuchMethodError: clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap;" today |
| 05:47 | sm0ke | seen before? |
| 05:47 | llasram | ,`#(every? identity &%) |
| 05:47 | clojurebot | (fn* [] (clojure.core/every? clojure.core/identity sandbox/&%)) |
| 05:47 | llasram | Er, |
| 05:47 | llasram | ,`#(every? identity %&) |
| 05:47 | clojurebot | (fn* [& rest__49__50__auto__] (clojure.core/every? clojure.core/identity rest__49__50__auto__)) |
| 05:48 | llasram | Ther ewe go |
| 05:48 | Bronsa | sm0ke: using an AOT compiled cljs source against clojure >1.4.0 on clojure 1.3.0 |
| 05:48 | Bronsa | sm0ke: or compiled against >1.5.0 on clojure 1.4.0, I don't remember when that done |
| 05:49 | dissipate | pbw, yeah, like 'apply' it unboxes the arguments from the list/vector |
| 05:49 | sm0ke | hurm there is no cljs for sure, must be the second one then |
| 05:54 | dissipate | ,(and) |
| 05:54 | clojurebot | true |
| 05:54 | dissipate | ,(or) |
| 05:54 | clojurebot | nil |
| 05:54 | dissipate | pop quiz. why is (and) true? |
| 05:56 | pbw | So it will return true if later anded with true? |
| 05:57 | dissipate | pbw, yep, put another way, it's because it is the identity of 'and'. |
| 05:57 | dissipate | pbw, it doesn't change the result of an 'and' |
| 05:57 | dissipate | ,(+) |
| 05:57 | clojurebot | 0 |
| 05:57 | dissipate | pbw, same reason why (+) is 0 |
| 05:58 | dissipate | pbw, but i still don't know why (or) is 'nil' and not 'false' |
| 05:58 | dissipate | ,(or) |
| 05:58 | clojurebot | nil |
| 05:58 | Bronsa | dissipate: no reason |
| 05:58 | CookedGryphon | dissipate: nil *is* false |
| 05:58 | Bronsa | CookedGryphon: false-y |
| 05:58 | dissipate | (= nil false) |
| 05:58 | llasram | ,(identical? false nil) |
| 05:58 | clojurebot | false |
| 05:58 | CookedGryphon | falsy-y |
| 05:59 | Bronsa | dissipate: I guess nil plays nicer with seqs than false |
| 05:59 | dissipate | ,(and true nil) |
| 05:59 | clojurebot | nil |
| 05:59 | llasram | Which isn't really a great justification... |
| 06:00 | dissipate | why does 'and' evaluate to its first falsy value instead of just 'false'? |
| 06:01 | llasram | dissipate: Because it evaluates to the value of the last argument it evaluates |
| 06:01 | sm0ke | Bronsa: indeed, bumping clojure version to 1.5.1 in my project seems to have fixed it |
| 06:01 | llasram | ,(and false 17) |
| 06:01 | clojurebot | false |
| 06:01 | llasram | ,(and true 17) |
| 06:01 | clojurebot | 17 |
| 06:01 | sm0ke | but where the hell is that >1.5.0 compiled source is coming from! |
| 06:02 | sm0ke | i was using lein-junit and i think its the culprit https://github.com/febeling/lein-junit/blob/master/project.clj |
| 06:02 | llasram | sm0ke: Could be any of your deps unfortunately :-( I know Storm messed up that way, at least at one point |
| 06:02 | sm0ke | can a dependency be excluded from plugins? |
| 06:02 | dissipate | llasram, i see, makes sense |
| 06:03 | llasram | sm0ke: Why do you think it's lein-junit? |
| 06:03 | dissipate | llasram, but we still don't know why (or) is 'nil' |
| 06:03 | sm0ke | llasram: well because lein deps :tree shows clojure 1.4.0 overrwites others |
| 06:04 | llasram | sm0ke: Oh, separate problems of someone using version ranges? I misunderstood -- I thought problem was one of your dependencies was AOT compiled and thus implicitly overriding your clojure dep w/ separate AOTed copy |
| 06:05 | llasram | dissipate: Yeah, that seems wrong to me -- does seem like it should be `false`. Not that it ever actually comes up |
| 06:05 | llasram | I mean, since `or` is a macro, I can't imagine the 0-argument version gets called very frequently |
| 06:08 | visof | how can i accumulate the result of recursion on a list? |
| 06:08 | visof | i mean the basic way |
| 06:08 | Glenjamin | the 0-arity versions should be an identity |
| 06:08 | Glenjamin | ,(= (or 'x (or)) 'x) |
| 06:08 | clojurebot | true |
| 06:08 | llasram | visof: `reduce`? |
| 06:08 | Glenjamin | that should be true for basically all functions |
| 06:08 | Glenjamin | ,(= (and (and) 'x) 'x) |
| 06:08 | clojurebot | true |
| 06:09 | Glenjamin | erm |
| 06:09 | Glenjamin | ,(= (and 'x (and)) 'x) |
| 06:09 | clojurebot | false |
| 06:09 | llasram | Glenjamin: I think you may have scrolled back too far :-) |
| 06:09 | Glenjamin | oh right, i see |
| 06:10 | gyim | llasram: I think the reason for (or)=nil is that (or arg1 arg2 ...) returns the first argument that is not nil/false. So it does not return a logical value (true/false), it returns one of the arguments. And if there are no arguments, there is no reason to return true/false |
| 06:10 | Glenjamin | (or) => nil produces an identity, it seemed like the question was hanging :) |
| 06:10 | visof | llasram: well, i'm walking on a list if found element matched to another list walk again for this list else element, how can i collect all result? |
| 06:10 | llasram | gyim: You know, that makes sense. Good point! |
| 06:11 | visof | what i thought: iterate over a list, if element not list return element else walk sublist |
| 06:11 | llasram | Glenjamin: Right, but it seemed like the actually-boolean identity value of `false` would have been better, before gyim's suggiestion |
| 06:11 | Glenjamin | oh, i see |
| 06:11 | Glenjamin | yeah, they're equivalent i guess |
| 06:12 | llasram | visof: Example inputs and results? I'm not following |
| 06:18 | visof | llasram: https://www.refheap.com/85475 , i know this example like flatten list, but i want to understand teh concept, how can i collect the final result from this code? |
| 06:19 | llasram | visof: Well, to start with, you don't use doseq :-) |
| 06:19 | llasram | You can call a function recursively from any of the higher-order sequence functions |
| 06:20 | llasram | You can usually handle most patterns with `map` etc and/or `reduce` |
| 06:20 | jkj | how should i spread io work into multiple workers? ... can't wrap my head around e.g. how to keep 5 futures running |
| 06:20 | llasram | visof: Otherwise `loop`/`recur` |
| 06:21 | llasram | visof: Without something more specific, I'm not sure what else to add |
| 06:22 | llasram | jkj: You can fake it, but IMHO it usually isn't worth it. Just drop down to interop and use the Java standard lib executor service stuff w/ j.u.c queues |
| 06:22 | Glenjamin | jkj: i think that's agents or core.async territory |
| 06:22 | llasram | jkj: First-class functions makes it far more pleasant to work with than from raw Java |
| 06:23 | Glenjamin | i would recommend believing llasram over me in this case, i've only done non-io paralleism |
| 06:24 | jkj | llasram: ok. thx |
| 06:24 | visof | llasram: so what should the code looks like? |
| 06:25 | llasram | visof: What's a specific problem you'd like to solve? Like, just for an example, re-implement `flatten` ? |
| 06:25 | visof | yeah but in this shape of code |
| 06:26 | llasram | In what sense? |
| 06:27 | visof | llasram: the code i pasted, i'll replace doseq to reduce? |
| 06:28 | llasram | You've got a few options. You can create something non-lazy using `reduce`. If you want something lazy, you'll need to use explicit recursion with `lazy-seq` |
| 06:29 | visof | llasram: so it should be like (reduce conj [] (code)) ? |
| 06:30 | llasram | visof: Not quite |
| 06:30 | visof | llasram: ? |
| 06:31 | llasram | Just a sec... `flatten` is kind of an annoying example |
| 06:37 | llasram | visof: flatten just really is not a good example, but here you go anyway: https://www.refheap.com/85476 |
| 06:38 | TerranceWarrior | is there a way to use clojure as a scripting language or unreal udk 4? |
| 06:39 | llasram | visof: Do you have any other example in mind of what you're trying to achieve? Right now it more seems like there's just a technique you want to use, but don't have any particular problems to solve with it |
| 06:39 | llasram | Which makes it difficult to discuss |
| 06:39 | ssideris | TerranceWarrior: does UDK 4 support java or javascript for scripting? |
| 06:52 | TerranceWarrior | ssideris: nope |
| 06:52 | TerranceWarrior | ssideris: just c++ |
| 07:28 | turbopape | Hi guys, I'am trying to put a restart-agent in a set-handler-error! fn, this seems not to be working. is this a known problem, like I'm not allowed to restart inside an agent error handler function ? |
| 07:59 | schmir | I'm using clojure.java.jdbc to connect to an 16 year old informix SE database, that's a bit misconfigured. the configured character code page is wrong and I would need a kind of a hook to convert strings to the right encoding. is there a way to do that? |
| 08:10 | martinklepsch | when I use dorun to run sth like (map f coll) does this actually also run all map calls that come furhter down the line? |
| 08:21 | pbw | schmir: I don't know much about this stuff, but slurp accepts a file encoding argument. java.nio.charset package contains CharsetDecoder and there's a java.nio.charset.spi package for defining charset providers. You may be able to find such a provider for Informix database. |
| 08:28 | schmir | pbw: the informix jdbc driver already does the conversion. but the database is itself is misconfigured. thanks for the pointers. |
| 08:34 | martinklepsch | when I (dorun something) is that recursive? i.e. when something in there returns a lazy seq, is that also fully eval'd? |
| 08:46 | hyPiRion | no |
| 08:47 | hyPiRion | ,(dorun (list (range))) |
| 08:47 | clojurebot | nil |
| 09:02 | Raynes | Side effects of waking up at 4AM: you make conch throw exceptions for non-zero exit codes. |
| 09:04 | mdrogalis | Heh, morning Raynes. |
| 09:07 | hyPiRion | Raynes: no way there's 4 am there now |
| 09:07 | Raynes | hyPiRion: Well it's 6AM now. |
| 09:07 | Raynes | I didn't say it was easy. |
| 09:07 | Raynes | :P |
| 09:08 | hyPiRion | oh wow, it really is. |
| 09:09 | gfredericks | if you lived in chicago, you'd be home by now |
| 09:09 | hyPiRion | gfredericks: Didn't know chicago were in Europe, but yeah. |
| 09:10 | gfredericks | chicago is wherever you are most happy |
| 09:10 | hyPiRion | clojurebot: chicago? |
| 09:10 | clojurebot | Pardon? |
| 09:10 | gfredericks | clojurebot: the chicago |was| inside you the whole time |
| 09:10 | clojurebot | Ack. Ack. |
| 09:11 | mdrogalis | You never needed to go to Chicago. The irony is, you're always there. |
| 09:38 | _oggy | i want to define a function which takes either one or two arguments (the first one is optional). what's the standard clojure way of doing this? |
| 09:38 | mdrogalis | _oggy: Optional args can only go at the end. |
| 09:38 | mdrogalis | Maybe take a single parameter as a map. |
| 09:38 | _oggy | can i use a multimethod? |
| 09:39 | justin_smith | mdrogalis: if it is one or two args you can do the first as optional |
| 09:39 | mdrogalis | justin_smith: Yeah, that makes sense. Whenever someone asks for this, I always picture them requesting for something like (f x=42, y) {...} |
| 09:39 | justin_smith | ,((fn f ([a] (f nil a)) ([b a] [a b])) nil) |
| 09:39 | clojurebot | [nil nil] |
| 09:39 | justin_smith | ,((fn f ([a] (f nil a)) ([b a] [a b])) 1) |
| 09:39 | clojurebot | [1 nil] |
| 09:40 | justin_smith | ,((fn f ([a] (f nil a)) ([b a] [a b])) 1 2) |
| 09:40 | clojurebot | [2 1] |
| 09:40 | justin_smith | something like that at least |
| 09:42 | _oggy | justin_smith: ah, i think i see what you did there :) can i do the same with defn? |
| 09:42 | justin_smith | yes, defn is just (def (fn ...)) plus some metadata |
| 09:43 | justin_smith | well (def foo (fn ...)) but you get the idea |
| 09:44 | _oggy | yup, thanks! |
| 09:44 | justin_smith | ,(map #(apply (fn f ([a] (f :default a)) ([b a] [a b])) %) [[1] [1 2]]) ; getter example |
| 09:44 | clojurebot | ([1 :default] [2 1]) |
| 09:44 | justin_smith | *better |
| 09:51 | martinklepsch | I want to run a fn that creates a lazy seq for profiling and I have one toplevel dorun but that does not evaluate lazy sequences further down the line. (thanks hyPiRion) — I guess the easiest way to force complete evaluation would be to print all the elements but that doesn't seem "right" |
| 09:52 | martinklepsch | what other options are there for that sort of stuff? |
| 10:05 | emlyn | martinklepsch: you could flatten it, or anything else that would walk the whole tree |
| 10:07 | justin_smith | emlyn: oh, flatten for side effects? |
| 10:08 | justin_smith | ,(type (flatten (map #(range %) (range)))) |
| 10:08 | clojurebot | clojure.lang.LazySeq |
| 10:08 | justin_smith | emlyn: that won't work |
| 10:09 | justin_smith | if that had forced evaluation, clojurebot would have timed out |
| 10:10 | martinklepsch | justin_smith, what else should I do then? |
| 10:11 | justin_smith | clojure.walk/post-walk or the likes would be guaranteed to hit everything |
| 10:14 | martinklepsch | justin_smith printing everything might also do it, no? |
| 10:15 | martinklepsch | here is a bit more context to the problem I'm trying to solve: https://github.com/ptaoussanis/timbre/issues/64#issuecomment-43066222 |
| 10:16 | justin_smith | martinklepsch: print for side effects just feels yucky |
| 10:17 | martinklepsch | justin_smith, yeah sure, just trying to understand better |
| 10:18 | justin_smith | change read-file to (comp dorun read-file) |
| 10:18 | justin_smith | or (comp doall read-file) if you want the result |
| 10:18 | justin_smith | or use doseq instead of map if you don't need the result |
| 10:20 | no7hing | what’s the scope of *warn-on-reflection* if set e.g. in the core namespace? |
| 10:21 | justin_smith | ,(meta #'*warn-on-reflection) |
| 10:21 | martinklepsch | justin_smith: (profile :info :read-file (dorun (map (comp dorun read-file) (take 4 files))))) |
| 10:21 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: *warn-on-reflection in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:21 | no7hing | and reflections occur in namespaces used by that one? |
| 10:21 | martinklepsch | like this? |
| 10:21 | nkoza | there is a macro to qualify all symbols in an expression? like (themacro ([hi ho aliastons2/hu {::a 3}])) ;=> '(myns/hi myns/ho ns2/hu {:myns/a 3}) |
| 10:21 | justin_smith | ,(meta #'*warn-on-reflection*) |
| 10:21 | clojurebot | {:added "1.0", :ns #<Namespace clojure.core>, :name *warn-on-reflection*, :doc "When set to true, the compiler will emit warnings when reflection is\n needed to resolve Java method calls or field accesses.\n\n Defaults to false."} |
| 10:22 | no7hing | so it would be global |
| 10:22 | justin_smith | no7hing: looks like it is global in scope, not a dynamic var |
| 10:22 | justin_smith | yeah |
| 10:22 | justin_smith | ,`(+ - *) nkoza: |
| 10:22 | clojurebot | (clojure.core/+ clojure.core/- clojure.core/*) |
| 10:22 | no7hing | visualvm says my application is spending 50% of it’s time on reflection - see no warnings though =/ |
| 10:22 | justin_smith | nkoza: that is a read macro, not macro |
| 10:23 | justin_smith | no7hing: try "lein check" if you are using lein |
| 10:23 | no7hing | using it and will do |
| 10:24 | justin_smith | no7hing: there are other tricks with reflection on numeric types that are a special case, there is a numeric lib that helps with making sure things are unboxed and numeric reflection is eliminated though ... let me find it |
| 10:24 | nkoza | justin_smith: but you can't define a macro with it, (defmacro m [expr] `(~expr)) will not work, I want to qualify the expression before using it in the macro |
| 10:25 | justin_smith | ,(resolve '+) maybe this? |
| 10:25 | clojurebot | #'clojure.core/+ |
| 10:25 | justin_smith | but that only works for individual symbols |
| 10:25 | justin_smith | not expressions |
| 10:28 | justin_smith | martinklepsch: well, the outer dorun means you don't need the result right? |
| 10:29 | martinklepsch | justin_smith, in that case yes. I actually only care for the result of the profiling |
| 10:30 | justin_smith | (doseq [f (take 4 files) _ (read-file f)] nil) |
| 10:30 | justin_smith | maybe |
| 10:32 | nkoza | justin_smith: resolve also only works with vars |
| 10:36 | justin_smith | nkoza: what other than a var would you want to explicitly namespace qualify? |
| 10:36 | nkoza | keywords, for example |
| 10:37 | martinklepsch | justin_smith, both work. thanks a ton! |
| 10:39 | no7hing | justin_smith thanks so far for your help |
| 10:46 | justin_smith | ,(= ::foo :foo) |
| 10:46 | clojurebot | false |
| 10:47 | justin_smith | nkoza: the qualified version of a keyword is not equal to the unqualified form |
| 10:47 | justin_smith | ,::foo |
| 10:47 | clojurebot | :sandbox/foo |
| 10:47 | justin_smith | ,`(:foo) also |
| 10:47 | clojurebot | (:foo) |
| 10:50 | zeeshanlakhani | probably a stupid question, but am attempting to do a set of async tasks on a request (tasks that I don't need a return value from), my thought was to use futures, but i wanted to see if people would use something else or still use core.async for such an example |
| 10:51 | nkoza | justin_smith: I know, but I want to get the ::foo form and qualify it (with the rest of the expression) |
| 10:51 | justin_smith | ahh |
| 10:51 | justin_smith | to be clear, ::foo is a reader convenience, and it is changed to :ns/foo at read time |
| 10:51 | nkoza | justin_smith: basically I need what syntax-quote does but in runtime |
| 10:52 | melipone | hi! Is the order guaranteed with pmap? |
| 10:52 | justin_smith | nkoza: syntax-quote does not turn :foo into :ns/foo |
| 10:52 | clgv | melipone: yes |
| 10:52 | nkoza | justin_smith: good point |
| 10:52 | justin_smith | nkoza: and the reader makes ::foo into :ns/foo without syntax quote |
| 10:52 | melipone | clgv: thanks |
| 10:52 | clgv | melipone: but pmap sucks in parallelization if you want to keep your available cores busy ;) |
| 10:53 | melipone | clgv: yes, I know, but it works for me |
| 10:54 | Glenjamin | reducers/fold also guarantees result order, but not execution order |
| 10:55 | clgv | Glenjamin: execution order is not guaranteed with pmap neither |
| 10:56 | melipone | off-topic: folks, what's the shortcut in IRC to get the name of the person you want to respond to? |
| 10:56 | Glenjamin | really? i thought it just did approximately (map deref (map future coll)) |
| 10:56 | Glenjamin | with the futures being slightly ahead of the derefs |
| 10:58 | nkoza | justin_smith:ok, then maybe I need to walk all the expression doing resolve on each symbol. |
| 10:58 | clgv | Glenjamin: pretty close yes. it creates k futures that run in parallel |
| 10:58 | clgv | $source pmap |
| 10:58 | lazybot | pmap is http://is.gd/98SQJR |
| 10:59 | nkoza | justin_smith: thanks for your responses. |
| 11:03 | justin_smith | melipone: that is client specific, on my client it is tab |
| 11:06 | jcromartie | is there anything like (filter-when x f coll) |
| 11:06 | jcromartie | I want to do (if x (filter f coll) coll) |
| 11:06 | jcromartie | but in a ->> |
| 11:06 | jcromartie | and I don't want cond-? |
| 11:06 | jcromartie | I mean cond-> |
| 11:10 | pyrtsa | I think it'd be hardly readable. Would using as-> be an option? |
| 11:10 | stuartsierra | (-> coll (cond->> x (filter f))) ? |
| 11:11 | pyrtsa | The question was in a ->>, so I assume it's something like (->> coll (map f) ... ). |
| 11:12 | nkoza | jcromartie: what about (-> x (if (filter f coll) coll)) |
| 11:12 | pyrtsa | Here's a contrived way to achieve it: (->> coll ... (filter (if x f (constantly true))) |
| 11:13 | pyrtsa | (Contrived, because obviously the filtering step is extra work in the if-not case.) |
| 11:20 | adsisco | I'm follow following the tutorial in the book "Web Development with Clojure", any idea why my /css/screen.css is the default one despite me having already made changes? I've did lein clean and recompile to no avail. |
| 11:24 | clgv | ,(time (doall (pmap (fn [i] (Thread/sleep (* (- 30 i) 100)) (println i) i) (range 30)))) |
| 11:24 | clojurebot | #<SecurityException java.lang.SecurityException: no threads please> |
| 11:24 | clgv | :/ |
| 11:25 | clgv | Glenjamin: I tried to verify my sliding window of futures understanding with it. but it just proved it wrong... |
| 11:29 | clgv | oh wait chunked seqs.. |
| 11:32 | clgv | replace (range 30) by (take-while #(< % 30) (iterate inc 0)) ^^ |
| 11:36 | coventry | clgv: How does chunking affect it? Also confused about why replacing (range 30) with the vector literal [0 ... 29] doesn't change the behavior. |
| 11:38 | coventry | Oh, reading the source for pmap makes it clear. |
| 11:39 | clgv | coventry: the new aspect I discovered is that #cpu+3 futures are runnning at the same time. from reading the source I thought until now that the number is #cpu+2 |
| 11:42 | mpenet | no7hing: justin_smith was thinking about https://github.com/ztellman/primitive-math I believe |
| 11:42 | mpenet | |
| 11:43 | clgv | since when does the following throw an exception? &(+ 3.0 3) |
| 11:43 | coventry | clgv: What your example suggests to me is that pmap's (map #(future (f %)) coll) will kick off far more futures than you expect in some circumstances because of chunking. That could probably be made a bit smarter. |
| 11:44 | cbp | clgv: never ? |
| 11:44 | clgv | coventry: yeah that as well. but I tried to verify the "future sliding window of size k" behavior |
| 11:44 | clgv | cbp: the primitive-math lib states that ^^ |
| 11:45 | clgv | oh it doesnt talk of clojure.core/+ I guess... |
| 11:45 | cbp | it's the library's yeah |
| 11:48 | martinklepsch | if I have an 8 core machine is there some ideal number of threads to run big computations of a queue? or is the best to just test various configurations? |
| 11:49 | martinklepsch | (I've previously been told to just test but I'm curious what other people may say) |
| 11:49 | cbp | number of cores + 2 seems to be the magic number for some of clojure's internals |
| 11:50 | cbp | or was it 42 |
| 11:50 | cbp | yes test :-) |
| 11:50 | melipone | justin_smith: I am using webchat. do u know what it is? |
| 11:52 | arrdem | martinklepsch: just test it already |
| 11:53 | martinklepsch | arrdem, did you tell me to test it? |
| 11:53 | coventry | There are surprisingly few papers about determining the optimal number of threads for a given computation. I guess because it's such a general question that it's hard to say anything useful and specific about it. |
| 11:53 | arrdem | (inc coventry) |
| 11:53 | lazybot | ⇒ 7 |
| 11:55 | TimMc | martinklepsch: I think the answer also depends on the cache layout, the kernel's scheduler, etc. |
| 11:55 | arrdem | workload and hardware factors in addition to OS level details... |
| 12:04 | clgv | martinklepsch: well, it depends on your hardware as well. if there is hyperthreading you could use 2*#cpus or only #cpus depends whether your application profits from hyperthreading... |
| 12:04 | martinklepsch | clgv, it's a VPS |
| 12:05 | clgv | martinklepsch: "#cpus" should have been number of physical cores... |
| 12:05 | clgv | martinklepsch: I meant cpu hardware ;) |
| 12:09 | gfrederick_s | is there a library that does prn? |
| 12:11 | gfrederick_s | if not I might have to make one |
| 12:13 | gfrederick_s | more directly I want to make edn extensibly useful within libraries |
| 12:19 | no7hing | mpenet, justin_smith: lein check helped a lot and once the culprits where gone uncovered some other issues |
| 12:21 | no7hing | now we’ve got another candidate in visualvm, who’s taking up a lot of time: clojure.lang.Symbol.intern |
| 12:23 | hiredman | no7hing: are you parsing json or clojure? |
| 12:25 | hiredman | no7hing: is visualvm connected to the right process? |
| 12:26 | no7hing | hiredman: i’am converting excel files to json, in a rather wasteful way i’ll admit, but we’re wasting that time at unexpected spots |
| 12:26 | no7hing | hiredman: https://github.com/mhaemmerle/excel-to-json |
| 12:30 | hiredman | no7hing: are you sure you are connected to your running project and not lein's jvm? |
| 12:31 | hiredman | no7hing: it looks like you are are generating keywords when converting from excel to json for some reason |
| 12:31 | kadodka | /help levers |
| 12:31 | kadodka | /help levels |
| 12:32 | hiredman | no7hing: don't do that and you'll be fine |
| 12:38 | no7hing | hiredman: i triple-checked and i’am really connected to the process in question; here’s a screenshot of the thing http://i.imgur.com/RRKLpC3.png |
| 12:39 | hiredman | no7hing: keywords and symbols (keywords are actually backed by a symbol) have some amount of overhead to create, if you want to be really fast stop generating keywords in https://github.com/mhaemmerle/excel-to-json/blob/master/src/excel_to_json/converter.clj |
| 12:41 | no7hing | hiredman: are there any alternatives - short of refactoring the code? also asking for another project |
| 12:43 | hiredman | no7hing: well, looking at the screenshot, Symbol.intern is not at the top of the list of hot spots |
| 12:43 | hiredman | my advice is for if it is |
| 12:44 | hiredman | geez, yeah, it is right there in the call tree, keyword -> symbol -> String.intern |
| 12:44 | no7hing | hiredman: another view on the data: http://i.imgur.com/qIrzSfl.png - thanks for your help so far |
| 12:45 | no7hing | i guess this means back to the drawing board for me |
| 12:45 | hiredman | so the same advice, if all you time is spent generating keywords or symbols, and you don't need the semantics of those things, then don't make them |
| 12:45 | no7hing | as you see in the code, i’am just switching on them |
| 12:45 | hiredman | which you can do on strings just fine |
| 12:46 | Raynes | Glenjamin: https://github.com/Raynes/dox First draft. |
| 12:46 | no7hing | which i actually might just do, before we refactor the code next |
| 12:46 | MarkStang | I have a wrapper I wrote for a Java API, how do I create the same wrapper for a different API? Like an Interface for a Namespace? |
| 12:47 | no7hing | fully qualified keywords wouldn’t help either i guess; seems my erlang mindset has bitten me here (where atoms aka symbols are cheap) |
| 12:48 | MarkStang | Is there a way to "specify" that or do I just have keep them in-sync |
| 12:48 | Glenjamin | Raynes: looks good, might be worth making the message an configuration param |
| 12:48 | Glenjamin | conch is neat |
| 12:48 | Raynes | What message? |
| 12:48 | Glenjamin | the commit message |
| 12:48 | Raynes | Ah |
| 12:49 | Glenjamin | does conch run the program directly, or via a shell? |
| 12:49 | Raynes | Directly. |
| 12:49 | Raynes | Hence the shitty glob stuff. |
| 12:49 | Glenjamin | yeah |
| 12:49 | hiredman | no7hing: they are pretty cheap, but they do enforce certain semantics, the string backing a symbol is interned, keywords are interned so they have reference equality |
| 12:49 | hiredman | the machinery to enforce that has a cost |
| 12:50 | Raynes | Glenjamin: I actually made some pretty big changes to conch while using it here. |
| 12:50 | Raynes | Just this morning. |
| 12:50 | hiredman | there is a recent patch (not sure what the status is) for speeding up keyword generation though |
| 12:50 | Raynes | Glenjamin: In particular, I got incredibly frustrated because failing commands were just passing by. |
| 12:50 | Raynes | So I released a new version that can throw exceptions for non zero exit codes. |
| 12:50 | Raynes | Made me incredibly happy. |
| 12:50 | Raynes | I'm amazed nobody has bitched about that not being there yet. |
| 12:50 | hiredman | MarkStang: there is no way to parameterize a namespace, but you can use multimethods or protocols for polymorphism |
| 12:50 | Raynes | I used conch for 5 minutes and wanted it :P |
| 12:52 | MarkStang | hiredman: The problem is that all the functions are identical, just the underlying implementation is different. So, the signatures are all identical. |
| 12:54 | arrdem | Raynes: nice! |
| 12:54 | MarkStang | hiredman: Not sure what I am even looking for... Or what it means to switch between the two implementations? Or how do I switch? Change the "requires" from one to the other? |
| 12:54 | hiredman | MarkStang: what is the problem with that? |
| 12:55 | MarkStang | hiredman: I am wondering if my architecture is correct, maybe I should be passing in the "namespace". |
| 12:56 | hiredman | MarkStang: you would pass some object that you do dispatch on |
| 12:56 | hiredman | it really depends what you want |
| 12:57 | MarkStang | hiredman: yeah, I think that is my problem, not sure what I want, current design evolved out of implementation... Back to the drawing board... |
| 12:57 | Glenjamin | you could even receive a map of {:key fn} |
| 13:01 | MarkStang | hiredman: pass in a map of functions or just change the "use" or "requires", it is like I need an object that has a bunch of functions that can be passed around, I wonder if Stuart Sierras components will work here? |
| 13:02 | MarkStang | hireman: a stateless object, only functions |
| 13:03 | no7hing | hiredman: yeah, been using the keyword in other places as a fun for group-by for example; will look for the patch and still switch to strings |
| 13:03 | hiredman | MarkStang: sure |
| 13:07 | arrdem | what's the procedure for adding contributors and/or requesting contributor status to a contrib project? |
| 13:10 | technomancy | "don't call us; we'll call you" |
| 13:21 | arrdem | that's what I thought. kk. forks it is. |
| 13:27 | goodgravy | hi all, I’ve a question about the people function towards the bottom of https://github.com/swannodette/om/wiki/Basic-Tutorial |
| 13:29 | goodgravy | specifically, the two forms of (update-in x …) followed by x in the mapv – my mental model is that the mapv should just return the original seq unaltered |
| 13:29 | goodgravy | because update-in doesn’t change in-place. however, that isn’t the case. can anyone shed some light? |
| 13:30 | pyrtsa | There's an if block: (if (:classes x) (update-in ...) x). |
| 13:30 | arrdem | goodgravy: right. Update-in returns an altered copy, and mapv is just map forced into a vector. |
| 13:30 | pyrtsa | I.e. there is no "update-in followed by x", it's either or. |
| 13:30 | goodgravy | ahhhh, OK I see – thanks that’s clear now |
| 14:13 | {blake} | So...the iloveponies clojure course has an exercise where you give all the rotations (rotations [a-seq]) of a sequence--e.g. for [1 2 3], ([1 2 3][2 3 1][3 1 2])--and I solved it but I used a nested function that carried a count--inner-rot [a-seq count)--so I could know when to stop. Since preserving state is the next lesson, I don't think that's the solution they were trying to lead me to. Their hint is to use "concat". Any thoughts on how that might be do |
| 14:13 | {blake} | ne? |
| 14:15 | amalloy | i don't see any obvious solutions that involve concat |
| 14:15 | {blake} | Well, that's reassuring. I thought maybe concat with partition? |
| 14:16 | {blake} | The whole unit is on recursion, though, and I don't see how you do recursion (without carrying some state) and know when to stop. |
| 14:16 | dbasch | well, concat butlast with [first] |
| 14:16 | dbasch | sorry, rest with first |
| 14:16 | {blake} | Oh, right, that's probably what that is. |
| 14:16 | amalloy | {blake}: i would have written https://www.refheap.com/25947cbf86a21575a67a8a3a6 |
| 14:17 | {blake} | I did...(concat (drop 1 seq2) (take 1 seq2)). |
| 14:17 | amalloy | maybe there's something cleverer |
| 14:17 | {blake} | amalloy: For loops are next unit. =P I thought about that, too. |
| 14:18 | {blake} | It's a lot cleaner. Might just be bad organization. |
| 14:18 | {blake} | Yours I mean, amalloy. |
| 14:19 | amalloy | {blake}: https://www.refheap.com/8505f3f2524a32dba9e8d503e is another approach, with recursion |
| 14:19 | amalloy | `(~@(rest coll) ~(first coll)) is the same as (concat (rest coll) [(first coll)]) but reads nicer imo |
| 14:19 | hlship | Has much changed in terms of clojure.main and clojure.repl between 1.5 and 1.6? |
| 14:20 | hlship | Some hacks I was using to override clojure.repl/pst that worked in 1.5 aren't working in 1.6 |
| 14:20 | {blake} | amalloy, yes, that's very close to what I did. (Tho', again, yours is cleaner.) |
| 14:20 | llasram | Could use `iterate` too |
| 14:21 | amalloy | llasram: iterate is going to be a little awkward, because you need n as a state variable that you don't return |
| 14:21 | amalloy | obviously it's possible, but i don't think it reads very well |
| 14:21 | llasram | https://www.refheap.com/85491 ? |
| 14:21 | amalloy | oh, i see. sure |
| 14:21 | {blake} | llasram, No iterate yet. Just conditionals, predicates and direct recursion. |
| 14:21 | amalloy | my n is just a silly version of take |
| 14:23 | {blake} | llasram, Worth studying, thanks. |
| 14:27 | dbasch | {blake}: I’m guessing that for your exercise they meant something like this https://www.refheap.com/85492 |
| 14:42 | {blake} | dbasch, Maybe, though we have neither "loop" nor "recur" yet! |
| 14:51 | dbasch | {blake}: here’s another version with concat and without loop https://www.refheap.com/85494 |
| 14:56 | {blake} | dbasch, Yep, I'll bet that's it. The solutions have been "map" heavy. Thanks, I'll study that one, too. |
| 14:57 | {blake} | I've gotten to where I can come up with A solution for problems, but not necessarily one that feels like I've got any real facility with Clojure. |
| 15:00 | dbasch | {blake}: yes, it takes time for the clojurey instincts to start becoming natural |
| 15:00 | dbasch | {blake}: sometimes you think you came up with something clever and another person does something cleaner, shorter and more efficient |
| 15:01 | {blake} | dbasch, Yeah, and I'm not at the point where I can do anything but goggle at it. =P |
| 15:03 | DomKM | What's the purpose of type hinting both the var and args vector? https://github.com/ztellman/clj-radix/blob/master/src/clj_radix/utils.clj#L80-81 |
| 15:03 | {blake} | There was a unit on evaluating a poker hand, and I had an awful solution (that worked, but still). Then I found: |
| 15:03 | DomKM | Do they do different things? |
| 15:03 | {blake} | (defn value [hand] |
| 15:03 | {blake} | (->> checkers |
| 15:03 | {blake} | (filter #((first %) hand)) |
| 15:03 | {blake} | (map second) |
| 15:03 | {blake} | (apply max))) |
| 15:03 | {blake} | Took me half-an-hour to figure out how it worked. |
| 15:04 | amalloy | {blake}: plz bro. refheap.com. no long pastes in here |
| 15:05 | {blake} | amalloy, Sorry! Won't do it again. |
| 15:05 | amalloy | DomKM: hinting the arglist provides a version that actually returns a primitive. i'm not sure hinting the var does anything interesting if he's already hinting the arglist, but it might |
| 15:06 | DomKM | amalloy: would hinting the var do anything if the args vector weren't hinted? |
| 15:06 | coventry | amalloy: Where's that documented? |
| 15:06 | amalloy | DomKM: hinting a var with a primitive is usually, as i understand it, not meaningful |
| 15:07 | amalloy | {blake}: so checkers is a seq of pairs [f n], where f is a function checking whether a hand qualifies, and n is a number saying how valuable that hand-type is worth? |
| 15:07 | {blake} | amalloy, Yeah. |
| 15:08 | amalloy | i dunno, coventry. i wouldn't be surprised to hear that the answer is "nowhere", or "in the changelist for clojure 1.3" |
| 15:08 | DomKM | amalloy: so is hinting it with a non-primitive meaningful? I was previously only aware of hinting the args vector. |
| 15:08 | amalloy | DomKM: yes, definitely |
| 15:08 | {blake} | And I'm weak on threading macros; I couldn't figure out what was being passed to what. Also the "second" threw me off. |
| 15:08 | amalloy | hinting the arg-vec only became possible in clojure 1.3 |
| 15:09 | amalloy | hinting the var name was used before that to indicate what object-type a function returned (and functions always had to return an object) |
| 15:09 | DomKM | amalloy: ah, thanks |
| 15:09 | coventry | amalloy: Oh well. |
| 15:10 | amalloy | the arglist hinting syntax was added primarily for functions taking and/or returning primitives, but i don't know what it does when something is hinted as an object type, or when a var is hinted with a primitive |
| 15:10 | coventry | {blake}: You can put something like (#(do (println "value after filter" %) %)) in the threading macro arguments, to see what's being passed to what. |
| 15:11 | {blake} | coventry, What's the "(#" opener signify? |
| 15:11 | coventry | {blake}: It's an anonymous function. |
| 15:11 | {blake} | Or, I guess that's "(" followed by "#(". |
| 15:11 | {blake} | Duh, right. |
| 15:12 | {blake} | coventry, So it just passes the argument through |
| 15:13 | amalloy | coventry: http://dev.clojure.org/display/design/Enhanced+Primitive+Support is linked to from the 1.3 changelist. there's also http://dev.clojure.org/display/design/Documentation+for+1.3+Numerics, and i think those two constitute the entirety of official documentation on the topic |
| 15:13 | coventry | amalloy: Thanks. |
| 15:38 | Norrit | Hi, little question: Is there a function to add an element to a seq at a specific index? (add [0 1 2 3] 1 99) => [0 99 1 2 3] |
| 15:39 | justin_smith | ,(seq? [0 1 2 3]) (pedantry) |
| 15:39 | clojurebot | false |
| 15:40 | justin_smith | Norrit: you can assign the value at an index of a vector, or append a vector, or prepend a seq |
| 15:40 | Norrit | or vector... |
| 15:40 | justin_smith | Norrit: you can make your own insertion function, but there is no clear right way to do it - the others are build in because they have a single simple and fast way to implement it |
| 15:41 | Norrit | ok, but I need an add like the one on the java lists |
| 15:41 | Norrit | ah, ok |
| 15:42 | justin_smith | ,((fn [s p e] (concat (take p s) [e] (drop p s))) [0 1 2 3] 1 99) |
| 15:42 | clojurebot | (0 99 1 2 3) |
| 15:42 | Norrit | building my own one shouldnt be so hard |
| 15:42 | justin_smith | that said, the above is straightforward if using seqs is the main target case |
| 15:43 | Norrit | thx, I will try that out |
| 15:56 | jcromartie | at 6 named params, you should probably just use a map, no? |
| 15:57 | llasram | s,6,1, IMHO |
| 16:10 | tbaldridge | all parameters should be maps, except that would be horrible for any human to program with, so I'd say use maps as much as can be tolerated. |
| 16:14 | amalloy | i wonder, tbaldridge: what would -> and ->> look like, in the world where every function takes exactly one arg, a map? |
| 16:15 | amalloy | (i think that's the world you were suggesting, but i'm not sure i read it right) |
| 16:15 | tbaldridge | yeah it is a interesting question |
| 16:15 | tbaldridge | and yes that was what I was talking about |
| 16:16 | tbaldridge | so the idea is, currently (->) has a convention of "first arg". So instead of a positional convention, perhaps a named convention? :first-arg or :coll ? |
| 16:18 | hiredman | tbaldridge is advocating a map monad, so you'll need a map monadic bind for composing this functions |
| 16:18 | hiredman | I guess that isn't exactly right, but you would want a more powerful function composition |
| 16:19 | hiredman | and can functions only return a map? or not? so you have to box values in a map before calling a function |
| 16:19 | llasram | Yeah, but the compiler can elide all that |
| 16:19 | llasram | Easy-peasy |
| 16:20 | hiredman | it is the inverse of a monad really, a map value box goes in, and a value goes out, is that a comonad? |
| 16:20 | amalloy | hiredman: i think so, actually |
| 16:21 | hiredman | so, a map comonad |
| 16:22 | tbaldridge | does it matter what monad it is? :-P |
| 16:23 | technomancy | ~正名 |
| 16:23 | clojurebot | If language is not correct, then what is said is not what is meant; if what is said is not what is meant, then what must be done remains undone; if this remains undone, morals and art will deteriorate; if justice goes astray, the people will stand about in helpless confusion. Hence there must be no arbitrariness in what is said. This matters above everything. |
| 16:23 | tbaldridge | o.O |
| 16:23 | technomancy | https://en.wikipedia.org/wiki/Rectification_of_names |
| 16:24 | amalloy | today i learned (a) clojurebot can translate chinese; (b) there's a lot of information in two chinese characters |
| 16:25 | hiredman | technomancy flashed those chinese characters in to the optic nerves of the entire conj one year |
| 16:25 | technomancy | takahashi method |
| 16:27 | whodevil | hello, I'm curious if anyone has any ideas on code style formatting for clojure. This is to make sure all indents and things are consistent in my project. I've seen things like this in intellij for java/groovy, and js-beautify. Is there something like this for clojure? |
| 16:27 | llasram | whodevil: Emacs |
| 16:27 | whodevil | thank you for your snark, but is there a real answer behind that? |
| 16:28 | llasram | whodevil: Well, the "ha ha only serious" that AFAIK Clojure's base indentation style is "whatever Emacs does with Lisp". I'm not aware of any standalone code pretty-printers, but there may be one... |
| 16:29 | whodevil | ok, good to know, thanks! |
| 16:30 | AimHere | Lisp code style formatting is obvious to anyone who uses Lisp |
| 16:30 | sveri | Hi, does someone here know how I can set an attribute in enlive conditionally? When I do something like (do-> (content "foo") (when cond (set-attr :selected true))) I get a NPE in case the condition is not met |
| 16:30 | whodevil | AimHere: you are missing the point |
| 16:31 | AimHere | What I mean is that all lisp users intuitively agree on the format without thinking about it; for some bizarre reason, there isn't a need for it or for holy wars, as there is in C-style languages |
| 16:32 | amalloy | AimHere: "intuitively" there is clearly wrong. most lisp users get it wrong at first, putting trailing parens on their own lines, etc etc, until they post in a forum or irc and the combined wrath of all lispers is focused on them |
| 16:32 | llasram | AimHere: I don't believe that's true, even in that more limited form |
| 16:32 | AimHere | Name two schools of lisp indentation style |
| 16:33 | llasram | Handling of the subsequent sub-forms of a form where the second+ sub-forms are the line following the function-position form |
| 16:33 | amalloy | AimHere: people who line subsequent args up with the first arg, and people who indent each line by 2 spaces |
| 16:34 | AimHere | See, they don't have a name |
| 16:34 | AimHere | Not like 'Whitesmiths' or 'Allmans' or 'K&R' or 'One True Braces' or 'GNU style' |
| 16:34 | llasram | Actually, I think they might be "Emacs style" vs "Vim style" |
| 16:35 | AimHere | Lisp indentation religious wars haven't been persistent enough to have been named! |
| 16:35 | bendlas | Doesn't emacs' clojure-mode use a mixed form with arg alignment as default and 2 space indent for do and def* forms? |
| 16:36 | bendlas | I think there is definitely room for a unified indentation library |
| 16:36 | whodevil | The reason I'm asking this is that I'm taking on a project with my team that will be written in clojure, some of the people do not have much lisp/clojure experience, so it would be helpful for them to be able to hit "format code" and get the correct code style |
| 16:37 | bendlas | whodevil: last time I checked the outlook there was a bit bleak, if not everybody uses the same tool |
| 16:37 | sveri | whodevil: the cursive plugin does that |
| 16:37 | amalloy | whodevil: technomancy has some incantation to invoke emacs in batch mode and ask it to format a string for you then print it to stdout |
| 16:38 | whodevil | I looked into cursive, it seems very promising since my team already uses intellij, but it appears to only be in early access. |
| 16:38 | whodevil | amalloy: I'll look into that |
| 16:41 | sveri | whodevil: Well, from my point of view it is more useable than the eclipse alternative. regarding editor features it is also preferable to lighttable. However I almost always have a lighttable instance open for the instant repl feature, so a combination of lighttable and cursive works best for me (I am leaving emacs out as I never used it and dont have the time to get adapted to it) |
| 16:41 | Frozenlock | Is there a way for compojure to know the scheme when used with nginx? |
| 16:42 | Frozenlock | As it is, nginx is dealing with the ssl stuff, and when I check the :scheme in compojure, it returns :http :-( |
| 16:42 | Glenjamin | Frozenlock: one sec |
| 16:43 | Glenjamin | Frozenlock: i use this behind heroku's ssl terminator |
| 16:43 | Glenjamin | https://www.refheap.com/85497 |
| 16:44 | tbaldridge | whodevil: I've pretty much switched away from emacs to Cursive these days. I highly recommend it. |
| 16:44 | Frozenlock | Glenjamin: Oh wow, that might just do it. Thanks! |
| 16:44 | Glenjamin | is intellij quite scriptable tbaldridge? |
| 16:45 | Glenjamin | Frozenlock: will need something like "proxy_set_header X-Forwarded-Proto $scheme;" in nginx if you don't already have it |
| 16:45 | tbaldridge | Glenjamin: I haven't tried. I've mostly been sticking with rebinding keys. That being said, I never really scripted emacs either. |
| 16:46 | Frozenlock | Glenjamin: my nginx knowledge is abyssal, so I'm sure it isn't :-p |
| 16:46 | Glenjamin | very deep? :p |
| 16:46 | Frozenlock | err... Yeah, so deep that I can't get it |
| 16:46 | amalloy | Glenjamin: cavernously empty |
| 16:47 | TEttinger | Abysmal? |
| 16:48 | pandeiro | what happened to the repl error buffer in cider? where did it go and how do i get it back? |
| 16:53 | Frozenlock | Glenjamin: It works! Thank you very much :-D |
| 17:02 | sveri | so if someone got a tip on enlive I would be happy to get this question answered: https://groups.google.com/forum/#!topic/enlive-clj/IdQavf_Whlc |
| 17:17 | jjl`_ | is there a convenient reference for all of the clojure sequence protocols, ISeq and such? |
| 17:19 | bbloom | ~colls |
| 17:19 | clojurebot | colls is seqs |
| 17:19 | amalloy | i think TimMc has something? |
| 17:19 | bbloom | ~seqs |
| 17:19 | clojurebot | seqs is http://www.brainonfire.net/files/seqs-and-colls/main.html |
| 17:19 | bbloom | dammit. i did ~colls last time too |
| 17:20 | amalloy | that's the thing i was thinking of |
| 17:21 | jjl`_ | ta |
| 17:21 | amalloy | i'm not sure it actually addresses jjl`_'s question, since it doesn't really discuss the interfaces explicitly |
| 17:22 | jjl`_ | yeah, i'm actually interested in the differences between the interfaces |
| 17:22 | arrdem | if we're gonna do the One True Indenter thing can it at least eat EDN/t.a so that it's useful and built atop sane things rather than being some regex janky in emacs? |
| 17:24 | waynr | anyone have advice for getting project info from command line |
| 17:26 | arrdem | what kind of info are you after? |
| 17:26 | waynr | project name and version |
| 17:26 | waynr | currently using awk |
| 17:27 | arrdem | so technically there isn't as you'd have to implement a full lisp reader in Awk/Bash which would be a pain. |
| 17:27 | bbloom | waynr: is awk getting the job done? if so, stick with that |
| 17:27 | waynr | was thinking there might be a leign plugin that spews project map |
| 17:28 | waynr | lein* |
| 17:28 | gtrak | lein-pprint |
| 17:28 | waynr | oh yeah |
| 17:28 | gtrak | you could probably abuse cljs+node.js for command-line speed. |
| 17:28 | gtrak | it's got a reader. |
| 17:29 | gtrak | but if you're running lein-pprint that's moot. |
| 17:29 | waynr | lein-pprint will do |
| 17:31 | waynr | thanks bbloom arrdem gtrak |
| 17:32 | arrdem | waynr: if you need speed it's probably safe to write an awk script that just pulls the first line of the file and matches "(defproject (\w+) \"[^\"]+\"\n |
| 17:34 | hlship | ... and of course, my problem wasn't Clojure, it was me. Meanwhile, new version of pretty now can filter exception output FTW |
| 17:36 | waynr | arrdem: speed isn't important, just wanted to pull project name and version for a continuous integration job |
| 17:39 | {blake} | ,(first {:a 1 :b 2}) |
| 17:39 | clojurebot | [:b 2] |
| 17:39 | {blake} | ,(first {:a 1 :b 2 1 4}) |
| 17:39 | clojurebot | [1 4] |
| 17:39 | {blake} | Huh. In my REPL, the first returns {:a 1}. |
| 17:40 | jeremyheiler | maps aren't ordered |
| 17:40 | {blake} | But I guess it doesn't matter. |
| 17:40 | {blake} | ,(first {:a 1 :b 2 :c 3 :q 4 1 4}) |
| 17:40 | clojurebot | [:q 4] |
| 17:40 | bbloom | and things like hashing may change between versions |
| 17:41 | {blake} | I thought maybe it was looking for a map key of "1" but that doesn't appear to be the case. |
| 17:41 | amalloy | {blake}: it definitely doesn't return {:a 1}. it may return [:a 1] |
| 17:41 | {blake} | Yes, vector, sorry. |
| 17:41 | jeremyheiler | it actually isn't a vector either |
| 17:42 | jeremyheiler | it's a map entry |
| 17:42 | amalloy | jeremyheiler: yes it is |
| 17:42 | amalloy | map entries are vectors |
| 17:42 | jeremyheiler | ,(key [1 2 ]) |
| 17:42 | amalloy | &(vector? (first {:a 1})) |
| 17:42 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry> |
| 17:42 | lazybot | ⇒ true |
| 17:42 | arrdem | ,(class (first {1 2})) |
| 17:42 | clojurebot | clojure.lang.MapEntry |
| 17:42 | amalloy | not all vectors are mapentries, but mapentries are vectors |
| 17:42 | jeremyheiler | ,(key (first {:a 1})) |
| 17:42 | clojurebot | :a |
| 17:42 | jeremyheiler | amalloy: ah, sure. |
| 17:42 | arrdem | ,(source vector?) |
| 17:42 | clojurebot | Source not found\n |
| 17:43 | arrdem | ,(vector? (first {:1 2})) |
| 17:43 | clojurebot | true |
| 17:45 | {blake} | ,(let [victor ["roger" "Roger"]] (vector? victor)) |
| 17:45 | clojurebot | true |
| 17:45 | arrdem | heh |
| 17:46 | bbloom | don't call me shirley! |
| 17:46 | arrdem | gtrak: does cider/clojure-mode have a folding capability? |
| 17:46 | gtrak | I don't think so. |
| 17:46 | gtrak | wanna write it? |
| 17:46 | gtrak | ;-) |
| 17:47 | arrdem | gtrak: this summer may be an exercise in writing the bits that need rather than the compiler I planned on :P |
| 17:47 | gtrak | just steal some code from org-mode, can't be that complicated. |
| 17:47 | arrdem | "can't be that complicated" he said. "just parse the cfg with regexes" he said. |
| 17:48 | gtrak | or just reimplement cider as an org-mode extension. |
| 17:48 | arrdem | if it means that I can write working org-mode in comments and docstrings... |
| 17:49 | cbp | what about docstrings in orgmode syntax |
| 17:51 | arrdem | cbp: is this considered a feature or a defect/product of insanity |
| 17:52 | cbp | but now you can use org-mode to evaluate examples in docstrings |
| 17:58 | Frozenlock | cbp: org-mode's table format already made its way in clojure. What's a little docstring in comparison? :-p |
| 17:59 | arrdem | Frozenlock: if it buys us better documentation and easier code reading a docstring's a small price to pay :P |
| 18:00 | amalloy | Frozenlock: has it? what's org-mode's table format? |
| 18:00 | arrdem | amalloy: |coll1|coll|coll2|...|colln| |
| 18:01 | Frozenlock | amalloy: https://groups.google.com/forum/#!topic/clojure/71MEGeYiUKA |
| 18:01 | Frozenlock | Searching for the jira request... |
| 18:01 | Frozenlock | Ah! Here http://dev.clojure.org/jira/browse/CLJ-1009 |
| 18:06 | amalloy | Frozenlock: implementation of print-table contains (apply str (interpose divider foo)). does halloway not know about join? |
| 18:07 | Frozenlock | That'd be quite surprising |
| 18:08 | nullptr | faster than adding the :require, probably |
| 18:12 | arrdem | sounds like a cleanup ticket... |
| 18:25 | arrdem | we don't have an explicit recursive let structure do we? |
| 18:30 | bbloom | Paul Phillips is always entertaining, but i'm never sure if he's entertaining for good or bad reasons .... anyway, i was scrubbing through this video: https://www.youtube.com/watch?v=uiJycy6dFSQ&feature=youtu.be |
| 18:30 | bbloom | saw that List(1, 2, 3).toSet() in scala returns false... |
| 18:31 | bbloom | b/c apparently that's actually List(1, 2, 3).toSet.apply(()) where () is unit |
| 18:31 | bbloom | and unit is not a member of the Set[Int] |
| 18:31 | bbloom | madness... |
| 18:41 | amalloy | bbloom: i just watched my first paul phillips video this morning |
| 18:41 | bbloom | amalloy: he's highly animated |
| 18:42 | rlinehan | /join #clojure-pdx |
| 18:43 | egghead | lol that video amalloy |
| 18:43 | bbloom | which video are you referring to in particular? |
| 18:44 | egghead | https://www.youtube.com/watch?v=uiJycy6dFSQ ? |
| 18:44 | bbloom | yeah, that's the one i'm scrubbing trhough now |
| 18:53 | nbeloglazov | Anyone from clojars team here? Could you help with: https://github.com/ato/clojars-web/issues/208? |
| 18:55 | phuu | hey #clojure. I want to get into writing http stuff with clojure (have previously just used cljs) – where best to start? http-kit, or lower level? |
| 18:56 | egghead | phuu: depends on what you want to do, I like liberator for http apis |
| 18:56 | technomancy | nbeloglazov: sure; taking a look |
| 18:57 | phuu | egghead: i want to get a really good understanding of the fundamentals & idioms, so I see the problems the higher level stuff is solving. |
| 18:57 | phuu | egghead: seems I could look at ring? |
| 18:57 | egghead | ring is just the http model, similar to rack in ruby or wsgi in python |
| 18:58 | justin_smith | phuu: yeah, http-kit + ring is a decent place to start |
| 18:58 | justin_smith | but you will want a routing lib very quickly |
| 18:58 | justin_smith | good idea to try things basic first though |
| 18:59 | justin_smith | also ring is extremely modular, so you can start super basic and add middleware as you need features |
| 18:59 | justin_smith | which is a much nicer way to do things than config / di / whatevs |
| 19:01 | phuu | cool, thanks both |
| 19:05 | numberten | can someone explain to me the difference between '(+ 1 2 3) and (list + 1 2 3) |
| 19:05 | numberten | I thought these two would be the same but (= '(+ 1 2 3) (list + 1 2 3)) returns false |
| 19:05 | gtrak | ,+ |
| 19:05 | clojurebot | #<core$_PLUS_ clojure.core$_PLUS_@16e0d97> |
| 19:05 | gtrak | ,'+ |
| 19:05 | clojurebot | + |
| 19:05 | cbp | numberten: quote prevents the evaluation of all its arguments |
| 19:06 | cbp | numberten: list is a regular function so all of its arguments are evaluated |
| 19:06 | numberten | so (= `(~+ 1 2 3) (list + 1 2 3)) should be true? |
| 19:06 | cbp | ,'(+ (+ 1 2) 3) |
| 19:06 | clojurebot | (+ (+ 1 2) 3) |
| 19:06 | gtrak | ,`~+ |
| 19:06 | clojurebot | #<core$_PLUS_ clojure.core$_PLUS_@16e0d97> |
| 19:06 | gtrak | yes |
| 19:06 | cbp | (list + (+ 1 2) 3) |
| 19:06 | nbeloglazov | technomancy: thanks, but didn't help for some reason. Will dig into it tomorrow. |
| 19:07 | gtrak | numberten: no |
| 19:07 | gtrak | it's still quoted, but the first thing is resolved by unquote. |
| 19:07 | gtrak | ,`(~+ 1 2 3) |
| 19:07 | clojurebot | (#<core$_PLUS_ clojure.core$_PLUS_@16e0d97> 1 2 3) |
| 19:07 | technomancy | nbeloglazov: the inability to redeploy over an existing version only applies to non-snapshots |
| 19:08 | technomancy | so in this case it's probably not a server-side issue |
| 19:08 | gtrak | ,(eval `(~+ 1 2 3) ) |
| 19:08 | clojurebot | #<ExceptionInInitializerError java.lang.ExceptionInInitializerError> |
| 19:08 | numberten | ,(= `(~+ 1 2 3) (list + 1 2 3)) |
| 19:08 | clojurebot | true |
| 19:08 | gtrak | oh, it didn't like that. |
| 19:09 | numberten | ,(eval '(+ 1 2 3)) |
| 19:09 | clojurebot | 6 |
| 19:09 | gtrak | interestingly, that doesn't blow up in my cider repl. |
| 19:09 | numberten | ,(eval (list + 1 2 3)) |
| 19:09 | clojurebot | #<ExceptionInInitializerError java.lang.ExceptionInInitializerError> |
| 19:09 | amalloy | numberten: yes, (= `(~+ 1 2 3) (list + 1 2 3)) should be true |
| 19:09 | gtrak | &(eval `(~+ 1 2 3) ) ; try a better bot |
| 19:09 | lazybot | java.lang.SecurityException: You tripped the alarm! eval is bad! |
| 19:09 | gtrak | heh |
| 19:10 | amalloy | &(= `(~+ 1 2 3) (list + 1 2 3)) |
| 19:10 | lazybot | ⇒ true |
| 19:11 | numberten | so the '(+ 1 2 3) case leaves the first argument as a symbol |
| 19:11 | numberten | and the unquote or the list case refer to the function? |
| 19:12 | amalloy | yes |
| 19:13 | numberten | does eval run eval recursively on all arguments? |
| 19:13 | amalloy | that's not really a good way to describe it |
| 19:13 | numberten | hah okay |
| 19:13 | amalloy | eval evaluates a data structure as code; the evaluation rules for an object dictate how and whether its arguments are evaluated |
| 19:14 | amalloy | eg, in (eval '(+ a b)), then +, a, and b are all evaluated |
| 19:14 | numberten | i see |
| 19:14 | amalloy | but in (eval '(quote (+ a b))), nothing much is evaluated |
| 19:15 | amalloy | in general, (eval 'x) behaves the same as just x |
| 19:15 | numberten | so the evaluation rules for a form are to either execute the function in function position with the arguments passed after it. or to find the function associated with that symbol and execute that function with the arguments passed after it? |
| 19:16 | numberten | and those evaluation rules treat '(+ 1 2 3) and (list + 1 2 3) the same? |
| 19:16 | amalloy | no, '(+ 1 2 3) and (list + 1 2 3) are very different |
| 19:17 | amalloy | functions should never be in the function position of a data structure to be evaluated; it should always be a symbol *naming* a function |
| 19:17 | numberten | i thought the only difference was that the first element in the result list of the former is a symbol that refers to the addition function |
| 19:17 | numberten | ah |
| 19:17 | amalloy | it so happens that, for some functions, it works |
| 19:17 | amalloy | but you should always have a symbol, or a list or whatever. something which , *when evaluated*, yields a function. not something which is already a function |
| 19:24 | numberten | would you say it's then better form to quote things that will be evaluated to functions in list |
| 19:24 | numberten | for ex: (list '+ 1 2 3) as opposed to (list + 1 2 3) |
| 19:26 | amalloy | if you were building something to eval, then the first would be clearly better than the second. not as a matter of form, but of correctness. better still is (list `+ 1 2 3), because who knows, it might be evaluated in a context where clojure.core/+ isn't referred |
| 19:28 | numberten | alright thank you |
| 19:44 | tolstoy | Anyone know why in OM I might get this when attempting to set-state! [Error] Error: No protocol method IRenderQueue.-queue-render! defined for type null: |
| 19:50 | gtuckerkellogg | in my current cider setup (which is pretty brain-dead simple) cider-jump is taking me to files like form-init4938858926778412808.clj, which is obviously not what I want. |
| 19:59 | tolstoy | I can't seem to set local component state in Om for some reason. Very odd. |
| 20:01 | tolstoy | And now it works. I knew if I type something here I'd get it working. ;) |
| 20:04 | {blake} | I wanna condp the count of a seq. For 0 or 1, I want to do one thing. For 2, I want to do something else. For more than 2, I want to do a third thing. |
| 20:06 | {blake} | My instinct was to do this as (condp < (count [1 2 3 4]) but that's...not right. |
| 20:08 | mange | {blake}: Something like this? (condp >= (count [1 2 3]), 1 :zero-or-one, 2 :two, :more-than-two) |
| 20:08 | {blake} | Because I end up saying, essentially, (< count 2) when I want (< 2 count.) |
| 20:09 | {blake} | mange: Yeah, I thought I'd flip it but I'm getting an error... |
| 20:09 | mange | What error are you getting? |
| 20:10 | {blake} | "ClassCastException clojure.lang.Keyword cannot be cast to java.lang.Number " |
| 20:10 | mange | What exactly are you running to get that? |
| 20:10 | pandeiro | anyone know how i can get cider to show me stacktraces again? feel like i'm programming with a blindfold |
| 20:11 | {blake} | Well, let's try it: |
| 20:11 | hiredman | ,(+ :foo 1) |
| 20:11 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number> |
| 20:11 | hiredman | ,(> :foo 1) |
| 20:11 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number> |
| 20:11 | mange | Why are you comparing a keyword with a number? |
| 20:11 | {blake} | ,(condp < (count [1 2 3 4]) 2 "heh" :else "whoa") |
| 20:11 | clojurebot | "heh" |
| 20:11 | {blake} | ,(condp > (count [1 2 3 4]) 2 "heh" :else "whoa") |
| 20:11 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number> |
| 20:11 | mange | condp doesn't have the :else like cond does. |
| 20:12 | mange | If you have an odd number of arguments then the last one is the "else". |
| 20:12 | {blake} | mange: Important safety tip. Thanks. |
| 20:12 | mange | ,(condp >= (count [1 2 3]), 1 :zero-or-one, 2 :two, :more-than-two) |
| 20:12 | clojurebot | :more-than-two |
| 20:13 | {blake} | So, it's... (> count 2), then (> count :else)...hence the problem. |
| 20:13 | mange | Yep. You wouldn't have seen that in the (< count 2) case because it would short circuit before then. |
| 20:15 | {blake} | Hmmph. |
| 20:22 | gtuckerkellogg | Does anyone else have this problem? in my current cider setup (which is pretty brain-dead simple) cider-jump is taking me to files like form-init4938858926778412808.clj, which is obviously not what I want. |
| 20:22 | gtuckerkellogg | It looks like this : https://www.refheap.com/85506 |
| 20:28 | mange | pandeiro: what do you have cider-popup-stacktraces and cider-repl-popup-stacktraces set to? If either of those is t you should get some stacktraces. |
| 20:39 | pandeiro | mange: the former is set to t |
| 20:39 | pandeiro | the weird thing is i have no *cider-error* buffer |
| 20:43 | amalloy | {blake}: well, in fairness, you shouldn't really be saying (< (count anything) 2) anyway. it might be infinite, after all! |
| 20:45 | Frozenlock | amalloy: Wow, I never thought of that. :-/ |
| 20:46 | amalloy | Frozenlock: (< (count x) 2) is better written as (not (next x)), for example |
| 20:47 | Frozenlock | shame on me https://github.com/Frozenlock/historian/blob/master/src/cljx/historian/core.cljx#L69 |
| 20:47 | mange | amalloy: I think it depends on the code being written. There are some cases when you can be pretty confident that your sequence will be finite, in which case the count way is much easier to read. |
| 20:49 | amalloy | mange: just because it's finite doesn't mean you should count it if you don't care about the count. maybe it's really slow to produce, for example. but (< (count 2) xs) reads as "less than two items in xs". compared to (not (next xs)) reading as "no second item in xs": seems about the same |
| 20:49 | mange | If I'm writing a macro I'm not going to use (not (nnext x)), because I have to stop and think about what that's trying to say, whereas (< (count x) 3) is more immediately obvious. |
| 20:49 | amalloy | also avoids the problem of gettnig < vs > the wrong way round like {blake} did. it's *not* immediately obvious to all readers which way those go |
| 20:51 | amalloy | mange: if the thing you're counting is a form passed to a macro, you're usually fine, although those *can* still be infinite |
| 20:51 | amalloy | (defmacro foo [] `(manges-macro ~@(range))) |
| 20:51 | amalloy | obviously in that case the code is doomed to fail anyway, but it's better to fail than to be stuck counting the inputs forever |
| 20:53 | gtuckerkellogg | I see. The whole file needs to be compiled and loaded as the last step for any findable defs. |
| 20:54 | mange | amalloy: Yeah, that's a fair call. Somewhat unlikely in practice, but I get what you mean. |
| 20:56 | amalloy | mange: interestingly my example was wrong: i can't get any macro to accept an infinite number of arguments |
| 20:56 | amalloy | but you can pass a single argument whose size is infinite, and the same thing applies |
| 20:57 | noonian | hmm, can't you just do (defmacro foo [& args] ...)? |
| 20:57 | noonian | i come into the conversation late |
| 20:57 | noonian | came* |
| 20:58 | amalloy | noonian: yes, but try actually *passing* an infinite number of args |
| 20:58 | amalloy | with eg, (defmacro bar [] `(foo ~@(range))) |
| 20:58 | noonian | well, thats a little different since you aren't even calling the macro |
| 20:59 | amalloy | uh. yes you are? when you write (bar), (foo 0 1 2 3 4 5 ...) gets called |
| 20:59 | noonian | ah, yes |
| 21:00 | noonian | as long as you don't try to consume the entire infitel list you will be fine though |
| 21:00 | amalloy | and `(foo ~@(range)) reads as (clojure.core/seq (clojure.core/concat (clojure.core/list (quote dsapi.server.cluster/foo)) (range))), so it's not like the reader is getting stuck. i'm curious who *is* getting stuck |
| 21:00 | mange | noonian: It still doesn't work, even if it's just (defmacro foo [& args] (first args)) |
| 21:00 | amalloy | noonian: nope. try (defmacro foo [& args] 0) |
| 21:01 | amalloy | what you're saying works for functions, but apparently not for macros |
| 21:01 | dabd | I want to call a Java method expecting int[] how can I pass it from Clojure? Thanks |
| 21:01 | noonian | uh, that worked for me |
| 21:01 | dabd | it says Persistent vector can't be cast to I |
| 21:02 | amalloy | noonian: you did this, and it worked? (defmacro foo [& args] 0) (defmacro bar [] `(foo ~@(range))), (foo) |
| 21:02 | amalloy | wait, it works for me that way |
| 21:02 | amalloy | what did i have wrong before? |
| 21:02 | dabd | nvm found it: int-array |
| 21:03 | mange | amalloy: (bar) at the end, not (foo) |
| 21:03 | amalloy | oh, thank you |
| 21:03 | noonian | mange: you need to syntax quote the (first args) like '(first args) |
| 21:03 | amalloy | good. taht's still broken |
| 21:03 | amalloy | noonian: that makes no sense in the context of this discussion |
| 21:03 | mange | noonian: No, because args won't exist in the quoted form. We're being passed an infinite list of forms and we want to return the first one as the new code. |
| 21:04 | noonian | as i said, i missed the beginning of it and am just trying to make sense of it |
| 21:05 | noonian | that makes more sense |
| 21:08 | amalloy | mange: i'd love to find out what causes this behavior, even though i never expect to run into it in real life. i don't see any obvious culprits in the compiler |
| 21:08 | amalloy | oh wait, i think i see it |
| 21:09 | amalloy | macroexpand1 calls Var/applyTo, which delegates to AFn/applyToHelper |
| 21:09 | amalloy | in the 20+ args case, that uses seqToArray |
| 21:10 | amalloy | because AFn instances don't expect to have more than 20 args - vararg functions usually go through RestFn |
| 21:11 | mange | That would do it. |
| 21:13 | amalloy | wild |
| 21:13 | amalloy | i wonder if that's a bug, or just "dude you're not supposed to do that" |
| 21:14 | mange | I'd lean towards saying it's a bug, but I also think you're not supposed to do that. |
| 21:16 | amalloy | mange: i found a simple way to prove this is what's going on, by the way |
| 21:16 | amalloy | doesn't even need macros |
| 21:16 | amalloy | (defn foo [& args] (first args)) (apply foo (range)) returns 0, but (apply #'foo (range)) hangs |
| 21:17 | amalloy | i'd say *that* is clearly a bug |
| 21:17 | mange | Yeah, that is far more obviously a bug. |
| 21:18 | bbloom | hmm, i'm not sure |
| 21:18 | mange | I'm not familiar with Clojure's internals, but I assume that the var dispatches to the AFn method rather than the RestFn? |
| 21:18 | bbloom | i ran in to this while working on eclj |
| 21:18 | bbloom | there's a question of when arguments are evaluated |
| 21:18 | bbloom | and what it even means to "evaluate" a lazy argument list |
| 21:22 | amalloy | mange: well, AFn has a static helper, and RestFn doesn't. rather, clojure functions like (fn foo [& args]] ...) extend RestFn and provide an implementation |
| 21:22 | amalloy | so the var uses AFn's helper to decide which arity of the function it's wrapping to call |
| 21:23 | amalloy | but that helper can't cope with non-realized args |
| 21:23 | narayana_ | hello i am new in clojure i wish ask one thing about internal stuffs in clojure |
| 21:24 | narayana_ | how can i load other deps dynamic |
| 21:25 | narayana_ | when i don't having lein |
| 21:25 | narayana_ | sorry for my bad english |
| 21:26 | justin_smith | narayana_: alembic can find and bring in dependencies at runtime |
| 21:26 | justin_smith | https://github.com/pallet/alembic |
| 21:28 | mange | amalloy: That sounds like a slightly different, but closely related, bug, then? So at least two places assume the argument list is finite (one in macro expansion, one in var dispatch)? |
| 21:28 | amalloy | mange: no, just vars |
| 21:28 | amalloy | macroexpansion goes through the var |
| 21:28 | mange | Ah, okay. That makes more sense. |
| 21:28 | bbloom | this seems to hang my repl: (eval (list* first (range))) |
| 21:28 | narayana_ | that is not what i am thinking sometimes on my tablet i just running repl |
| 21:29 | bbloom | it's not even a sensible expression, i meant to write foo there |
| 21:29 | bbloom | heh |
| 21:29 | amalloy | bbloom: well, the result is infinite, so if you're trying to print it...? |
| 21:29 | amalloy | oh wait |
| 21:29 | bbloom | ,(eval (list* first [5 10 15])) |
| 21:29 | mange | bbloom: It does seem like the evaluation time is a bit "flexible", which is troubling when any of those arguments could perform side effects. |
| 21:29 | clojurebot | #<ExceptionInInitializerError java.lang.ExceptionInInitializerError> |
| 21:30 | bbloom | mange: yeah.. but.... if you want your side effects to occur in a particular order, use let or do |
| 21:30 | bbloom | yes, clojure promises left to right evaluation of arguments... but only b/c it's implemented that way |
| 21:30 | bbloom | i assume anyway |
| 21:30 | amalloy | bbloom: isn't that trying to run (first 0 1 2 3 4 ...)? that fails for exactly the same reason that (apply first (range)) does |
| 21:30 | amalloy | which is that it goes through AFn, not RestFn (since first isn't a RestFn) |
| 21:31 | amalloy | another close cousin of the defect i just discovered |
| 21:31 | bbloom | amalloy: right. i was just exploring in the repl & i had to kill my lein proc b/c of it |
| 21:31 | amalloy | bbloom: emacs master race. i just use C-c C-c to stop execution |
| 21:32 | bbloom | amalloy: does that talk to the jvm on another thread? |
| 21:32 | mange | "Both the operator and the operands (if any) are evaluated, from left to right", https://clojure.org/evaluation |
| 21:32 | bbloom | b/c it definitely doesn't work in my terminal |
| 21:32 | mange | Left to right is guaranteed by this page (which is as close to a spec as I know of). |
| 21:32 | amalloy | bbloom: i dunno. i use swank. maybe that doesn't work anymore in cider |
| 21:33 | amalloy | mange: the JLS also makes this guarantee, so it was reasonable enough for clojure to follow in those footsteps |
| 21:33 | mange | But that's not true with respect to infinite argument lists, because they could be evaluated in whatever order. |
| 21:34 | mange | Well, not actually, still left to right, but not before evaluation. |
| 21:34 | amalloy | it must use another thread, i guess, because what happens is i get a ThreadDeathError |
| 21:34 | bbloom | amalloy: ah yes, ThreadDeathError |
| 21:34 | bbloom | which you apparently need to catch and rethrow anywhere you have a (catch Throwable ...) |
| 21:34 | dabd | I'm trying to call some Java code from Clojure. The Java code reads a file which is a resource in the jar and it works fine. When I call the Java code from jar it can't find the file. Could this be a problem with classpaths? Thanks |
| 21:35 | bbloom | (catch Exception ...) isn't general enough and (catch Throwable ...) is TOO general |
| 21:35 | bbloom | :-/ |
| 21:35 | mange | So the function can be called before its arguments are evaluated if they're in a lazy sequence, which goes against the page talking about evaluation order. |
| 21:35 | dabd | I mean to write: When I call the Java code from clojure it can't find the file |
| 21:35 | bbloom | mange: thanks for the "evaluation" page reference |
| 21:36 | bbloom | amalloy: i'm wondering if there is a way to trick the implementation in to calling eval on the first 20 arguments, but not the remaining |
| 21:36 | bbloom | eg if there are side effects |
| 21:36 | amalloy | bbloom: what Errors do you think you should be catching? |
| 21:37 | bbloom | amalloy: like in a test framework or something |
| 21:38 | bbloom | amalloy: http://docs.oracle.com/javase/7/docs/api/java/lang/AssertionError.html |
| 21:38 | bbloom | seems like a useful non-Exception-subclass |
| 21:38 | amalloy | bbloom: fine, but those should be caught separately, in the particular cases you want to catch an assertion. you don't want to catch all Errors generally |
| 21:39 | amalloy | (try ... (catch Exception e ...) (catch AssertionError e ...)) |
| 21:39 | amalloy | there are *way* more Errors you don't want to catch than those that you do |
| 21:39 | bbloom | amalloy: either way i have to enumerate some special cases either to permit ThreadDeath to pass or to capture assertions |
| 21:39 | amalloy | so i wouldn't worry about the fact that ThreadDeathError is one you don't want to catch |
| 21:39 | amalloy | bbloom: for sure |
| 21:39 | amalloy | and it's the second case. enumerate the special case of things you want to catch |
| 21:40 | bbloom | i mean, i dunno.... there's also IOError and a bunch of other weird random things. see list: http://docs.oracle.com/javase/7/docs/api/java/lang/Error.html |
| 21:41 | bbloom | seems to me that ThreadDeath shouldn't exist at all |
| 21:41 | bbloom | just kill the bloody thread |
| 21:41 | amalloy | bbloom: right, and you don't want to catch any of those either |
| 21:42 | amalloy | i don't know what throws IOError, having never received one in my life, but it's a lot more serious than IOException and i wouldn't try to catch it |
| 21:42 | bbloom | fair enough |
| 21:42 | bbloom | anyway: more interesting is the question of argument eval beyond 20 |
| 21:43 | amalloy | i remember way back in the day i used ThreadDeath for flow control |
| 21:43 | cbp` | wat |
| 21:44 | amalloy | implementing an automaton thingy of my own, with psuedo threads. i threw ThreadDeath myself to indicate that one of those threads was done |
| 21:44 | amalloy | so thoroughly misguided |
| 21:45 | TerranceWarrior | anyone looking for a clojure programmer as an intern or for $15 an hour(i have over 20 years in many other software programming languages). |
| 21:45 | amalloy | this would be in like 2007 |
| 22:02 | srruby | I am new to core.logic. In core.logic I try (fd/+ a b c 10) and I get an arity exception. (fd/+ a b 10) works. Any ideas? Thanks, John |
| 22:09 | dabd | I need to find the last occurence of a string within a large string. What is the fastest way to achieve this? |
| 22:09 | dabd | Actually i need the index of the last occurence |
| 22:10 | nullptr | (.lastIndexOf haystack "needle") |
| 22:10 | nullptr | ,(.lastIndexOf "haystack" "y") |
| 22:10 | clojurebot | 2 |
| 22:10 | dabd | oh so simple thanks! |
| 22:36 | tmciver | Could someone explain to me the difference between using 'lein install' and 'lein localrepo install ...'? |
| 22:38 | mange | tmciver: it looks like 'lein install' installs the current project to the local maven repository; 'lein localrepo install' installs a specified jar to the local repo with a given groupId, artifactId and version |
| 22:41 | tmciver | mange: hmm, not sure I understand. What if you tell localrepo to install a version that's not the project's current version, i.e., a previous version? |
| 22:42 | mange | With localrepo you have to provide an actual jar file. With 'lein install' it will take the project you're currently in, compile it, put it in a jar and install it to the local repo. |
| 22:43 | tmciver | mange: OK, that doesn't seem very useful to me :) but people seem to be using localrepo so I guess it is. |
| 22:43 | mange | To make 'lein localrepo install' do the same thing as 'lein install' you'd have to do something like 'lein jar && lein localrepo install target/jarName.jar group/artifact 0.1.0' |
| 22:43 | mange | localrepo lets you install jars that you don't own into your local maven repo, which then means you can include them in a lein project.clj file and have them added properly. |
| 22:44 | tmciver | mange: ah ha! Now I see it's utility. Thanks. |
| 22:44 | tmciver | s/it's/its |
| 22:44 | mange | No worries! |
| 22:51 | tomjack | "java.lang.AssertionError: Assert failed: (every? (comp identity :id) %) at clojure.tools.cli$compile_option_specs.invoke(cli.clj:241)" :) |
| 23:03 | dgleeson | hello, I'm pretty new to clojure. I have a vector filled with maps, I'd like to iterate over the vector and put the maps into a core.async chan. I'm struggling trying to figure out how to loop over the vector. Can someone give me a hint? |
| 23:05 | tomjack | (core.async/onto-chan ch the-vector) |
| 23:05 | justin_smith | also, in the more general case, using a map where a seq is expected will give you [key, value] pairs |
| 23:06 | justin_smith | ,(map identity {:a 0 :b 1 :c 2}) |
| 23:06 | clojurebot | ([:c 2] [:b 1] [:a 0]) |
| 23:06 | justin_smith | oh, wait |
| 23:06 | justin_smith | you are talking about a vector of maps |
| 23:06 | justin_smith | ,(map :a [{:a 0} {:a 1} {:a 42}]) |
| 23:06 | clojurebot | (0 1 42) |
| 23:07 | dgleeson | tomjack: oh cool, I was making that way harder than it should have been |
| 23:08 | dgleeson | this is the data structure I got back from this rest client I'm using. It seems weird that it would return a vector. I think I'm still not sure exactly why I would use a vector over a list. |
| 23:09 | dgleeson | I have [{:node "node name"} {:node "other node name"}] |
| 23:09 | dgleeson | except the vector might have 20,000 maps in it |
| 23:09 | dgleeson | which is why I chose to look into core.async |
| 23:10 | dbasch | dgleeson: the only reason to use a list is if you need to insert elements in the front |
| 23:11 | dbasch | dgleeson: if you may need to do random access, you definitely want a vector |
| 23:12 | dgleeson | interesting |
| 23:13 | justin_smith | dgleeson: you can use a vector pretty much anywhere you would use a list |
| 23:13 | justin_smith | dgleeson: and for this reason the standard json libs return vectors |
| 23:27 | storme_ | Is it bad practice to call functions from a macro? |
| 23:29 | dgleeson | ok, so now I have my maps onto my channel, is there an easy way to loop read until the channel is closed? |
| 23:31 | dgleeson | something like (while !nil ( do-some-stuff (<!! chan ))) |
| 23:31 | dgleeson | ? |
| 23:36 | dgleeson | I think I just need to read through this core.async walkthrough again :P |
| 23:36 | egghead | dgleeson: :p |
| 23:37 | egghead | go-loop and when msg should do it |
| 23:46 | l1x | dgleeson: depends how you would like to process it but there are two significantly different ways, the lazy and the eager way (there is something in between when part of the sequence is eager) |
| 23:46 | akurilin | For the linux/ubuntu folks among you, do you have a trick from switching between two java versions installed side-by-side on the same machine? |
| 23:46 | l1x | akurilin: http://askubuntu.com/questions/315646/update-java-alternatives-vs-update-alternatives-config-java |
| 23:47 | l1x | ,(doseq [n [{:nodeA 1} {nodeB 2}] ] (println n)) |
| 23:47 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: nodeB in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 23:47 | l1x | ,(doseq [n [{:nodeA 1} {:nodeB 2}] ] (println n)) |
| 23:47 | clojurebot | {:nodeA 1}\n{:nodeB 2}\n |
| 23:47 | akurilin | l1x: okie dokie |
| 23:48 | l1x | ,(for [n [{:nodeA 1} {:nodeB 2}] ] (println n)) |
| 23:48 | clojurebot | ({:nodeA 1}\n{:nodeB 2}\nnil nil) |
| 23:48 | l1x | dgleeson: see the difference? |
| 23:49 | l1x | i guess it is not trivial first but the later is producing a lazy-seq |
| 23:49 | akurilin | l1x: man that was simple, I can't trust something that works that nicely |
| 23:49 | akurilin | where's the pain? |
| 23:49 | l1x | hahahaha |
| 23:49 | l1x | akurilin: sorry to disapoint |
| 23:52 | l1x | i spent the entire day trying to figure out how to deal with kafka iterator in Clojure but no luck, if anybody wants to help here is the question http://stackoverflow.com/questions/23668308/what-is-the-correct-way-of-using-kafka-iterate-in-clojure |
| 23:52 | akurilin | So to go from clj 1.5.1 to 1.6 I just need to update the version in my project file and lein will take care of the rest? |
| 23:53 | devn | hmph, maybe this is REPL or AWS SDK related, but... I have a pending atom (def pending (atom 0)), and then I have a progress-listener, which increments the pending atom when the event is :started, and decs it with it's :completed. The odd thing is, the inc in the :started event never seems to fire on the /first/ event. It works fine for all subsequent events. |
| 23:53 | devn | Meaning I always end up at -1 |
| 23:53 | l1x | akurilin: yes |
| 23:53 | l1x | where is the pain again?! |
| 23:54 | devn | i've hidden it, in my codebase |
| 23:54 | l1x | :)) |
| 23:54 | l1x | devn: can you show the code? |
| 23:58 | l1x | devn: https://gist.github.com/l1x/596baf96f000299f30db |