#clojure log - Mar 25 2015

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

0:42 elvis4526: Is it possible to always use the latest version of a given lib in project.clj ?

0:43 instead of always manually identifying the desired version.

0:45 Found it. You can use "LATEST" as the version.

0:45 is it a good practice in general ?

0:49 gws: elvis4526: not in my experience, better to specify the dependencies explicitly and use something like https://github.com/xsc/lein-ancient periodically

0:49 mrcheeks: elvis4526:What will you answer if a release is unstable and breaks an existing working application "I use the latest?" ->.

0:56 elvis4526: Got it thanks

0:58 underplank: Hi all. Im messing around with building a proxy using compujure and ring.

0:58 Im looking at the incoming request and the :body key has a HttpInput class.

0:59 I’ve read that I should just be able to slurp this. and that seems ok. But if its empty I get and exception.

0:59 Is there an easy way to check if its empty before I slurp it?

1:00 amalloy: underplank: someone else has already slurped it; these streams are not "reusable". probably it is some middleware reading the body to parse out form params or something

1:01 underplank: hmm.. so is my best bet to just catch that exception? and mark it as an emtry string?

2:34 elvis4526: is it possible to use clojurescript from clojure ?

2:50 Kneiva: elvis4526: what would you do with that?

2:54 Seylerius: ,(defn dedup [seqq] (if (= (first seqq) (second seqq)) (dedup (next seqq)) (concat [(first seqq)] (dedup (next seqq)))))

2:54 clojurebot: #'sandbox/dedup

2:55 Seylerius: ,(dedup [1 2 2 3 3])

2:55 clojurebot: #error{:cause nil, :via [{:type java.lang.StackOverflowError, :message nil, :at [clojure.lang.RT seq "RT.java" 487]}], :trace [[clojure.lang.RT seq "RT.java" 487] [clojure.lang.RT next "RT.java" 647] [clojure.core$next__4063 invoke "core.clj" 64] [clojure.core$second__4069 invoke "core.clj" 96] [sandbox$dedup invoke "NO_SOURCE_FILE" 0] ...]}

2:55 Seylerius: ,(defn dedup [seqq] (if (= (first seqq) (second seqq)) (dedup

2:55 (rest seqq)) (concat [(first seqq)] (dedup (rest seqq)))))

2:55 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:56 Seylerius: ,(defn dedup [seqq] (if (= (first seqq) (second seqq)) (dedup (rest seqq)) (concat [(first seqq)] (dedup (rest seqq)))))

2:56 clojurebot: #'sandbox/dedup

2:56 elvis4526: Kneiva: I was just rendering if this was possible

2:56 Seylerius: ,(dedup [1 2 2 3 3])

2:56 clojurebot: #error{:cause nil, :via [{:type java.lang.StackOverflowError, :message nil, :at [clojure.lang.PersistentList$EmptyList first "PersistentList.java" 158]}], :trace [[clojure.lang.PersistentList$EmptyList first "PersistentList.java" 158] [clojure.lang.RT first "RT.java" 625] [clojure.core$first__4061 invoke "core.clj" 55] [sandbox$dedup invoke "NO_SOURCE_FILE" -1] [sandbox$dedup invoke "NO_SOURCE_FIL...

2:56 elvis4526: like for hiccup and garden

2:56 Seylerius: Ach.

3:11 amalloy: Seylerius: you're missing a base case, for if the coll is empty

3:25 Ricardo-Arges: Morning

3:26 Is there any particular convention for when a function starts with an underscore?

3:28 Like question mark for predicates.

4:56 zot: g'morning. i'm working on translating some code from cljs -> clj, and it makes heavy use of mutable data. in one case, there's a deftype which includes 2 ^:mutable fields, which I initially changed to ^:volatile-mutable, only to find that doing so isn't trivial. is re-wrapping everything as atoms the best alternative? the code in question is here: https://github.com/tonsky/datascript/blob/master/src/datascript/impl/entity.cljs#L65 and my brok

4:56 any wisdom, thoughts or smart-ass-ery is appreciated :)

4:58 ordnungswidrig: zot: that's not trivial but I guess an atom might be the best to use. For performance you can later still migrate to volatiles.

4:59 zot: yeah, that was my thinking; but just so that i know — why doesn't normal access work when it's a vol-mut? or am i doing something stupid to make that also fail?

5:04 ordnungswidrig: zot: I've got no experience with vol-muts :-(

5:22 Seylerius: ,((fn dedup [seqq] (if (not (empty? seqq)) (if (= (first seqq) (second seqq)) (dedup (rest seqq)) (concat [(first seqq)] (dedup (rest seqq)))) (seqq))) [1 1 2 3 3 2 2 3])

5:22 clojurebot: #error{:cause "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn", :at [sandbox$eval25$dedup__26 invoke "NO_SOURCE_FILE" 0]}], :trace [[sandbox$eval25$dedup__26 invoke "NO_SOURCE_FILE" 0] [sandbox$eval25$dedup__26 invoke "NO_SOURCE_FILE" 0] [sandbox...

5:23 TEttinger: ,(defn dedup [seqq] (if (not (empty? seqq)) (if (= (first seqq) (second seqq)) (dedup (rest seqq)) (concat [(first seqq)] (dedup (rest seqq)))) seqq))

5:23 clojurebot: #'sandbox/dedup

5:24 TEttinger: ,(dedup [1 1 2 2 3 3 3 2 3 ])

5:24 clojurebot: (1 2 3 2 3)

5:26 Seylerius: Lol. That's all I needed: to remove a set of parens.

5:32 * TEttinger grins

5:32 TEttinger: I think that might be handled better with reduce than recursion

5:32 ,(defn dedup [seqq] (if (not (empty? seqq)) (if (= (first seqq) (second seqq)) (dedup (rest seqq)) (concat [(first seqq)] (dedup (rest seqq)))) seqq))

5:33 oddcully: the curse of the lispaneer... to few or to many

5:33 clojurebot: #'sandbox/dedup

5:33 TEttinger: ,(apply dedup (range 1000))

5:33 clojurebot: #error{:cause "Wrong number of args (21) passed to: sandbox/dedup", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (21) passed to: sandbox/dedup", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 140] [clojure.lang.AFn applyToHelper "AFn.java" 403] [clojure.lang.AFn applyTo "AFn.ja...

5:33 TEttinger: ,(dedup (range 1000))

5:33 clojurebot: (0 1 2 3 4 ...)

5:33 TEttinger: aw

5:33 ,(dedup (repeat 1000 1))

5:33 clojurebot: (1)

5:34 TEttinger: ,(dedup (repeat 100000 1))

5:34 clojurebot: #error{:cause nil, :via [{:type java.lang.StackOverflowError, :message nil, :at [clojure.core$repeat$fn__4585 <init> "core.clj" 2865]}], :trace [[clojure.core$repeat$fn__4585 <init> "core.clj" 2865] [clojure.core$repeat invoke "core.clj" 2861] [clojure.core$repeat$fn__4585 invoke "core.clj" 2865] [clojure.lang.LazySeq sval "LazySeq.java" 40] [clojure.lang.LazySeq seq "LazySeq.java" 49] ...]}

5:34 TEttinger: there we gi

5:34 go

5:36 deadghost: so for clojure web security there's friend and buddy

5:36 luminus uses buddy

5:37 does anyone have any opinions on these before I blindly pick one

5:38 TEttinger: ,(defn dedup2 [coll] (if (seq coll) (reduce #(if (= %2 (last %1)) %1 (conj %1 %2)) coll)))

5:38 clojurebot: #'sandbox/dedup2

5:38 TEttinger: ,(dedup2 [1 2 3 1 1 1 1 1 2 2 2 3 2 3 2 2])

5:38 clojurebot: #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.lang.RT next "RT.java" 647] [clojure.core$next__4063 invoke "core.clj" 64] [cloj...

5:39 Glenjamin: ,(defn distinct-consequtive [sequence] (map first (partition-by identity sequence))) ; nicked from http://clojuredocs.org/clojure.core/distinct

5:39 clojurebot: #'sandbox/distinct-consequtive

5:39 TEttinger: ah, that's better Glenjamin

5:40 Glenjamin: i take no credit

5:41 TEttinger: ,(defn dedup2 [coll] (if (seq coll) (reduce #(if (= %2 (last %1)) %1 (conj %1 %2)) [(first coll)] (rest coll))))

5:41 clojurebot: #'sandbox/dedup2

5:41 TEttinger: ,(dedup2 [1 2 3 1 1 1 1 1 2 2 2 3 2 3 2 2])

5:41 clojurebot: [1 2 3 1 2 ...]

5:41 TEttinger: ,(dedup2 (repeat 100000 1))

5:41 clojurebot: [1]

5:41 TEttinger: yessss

5:42 ,(distinct-consequtive (repeat 100000 1))

5:42 clojurebot: (1)

5:46 ordnungswidrig: ,(distinct-consequtive [1 1 2 2 1 nil nil false false true true])

5:46 clojurebot: #error{:cause "Unable to resolve symbol: distinct-consequtive in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: distinct-consequtive in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: di...

5:47 Glenjamin: sounds like the repl reset

5:47 ,(defn distinct-consequtive [sequence] (map first (partition-by identity sequence))) ; nicked from http://clojuredocs.org/clojure.core/distinct

5:47 clojurebot: #'sandbox/distinct-consequtive

5:47 ordnungswidrig: ,(defn distinct-consequtive [sequence] (map first (partition-by identity sequence)))

5:47 clojurebot: #'sandbox/distinct-consequtive

5:47 ordnungswidrig: ,(distinct-consequtive [1 1 2 2 1 nil nil false false true true])

5:47 clojurebot: (1 2 1 nil false ...)

5:47 TEttinger: huh, it did it with a " ," at the start

6:31 patrkris: hello. I have a project with a src directory, and within it, I have a user.clj file used in the REPL. how do I exclude this file completely when running lein jar/uberjar? maybe I shouldn't even place the file in my src directory?

6:32 justin_smith: patrkris: :uberjar-exclusions maybe?

6:32 patrkris: you can always have a different :source-paths for dev profile, and keep user.clj in a different directory, yeah

6:33 patrkris: justin_smith: ah yeah, of course. I will move user.clj somewhere else. thanks

6:33 justin_smith: patrkris: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L388 - it looks like you can exclude it by regex too, but I think a separate dir is cleaner, yeah

6:34 patrkris: justin_smith: I triede skipping by regex, and it does exclude the file from the jar, but still compiles the namespace and adds the resulting class file

6:35 justin_smith: ahh, you may need to exclude the class too, or of course just use separate paths, that's cleaner anyway

6:38 patrkris: yeah, separate paths it is

6:38 :)

6:38 thanks again

7:14 dysfun: why are all the line numbers on compile errors off by a few lines?

7:15 in this case, it complained about line 65 when it meant line 71

7:17 justin_smith: dysfun: is it complaining about your original file, or one of those /tmp/form-init... things/

7:25 dysfun: my original file

7:25 it's when the files get loaded by autotest

7:33 is there a workaround to be able to assign metadata to a keyword?

7:34 i need a sentinel value and it seemed like a sensible option, but i also need to pass metadata

7:35 current option seems like defining a type, but not keen on that

7:35 justin_smith: dysfun: anonymous var? an atom holding the keyword as its value?

7:36 dysfun: atom i was considering too

7:36 sod it, i'll use an atom

7:38 justin_smith: also, the atom itself can be the sentinal (checked by equality) and instead of metadata, it can actually hold the data

7:39 dysfun: what are the rules for equality of atoms, then? ref matching?

7:39 justin_smith: identity

7:39 ,(= (atom 1) (atom 1))

7:39 clojurebot: false

7:39 justin_smith: that's why it's useful as a sentinal that holds a value

7:39 dysfun: ,(let [a (atom 1)] (= a a))

7:39 clojurebot: true

7:40 dysfun: cool. thanks

7:43 ugh. i'm going to have to shove this into the dynamic binding hackery i'm doing with other stuff in order to make it safe to use several at once

7:56 noncom: hi,l anyone familiar with clj-http here?

7:57 justin_smith: I use it.

7:57 noncom: i am trying to port a http request from curl to clj-http and not getting much success with it..

7:57 justin_smith: any particular aspect?

7:57 noncom: look here http://support.hockeyapp.net/kb/api/api-apps the one at the bottom of the Upload App section

7:57 the error in the response is "415 Unsupported Media Type"

7:59 justin_smith: I assume the @ is special, and tells curl to provide the file?

8:00 noncom: yes

8:00 here is what i send: https://www.refheap.com/98864

8:01 justin_smith: doesn't it need the zip too?

8:02 I'm guessing the error is more about the data that API expects

8:02 noncom: the dsym.zip? no, it is optional..

8:02 justin_smith: oh, OK

8:02 noncom: yes, the error with the data type.. i just don't know how to make it the correct data type i think..

8:02 do i link the file correctly at all?

8:03 justin_smith: yes, that is how it should be provided

8:03 though io/file will totally let you reference a non-existent file

8:03 (in case you wanted to write / create it)

8:03 oh wait

8:03 the file has to go in :multi-part

8:04 noncom: search for "file" down from this link https://github.com/dakrone/clj-http#usage

8:05 so :multi-part is a separate heading, alongside :form-params

8:05 noncom: ah..

8:05 with :name "ipa" i guess..

8:06 justin_smith: yeah, I think so

8:06 one great thing about clj-http is the examples are pretty comprehensive

8:07 noncom: but you see, i am not a great expert in http..

8:07 i know it is simple, but still cen't get used to the multipart things..

8:08 justin_smith: yeah, multipart trips me up too

8:08 though I also don't need it very often

8:09 noncom: that's the problem :) i use them once a year, and each time is like the fist time

8:09 f3ew: What are the currently recommended books for clojure?

8:09 justin_smith: ~books

8:09 clojurebot: books is programming clojure

8:09 justin_smith: there are more

8:09 ~books

8:09 clojurebot: books is programming clojure

8:10 justin_smith: sometimes I really don't like the factoid system

8:10 noncom: yeah :)

8:10 f3ew: justin_smith: I'll take the one, as long as it's reasonably good

8:10 justin_smith: yeah

8:11 that's probably the best beginner one, it's the one from o'reilly

8:11 there are also some decent online intros, clojure for the brave and true, and aphyr's clojure from the ground up series

8:13 f3ew: Yeah, I'm learning Clojure for Riemann

8:13 Ricardo-Arges: Can anyone comment on if liberator is still acive?

8:13 f3ew: and I'm missing the ability to just push a print statement in for debugging

8:15 justin_smith: f3ew: oh yeah, that's from aphyr isn't it

8:15 dysfun: can i get an anonymous dynamic var?

8:16 justin_smith: dysfun: that's what with-local-vars does, kind of, but then everything needs to be inside its body

8:16 dysfun: yes, that's not possible

8:17 i don't need mutability, i just need dynamic scope

8:17 and the ability to hold metadata

8:17 otherwise i'm going to have to rewrite all my code to pass around a context object and it was nice and clean...

8:18 hyPiRion: What's the point of an anonymous var then? How do you think you could reference it?

8:18 dysfun: Ricardo-Arges: yes, it seems to be quite active

8:18 well ideally i'd like to create a lexical with dynamic scope heh

8:18 Ricardo-Arges: Thanks dysfun. Was looking at the repo but most of the activity seemed to be on the documentation branch. Lots of unmerged, uncommented pull requests.

8:18 So I was wondering.

8:19 dysfun: there seem to be lots of users too

8:19 f3ew: justin_smith: yes

8:20 Ricardo-Arges: Probably yogthos' fault. At least I heard of it initially from his book.

8:21 * f3ew hates on null pointer exceptions

8:22 justin_smith: f3ew: I encourage learning some clojure, but it can also be helpful to use a profiler to see exactly what's happening when the error occurs

8:25 f3ew: I would prefer to know what I'm doing before using tools though :)

8:25 justin_smith: yup, fair enough :)

8:25 f3ew: I'm cargo culting stuff at the moment, and I don't like that :)

8:26 noncom: justin_smith: tried making multipart - still the same error: "415 Unsupported Media Type"

8:27 justin_smith: f3ew: fwiw, clojure has a repl that can bootstrap quickly from cargo cult stuff if you use it right. Break things down into the innermost forms, try variations on them to see if the things you expect to work, do, and the things you expect to fail, fail.

8:27 it can be very informative

8:30 noncom: that's odd - do you need to provide a content-type or content-disposition or anything?

8:32 noncom: probably.. i just dont know what does curl put there..

8:32 what content type..

8:33 justin_smith: noncom: that's probably not it at all

8:40 noncom: uhh.. maybe i am dense, but i really feel like http is coming from the past century

8:41 justin_smith: noncom: what I would do next is make a simple http endpoint that allows file upload, and verify it works from a browser, and then make it work from clj-http

8:41 it's a bit roundabout, but that eliminates a point of failure

8:41 and it's easier when you can debug from both ends

8:43 f3ew: noncom: it is :)

8:44 noncom: yeah, well, will then be hunting the actual request-response things.. try to figure out what it should be. curls has a -verbose key, so it will be of aid too...

8:46 justin_smith: noncom: there is also tcpdump, you could compare dumped post requests coming from your own code vs. curl

8:49 jonathanj: where could i ask questions about gloss?

8:49 justin_smith: jonathanj: ztellman is known to hang out here from time to time, and there are definitely people here who use gloss

8:49 $seen ztellman

8:50 lazybot: ztellman was last seen quittingQuit: ["Textual IRC Client: www.textualapp.com"] 2 weeks and 2 days ago.

8:50 justin_smith: oh, it's been that long!

8:51 ane: woot, the cider clj-debugger is making leaps

8:58 jonathanj: does gloss have any kind of validation/assert stuff built into it that i can't seem to find in the documentation?

9:00 for example, specifying an upper limit on a length-prefixed value

9:06 acron^: how do I reference a public field on a class in Java?

9:06 (StringEncoder. CharsetUtil.UTF_8) gives me "class not found: CharsetUtil.UTF_8"

9:07 UTF_8 is just a static field on CharsetUtil

9:11 Got it....

9:11 CharsetUtil/UTF_8

9:11 it's that easy

9:46 J_Arcane: omg i am so dumb. I spent nearly the last two hours to come up with this, when a simple zip map of tails and inits does the same thing: https://www.refheap.com/98870

9:49 jonathanj: there's not a gloss mailing list is there? (i couldn't find one)

9:50 should i just post to the clojure mailing list with my gloss question?

9:55 pkug: is there a shorter way to filter out the subsequences of length < 2, than doing a filter with #() macro comparing 'count' ?

9:56 noncom: jonathanj: you can also try to pm zach

9:56 like on github

9:56 i did this once

9:57 pkug: i can't think of any//

10:05 jonathanj: you could (ab)use `second` as your pred

10:06 ,(filter second [[] [1] [1 2] [1 2 3]])

10:06 clojurebot: ([1 2] [1 2 3])

10:06 noncom: wow

10:06 jonathanj: of course that's prone to being wrong:

10:07 ,(filter second [[] [1] [1 nil] [1 2 3]])

10:07 clojurebot: ([1 2 3])

10:07 hyPiRion: yeah, that's not good

10:07 ,(filter nnext [[] [1] [1 nil] [1 2 3]])

10:07 clojurebot: ([1 2 3])

10:08 pkug: Can somebody take a look and give me some feedback/critics on the style and code https://gist.github.com/pkug/ebf4e31e470a53c48ef4 ? it's my solution to https://www.4clojure.com/problem/53

10:08 hyPiRion: ,(filter next [[] [1] [1 nil] [1 2 3]]) ;; this should work?

10:08 clojurebot: ([1 nil] [1 2 3])

10:08 noncom: pkug: use ->

10:09 or i mean ->>

10:09 pkug: is it possible to automatically convert to that style?

10:12 noncom: not sure.. i know of no automatic means for that

10:13 pkug: also, if you're not after a one-liner specifically, probably a let statement with named steps would help.. but that is more a question of style than correctness

10:18 jonathanj: is there something that lets me (map) over a map but only transform the values?

10:19 there's map-vals in the plumbing library i think?

10:19 the-kenny: (zipmap (keys m) (map ... (vals m)))

10:42 jonathanj: is cider still the way to go for clojuring in my emacs?

10:42 ane: yes

10:44 mpenet: the-kenny: while this works on the current version, there is no guarantee that keys and vals return the same order

10:44 sobel: so, i want a vector, but (conj nil ...) produces a list. i hacked it with (conj [] ...). is this gross, is there a much better way?

10:45 the-kenny: mpenet: I know

10:45 mpenet: I'd rather use reduce-kv

10:45 it's probably faster too

10:47 Glenjamin: i tend to use either reduce-kv or (into {} (for

10:48 hyPiRion: mpenet: there's a guarantee on that actually

10:48 rhickey verified it in a Jira issue some months ago

10:49 mpenet: oh really?

10:50 kungi: Does lein uberjar porform clean befora a build?

10:50 mpenet: ah yes, kinda new CLJ-1302

10:50 Morgawr: Has anybody else experienced massive memory leaks (or what I assume are memory leaks) in very long lasting lein cljs autobuild processes (or clojure repls in general)? I'm not sure if it's because I suspend a lot of times across multiple days with my laptop, but I've had this happen so many times

10:51 I usually keep a repl open and a lein cljsbuild auto running 24/7 because it's faster than closing/opening them when I am working

10:51 and after a day I see that together they are consuming around 4-5GB of ram

10:51 even if I am not using them at all

10:51 I have to kill them and restart them and then they go back to using whatever normal (or what I consider to be normal) ram usage

10:52 I've tried looking around for bug reports or other people mentioning it but I couldn't find much, I'm curious to see if I'm the only one that experienced something like this

10:53 gfredericks: if a ring response is associated with resources that need to be cleaned up after the response is done, is there any reason I can't just make a wrapped InputStream that does cleanup on .close?

10:53 I feel like there was something about this that didn't work but I can't remember what

10:53 the-kenny: gfredericks: I did that for a project

10:53 (to delete temporary-files)

10:54 Morgawr: sobel: (into [] ...) will make sure to return a vector

10:55 gfredericks: hmm

11:01 idnar: I think (vec ...) is a better spelling of that?

11:04 Morgawr: idnar: I was under the impression that it's more idiomatic to use (into <collection> ...) because it're more 'standardized' across different collection types, but speed-wise I'm not sure which one is faster and which one is not

11:04 ,(time (into [] (take 10000 (repeat 1))))

11:04 clojurebot: "Elapsed time: 486.975998 msecs"\n[1 1 1 1 1 ...]

11:04 Morgawr: ,(time (vec (take 10000 (repeat 1))))

11:04 clojurebot: "Elapsed time: 303.064245 msecs"\n[1 1 1 1 1 ...]

11:04 Morgawr: Well there you go :)

11:04 the-kenny: Microbenchmarks don't say anything.

11:04 Morgawr: I know :P

11:05 it was just my curiosity

11:05 idnar: heh

11:08 sobel: vec it is

11:09 idnar: ,(time (take 10000 (repeat 1)))

11:09 clojurebot: "Elapsed time: 0.050243 msecs"\n(1 1 1 1 1 ...)

11:09 idnar: ah

11:11 so I think one "nice" thing is that if you pass a Java array to vec, it'll just alias it instead of copying it (but that's not so nice if you modify the array later)

11:27 irctc__: hi all, question, why does (with-meta list {:a 1}) blow up my repl?

11:39 {blake}: irctc__: I get "UnsupportedOperationException".

11:40 Bronsa: irctc__: attaching metadata to function objects is not a good idea. `list` is not implemented like a normal function for bootstrapping purposes

11:42 susej: advice please if clojure is a good first programming language for a 40 year old noob?

11:56 oddcully: susej: what other languages are in your selection?

11:59 susej: oddcully: I tried python and ruby, but after i followed a very short tutorial, clojure made more sense to me. I know html/css and the very basics of javascript.

12:01 nullptr: susej: you might consider clojurescript, through which can leverage the javascript knowledge you've already gained

12:02 patrickgombert: susej: there is a language called scheme which is used in a book called Structure And Interpretation Of Computer Programs. I’d recommend installing scheme and going through the book if you’re up for it.

12:02 but scheme is a lisp dialect so if clojure makes sense then scheme will make sense as well :)

12:02 susej: nullptr: but don't I need to know clojure to start playing with clojurescript?

12:04 patrickgombert: I would go through the book if it cement my knowledge

12:06 nullptr: susej: no, much of the language is the same, so if you become proficient with one the other should feel quite natural

12:07 the major differences are in the things you interact with outside the language (javascript vs. jvm)

12:08 noncom: i have not revisited clojurescript for a long time already.. and i am wondering, is it still a common case, when you get errors, they are shown in the autogenerated javascript and you have to deal with the headache to projecting them on the cljs source?

12:08 or are there sourcemaps already and good debugging?

12:09 in other words, can i forget about js when in cljs, like i forget about js when in coffeescreept?

12:09 Jaood: there are sourcemaps

12:10 susej: I would suggest http://www.ccs.neu.edu/home/matthias/HtDP2e/Draft/index.html, then you can move to clojure if you really wish, it would be easy

12:10 noncom: and the second question - is there still a penalty of having to download many kilobytes of cljs interpreter on every cljs-enabled page?

12:13 susej: Jaood: Thank you.

12:16 nullptr: noncom: source maps have improved dramatically. there is no such thing as a cljs interpreter -- cljs compiles to javascript and is interpreted as such. using {:optimizations :advanced} causes the base bits of cljs (like persistent collections) to be represented very efficiently, so that isn't a practical concern.

12:17 nuwanda_: nullptr: I wouldn't say it isn't a practical concern, if js size is a huge concern then cljs will likely be a problem. I agree in the vast majority of cases it's a non-issue.

12:18 susej: Jaood: Is clojure that that book teaches?

12:19 nullptr: nuwanda_: for all but the most trivial applications (vanilla js, no dependencies at all), the benefits of advanced compilation (especially with the new modules capability) outweigh the cost that cljs adds to the base

12:19 nuwanda_: nullptr: sure, I agree

12:21 nullptr: i just built a cljs app that prints 'hi' to the js console, with advanced compilation it's 1,435 bytes

12:21 Jaood: susej: no, it uses Racket, which is also a lisp, but the important point is that the book will teach you much more than just learning the syntax and semantics of some language, transitioning to Clojure after going through that book is trivial.

12:23 susej: one thing that can may hold you down in Clojure is the Java baggage

12:28 susej: Jaood: I plan to learn clojure then clojurescript to build web apps. I "know" that clojure runs on JVM, but I have faith that ĩ will get the hang of that eventually.

12:30 je: how can I tell the Java environment that my Clojure function can throw a specific exception (so the Java IDE knows)?

12:34 justin_smith: je: we don't do checked exceptions - is it just a preference thing that you want to declare it?

12:36 je: justin_smith: I'm writing a lib in Clojure and I am pretty sure that my Java colleagues will ask why their IDE doesn't tell them that this function can throw an exception... thats the problem I'm trying to solve? Was that an answer to your question?

12:37 in Java I think one would write something like: public void myMethod() throws Exception {}

12:37 justin_smith: je: OK, yeah. I don't even know how you would declare a checked exception from Clojure, and now that I think of it I have never seen this question before even. I'm sure there is some way to do it.

12:38 unless it's the case that it would require some byte code emitting that Clojure isn't at all set up to do

12:38 je: yeah, the problem is that clojure doesn't compile to java, it compiles to byte code

12:38 so knowing the java syntax doesn't really help much

12:38 hyPiRion: Oh, bypassing sneakyThrow? Not sure that's possible actually.

12:39 or the compiled variant thereof

12:39 je: justing_smith: just wrote the Java code to make my question more clear

12:39 justin_smith: hyPiRion: oh, clojure uses a hacked variant of throw to avoid the checked exceptions?

12:39 Glenjamin: do java people still use checked exceptions?

12:39 justin_smith: je: oh, yeah, that makes sense, sure

12:39 Glenjamin: i thought that had fallen out of favour

12:39 justin_smith: Glenjamin: I guess some people expect it

12:40 hyPiRion: justin_smith: the java parts of Clojure

12:40 justin_smith: hyPiRion: ahh, OK

12:41 hyPiRion: justin_smith: https://github.com/clojure/clojure/blob/433ff95e237d0ec2bbd8b872b997b69a2b3cca81/src/jvm/clojure/lang/Util.java#L228-L245

12:43 je: so I guess the conclusion is that it isn't possible, but thanks for the quick reply :-)

12:45 justin_smith: je: there might be a way to do it

12:46 it's a rarely asked question

12:47 je: justin_smith: uhh interesting

12:48 BinaryResult: just a reminder, Disco Melee is hiring clojure devs https://docs.google.com/document/d/1GvnrSCUbYgbY9XdFs_DUx-0QZG2bIYT8Mbr0zdpTeew/edit?usp=sharing

12:50 justin_smith: je: what hyPiRion pointed out prevents clojure's java code from using checked exceptions, but that doesn't mean one couldn't hypothetically make the compiler emit one... That's my take at least.

12:55 je: justin_smith: I think this is currently a bit out of my league, I'll live without for now but thanks for your time

12:56 patrickgombert: My understanding is that checked exceptions don’t make it to bytecode, so there can’t be checked exceptions in whatever clojure emits

12:56 they’re a java construct not a jvm construct

12:56 also, I could be totally wrong

12:56 nullptr: if your java colleagues are expecting/wanting checked exception, clojure adoption might be a bit of an ... umm ... uphill battle

13:02 N8Dawg: @Bronsa there are reasons you'd want to add metadata to functions, what if i want the function form attached to the function?

13:03 Bronsa: N8Dawg: not saying one shouldn't do it -- just that it's generally not a good idea. Usually better to attach that metadata to the var instead

13:05 patrickgombert: it's actually possible to compile the checked exceptions in the method signature of the emitted bytecode, it's just that the vm verifier ignores it

13:06 patrickgombert: Bronsa: is that the default?

13:06 or is it just for IDEs and such to make sense of it

13:08 Bronsa: patrickgombert: I believe it's there for tools/javac (like the vararg attribute)

13:38 http://i.imgur.com/m5nAEoH.png seeing this makes me sad

13:39 Glenjamin: it possibly reflects an increase in userbase

13:39 that that's one positive

13:39 justin_smith: Bronsa: maybe that's a sign of how ambitious 1.7 has been?

13:42 mpenet: It's 1.6 birthday the day after tomorrow!

13:44 Bronsa: tons of tickets are waiting with patches tho, the whole process (triage, vetting, etc) takes a long time

13:44 and probably too few people hold the reins

13:45 Bronsa: mpenet: I know that too well, unfortunately

13:45 Glenjamin: from the outside it sometimes looks like the process is designed to deter contribution

13:45 mpenet: it's demotivating yeah

13:47 hiredman: the whole thing is some kind of negative spiral, you don't want to release with outstanding issues, so you invest a lot of time fixing issues so you can make a release, and the more time you spend fixing issues the more time there is for new issues to be opened

13:47 mpenet: and some tickets in limbo have some very nice patches ready

13:48 ex the work from ztellman on collections

13:48 hiredman: the perfect is the enemy of my friend's bridges

13:48 mpenet: hiredman: true

13:48 I am all for short release cycles personnally

13:50 hiredman: ztellman's collection work is a great example, this is good stuff that was defered because the 1.7 release will happen real soon now

13:51 mpenet: funny that we're reaching the 1 year mark now

13:51 given the comments on this ticket

13:51 hiredman: and, like, we are getting a socket repl in core

13:52 mpenet: :]

13:55 actually 1.6 release date was exactly 1 year ago! not a few days off

13:55 anyway...

14:00 hiredman: I have a patch from july of last year, which had the fix version moved from 1.7 to 1.8 in october

14:05 the comments on ztellman's patch for holding off till the 1.8 release are something like "we've decided to hold off on anything not entirely baked for 1.7" but then months later the socket repl stuff hits jira apparently out of the blue

14:06 with, as far as I know, no design discussion in the wiki

14:11 wagjo: fyi Dunaj has incorporated ztellman's tuples into the core

14:11 hiredman: which is not to say that design discussion didn't happen, it must have, but it happened behind a door somewhere, so of course the first reaction to it is wtf

14:13 wagjo: http://www.dunaj.org/dunaj.coll.tuple.api.html

14:14 Bronsa: wagjo: afaik the proposal in the clj jira is about making those tuples an optimization over persistentvector rather than just adding as another available collection

14:14 hiredman: (and specifically for socket repl, "what about nrepl?")

14:15 Bronsa: wagjo: does dunaj implement it this way?

14:15 wagjo: Bronsa: I know, tuples are used heavily internally in Dunaj to improve performance

14:16 Bronsa: nice

14:16 wagjo: in Dunaj, (class (vec [1 2 3])) returns dunaj.coll.tuple.Tuple3

14:16 I left [] literal a persistent vector for backwards compatibility, but otherwise tuples are used whenever possible

14:17 justin_smith: wagjo: oh, that's your project? cool stuff. I've been impressed by all the things I have seen so far.

14:17 wagjo: (class (first {:foo 1 :bar 2}))

14:17 returns tuple too

14:17 Bronsa: wagjo: I believe the proposal is to make [] literals use tuples aswell

14:18 wagjo: justin_smith: thank you

14:18 Bronsa: just like {} literals use PAMS

14:18 wagjo: Bronsa: I hope they will get incorporated into Clojure too, but for now I left [] literals intact in Dunaj

14:19 hiredman: http://dev.clojure.org/jira/browse/CLJ-1610

14:19 (speaking of maps)

14:19 wagjo: Zach has a proposal for 'associative tuple' too

14:19 I haven't included in in Dunaj though

14:19 mpenet: yes in jira he's talking about other collection types as well

14:19 wagjo: hiredman: exactly :)

14:20 mpenet: -> Voted (15)

14:25 bacon1989: is there a broader article on Dunaj? I don't really see the reasons for it

14:25 wagjo: bacon1989: see http://www.dunaj.org/rationale.html

14:26 arrdem: Idle idea, has anyone looked at the socket REPL patches to see if they have to be in core for some reason?

14:27 bacon1989: I see, but all I see are the shortfalls involved in fragmenting away from the clojure.core

14:34 wagjo: bacon1989: I agree that there are shortcomings, but in my opinion benefits outweighted them.

14:35 bacon1989: Rich stated in 2012 that we need reducible I/O sources and so far nobody released something usable.

14:37 bacon1989: some things cannot be done gradually through patches as they are hard to evaluate until they are done completely

14:38 bacon1989: and how else can you evaluate a synergistic effect if not through a Clojure fork?

14:50 justin_smith: arrdem: my totally naive hunch is that since clojure is at its heart truly a repl, there are core changes that would make it more elegant, even if the feature itself could be outside core

14:56 bacon1989: wagjo: good point, I can see it as a good prototype maybe. It suggests there will be backwards compatibility with existing code.

14:57 Not that I wouldn't use it, if it became the new standard

14:57 justin_smith: maybe it could end up being like the arch / debian split - one which gets features first, the other rarely if ever breaks

14:58 wagjo: bacon1989: there already is backwards compatibility, All described in Dunaj is already implemented, and is nearly feature complete

15:11 sobel: hmm. clojure is already a small enough branch in the broader java ecosystem. not sure i'd want to venture even farther off the beaten path.

15:17 xemdetia: dunaj.org is marked as suspicious by my stuff lol

15:18 sobel: heh

15:46 mikerod: In a profiler if I see clojure.lang.Compiler.access$100 - what is this?

15:46 I get that $100 part means it is probably some anonymous inner class. I don't get what the "access" part is I don't think

15:49 Bronsa: mikerod: that's javac magic for accessing private fields of outer clases from inner classes

15:52 hiredman: if you are profiling and seeing bits from the compiler in your profile, that would be a red flag for me that I was profiling incorrectly

15:54 justin_smith: or, a sign that you can likely fix your performance issue by not using eval

15:54 puredanger: hiredman et al, re the discussion a couple hrs ago on jira and planning decisions. decisions are made every week on this stuff - sometimes decisions are made with one expectation of near-term events and then things change. It is thus inevitable that decisions made at one point in time are at odds with decisions made at other points in time.

15:54 hiredman: I would generally be profiling the sort of steady state of the app, while compilation happens at the start (unless you are calling eval all over the place)

15:55 puredanger: no one is more acutely aware of the status of the issues in jira and the timeline of the releases than me

15:57 and it is simply incorrect that there are zillions of patches just "ready to commit". look at the many revisions of any patch that goes into the release to see that that isn't true.

15:58 joshhartigan: is there a way for me to mute the 'welcome message' of `lein repl`

15:59 gfredericks: I think lein repl-options has that

15:59 (the project.clj key)

16:00 joshhartigan: thank you

16:00 puredanger: re the tuples thing in particular, I sat down with Zach at the Conj and we did a surface review of his patch and found a half dozen things that needed to be changed plus there is some integration work that is not addressed in the patch at all. it's great stuff and I look forward to integrating it. I wish it was in now, but adding that to the release would not have sped anything up.

16:01 hiredman: puredanger: sure, thank you for your hardwork, I am not questioning that, I am sort of as a step back at the meta level, the way things are done from my perspective seems to result in a number of undesirable properties, regardless of the high quality way it is done

16:02 puredanger: if the issue is getting smaller things into the release stream faster, then I think that's a reasonable complaint

16:03 I don't actually think most companies or projects integrate major releases more than twice / year. I personally would like to be doing 2 per year. Or 1 big / 1 small per year.

16:05 hiredman: puredanger: have you guys considered declaring some kind of feature freeze in preparation for a release? sometimes it seems like that is the intent behind decisions on some patches, but then new features land anyway

16:06 wagjo: beta release is a feature freeze AFAIK

16:06 puredanger: well like I said, things change sometimes

16:06 generally once we go beta, we do not add new new features

16:08 hiredman: it just seems like the longer it takes to cut 1.7, the more ideas / features / bugs / etc will be reported, and if that work in turn effects the scope of 1.7 …

16:09 puredanger: welcome to my life :)

16:10 but you need to flip perspective and ask whether we are continuing to build a great language with high quality and most needed things fixed

16:10 while there is an insatiable desire for more, I think we are

16:10 wagjo: it seems to me that outstanding issues with transducers (e.g. transformation to lazy seqs) are what keeps 1.7 from releasing

16:11 puredanger: I think reader conditionals has been more of a long pole than that

16:11 wagjo: well yeah, I'm actually surprised that the decision has been made so soon :)

16:13 puredanger: not having feature expressions / reader conditionals ready was the major thing that delayed a beta and feature freeze

16:13 wagjo: puredanger: you guys are doing a great work. The quality of releases wrt the backwards support for existing code is amazing

16:14 puredanger: it's important, and hard.

16:14 gfredericks: puredanger: I am curious about what the most regretted features/details are from that perspective

16:15 puredanger: not sure what you mean

16:15 you mean things we'd change if we could?

16:15 gfredericks: things you would jump at the chance to remove if not for backward compatibility

16:15 puredanger: there's a zillion little things

16:16 gfredericks: I can never tell when looking at some old obscure feature if rich still thinks it's a good idea or not

16:16 hiredman: (changes.md has something like 19 bug fixes, all not in a release yet)

16:17 puredanger: some of the stuff I've been working on lately with 1603 and 1515 have really highlighted some murkiness around the contract of what a sequence function returns

16:17 I think it would be best if most sequence functions were seqable -> seqable

16:18 but many are effectively seqable -> seq which greatly increases the set of commitments on the return

16:19 anti-freeze: So, I'm trying to figure out why it takes > 5 minutes for lein repl to get started and visual VM is crashing on me while I'm profiling

16:19 Seems like something to do with sun.rmi.transport.tcp.TCPTransport

16:19 puredanger: anti-freeze: have you tried just taking thread dumps while it's starting? ctrl-\ on *nix or ctrl-break on win

16:20 justin_smith: there's also jstack

16:20 puredanger: yes, or jstack if multiple jvms involved

16:21 anti-freeze: Would you care to see the thread dump?

16:22 https://www.refheap.com/98885

16:22 sdegutis: Given a [1,2,7,9,8,5,1,0,1], what's a splendid way to return both how many items are odd and how many aren't in one fell swoop?

16:23 justin_smith: ,(map (comp count val) (group-by odd? [1,2,7,9,8,5,1,0,1]))

16:23 clojurebot: (6 3)

16:23 ordnungswidrig: nice

16:23 wagjo: puredanger: well the IReduceInit is a great step towards cleaning collection internals, hope you'll find a way to integrate it with existing contracts

16:23 sdegutis: Thanks justin_smith.

16:23 Bronsa: puredanger: dunno if I already asked you but – suppose I stumble upon a ticket that's obviously no longer relevant (no longer reproducible/things changed, e.g. clj-273 from today), is it ok for me to close it or should I just comment on it and let you or other screeners close it?

16:23 ordnungswidrig: justin_smith: but you cannot be sure on the order of the result

16:23 sdegutis: justin_smith: I was trying to figure out a way using juxt.

16:24 ordnungswidrig: ,(map (comp count val) (group-by odd? [2,1,7,9,8,5,1,0,1]))

16:24 clojurebot: (3 6)

16:24 sdegutis: But it didn't work out.

16:24 justin_smith: ordnungswidrig: oh, yeah :)

16:24 puredanger: wagjo: I think there is great regret on following CL re reduce vs reduce with initial value. hard to undo now though.

16:24 ordnungswidrig: ,(map (juxt (comp count val) key) (group-by odd? [1,2,7,9,8,5,1,0,1]))

16:24 clojurebot: ([6 true] [3 false])

16:24 justin_smith: sdegutis: ordnungswidrig has a good point

16:24 puredanger: Bronsa: I'd prefer to close it - what you did there was great

16:24 Bronsa: ok

16:24 sdegutis: ordnungswidrig: very true

16:25 puredanger: Bronsa: but even if you did, I would have checked it either way so it's not a huge deal

16:25 sdegutis: I was thinking something with (juxt filter remove) and count.

16:25 But meh.

16:26 justin_smith: ,(reduce (fn [[odd even] n] (if (odd? n) [(inc odd) even] [odd (inc even)]) [0,0] [1,2,7,9,8,5,1,0,1])

16:26 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

16:26 justin_smith: oops

16:26 ordnungswidrig: sdegutis: that would work but traverse the fn twice. I'm sure another way would be to use transducers ...

16:26 justin_smith: ,(reduce (fn [[odd even] n] (if (odd? n) [(inc odd) even] [odd (inc even)])) [0,0] [1,2,7,9,8,5,1,0,1])

16:26 clojurebot: [6 3]

16:26 sdegutis: Ah.

16:26 Oops, did I just nerd snipe?

16:26 justin_smith: that does less extra work than the others too

16:26 nerd snipe?

16:27 mikerod: Bronsa: thanks I should have considered that. inner class java magic of course makes sense now.

16:27 ordnungswidrig: ,(->> [1 2 7 9 8 5 1 0 1] (map odd?) frequencies)

16:27 clojurebot: {true 6, false 3}

16:28 ordnungswidrig: ,(->> [1 2 7 9 8 5 1 0 1] (map odd?) frequencies ((juxt [true false|)))

16:28 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

16:28 mikerod: hiredman: the issue is actually the Clojure compiler is hanging for very long times during a macro expansion for me

16:28 and only in some strange edge case that I'm trying to narrow down to

16:28 so I am needing to look closely at the Compiler's path it is taking in my profiling.

16:29 hiredman: I guess, or run screaming from the macro?

16:29 mikerod: And in reality, a lot of the time when I've worked with Clojure I've found paying close attention to the Compiler's stack to be useful - but that is because I've worked a lot in the world of macros and even sometimes - though rarer - eval

16:30 hiredman: the macro seems harmless and works most of the time though, so I just was shooting for an understanding

16:30 adding a type hint is the culprit :)

16:30 was hoping to at least understand if I'm hitting a compiler bug or something

16:30 hiredman: I guess?

16:30 mikerod: a type hint + cond->

16:30 very weird, hopefully I can recreate at some point

16:32 hiredman: I just, I dunno, in five years of writing clojure for work that hasn't come up for me, so it makes we wonder about why that could be, and I can only assume we have differing ideas of what a harmless macro is?

16:33 or just how much macros and eval are needed?

16:33 or I dunno

16:33 ordnungswidrig: hmm, I think macros might be overused in this case...

16:36 hiredman: on the other hand I suspect I have horrified many without using a macro or eval, so whatevs

16:37 puredanger: Bronsa (or anyone) - I'd love a simple test to repro the regression in http://dev.clojure.org/jira/browse/CLJ-1681 . It's not just a nil in the arg list - I think it's more subtle than that but I haven't had a chance yet to dig in.

16:39 ordnungswidrig: hiredman: :-)

16:39 mikerod: hiredman: I think I can agree with you that generally if I'm profiling for performance problems I shouldn't be analyzing Clojure compiler speed. So maybe I just misinterpreted your statement

16:39 If it is coming down to eval or macro expansion speed - clearly you're off the deep-end

16:40 idnar: I'm writing a defthingy type macro; in it, I see that ~name is something like #<Unbound Unbound: #'some-ns/some-name> which I guess is some kind of symbol thing

16:40 mikerod: what I'm observing is a macro that works fine

16:40 idnar: how do I get just "some-name" out of that?

16:40 mikerod: but occasionally it gets some input and the compiler hangs for thousands of seconds

16:40 it looks to be in an endless loop, but it terminates eventually

16:40 and removing a type-hint makes it fast again - but adds reflection warnings

16:40 Bronsa: puredanger: I have a repro case, I just need to find a method in the java stl to use

16:41 mikerod: or I can leave the type-hint aand alter the macro to not expand to a use of cond-> and it is fine.

16:41 So I'm just trying to narrow down to a reproducing simpler case and see if I'm hitting a compiler edge case, defect, bad macro etc.

16:41 puredanger: Bronsa: that was what I ran into as well. do you need multiple methods with same arity but differing types?

16:42 Bronsa: puredanger: yes, and I think i found one

16:43 hiredman: mikerod: that does sound interesting though

16:44 amalloy: mikerod: i imagine you can't share the macro definition?

16:44 Bronsa: ,*warn-on-reflection*

16:44 clojurebot: false

16:44 Bronsa: ,(set! *warn-on-reflection* true)

16:45 clojurebot: #error{:cause "Can't change/establish root binding of: *warn-on-reflection* with set", :via [{:type java.lang.IllegalStateException, :message "Can't change/establish root binding of: *warn-on-reflection* with set", :at [clojure.lang.Var set "Var.java" 221]}], :trace [[clojure.lang.Var set "Var.java" 221] [sandbox$eval47 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] ...

16:45 Bronsa: oh well

16:45 * puredanger saw that one coming

16:45 Bronsa: (defn f [a] (.divide 1M a nil)) is a repro case

16:45 mikerod: amalloy: trying to get a shareable version of it

16:46 puredanger: Bronsa: sounds good. would like a patch on there with a test and seemed like a ternary if could have simplified the change quite a bit.

16:49 Bronsa: puredanger: don't think a ternary would help -- that would make it x.foo? (x.bar() == null? "null" : x.bar().baz()) : "unknown"

16:49 puredanger: yeah, I guess there's 2 levels there

16:50 Bronsa: the if is also nice since we can avoid calling .getJavaClass() twice

16:51 puredanger: don't care - in a warning

16:51 Bronsa: oh, right

16:51 puredanger: what if it was ( (arg.hasJavaClass() && arg.getJavaClass() != null) ? arg.getJavaClass().getName() : "unknown" )

16:52 printing null for a type seems wrong to me

16:52 the instance is null, could be any type, so "unknown" seems fine

16:53 I'm just trying to get a super simple patch I can screen here

17:04 gfredericks: what's the correct way to make a reducible thing in 1.6?

17:04 I implemented clojure.core.protocols/CollReduce and that seemed to work

17:05 amalloy: gfredericks: i think that is the way

17:10 gfredericks: kthx

17:16 puredanger: that is a way

17:17 gfredericks: I tried implementing clojure.lang.Reduce but clojure.core/reduce did not respect that

17:17 puredanger: if it's a Java class that you can affect directly, extend IReduceInit or IReduce. otherwise extend CollReduce

17:18 gfredericks: you mean IReduce?

17:18 gfredericks: ,(reduce conj [] (reify clojure.lang.IReduce (reduce [_ f start] "TWELVE")))

17:18 clojurebot: "TWELVE"

17:18 gfredericks: hm

17:18 &(reduce conj [] (reify clojure.lang.IReduce (reduce [_ f start] "TWELVE")))

17:18 lazybot: ⇒ "TWELVE"

17:18 puredanger: there have been changes in reduce in alpha5 around this

17:18 gfredericks: &*clojure-version*

17:18 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

17:18 Bronsa: (inc puredanger)

17:18 lazybot: ⇒ 38

17:18 gfredericks: yeah on my 1.6 it fails

17:18 puredanger: but CollReduce is currently ambiguous in that it catches more than one interface and classes implementing multiple will go an arbitrary path

17:19 gfredericks: with not being able to create an ISeq

17:19 puredanger: in particular things that are IReduce, Iterable, and a seq are a bit of a muddle

17:20 I've talked to Rich about it a bit and we still might adjust some things there before 1.7 releases

17:21 Bronsa: puredanger: the special casing there is just to pick the fastest path right?

17:21 puredanger: right now reduce and transduce explicitly check for and use the IReduce paths if they exist before even hitting CollReduce

17:21 yeah, it's all trying to take care of these overlapping cases

17:22 this is the part of protocols and interface extension that requires some care

17:23 gfredericks: puredanger: I assume mixing CLJ-1237 would just make it too complicated?

17:24 puredanger: personally I'd like to have a preference mechanism for protocols like multimethods but Rich has said no to that for now at least

17:24 1237 is, I think, a consequence of various things

17:24 Bronsa: puredanger: that would be really nice, yeah

17:24 puredanger: in particular use of concat

17:25 gfredericks: sure

17:25 puredanger: ala Stuart's "concat bomb"

17:25 so just don't use concat :)

17:26 all of the examples in that ticket I would do in different ways now using into or cat transducers

17:26 gfredericks: ~concat is considered a cat

17:26 clojurebot: A nod, you know, is as good as a wink to a blind horse.

17:26 puredanger: clojurebot contains multitudes

17:27 gfredericks: yeah it's not hard to avoid once you know to avoid it

17:27 puredanger: if you find yourself ever doing "apply concat" then …. don't

17:28 wink: clojurebot highlights me a lot lately

17:28 puredanger: heh

17:28 Glenjamin: hrm, i did apply concat for something recently...

17:28 i think it was kwargs

17:28 gfredericks: puredanger: that's interesting you put it that way because the classic concat bomb is via "reduce concat" and "apply concat" fixes it

17:29 puredanger: well that would replace one with many

17:29 gfredericks: ,(->> (range 100000) (map list) (reduce concat) (first))

17:29 puredanger: I mean many with one

17:29 clojurebot: #error{:cause nil, :via [{:type java.lang.StackOverflowError, :message nil, :at [clojure.core$seq__4079 invoke "core.clj" 135]}], :trace [[clojure.core$seq__4079 invoke "core.clj" 135] [clojure.core$concat$fn__4166 invoke "core.clj" 689] [clojure.lang.LazySeq sval "LazySeq.java" 40] [clojure.lang.LazySeq seq "LazySeq.java" 49] [clojure.lang.RT seq "RT.java" 485] ...]}

17:29 gfredericks: ,(->> (range 100000) (map list) (apply concat) (first))

17:29 clojurebot: 0

17:29 puredanger: so I guess maybe that's not a good formulation

17:31 maybe: don't use concat such that it may be applied an arbitrary number of times?

17:31 hiredman: only be as lazy as you need to be

17:32 puredanger: or don't be recursively lazy ;)

17:32 Glenjamin: has anyone played much with the not-lazy-by-default dunaj stuff?

17:39 jdeisenberg: I am having problems installing the Cursive plugin with the latest IntelliJ community edition (14.1)

17:39 Or rather, it's installed, but I don't see its settings anywhere in the "settings" dialog.

17:40 surrealanalysis: I’m playing around with Overtone, but for some reason “kill” doesn’t seem to be loaded into the repl - is there anything I need to do to get it going? Right now I’m only :use-ing overtone.live and a sampled-piano

17:40 cfleming: jdeisenberg: They're under "Other settings" at the moment, I haven't updated them for the new v14 settings setup yet

17:42 jdeisenberg: I'm looking at Other settings/ default settings/ Tools -- nothing seems to be there.

17:45 zot: so i've just scraped together a quick hack interval tree built on sorted-set-by; it took some trial and error (ie, misunderstanding subseq). anybody care to give it a look, and see if I'm setting myself up for tears? https://gist.github.com/benfleis/6bafac50007625aebcef

17:46 wagjo: Glenjamin: have you? they may be a bit unintuitive to use as they no longer cache computed values

17:46 jdeisenberg: cfleming: Cursive does not show up under Other settings/configure plugis

17:46 Glenjamin: i haven't had a chance to try it out yet, only read some of the guides

17:47 sounds very interesting, it's great to see some experimentation around the core platform

17:49 jdeisenberg: cfleming: I uninstalled and reinstalled plugin from http://cursiveclojure.com/plugins-14.xml

17:52 gfredericks: I'm playing around with using CollReduce to represent the results of db queries

17:52 hiredman: ++

17:52 gfredericks: and I'm not sure which of the various reducey paradigms would apply

17:53 e.g., if I want to map the results

17:53 do I want the map transducer?

17:53 or some kind of function that takes the reducible and returns another reducible?

17:53 which is different from the transducer since that deals with reducing-functions instead of reducible quasicollections

17:53 hiredman: (which is clojure.core.reducers/map)

17:54 gfredericks: hiredman: does that do reducible->reducible without mucking with forkjoin?

17:54 hiredman: gfredericks: yes

17:54 gfredericks: (and is it "lazy" in the sense of not doing anything immediately?)

17:54 hiredman: forkjoin only happens if you call fold

17:54 gfredericks: yes

17:54 http://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html

17:54 gfredericks: this must be exactly what I want then

17:55 hiredman: thanks

17:56 hiredman: transducers are, I think, strictly better than reducers

17:56 cfleming: jdeisenberg: You need to change the plugin repo for v14.1: https://cursiveclojure.com/userguide/

17:56 wagjo: Glenjamin: thank you, I hope Dunaj's experiments will pave the way for feature enhancements in Clojure. Or at least show which way not to go :)

17:57 jdeisenberg: cfleming: Ah. missed the extra .1

17:57 hiredman: but transducers are more about composing collection operations in to a single operation than passing collections through it, which is a different headspace than you will be in from seqs

17:58 reducers can do the more familiar apply function, get a new result, apply another function, etc

17:59 gfredericks: hiredman: yeah I couldn't figure out a natural code structure to use with transducers

18:04 hiredman: I haven't used transducers in anger yet, but I have to think the style of build "super operations" could easily lead to sort of layering violations, so the right pattern might be transducer super ops within a "layer", and some abstract reducible thing (CollReduce, IReduceInit, etc) between or something

18:05 dnolen: Bronsa: did CLJ-1677 make into tools.reader?

18:06 Bronsa: https://github.com/clojure/clojure/commit/3d216d45b63781586bb79144268bb2fb88dd6f28

18:07 puredanger: hiredman: transducers do not currently a) work specially with kv stuff or b) do the parallel fold/reduce stuff

18:07 Bronsa: dnolen: no -- I don't think we need it. starting line/col can be changed by using the type ctors rather than the factory functions

18:07 hiredman: puredanger: right

18:07 puredanger: so transducers are not a superset of reducers capabilities or "strictly" better

18:07 yet

18:07 hiredman: puredanger: the lack of specialness around k/v stuff seems like a feature to me :)

18:08 puredanger: yes and no :)

18:08 the specialness avoids intermediate objects so …

18:09 dnolen: cfleming: ^ Bronsa's answer about CLJ-1677 might be interesting to you

18:09 Bronsa: dnolen: I'd take a patch if you need it though

18:09 dnolen: Bronsa: don't need it, but cfleming might

18:09 hiredman: https://github.com/aphyr/tesser is really neat if you are in to folds

18:09 cfleming: dnolen: Yeah, thanks - I'll have a go at using that

18:10 puredanger: hiredman: if use transduce or eduction, you'll get a reducible result which might be useful for the next application

18:10 hiredman: puredanger: ah

18:11 puredanger: but you are then explicitly materializing in that step

18:11 hiredman: that may be for the best

18:11 puredanger: in some cases, yes. depends.

19:35 warz: hi all. im new to both clojure and emacs. is there a way, in emacs, to bring up the defintion of a function? i realize this is likely difficult, since emacs just seems to operate on files and doesn't quite have a concept of a whole project, etc. (at least in my limited exposure)

19:35 like with compojure and ring, i find myself having several chrome tabs open for each project's repo on github, and im constantly going to each functions code

19:36 justin_smith: warz: with cider it's M-.

19:36 warz: also - here is a trick you can use: go to the top level of the project, and open not any file, but just the directory

19:37 then that will open the dired view

19:37 next, move the cursor to one of your folders, and type the letter "i"

19:37 that will show all files in that directory below the parent

19:42 warz: hrm, ok i dont think im using cider. i followed the tutorial here: http://www.braveclojure.com/basic-emacs/

19:43 im familiar with cider too, but i see no ref to it in this

19:43 maybe i should try using cider, since it seems to be more common

19:43 justin_smith: warz: OK, that's fine, the dired think should work

19:43 warz: cider can be a pain in the ass, it has great features, but it breaks a lot

19:46 warz: dired mode seems pretty powerful, nice

19:49 oh thats cool, that "i" command

19:49 SparkySparkyBoom: hiya folks

19:51 justin_smith: warz: also, in any emacs window, you can run "M-x describe-mode" to see all the key shortcuts

19:51 SparkySparkyBoom: is there anything like clojure's thread-first but for java methods that return void?

19:51 justin_smith: SparkySparkyBoom: maybe you want doto

19:51 or ..

19:51 SparkySparkyBoom: thank you

19:52 i just didn't want to repeat the instance variable while setting several internal vars

19:53 justin_smith: yeah, doto would be the one for that

19:55 elvis4526: Hello! Put bluntly, what is the difference between (use) and (require) ?

19:55 justin_smith: elvis4526: require is more more likely to lead to sanity.

19:55 hiredman: ~use

19:55 clojurebot: Only use :use with :only.

19:56 hiredman: well, that is outdated

19:56 justin_smith: they both modify the current namespace to make another namespace available (and load the other namespace if it hasn't been loaded yet)

19:56 hiredman: use is for all intents and purposes deprecated (I dunno if it is actually marked as such)

19:56 elvis4526: From what I understand, (:use compojure.route) "import" everything in compojure.route

19:57 from compojure.route (sorry)

19:57 justin_smith: exactly

19:57 elvis4526: What I wouldn't want this ?

19:57 justin_smith: well, import is its own thing (it's for classes), but that's the general idea

19:57 hiredman: importing everything like that makes it hard to figure out where parts of functionality come from

19:57 justin_smith: elvis4526: require is more selective, and if used properly (especially with the :as argument) leads to namespaces that are much easier to refactor

19:59 hiredman: it used to be require was to make sure another namespace was loaded, and use was to make the functionality from the other namespace available in the current one without having to namespace qualify the names

20:00 elvis4526: got it thanks

20:00 hiredman: and it proceeded that way for a time, and it was noticed that when using use, because it brought in everything, it made it annoying to read larger code bases, and some rough concensus was reached that require is superior

20:01 require was then enhanced so it now has all the functionality of use, but with better defaults

20:02 so require can :as, which lets you give a whole namespace a short alias, or :refer [...] which lets you bring in only selected bits, or :refer :all, which acts like use

20:03 require with :refer [...] is the same as the :only option for use that clojurebot mentioned

20:08 elvis4526: ty

20:09 Other question: Is there any rules concerning when it is "approriate" to close a sexp ?

20:09 wait i'll pastebin you something

20:09 justin_smith: elvis4526: as in formatting rules?

20:09 elvis4526: yeah

20:09 justin_smith: no dangling closing brackets

20:10 elvis4526: http://pastie.org/10053832#5

20:10 for instance at the end

20:10 is it okay if I close them all on the same line ?

20:10 justin_smith: all the close brackets should be on the same line as "js"

20:10 elvis4526: Oh really?

20:10 justin_smith: yeah

20:11 also, line 3 shouldn't be empty

20:11 that rule isn't as strict though

20:11 elvis4526: Later if I wanna add something after, let's say [:head

20:11 it's a lot easier when closing brackets are on seperate line

20:11 I can spot right away where to add it

20:11 justin_smith: elvis4526: hopefully your editor can handle such a complex operation

20:12 elvis4526: yeah I should definetly install paredit...

20:12 justin_smith: elvis4526: many of us use structured editing (eg. paredit)

20:12 yeah

20:21 ambrosebs: which version of asm is clojure.asm?

20:23 Bronsa: ambrosebs: 4.1

20:23 ambrosebs: and more importantly do I want to use it for bytecode manipulation?

20:23 Bronsa: ambrosebs: in clojure 1.7 at least

20:23 ambrosebs: I want to add a field to a existing classes

20:23 ok

20:26 hiredman: the version of asm in clojure, at least at one time, was a stripped down version

20:27 ambrosebs: right maybe I'll start out with the official asm jar instead

20:27 geol: Can someone please tell me how to define implement a protocol for anything which implements IMap

20:28 hiredman: what is IMap?

20:28 geol: map? uses (satisfies? IMap)

20:29 hiredman: not in clojure

20:29 you must be talking about clojurescript

20:29 geol: Interesting. I'm in CLJS land

20:29 * geol checks the sign on the door

20:30 geol: Should I be in another group?

20:30 hiredman: I dunno, people do ask cljs questions here

20:30 amalloy: geol: here is fine, but you should at least clarify when you are asking questions that aren't actually abotu clojure

20:30 justin_smith: geol: so, instead of using IMap you want to make another protocol that will be extended to IMap?

20:30 geol: yes, that's the idea

20:31 I'm writing a custom zipper and extend-type seems ugly

20:31 justin_smith: geol: in that case, make the protocol like usual, and then extend IMap to that protocol

20:31 geol: really! huh, thanks.

20:40 @justin_smith: mind looking at this please... I'm not having much luck. https://gist.github.com/olivergeorge/33cc516026bc57abd0bd

20:43 justin_smith: geol: you are using functions in there that IMap doesn't define

20:50 Bronsa: geol: you can't extend a protocol to a protocol

20:51 geol: @Bronsa: ah, that's what I was guessing. thanks.

20:51 @justin_smith: I think I had the IMap and IFieldZipper backwards... but I suspect also it's not possible. thanks for your help.

20:51 Bronsa: geol: also you don't need to use "@" when talking to somebody in IRC :)

20:52 geol: oops!

20:52 justin_smith: Bronsa: oops, I totally forgot about the not extending protocols to protocols thing

20:53 Bronsa: justin_smith: it's kind of unfortunate that we can't do that

20:53 justin_smith: geol: wouldn't it suffice to write your zipper function such that it calls the protocol methods in the protocols you are targeting?

20:55 geol: I think I understand. Effectively a switch statement on (map?) and (coll?)... yes, i think that works.

20:57 justin_smith: geol: you could even use a multimethod, which can be made to dispatch on class

20:57 geol: justin_smith: yes, I considered that. For now my (cond (map? x)...) approach is probably all I need

20:57 Thanks for the help

21:18 gfredericks: deleting 185 LOC of clojure is like deleting 2000 LOC of java

21:19 Shayanjm: true that

21:39 Need some advice re: how to approach this problem properly. I'm trying to generate x-y coordinates (corresponding to center points of circles) in a certain configuration. Here's a diagram (sorry if it's messy) of what the configuration looks like: http://puu.sh/gPNn8/474f8f7f7f.jpg

21:39 In that image I've also written the proposed output that a function would generate given a start point {:x x :y y}, and number of layers n. At n = 0, for instance, it would return [[start-point]]. At n = 1, it would return [[start-point] [x-y coords of circles in layer 1]].

21:40 I know how to calculate the vector for the next layer given the previous one, but I don't know how to properly string it all together to return one large vector of all layer coords

21:40 any direction would be great :)

21:44 justin_smith: Shayanjm: you could use iterate to generate the consecutive layers, and just grab the last layer you are interested in

21:44 ,(nth (iterate inc 0) 100)

21:44 clojurebot: 100

21:45 Shayanjm: justin_smith: the function I wrote to generate the next layer requires the previous layer as input

21:45 my brain just can't

21:45 justin_smith: Shayanjm: that's what iterate does

21:45 Shayanjm: seriously?

21:46 oh fantastic

21:46 mavbozo: ,iterate

21:46 clojurebot: #object[clojure.core$iterate "clojure.core$iterate@8445e42"]

21:46 mavbozo: ,(doc iterate)

21:46 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

21:46 justin_smith: Shayanjm: ^ that describes what you need, right?

21:47 you just take the nth from that

21:47 Shayanjm: yup that's excellent

21:47 justin_smith: or you could take from it until the vector has N items

21:47 or whatever

21:47 Shayanjm: thanks justin_smith - this solves it i think

22:01 justin_smith: I'm getting a null pointer exception when i try to use iterate

22:01 gisting, 1 min

22:01 justin_smith: Shayanjm: that indicates to me that at some point your function returns nil?

22:02 Shayanjm: justin_smith: it should not

22:03 turbofail: that's the beauty of nil though. it shows up whether it should or not

22:03 Shayanjm: justin_smith: https://gist.github.com/shayanjm/51cd5cbfc7e030798b3f

22:04 justin_smith: Shayanjm: why do you give it hash-maps in the examples that work, and a vector in the example that doesn't work?

22:04 maybe you wanted a hash map inside that vector?

22:04 Shayanjm: sorry it was a typo

22:04 i edited the gist

22:05 I passed it a hash map in reality

22:05 justin_smith: Shayanjm: you function does not take the same kind of data it returns

22:05 there is an extra () around the output

22:05 Shayanjm: oooooh

22:05 justin_smith: to use iterate, it has to take exactly the sort of data it returns

22:05 Shayanjm: you're right

22:06 justin_smith: also I think that list outside is totally pointless

22:06 Shayanjm: It probably is. is it better to use lists then?

22:06 justin_smith: that's not what I said

22:06 Shayanjm: or sequences*

22:07 justin_smith: I'm just saying the extra () is doing nothing, so stripping it in generate-next-layer (or not generating that outer list) should just fix things

22:07 Shayanjm: Oops I misread what you said, I thought you meant vector when you said list (python on the brain)

22:07 yeah the extra () was an accident

22:07 justin_smith: or, if it really needs to be there, you can change it to (iterate (comp generate-next-layer first) ...)

22:21 elvis4526: How do you render an attr without any value in hiccup ?

22:21 like <mytag attr>

22:22 justin_smith: elvis4526: that should be equivalent to <mytag attr=true>

22:22 right?

22:22 elvis4526: ahhh makes sense

22:27 {:attr true} makes it attr="attr"

22:33 justin_smith: elvis4526: I was going by this http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attributes

22:33 elvis4526: so yeah, attr="attr" is correct, looking at that page

22:37 elvis4526: oh cool

22:37 thanks

Logging service provided by n01se.net