#clojure log - May 14 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0: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

0: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/

0:02 that's all, just interesting I thought...

0:03 amalloy: ddellacosta: i stole it from him

0:03 ddellacosta: amalloy: well, there ya go

0: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?

0:04 leiningen seems rather heavy for that.. but maybe that's just because I'm not especially familiar with it?

0:08 hiredman: numberten: java -jar clojure.jar will start a very bare bones repl

0: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.

0:08 hiredman: numberten: java -cp clojure.jar clojure.main --help will print a list of command line options

0: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?

0:08 numberten: hiredman: alright thanks

0: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

0:09 it should behave something like this:

0:09 amalloy: (merge b a)?

0:10 Rosnec: amalloy, no, not merge

0:10 lemme write an example real quick

0:11 (replace-keys {:a :a-replacement, :b :b-replacement} {:a 4, :b 5, :c 6}) => {:a-replacement 4, :b-replacement 5, :c 6}

0:11 it's the keys I'm changing, not the values

0:12 amalloy: clojure.set/rename-keys

0:12 Rosnec: amalloy: :D

0:12 beautiful

0:14 actually, there's one thing that this doesn't cover in my usage, which might make me resort to writing somethign with reduce

0:14 I need to keep track of which keys I've successfully replaced

0:15 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

0:16 I suppose I could just check afterwards which keys from kmap exist in map

0:17 and dissoc them when I recur

0:26 technomancy: numberten: once you have a repl open, just run (clojure.test/run-tests) or (require 'some.ns :reload)

0:58 orknob: Is there an archive of this room anywhere? Asking since the room seems to be active outside of my working hours?

0:59 Jaood: the first result of googling "#clojure log freenode" for me

0:59 mdeboard: orknob: The channel logsare indexed by google

1:00 orknob: Also you might want to consider setting up/using an IRC bouncer

1:00 orknob: @Jaood ah, thanks. I searched for

1:01 @Jaood “freenode archives” and came up with http://www.irclog.org/network.php?net=freenode which doesn’t have Clojure

1:01 @mdeboard thanks. IRC n00b here. Looking up IRC bouncer.

1:03 technomancy: also, it's IRC, not twitter =)

1:03 danielcompton: Why is clojure.string and clojure.set included with Clojure core but not something like https://github.com/clojure/math.numeric-tower

1:03 technomancy: orknob: ^

1:03 danielcompton: historical reasons more than anything else

1:04 danielcompton: technomancy how does it distinguish between them?

1:04 technomancy: danielcompton: I don't understand the question

1:04 danielcompton: technomancy how would I know which is included and which is a separate dependency?

1:05 technomancy: the ones that are included are documented with clojure itself rather than being a separate project

1:08 danielcompton: Got it

1:15 dissipate: anyone else having trouble with http://tryclj.com/?

1:16 cbp`: which troubles?

1:18 dissipate: cbp`, timing out

1:19 cbp`: dissipate: you get Execution timed out! ?

1:20 danielcompton: dissipate working for me

1:20 dissipate: cbp`, yeah, the ajax calls are timing out

1:22 hmm, working now.

1:22 must have been lagged out

3:38 mskoud: what does (let [{widgets :body} (<! (http/get url))]... specifically the {widgets :body} mean?

3:40 sm0ke: how do i integrate junit tests into my lein project/

3:40 ?*

3: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`.

3:42 mskoud: ok, i see, thanks.

3:42 pyrtsa: It's just the ordinary use of maps in let bindings.

3:46 sm0ke: there is a https://github.com/febeling/lein-junit

3: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

3:58 martinklepsch: anyone here some experience profiling with timbre? is it possible to profile across multiple namespaces?

4:43 pbw: Can I use map to create a lazy sequence from two cycles?

4:48 dissipate: pbw, why not use a 'for'

4:48 pbw: Forgot to mention these are infinite sequences

4:49 Is that implied by "cycle"?

4:49 dissipate: pbw, http://clojuredocs.org/clojure_core/clojure.core/for

4:50 pbw: Digesting that now… thanks

4:53 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.

4:53 dissipate: pbw, (take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y]))

4:54 ;(take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y]))

4:54 ;;(take 5 (for [x (cycle [1 2 3]) y (cycle [1 2 3])][x y]))

4:56 pbw, not sure exactly what you are trying to do but 'for' will create a lazy sequence from two cycles. :D

4:56 pbw: Yes, but not in the right order.

4:56 (def cycle2 (cycle [true false]))

4:57 (def cycle3 (cycle [true true false]))

4:58 dissipate: pbw, and?

4:58 pbw: What I want is a cycle that is the logical and of the corresponding elements of the two cycles.

5:00 (take 6 (some-map cycle2 cycle3)) => [true false false false true false]

5:08 dissipate: pbw, hmm, looks like my solution is bad actually. :(

5: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.

5:12 If I try this: (def cycle23 (map and cycle2 cycle3))

5:12 I get Can't take value of a macro

5:13 jonathanj: #(and %1 %2)

5:14 pbw: That is accepted, but (take 19 (cycle23)) gives: ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

5:15 jonathanj: (take 19 cycle23)

5:15 i don't think you want to call your sequence

5:16 pbw: No, I don't! And that works.

5:16 (take 10 cycle23)

5:16 => (true false false false true false true false false false)

5:16 jonathanj: it's unfortunate that you can't just use `and` as is

5:17 pbw: Ok. Next question. Can I extend this so that it will take more than 1 cycles, rather than just two.

5:18 It is unfortunate. And that makes it awkward to get my next answer.

5:19 dissipate: pbw, yep, write a function that returns a lazy seq that takes an arbitrary number of cycles as arguments.

5:20 jonathanj: can you define an anonymous function that takes &?

5:20 nathan7: jumblerg: %&

5:20 jonathanj*

5:20 dissipate: jonathanj, yep

5:21 ssideris: or just (fn [& stuff] ...)

5:21 nathan7: (#(identity %&) 1 2 3) = [1 2 3]

5:21 jonathanj: <3

5:21 hrm

5:22 pbw: Trying to work out what's going on above.

5:22 dissipate: pbw, set up a multi-arity function the first arity being 2 and the second being arbitrary.

5:22 jonathanj: #(and %&) doesn't quite do what i expected

5:23 pbw: No. => ((true true) (false true) (true false) (false true) (true true) (false false) (true true) (false true) (true false) (false true))

5:23 jonathanj: i guess that's because it's doing (and [true false])

5:23 which is [true false]

5:23 pbw: Ok

5:24 @dissipate - I'll try that if I can't get a simpler thing working

5:25 jonathanj: i'm not exactly sure how you write this

5:25 dissipate: jonathanj, right, it actually becomes a single argument that is a vector of all the arguments

5:26 jonathanj, i think if you add an 'apply' it works

5:26 jonathanj: how do i use the bot? :P

5:26 ,(apply #(and %&) [true false])

5:26 clojurebot: (true false)

5:27 jonathanj: ,(#(apply and %&) [true false])

5:27 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

5:27 pbw: I've seen that error!

5:28 dissipate: ,(#(apply and %&) true false)

5:28 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

5: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.

5:28 ssideris: apply works on normal functions, but and is a macro

5:29 hence the error

5:29 dissipate: ssideris, i see. crappy. :( so what's the apply for macros?

5:30 http://clojuredocs.org/clojure_contrib/clojure.contrib.apply-macro/apply-macro

5:30 says to never use it. :(

5:30 jonathanj: well it is weird

5:30 dissipate: ,(#(apply-macro and %&) true false)

5:30 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: apply-macro in this context, compiling:(NO_SOURCE_PATH:0:0)>

5:30 jonathanj: almost as weird as (and) being a macro :P

5:31 emlyn: What about ,(reduce #(and %1 %2) [true false])

5:31 ,(reduce #(and %1 %2) [true false])

5:31 clojurebot: false

5:33 pbw: It's the unknown number of arguments that is the problem.

5:33 jonathanj: right, so if you: (defn and-fn [& args] (reduce #(and %1 %2) [true false])

5:33 then you can just write: (map and-fn cy1 cy2 cy3 ...)

5:33 emlyn: ,(reduce #(and %1 %2) [true false true true false])

5:33 clojurebot: false

5:33 pbw: Duh

5:34 ssideris: pbw: http://clojuredocs.org/clojure_core/clojure.core/every_q

5:34 leggo: though that won't short circuit

5:35 jonathanj: leggo: which? the reduce?

5:35 ssideris: leggo: it stops at the first false it encounters

5:36 look at the source

5:36 leggo: it does? how?

5:36 dissipate: http://stackoverflow.com/questions/9218044/in-clojure-how-to-apply-and-to-a-list

5:37 ssideris: leggo: recurs until it finds a false value

5:37 dissipate: ,(every? identity '(true false))

5:37 clojurebot: false

5:39 jonathanj: why is `and` a macro?

5:40 dissipate: jonathanj, good question, i have no idea why

5:40 CookedGryphon: jonathanj: so that it can short circuit

5:40 pyrtsa: To avoid evaluating more arguments if the result is already clear.

5:40 Bronsa: jonathanj: so that (and true (println "foo")) short circutis and doesn't print "foo"

5:41 jonathanj: i guess that makes sense

5:41 pbw: (def cyclen (map #(every? identity %&) cycle2 cycle3))

5: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?

5: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?

5:41 dissipate: ah, makes sense. yep, short circuiting can only truly be achieved as macro

5:41 pyrtsa: (and condition (println "foo")) is a poor example, though. One should use (when condition ...) for it.

5:41 pbw: (take 10 cyclen) => (true false false false true false true false false false)

5:41 Bronsa: ssideris: durr.

5:41 dissipate: in other languages like Python, the arguments must be evaluated first, so it's less efficient

5:41 ssideris: leggo: sorry to have confused you, I was talking about (every?)

5:41 Bronsa: well s/true/false

5:42 pyrtsa: But (when (and ...) ...) makes sense.

5:42 Bronsa: (and false (println "foo"))

5:42 leggo: ssideris ah ok

5:42 ssideris: Bronsa: ok, it makes sense like that :-)

5:43 dissipate: pbw, so it's working?

5: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

5:44 pbw: Yes. Thank you all. Btw, does every? short-circuit?

5:45 pyrtsa: Yes.

5:45 dissipate: ssideris, yes. in a function the arguments must be evaluated (i believe)

5:45 pbw: thanks. What does 'identity' do that makes the %& work?

5:46 dissipate: pbw, it 'unboxes' the arguments from the vector

5:47 pbw: Like 'apply'?

5:47 llasram: pbw: %& is part of the reader syntax for shorter anonymous functions

5:47 sm0ke: i keep getting "java.lang.NoSuchMethodError: clojure.lang.RT.mapUniqueKeys([Ljava/lang/Object;)Lclojure/lang/IPersistentMap;" today

5:47 seen before?

5:47 llasram: ,`#(every? identity &%)

5:47 clojurebot: (fn* [] (clojure.core/every? clojure.core/identity sandbox/&%))

5:47 llasram: Er,

5:47 ,`#(every? identity %&)

5:47 clojurebot: (fn* [& rest__49__50__auto__] (clojure.core/every? clojure.core/identity rest__49__50__auto__))

5:48 llasram: Ther ewe go

5:48 Bronsa: sm0ke: using an AOT compiled cljs source against clojure >1.4.0 on clojure 1.3.0

5:48 sm0ke: or compiled against >1.5.0 on clojure 1.4.0, I don't remember when that done

5:49 dissipate: pbw, yeah, like 'apply' it unboxes the arguments from the list/vector

5:49 sm0ke: hurm there is no cljs for sure, must be the second one then

5:54 dissipate: ,(and)

5:54 clojurebot: true

5:54 dissipate: ,(or)

5:54 clojurebot: nil

5:54 dissipate: pop quiz. why is (and) true?

5:56 pbw: So it will return true if later anded with true?

5:57 dissipate: pbw, yep, put another way, it's because it is the identity of 'and'.

5:57 pbw, it doesn't change the result of an 'and'

5:57 ,(+)

5:57 clojurebot: 0

5:57 dissipate: pbw, same reason why (+) is 0

5:58 pbw, but i still don't know why (or) is 'nil' and not 'false'

5:58 ,(or)

5:58 clojurebot: nil

5:58 Bronsa: dissipate: no reason

5:58 CookedGryphon: dissipate: nil *is* false

5:58 Bronsa: CookedGryphon: false-y

5:58 dissipate: (= nil false)

5:58 llasram: ,(identical? false nil)

5:58 clojurebot: false

5:58 CookedGryphon: falsy-y

5:59 Bronsa: dissipate: I guess nil plays nicer with seqs than false

5:59 dissipate: ,(and true nil)

5:59 clojurebot: nil

5:59 llasram: Which isn't really a great justification...

6:00 dissipate: why does 'and' evaluate to its first falsy value instead of just 'false'?

6:01 llasram: dissipate: Because it evaluates to the value of the last argument it evaluates

6:01 sm0ke: Bronsa: indeed, bumping clojure version to 1.5.1 in my project seems to have fixed it

6:01 llasram: ,(and false 17)

6:01 clojurebot: false

6:01 llasram: ,(and true 17)

6:01 clojurebot: 17

6:01 sm0ke: but where the hell is that >1.5.0 compiled source is coming from!

6:02 i was using lein-junit and i think its the culprit https://github.com/febeling/lein-junit/blob/master/project.clj

6:02 llasram: sm0ke: Could be any of your deps unfortunately :-( I know Storm messed up that way, at least at one point

6:02 sm0ke: can a dependency be excluded from plugins?

6:02 dissipate: llasram, i see, makes sense

6:03 llasram: sm0ke: Why do you think it's lein-junit?

6:03 dissipate: llasram, but we still don't know why (or) is 'nil'

6:03 sm0ke: llasram: well because lein deps :tree shows clojure 1.4.0 overrwites others

6: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

6:05 dissipate: Yeah, that seems wrong to me -- does seem like it should be `false`. Not that it ever actually comes up

6:05 I mean, since `or` is a macro, I can't imagine the 0-argument version gets called very frequently

6:08 visof: how can i accumulate the result of recursion on a list?

6:08 i mean the basic way

6:08 Glenjamin: the 0-arity versions should be an identity

6:08 ,(= (or 'x (or)) 'x)

6:08 clojurebot: true

6:08 llasram: visof: `reduce`?

6:08 Glenjamin: that should be true for basically all functions

6:08 ,(= (and (and) 'x) 'x)

6:08 clojurebot: true

6:09 Glenjamin: erm

6:09 ,(= (and 'x (and)) 'x)

6:09 clojurebot: false

6:09 llasram: Glenjamin: I think you may have scrolled back too far :-)

6:09 Glenjamin: oh right, i see

6: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

6:10 Glenjamin: (or) => nil produces an identity, it seemed like the question was hanging :)

6: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?

6:10 llasram: gyim: You know, that makes sense. Good point!

6:11 visof: what i thought: iterate over a list, if element not list return element else walk sublist

6:11 llasram: Glenjamin: Right, but it seemed like the actually-boolean identity value of `false` would have been better, before gyim's suggiestion

6:11 Glenjamin: oh, i see

6:11 yeah, they're equivalent i guess

6:12 llasram: visof: Example inputs and results? I'm not following

6: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?

6:19 llasram: visof: Well, to start with, you don't use doseq :-)

6:19 You can call a function recursively from any of the higher-order sequence functions

6:20 You can usually handle most patterns with `map` etc and/or `reduce`

6: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

6:20 llasram: visof: Otherwise `loop`/`recur`

6:21 visof: Without something more specific, I'm not sure what else to add

6:22 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

6:22 Glenjamin: jkj: i think that's agents or core.async territory

6:22 llasram: jkj: First-class functions makes it far more pleasant to work with than from raw Java

6:23 Glenjamin: i would recommend believing llasram over me in this case, i've only done non-io paralleism

6:24 jkj: llasram: ok. thx

6:24 visof: llasram: so what should the code looks like?

6:25 llasram: visof: What's a specific problem you'd like to solve? Like, just for an example, re-implement `flatten` ?

6:25 visof: yeah but in this shape of code

6:26 llasram: In what sense?

6:27 visof: llasram: the code i pasted, i'll replace doseq to reduce?

6: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`

6:29 visof: llasram: so it should be like (reduce conj [] (code)) ?

6:30 llasram: visof: Not quite

6:30 visof: llasram: ?

6:31 llasram: Just a sec... `flatten` is kind of an annoying example

6:37 visof: flatten just really is not a good example, but here you go anyway: https://www.refheap.com/85476

6:38 TerranceWarrior: is there a way to use clojure as a scripting language or unreal udk 4?

6: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

6:39 Which makes it difficult to discuss

6:39 ssideris: TerranceWarrior: does UDK 4 support java or javascript for scripting?

6:52 TerranceWarrior: ssideris: nope

6:52 ssideris: just c++

7: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 ?

7: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?

8: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?

8: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.

8:28 schmir: pbw: the informix jdbc driver already does the conversion. but the database is itself is misconfigured. thanks for the pointers.

8: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?

8:46 hyPiRion: no

8:47 ,(dorun (list (range)))

8:47 clojurebot: nil

9:02 Raynes: Side effects of waking up at 4AM: you make conch throw exceptions for non-zero exit codes.

9:04 mdrogalis: Heh, morning Raynes.

9:04 * Raynes tips his hat

9:07 hyPiRion: Raynes: no way there's 4 am there now

9:07 Raynes: hyPiRion: Well it's 6AM now.

9:07 I didn't say it was easy.

9:07 :P

9:08 hyPiRion: oh wow, it really is.

9:09 gfredericks: if you lived in chicago, you'd be home by now

9:09 hyPiRion: gfredericks: Didn't know chicago were in Europe, but yeah.

9:09 * gfredericks wonders if there's such thing as an anti-sequitur

9:10 gfredericks: chicago is wherever you are most happy

9:10 hyPiRion: clojurebot: chicago?

9:10 clojurebot: Pardon?

9:10 gfredericks: clojurebot: the chicago |was| inside you the whole time

9:10 clojurebot: Ack. Ack.

9:11 mdrogalis: You never needed to go to Chicago. The irony is, you're always there.

9: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?

9:38 mdrogalis: _oggy: Optional args can only go at the end.

9:38 Maybe take a single parameter as a map.

9:38 _oggy: can i use a multimethod?

9:39 justin_smith: mdrogalis: if it is one or two args you can do the first as optional

9: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) {...}

9:39 justin_smith: ,((fn f ([a] (f nil a)) ([b a] [a b])) nil)

9:39 clojurebot: [nil nil]

9:39 justin_smith: ,((fn f ([a] (f nil a)) ([b a] [a b])) 1)

9:39 clojurebot: [1 nil]

9:40 justin_smith: ,((fn f ([a] (f nil a)) ([b a] [a b])) 1 2)

9:40 clojurebot: [2 1]

9:40 justin_smith: something like that at least

9:42 _oggy: justin_smith: ah, i think i see what you did there :) can i do the same with defn?

9:42 justin_smith: yes, defn is just (def (fn ...)) plus some metadata

9:43 well (def foo (fn ...)) but you get the idea

9:44 _oggy: yup, thanks!

9:44 justin_smith: ,(map #(apply (fn f ([a] (f :default a)) ([b a] [a b])) %) [[1] [1 2]]) ; getter example

9:44 clojurebot: ([1 :default] [2 1])

9:44 justin_smith: *better

9: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"

9:52 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 ,(type (flatten (map #(range %) (range))))

10:08 clojurebot: clojure.lang.LazySeq

10:08 justin_smith: emlyn: that won't work

10:09 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 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 or (comp doall read-file) if you want the result

10:18 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 yeah

10:22 ,`(+ - *) 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 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 not expressions

10:28 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 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 ,::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 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 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 $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 I want to do (if x (filter f coll) coll)

11:06 but in a ->>

11:06 and I don't want cond-?

11:06 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 (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 Glenjamin: I tried to verify my sliding window of futures understanding with it. but it just proved it wrong...

11:29 oh wait chunked seqs..

11:32 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 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: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 cbp: the primitive-math lib states that ^^

11:45 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 (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 or was it 42

11:50 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 martinklepsch: I meant cpu hardware ;)

12:09 gfrederick_s: is there a library that does prn?

12:11 if not I might have to make one

12:13 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 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 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 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 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 /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 my advice is for if it is

12:44 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 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 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 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 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 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 So I released a new version that can throw exceptions for non zero exit codes.

12:50 Made me incredibly happy.

12:50 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 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 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 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 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 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 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 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 It's a lot cleaner. Might just be bad organization.

14:18 Yours I mean, amalloy.

14:19 amalloy: {blake}: https://www.refheap.com/8505f3f2524a32dba9e8d503e is another approach, with recursion

14:19 `(~@(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 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 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 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 {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 (->> checkers

15:03 (filter #((first %) hand))

15:03 (map second)

15:03 (apply max)))

15:03 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 {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 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 Duh, right.

15:12 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 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 (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 and yes that was what I was talking about

16:16 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 I guess that isn't exactly right, but you would want a more powerful function composition

16:19 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 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 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 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 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 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 Frozenlock: i use this behind heroku's ssl terminator

16:43 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 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 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 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 it's got a reader.

17:29 but if you're running lein-pprint that's moot.

17:29 waynr: lein-pprint will do

17:31 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 ,(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 it's a map entry

17:42 amalloy: jeremyheiler: yes it is

17:42 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 wanna write it?

17:46 ;-)

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 Searching for the jira request...

18:01 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 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 saw that List(1, 2, 3).toSet() in scala returns false...

18:31 b/c apparently that's actually List(1, 2, 3).toSet.apply(()) where () is unit

18:31 and unit is not a member of the Set[Int]

18:31 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 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 but you will want a routing lib very quickly

18:58 good idea to try things basic first though

18:59 also ring is extremely modular, so you can start super basic and add middleware as you need features

18:59 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 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 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 it's still quoted, but the first thing is resolved by unquote.

19:07 ,`(~+ 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 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 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 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 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 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 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 ah

19:17 amalloy: it so happens that, for some functions, it works

19:17 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 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 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 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 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 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 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 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:45 * Frozenlock hides all the code he's ever written

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 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 (defmacro foo [] `(manges-macro ~@(range)))

20:51 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 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 i come into the conversation late

20:57 came*

20:58 amalloy: noonian: yes, but try actually *passing* an infinite number of args

20:58 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 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 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 wait, it works for me that way

21:02 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 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 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 oh wait, i think i see it

21:09 macroexpand1 calls Var/applyTo, which delegates to AFn/applyToHelper

21:09 in the 20+ args case, that uses seqToArray

21:10 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 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 doesn't even need macros

21:16 (defn foo [& args] (first args)) (apply foo (range)) returns 0, but (apply #'foo (range)) hangs

21:17 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 there's a question of when arguments are evaluated

21:18 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 so the var uses AFn's helper to decide which arity of the function it's wrapping to call

21:23 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 how can i load other deps dynamic

21:25 when i don't having lein

21:25 sorry for my bad english

21:26 justin_smith: narayana_: alembic can find and bring in dependencies at runtime

21:26 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 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 heh

21:29 amalloy: bbloom: well, the result is infinite, so if you're trying to print it...?

21:29 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 yes, clojure promises left to right evaluation of arguments... but only b/c it's implemented that way

21:30 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 which is that it goes through AFn, not RestFn (since first isn't a RestFn)

21:31 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 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 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 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 :-/

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 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 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 amalloy: http://docs.oracle.com/javase/7/docs/api/java/lang/AssertionError.html

21:38 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 (try ... (catch Exception e ...) (catch AssertionError e ...))

21:39 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 bbloom: for sure

21:39 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 seems to me that ThreadDeath shouldn't exist at all

21:41 just kill the bloody thread

21:41 amalloy: bbloom: right, and you don't want to catch any of those either

21:42 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 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 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 Actually i need the index of the last occurence

22:10 nullptr: (.lastIndexOf haystack "needle")

22:10 ,(.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 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 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 ,(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 you are talking about a vector of maps

23:06 ,(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 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 I have [{:node "node name"} {:node "other node name"}]

23:09 except the vector might have 20,000 maps in it

23:09 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 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 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 something like (while !nil ( do-some-stuff (<!! chan )))

23:31 ?

23:36 I think I just need to read through this core.async walkthrough again :P

23:36 egghead: dgleeson: :p

23:37 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 ,(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 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 where's the pain?

23:49 l1x: hahahaha

23:49 akurilin: sorry to disapoint

23:52 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 Meaning I always end up at -1

23:53 l1x: akurilin: yes

23:53 where is the pain again?!

23:54 devn: i've hidden it, in my codebase

23:54 l1x: :))

23:54 devn: can you show the code?

23:58 devn: https://gist.github.com/l1x/596baf96f000299f30db

Logging service provided by n01se.net