#clojure log - Feb 11 2013

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

0:03 tomoj: wow

0:03 I assumed you had some crazy error while committing, your test is nuts

0:05 noncom: no, still, i don't get it.

0:05 )

0:06 ivan: is this one of those bugs where you write over the file before reading the entire file?

0:07 * ivan reads above

0:07 noncom: what i don't get in particular - is how it is first said that refs track a single location (contrasting them with vars) and then it is said that refs track multiple locations and agents - don't

0:07 technomancy: a ref tracks a location

0:08 multiple refs track multiple locations at the same time

0:08 multiple agents track multiple locations independently

0:08 "coordinated, synchronous change" <- what dosync is

0:09 clj_newb_234: anyone here also use scala? I'm trying to see if there is a way to take advantage of (1) clojure's persistent data structures + (2) clojure's macros, and yet (3) scala's type system

0:10 noncom: i use scala

0:10 technomancy: clj_newb_234: using clojure macros from scala doesn't make sense

0:10 data structures would though: https://github.com/codahale/yoink

0:11 noncom: what kind of profit are you expecting from using them this way?

0:12 i think that scala is still too restrictive with it's syntax and some simple things require a lot of boilerplate. i think that's where clojure can be well used to reduce the amount of code.

0:13 technomancy - the statements about multiple refs and multiple agents do not seem mutually exclusive. i still can't see the difference.

0:14 i'm sorry)

0:14 technomancy: noncom: the difference is dosync works on refs only

0:14 noncom: oh!

0:15 now i see)

0:15 agent's can't be synchronized with dosync and act independently in time..

0:15 technomancy: right-o

0:16 noncom: thank you! i think that the official docs need to be more explicit on this..

0:17 technomancy: the official docs could use a lot of things; more clarity not being on the list

2:24 nonuby: is this idiomatic, is there a simpler way https://www.refheap.com/paste/11165

2:37 cmdrdats: nonuby: you could: (reduce min (flatten (map :rates sample_data)))

2:39 metellus: ~flatten

2:39 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

2:40 cmdrdats: ye, i was about to say - you could probably use apply concat

2:40 metellus: or mapcat

2:41 cmdrdats: (reduce min (mapcat :rates sample_data))

2:41 nice - I didn't know about mapcat :) that's very handy

2:41 josteink: completely offtopic: is it just me going crazy or has chrome lately started NOT autocompleting adresses in the "awesome bar"?

2:42 metellus: cmdrdats: I only know about it from people doing ~flatten in here

2:42 josteink: not for me.. did you clear your history recently?

2:42 josteink: metellus: what I mean is I may start typing "cale"

2:42 cmdrdats: metellus: a useful learning experience - now I know too :D

2:43 josteink: metellus: but instead of completing, in the bar, to calendar.google.com, it's just one of 200 items in a list which I need to select

2:43 clojurebot: list* doesn't actually make a `list?`

2:43 josteink: metellus: it USED to complete in the bar, so I just needed to type "cale<enter>"

2:44 metellus: no idea, sorry

2:47 josteink: hm

3:12 nonuby: cmdrdatas, wouldnt (apply min (mapcat :rates sample_data)) be better? reduce will call min n times?

3:43 WokenFury: does clojure have a wrapper around java's ReentrantLock? I need a lock where one thread will do work and other threads can check the lock status and cancel their work instead of blocking/retrying

7:48 pjstadig: WokenFury: no wrapper, but you should be able to use ReentrantLock in that way

7:48 WokenFury: pjstadig: yep, implemented already. works well

7:49 pjstadig: hehe

7:49 yeah sorry, i guess you asked like 4hr ago :)

7:51 WokenFury: :)

9:38 jsabeaudry: Somehow my uberjar does not work this morning, even old versions in git, all of a sudden it cannot find my main class

9:41 im very scared about the implications of this

9:53 Blazeix: hi, i need to run a function on certain values in a map. i have this implementation: https://www.refheap.com/paste/11168

9:53 i'm pretty new to clojure, is that a idiomatic way to do it?

9:54 the idea is you'd call it like (map-selected-values mymap #(Integer/parseInt %) :key1 :key2)

9:58 Bronsa: Blazeix: (defn map-selected-vals [m f & ks] (into {} (for [k ks] (update-in m [k] f))))

9:58 hyPiRion: Bronsa: what

9:58 Bronsa: mhm, no wait

9:59 (defn map-selected-vals [m f & ks] (into {} (reduce #(update-in %1 [%2] f) m ks)))

9:59 this

9:59 ljos: (reduce #(update-in m [%] f) ks)

9:59 hyPiRion: You don't need the {}

9:59 ljos: no need for {}

10:00 oh.. a small mistake (reduce #(update-in %1 [%2]) m ks)

10:01 Blazeix: oh, cool. let me digest that a little bit

10:02 aroemers: Forgot the function f: (reduce #(update-in %1 [%2] f) m ks)

10:02 Blazeix: right

10:02 ljos: oh yeah. that last one is correct.

10:02 always something.

10:02 aroemers: heh

10:17 Blazeix: ok, i understand it now, thanks everyone

10:17 a common thread in my clojure learning is that i need to better grok reduce

10:22 pbuckley: ,(clojure.string/replace (str "{\"top-key\":{\"first-key\":\"" "first-val" "\",\"second-key\":\"" "second-val" "\"}}") #"\\" "")

10:22 clojurebot: "{\"top-key\":{\"first-key\":\"first-val\",\"second-key\":\"second-val\"}}"

10:22 pbuckley: ,(clojure.string/replace (str "{\"top-key\":{\"first-key\":\"" "first-val" "\",\"second-key\":\"" "second-val" "\"}}") "\\" "")

10:22 clojurebot: "{\"top-key\":{\"first-key\":\"first-val\",\"second-key\":\"second-val\"}}"

10:23 pbuckley: anyone know how to replace a backslash in a string using clojure?

10:23 or, alternately, use double quotes in a string without backslash-escaping them?

10:24 joegallo: i think you're being confused by the printed behavior

10:25 ,"\""

10:25 clojurebot: "\""

10:25 pbuckley: ah, so when I print it out, it escapes it

10:25 joegallo: (.indexOf "\"" \\)

10:25 ,(.indexOf "\"" \\)

10:25 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String>

10:25 joegallo: ,(.indexOf "\"" (str \\))

10:25 clojurebot: -1

10:25 pbuckley: but it isn't really escaped when I use it unprinted

10:25 joegallo: there isn't a backslash in the string "\"" there's a single character, a double-quot.

10:25 double-quote.

10:26 pbuckley: ok cool, thanks joegallo

10:26 alexnixon: can anyone confirm exactly why the implementation of 'drop' ( https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2568-L2578 ) pulls out the "step" function into a let binding? I suspect it's to avoid unnecessarily nesting a bunch of lazy-seq calls, but I'm unsure if there are locals-clearing/head retention issues being worked around too.

10:28 DerGuteMoritz: alexnixon: to avoid retention of the head I think, yep

10:31 though I think this could be achieved with (loop ...) as well

10:35 ah no, forget that last statement :-)

10:36 or actually

10:37 clgv: alexnixon: to have it private, I think. there is no other effect there

10:38 alexnixon: clgv: I mean why is the step function pulled out *at all*. You could write 'drop' with it in-line.

10:38 clgv: alexnixon: the author may have thought that it's better readable

10:38 DerGuteMoritz: you need a recursion target

10:38 a tail recursion target

10:39 alexnixon: DerGuteMoritz: a fn definition is a recur target

10:39 DerGuteMoritz: and yeah ((fn [n coll] ...)) would also work but is not as nice

10:39 gfrederi1ks: but you can't do it from within a lazy-seq

10:39 DerGuteMoritz: yep I mean that's the reason for having the fn at all

10:39 but loop would work, too here... and then you could even do it inline

10:40 gfredericks: drop is defined before loop apparently, but that's not too meaningful

10:41 DerGuteMoritz: hmm looking at take-last below it looks like it retains the head of coll

10:41 pbuckley: joegallo it seems that printing behavior also pollutes when I try to exec the string

10:42 DerGuteMoritz: at least while the loop is executing

10:43 joegallo: how are you trying to exec the string? maybe you should be pr-str'ing it before hand or something like that.

10:44 pbuckley: I'm trying to exec like this: (. (Runtime/getRuntime) exec curl-command)

10:45 joegallo: right... but where did curl-command come from?

10:46 alexnixon: DerGuteMoritz: I don't think the head is being retained there as 's' will be cleared on each recur

10:46 pbuckley: (str "curl -H 'Accept: application/vnd.example.v1' -H 'Content-type: application/json' -X POST -d '" "{\"top-key\":{\"first-key\":\"" "first-val" "\",\"second-key\":\"" "second-val" "\"}}" "' " my-url)

10:47 so you're saying it should be a pr-str instead of str?

10:47 joegallo: not necessarily

10:48 pbuckley: exec doesn't seem to like pr-str

10:48 I was trying to just quickly test something calling out to the system command using curl, but it looks like it's just too tricky with the backslashes involved

10:49 I can use clj-http, which I probably should have done in the first place

10:50 bordatoue: Hello, is there a cons equivalent in clojure similar to lisp

10:51 joegallo: pbuckley: (slurp (.getInputStream (. (Runtime/getRuntime) exec "echo \"foo\""))) works fine for me.

10:54 sh10151: https://github.com/Chouser/clojure-jna is very old, is there some better way to do simple JNA calls in Clojure?

10:55 pbuckley: joegallo: well, by some definitions of "works" - your backslash is still in the command that is exec'd

10:56 joegallo: no, no it isn't.

10:56 pbuckley: since I'm trying to pass json parameters to a rails app, it chokes on the backslashes and doesn't recognize the json as json

10:56 when I run the same command from the shell without backslashes, it is fine

10:57 joegallo: you are in java string

10:57 strings

10:57 dakrone: pbuckley: you'll have much more luck doing it with clj-http rather than shelling out to curl

10:57 joegallo: if i want to run `echo "foo"` at the command line, i need to represent that in a java string as "echo \"foo\""

10:57 pbuckley: yeah, shelling out to curl is a dead end I've been chasing down for too long

10:58 joegallo: you may be correct, but I'm not seeing it, and I don't think it's worth the time trying to figure out

10:58 lesson learned, don't try using backslashes in strings and clojure

10:58 joegallo: OMG

10:59 llasram: ...

10:59 danielglauser: bordatoue: There are two, cons and conj. http://clojuredocs.org/clojure_core/clojure.core/conj http://clojuredocs.org/clojure_core/clojure.core/cons

10:59 DerGuteMoritz: alexnixon: s will, but coll won't

10:59 alexnixon: only an issue if you pass in a seq already, of course

11:00 alexnixon: DerGuteMoritz: so is this naive implementation bad?: https://www.refheap.com/paste/11171

11:01 clgv: alexnixon: it is slow

11:02 alexnixon: and allocates more lazy-seq objects

11:02 alexnixon: clgv: I understand the allocation issue - is that the only downside?

11:03 clgv: alexnixon: well, what is its advantage?

11:05 alexnixon: clgv: I'm not contesting the current implementation, just trying to to understand why it is so. If there are reasons beyond extra allocations then that's interesting.

11:06 clgv: alexnixon: well, it is faster just to discard the top n elements and then return the rest

11:06 DerGuteMoritz: it's not fully lazy in fact then

11:06 alexnixon: clgv: yep, makes sense.

11:07 DerGuteMoritz: but due to chunking you can't rely on full laziness anyway

11:07 clgv: DerGuteMoritz: it is fully lazy^^

11:07 alexnixon: DerGuteMoritz: it is lazy - 'step' isn't called unless you realize the first item in the returned seq

11:07 clgv: oh right, not when chunking ;)

11:08 DerGuteMoritz: alexnixon: yeah but then it realizes the dropping in full

11:09 ah wait :-)

11:09 pbuckley: dakrone: thanks, clj-http works great

11:09 DerGuteMoritz: yeah alright, you can't drop more lazily, of course

11:09 alexnixon: :-)

11:11 clgv: ;)

11:11 bordatoue: danielglauser: I am looking for a lisp equivalent of cons such that cons of two number would give me a pair both the cons you have mentioned requires some col

11:12 DerGuteMoritz: bordatoue: Clojure doesn't have pairs

11:13 bordatoue: you can use (vector 1 2) or [1 2] instead

11:13 bordatoue: DerGuteMoritz: does it have somethign i can invoke car and cdr

11:13 DerGuteMoritz: bordatoue: no, it doesn't have car and cdr either

11:13 danielglauser: bordatoue: Ah. Thinking back to my Scheme days (15+ yrs ago) I believe cons would give you a pair. Folks typically just use a vector in Clojure.

11:14 ,(first [1 2])

11:14 clojurebot: 1

11:14 bordatoue: thanks DerGuteMoritz & danielglauser

11:14 DerGuteMoritz: yw

11:15 danielglauser: ,(rest [1 2])

11:15 clojurebot: (2)

11:15 Bronsa: ;(second [1 2])

11:15 ,(second [1 2])

11:15 clojurebot: 2

11:16 llasram: &(fnext [1 2]) ;; for completeness

11:16 lazybot: ⇒ 2

11:16 frozenlock: One can add metadata in an atom--> (atom a 10 :meta {:some-key some-value}), but how can you change it with reset! ?

11:18 llasram: frozenlock: I don't believe you can

11:18 frozenlock: Oh...

11:19 My first reflex in this case would be to use `def' inside a function instead of an atom, but I'm pretty sure the clojure's gnome will burn me for this. Suggestions?

11:19 s/gnome/gnomes

11:19 Bronsa: ,(alter-meta! (atom 10 :meta {:foo 1}) update-in [:foo] inc)

11:19 clojurebot: {:foo 2}

11:20 frozenlock: Bronsa: And this solves everything. Thank you :)

11:21 llasram: Cool. I didn't realize metadata on reference types other than vars worked that way. Makes sense though

11:21 (inc Bronsa)

11:21 lazybot: ⇒ 3

11:22 llasram: frozenlock: OOC, what are you doing with updating metadata on an atom?

11:23 frozenlock: llasram: I have a java objects that needs to be recreated once in a while. I store the configs in the meta data in order to be able to retrieve them and recreate it with the same configs. Although now that I think about it, I could simply use a second atom.

11:25 I don't know why I keep doing crazy stuff when the solution is so simple.

11:33 sh10151: anyone use lein-daemon? I'm getting null pointer exceptions from it, and I can't tell why -- I'm sure it's something silly

11:34 at leiningen.daemon_starter$daemon_starter.doInvoke(daemon_starter.clj:13)

11:34 looking at the code i think it's something in my :daemon param in project.clj? can't really tell...

11:39 arohner: oh hi, I was just thinking about you.

11:39 bordatoue: is there any way to identify a function

11:39 sh10151: arohner: I think I must be doing something silly with lein-daemon

11:39 bordatoue: is there a function type

11:40 sh10151: arohner: Most basic setup I can think of has a null pointer exception sometime after "waiting for pid file to appear" -- at leiningen.daemon_starter$daemon_starter.doInvoke(daemon_starter.clj:13)

11:41 jkkramer: bordatoue: ##(fn? map)

11:41 lazybot: ⇒ true

11:41 bordatoue: okay, how do i identify a function and a macro programically

11:42 ##(fn? (defmacro something [] nil))

11:42 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

11:43 rplaca: bordatoue: look at the metadata on the function and you'll see {:macro true}, iirc

11:44 jkkramer: ,(:macro (meta #'for))

11:44 clojurebot: true

11:44 bordatoue: what is the point of having fn? if i accidently pass in a macro

11:44 rplaca: bordatoue: a macro *is* a function

11:44 that takes code in and produces different code out

11:45 jkkramer: and you can't normally pass around macros

11:45 ,(fn? for)

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

11:45 bordatoue: rplaca: but fn? doesn't report it as a fn

11:45 gfredericks: ,(fn? @#'for)

11:45 clojurebot: true

11:46 bordatoue: okay, my error

11:46 calis: What Emacs setup are clojure hipsters using nowadays? Starter kit, prelude, Emacs Live... ?

11:47 bordatoue: gfredericks: why do we need sharp quote for macros not functions when passing to fn?

11:48 gfredericks: bordatoue: @#' is a hack for getting the function underlying a macro

11:48 not normally useful

11:49 llasram: &`@#'for

11:49 lazybot: ⇒ (clojure.core/deref (var clojure.core/for))

11:49 gfredericks: ,(reduce @#'or [false true false])

11:49 clojurebot: nil

11:49 edmund_: woah... wash your mouth out dude.

11:49 llasram: ^^ Er, if that helps

11:49 heh

11:50 HolyJak: calis: A question I'd also like answered. I guess every true Emacs geek uses his/her own setup. I, as a newbie, use Prelude and am planning on trying https://github.com/overtone/emacs-live once I get Emacs 24.3

11:51 One Emacs & Clojure hipster's setup is here: https://github.com/bodil/emacs.d

11:51 I guess you could also find Rich Hickey's emacs setup somewhere

11:52 edmund_: HolyJak: i'm a huge emacs live fan

11:53 technomancy: calis: I recommend starting your own and stealing liberally from the popular setups

11:53 if you add things one-by-one you'll have a better understanding of where various pieces come from

11:53 llasram: (inc technomancy)

11:54 lazybot: ⇒ 46

11:54 technomancy: 80-90% of the good stuff is available in independent packages anyway

11:54 pimeys: I'm still having this test of replacing vim with emacs+evil here at work

11:55 but somehow it still doesn't work like I want it to work

11:55 and some modes somehow dismiss the evil mode completely :P

11:55 technomancy: the thing about something as invasive as evil is that it doesn't compose well

11:55 pimeys: yep

11:56 the thing would be to learn to use emacs without evil

11:56 and then I start to wonder what's the profit

11:56 I really like emacs, how it uses elisp for plugins etc.

11:56 TimMc: &(@#'for nil nil `[a (range)] `[a (inc a)])

11:56 lazybot: ⇒ (clojure.core/let [iter__4468__auto__ (clojure.core/fn iter__15780 [s__15781] (clojure.core/lazy-seq (clojure.core/loop [s__15781 s__15781] (clojure.core/when-let [s__15781 (clojure.core/seq s__15781)] (if (clojure.core/chunked-seq? s__15781) (clojure.core/let ... https://www.refheap.com/paste/11174

11:56 pimeys: but the editor itself doesn't work for me, I need the command mode to be fast

11:57 technomancy: well I haven't used vim, but from what I've heard most of the benefits of text objects you get for free in lisps with paredit anway

11:57 pimeys: if I started learning an editor now, it would be emacs

11:57 but 15 years of vim history is not something you can change

11:58 llasram: Induced amnesia

11:58 pimeys: and there's still lots of things I love in vim, although for clojure emacs seems to be better

11:58 for slime etc.

11:59 and with ruby, vim just rocks

11:59 hashbang1: pimeys: you can bring some of that functionality into vim with tpope's foreplay, and are a number of slime-ish plugins for vim with screen or tmux

11:59 pimeys: I've tested those, the problem is vim itself

12:00 maybe just using an external REPL

12:00 arkx: Evil worked well for me. evil-paredit makes it work better with paredit as well, so you can gradually move to that.

12:00 nrepl.el rather than slime for me, though.

12:01 pimeys: and for every plugin I install I need to figure out the good command mode configuration

12:01 by default they have bindings with C or M

12:01 arkx: btw, long time no see :)

12:01 arkx: We talked here just last week :P

12:01 Same topic even.

12:02 pimeys: but in real life I haven't seen you since TKK

12:02 freshman year

12:02 arkx: But yeah, glad to see you've found Clojure as well

12:02 pimeys: still in reaktor?

12:02 arkx: Yup.

12:02 Coding Clojure at work currently. :)

12:02 pimeys: nice

12:03 it's very easy language actually, after Ruby

12:03 but still using Ruby for work

12:03 maybe I'll start doing evaluators with clojure and do real work with other languages :D

12:03 iwo: hey, does anyone know why, often when i use nrepl, i get suddenly kicked into nrepl-error buffer and i can't focus any other window?

12:03 i'm using emacs live

12:04 it seems like sudden nrepl gets into an error state and i can't continue because the nrepl-error window is forever stealing focus

12:04 even though nrepl-error is blank, and i haven't even executed anything

12:04 mathmonkey: Hi

12:04 technomancy: iwo: does emacs-live bring in nrepl-autocomplete?

12:04 iwo: i start typing into the nrepl prompt and suddenly it breaks

12:05 technomancy: I've heard of that package causing problems like that

12:05 iwo: technomancy: i'm pretty sure it does, yes

12:05 hashbang1: pimeys: i'm in a similar boat so i'm interested in potentially making the leap to emacs. I have a lot of time invested in vim, and evil-mode has been disappointing. I'm thinking I might just want to start from scratch and learn the default emacs keybindings instead.

12:05 technomancy: iwo: thanks for bringing up a great example of why it's better to add in packages by yourself so you can have a better understanding of how to debug them when problems arise. =)

12:06 iwo: also, has anyone else experienced strange formatting in nrepl in emacs? like you execute a function and see loads of whitespace, as if many newline chars have been printed?

12:06 pimeys: hashbang1: I'm just afraid of doing that, I've gained so much speed with command mode, and I don't know is the tradeoff to emacs worth it

12:06 arkx: I'm curious as to why evil-mode seems disappointing to others making the transition to emacs.

12:06 iwo: technomancy: :P

12:06 pimeys: arkx: maybe with configuration you can make it work like vim

12:06 arkx: What doesn't work? I was really impressed by how well it matched real vim, compared to say IntelliJ IDEA or Eclipse plugins.

12:07 pimeys: but, the biggest thing is that it's only the default vim stuff that is there

12:07 arkx: Those are always terrible.

12:07 pimeys: for new plugins, you have to write the workflow yourself

12:07 the bindings etc

12:07 gfredericks: arkx: I have a friend who switched with evil and still uses it

12:07 pimeys: I'm missing stuff like ysiw" :)

12:07 hiredman: .win 5

12:08 iwo: i seem to have the same problem as this guy http://clojure-log.n01se.net/date/2013-01-19.html#10:15a

12:08 arkx: Of course the plugin ecosystem is different between vim and emacs, but I found the core vim text editing functionality well implemented

12:08 pimeys: the thing is, that I need more than the core

12:08 floatboth: hi everyone

12:08 pimeys: so, it's better to learn emacs than use a vim layer on top of it

12:08 arkx: pimeys: do you use paredit?

12:09 pimeys: of course

12:09 floatboth: I have a weird problem

12:09 HolyJak: iwo, technomancy: regarding nrepl-autocomplete. that is why I wait for Emacs 24.3, I believe I have read somewhere that prior to that there might be some issues with te completion

12:09 hashbang1: pimeys: i'm thinking so. Otherwise I'm just going to keep wanting to shoehorn my vim experience into other editors, which will just lead to frustration.

12:10 floatboth: https://github.com/myfreeweb/swaggerator/blob/master/src/swaggerator/validator.clj – this works when not AOT-compiled

12:10 when it is, this is the stack trace:http://mfwb.us/9obI

12:10 pimeys: one thing that annoys me also is that when doing :some_command, ESC doesn't cancel it

12:11 it does nothing

12:11 small stuff, maybe that's fixable with configuration

12:11 is it the C-g?

12:11 arkx: I moved quite naturally to using both vim *and* emacs keybindings where they didn't conflict

12:11 hashbang1: pimeys: ugh yeah i was doing that too, i think its c-g

12:14 floatboth: google finds nothing for exceptions listed in http://mfwb.us/9obI

12:17 arkx: https://github.com/timcharper/evil-surround

12:18 But yeah, some friction is to be expected, obviously. I'm happy I kept going, it doesn't need to be either-or when it comes to editors. :P (Heresy I know.)

12:21 TimMc: floatboth: I don't see any obvious problems. Try doing a binary search -- remove half the code and see if the exception persists.

12:26 floatboth: oh wait, no, the problem is not in this namespace, it's in https://github.com/myfreeweb/swaggerator/blob/master/src/swaggerator/core.clj – using the controller macro from an AOT compiled namespace throws this exception

12:32 https://github.com/myfreeweb/swaggerator/blob/master/src/swaggerator/core.clj#L48 – something's wrong in this macro, but it only blows up after AOT compilation

12:34 llasram: floatboth: Superficial question -- why does the macro need to call `eval` vs just return a form to be evaluated?

12:37 floatboth: I don't know how else can I do this

12:38 I want to evaluate the body in a binding with some transients and call persistent! to get the results for metadata

12:40 If I just put everything inside a backquote and don't eval, it still doesn't work from AOT-compiled namespaces AND it doesn't pass the tests

12:41 llasram: floatboth: I was going to ask about that too... There's no way for the dynamic variables to end up taking on anything other than their initial empty values... Unless you're altering the current binding for the earmuffed vars in the code you eval?

12:42 floatboth: the code I eval alters them and I call persistent! on them and I assign them to the result of the evaluation

12:42 llasram: ~transients

12:42 clojurebot: transients are not mutable data structures: http://technomancy.us/132 or at least as far as you're concerned.

12:42 floatboth: everything works unless I use it from an AOT-compiled namespace

12:43 llasram: I think everything *appears* to work

12:43 And something about AOT-compilation is surfacing that some bits are broken

12:44 When you eval in macro-expansion, you are inserting the literal generated value for the next round of evaluation as if it had been produced by the reader

12:44 Sometimes that's what you want, but usually not

12:45 TimMc: Oof, that-ll do it.

12:45 *that'll

12:46 hiredman: that code is almost definitely not using transients correctly

12:47 https://github.com/myfreeweb/swaggerator/blob/master/src/swaggerator/core.clj#L39 definitely not

12:47 I would run, not walk, away from swaggerator

12:48 llasram: Calm down, hiredman. Bugs exist to be fixed :-)

12:48 floatboth: how do I use them correctly?

12:49 llasram: floatboth: Just like Clojure persistent structures. The only difference is that there's no guarantees about the old versions remaining unmodified

12:49 SegFaultAX: Really? "swaggerator"?

12:49 hiredman: llasram: bugs are one thing, not knowing how to use language features is another

12:51 TimMc: llasram: I think there's an implied "in its current state" -- which I would agree with.

12:51 hiredman: floatboth: http://clojure.org/transients

12:52 floatboth: ahh, "not designed to be bashed in-place"

12:52 ivan: someone oughta write a kibit rule for that

12:52 floatboth: should I use atoms?

12:53 TimMc: ivan: Detect transient ops in non-terminal position of do blocks?

12:54 ivan: TimMc: I suppose that would catch most of them

12:54 llasram: floatboth: If you can't achieve what you're trying to achieve by producing functional values, then that's usually approach

12:54 TimMc: You'd have to look for implicit do-blocks, e.g. doto, fn body, let body, when body...

12:54 llasram: s,approach,the approach,

12:56 floatboth: using atoms doesn't fix the problem

12:56 what the hell does "No matching ctor found for class clojure.lang.AFunction$1" mean anyway

12:58 joegallo: there's no such constructor for the first (or maybe it's second) anonymous class defined inside .../clojure/lang/AFunction.java

12:59 bbloom: floatboth: you're trying to instantiate a non-class object

12:59 er no rather i mean:

12:59 floatboth: you're passing the wrong arguments

13:00 floatboth: I mean I'm not calling any constructors… explicitly, at least

13:00 llasram: I'm about ~90% certain that you get there error when you try to re-eval an anonymous function which is a closure

13:00 bbloom: floatboth: provide more context, ie what code is failing

13:01 floatboth: more context: https://github.com/myfreeweb/swaggerator/blob/master/src/swaggerator/core.clj#L48

13:02 rmrfchik: hi. where I can in clojure sources a code which match java overloaded methods?

13:05 ah, Reflector.java

13:06 llasram: floatboth: I know it's invasive, but I'm pretty certain your problems here trace to your use of `eval` w/in macros

13:08 Someone correct me if I'm wrong, but I think the static initializer generated for AOTed namespaces is built from the post-macro-expansion code

13:09 If your macros are returning things other than forms to be re-consumed by the compiler, then all sorts of craziness breaks loose

13:11 floatboth: yeah, I'm sure it's this too

13:11 but I don't know how to do this without eval

13:11 dabd: I am trying to get nrepl to work on Emacs for Win. When I run M-x nrepl-jack-in from a source file it opens an empty *nrepl* buffer but there is no listener. Any help please?

13:12 TimMc: floatboth: What's the goal?

13:13 floatboth: to evaluate code inside a binding (to an atom), return the result of evaluation (which changes the atom) with the value of the atom as metadata

13:13 Raynes: $latest lein-ring

13:14 lazybot: [lein-ring "0.8.2"] -- https://clojars.org/lein-ring

13:14 gtrak: floatboth: really you should fix that use of transients, just because it's totally wrong. Who's to say some other weirdness isn't contributing to the problem?

13:14 floatboth: gtrak: I have changed it to atoms, just not pushed to github. doesn't fix the problem though

13:15 there's no exception if I just use one backquote and no eval, but it doesn't do the right thing then

13:15 gtrak: why are you interning?

13:16 floatboth: gtrak: where?

13:16 gtrak: 66

13:16 (intern *ns* n ...

13:16 that looks weird to me

13:17 floatboth: that's not related to the problem

13:17 gtrak: why not just say `(def ~n (controller ~url ~desc ~@body) ?

13:17 floatboth: just a weird habit, why not indeed

13:18 gtrak: it's also semantically different

13:19 I only use macros like that when they return a value, I would shy away from anything that does side effects at compile-time?

13:20 TimMc: floatboth: You have a habit of using intern and eval in macros? D-:

13:20 gtrak: b/c I'm just not sure what that means at run-time

13:20 floatboth: TimMc: yes :D

13:20 bbloom: gtrak: anything that defs is a side effect at compile time

13:20 gfredericks: are there any examples of legitimate side-effecting macros?

13:20 gtrak: bbloom: there's a difference between expanding to a def and doing a def

13:21 gfredericks: ignoring trivial side-effects like gensym

13:21 dabd: is there a way to do conditional compilation. I have a var that is a path that depends on the platform if on Win it has some value if on Linux it has another one. Any way to do this?

13:21 bbloom: gtrak: gfredericks: defmethod doesn't expand to a def

13:21 gfredericks: gtrak: they're both at compile time

13:21 bbloom: $source defmethod

13:21 lazybot: defmethod is http://is.gd/SK2aTC

13:22 gfredericks: defmethod doesn't side-effect

13:22 gtrak: gfredericks: gen-class?

13:22 TimMc: bbloom: It still doesn't appear to be a side-effecting macro.

13:22 bbloom: gfredericks: oh, you mean the macro side effects, not the result of it? i see

13:22 i misunderstood

13:22 gfredericks: bbloom: yeah

13:22 gtrak: that does seem to be the case, yes; cool, thanks

13:23 TimMc: gen-class isn't actually a var, is it?

13:23 gfredericks: I'm wondering about the absoluteness of claiming "Macros should always be pure functions"

13:23 TimMc: Oh weird, it's declared but I don't see a definition.

13:23 gfredericks: ,#'gen-class

13:23 bbloom: gfredericks: in theory there could be memoization & other internal side effects

13:23 gfredericks: dynamic code loading, etc

13:24 gfredericks: "Macros should usually always be pure functions"

13:24 TimMc: gfredericks: There's also referential transparency to consider.

13:24 clojurebot: #'clojure.core/gen-class

13:24 gfredericks: ,#'unquote

13:24 clojurebot: #'clojure.core/unquote

13:24 gfredericks: ,unquote

13:24 clojurebot: #<Unbound Unbound: #'clojure.core/unquote>

13:25 llasram: gen-class is very weird in how it does it's work during macro-expansion. I'm not clear on why it does that though -- I use a wrapped version which works just fine acting at code-execution-time

13:25 TimMc: (defmacro maybe [expr] (when (odd? (System/currentTimeMillis)) expr))

13:26 Or it could go out and check a server to see if the client has paid up.

13:26 gfredericks: most of my macros go out and check a server to see if the client has paid up.

13:26 (defmacro had-the-client-paid-up-at-compile-time? ...)

13:27 cemerick: lynaghk: every day that passes, I want elision of nested expressions in cljx more...

13:28 are you as opposed as you were last fall? (https://github.com/lynaghk/cljx/issues/5 FWIW)

13:29 TimMc: floatboth: Get your code working without any transients, eval, or side-effecting macros. If your code is still not working when AOT'd, bring it 'round again.

13:29 floatboth: almost got it

13:34 pbuckley: if I want to map a function that takes two arguments to a collection, should I use walk to make every item in the collection have the two arguments?

13:35 the first argument is constant, it isn't changing

13:35 it just seems I'm not doing this right because of how convoluted I seem to be getting

13:35 progo: how about partial

13:35 alexnixon: pbuckley: (map (partial f 42) coll), where '42' is your constant

13:36 pbuckley: thanks progo and alexnixon, I think that's what I was looking for

13:36 progo: you should have known lambdas as the other way to solve the situation, but partial is the clearest one

13:51 banjo: Does anyone know if the major clojure conferences (e.g., Clojure/West) are effective places for a startup to find and hire good clojure people?

13:51 Or is job searching/recruitment strongly de-emphasized?

13:52 technomancy: banjo: I wouldn't say it's discouraged. it used to be easier a couple years ago when there were fewer jobs; these days a bigger portion of attendees are already working in clojure.

13:52 gtrak: banjo: folks have booths and sponsor things like drinkups

13:53 ro_st: technomancy: job well done on 2.0.0 :-)

13:53 technomancy: ro_st: thanks! happy to have it out.

13:54 marcellusthecat: anyone have any experience and/or example projects using sandbar? seems like a pretty cool lib with solid documentation that hasn't really got much attention?

13:54 banjo: technomancy: I see, at this point are there many more companies recruiting than there are engineers job searching?

13:54 ro_st: marcellusthecat: all the cool kids use lib-noir nowadays

13:54 TimMc: technomancy: I suspect there's a feedback effect; employees are more likely to get a travel/fee reimbursement if their job involves Clojure...

13:55 marcellusthecat: ro_st: That's what i use now but it doesn't have any higher level form managment stuff, trying to figure out if it's worth exploring more

13:55 danielglauser: banjo: Depends on what you are looking for and how much location matters but there are quite a few Clojure user groups with people looking for Clojure gigs. Hint, I run one http://www.meetup.com/denofclojure/

13:56 banjo: I know a couple of folks up in Boulder who are actively looking for work

13:56 technomancy: banjo: just my suspicion, but I think TimMc is right that the conference is likely to draw attendees whose work will cover the expenses.

13:56 headshot: danielglauser: you in colo?

13:56 danielglauser: headshot: Yessir

13:56 headshot: i'm in foco

13:57 * gfredericks mutters "colocamotive" and wonders what it means

13:57 gfredericks: focorado?

13:57 marcellusthecat: i've been regurgitating the same form validation stuff from that noir-messageboard project, keep feeling like it's time for something new

13:57 danielglauser: headshot: foco?

13:57 headshot: fort collins

13:57 fort chronic

13:57 gfredericks: Fort, Co.

13:57 danielglauser: headshot: Nice!

13:58 TimMc: banjo: Have you looked at Functional Jobs? I don't know what their fees are like, but it's a known place for job-seekers to look.

14:00 banjo: danielglauser: Makes sense, and thanks for the group. If your friends are looking and you wouldn't mind referring them feel free to pm me.

14:00 danielglauser: headshot: a long way to travel but we do get folks from the Springs too. Come on down sometime.

14:00 amalloy: i was hoping foco was like "faux colorado", slang for some nearby state that wishes it could be colorado

14:00 headshot: heh

14:00 banjo: TimMc: I haven't, thanks for the reference.

14:01 danielglauser: banjo: If you don't mind send me some info via the meetup and I'll announce the position. I don't think it will get very far without even a brief description.

14:01 headshot: danielglauser: what's the meetup url?

14:01 that posted earlier?

14:01 danielglauser: headshot: http://www.meetup.com/denofclojure/

14:02 banjo: danielglauser: Thanks, will do.

14:03 llasram: That was exciting. Setting RET to paredit-newline in paredit's keymap stops RET from triggering evalulation in nrepl.el

14:03 I of course thought the particular command I was running was just mysteriously hanging everything

14:04 s,command,form,

14:04 Cool story, me

14:06 arrdem: /wc[A/join #yacc

14:09 headshot: danielglauser: thanks

14:10 amalloy: llasram: i think folks who use paredit in the repl bind S-RET or C-RET to send the current input

14:11 dabd: I am getting a blank *nrepl* buffer with no listener. But if I run lein repl on the command line it works fine. Any tips?

14:12 Emacs shows nothing useful on the Messages buffer

14:16 lynaghk: cemerick: I'm not super-opposed to the nested cljx expression rewrites

14:16 cemerick: it's not something I really want to get in the habit of, but I haven't been doing a ton of cross-platform code lately so I can't really speak for the needs of that (very tiny) community.

14:17 cemerick: before we go about implementing it in cljx, though, I'd rather see if we can merge with the lein-dalap guys

14:18 cemerick: since I do still firmly believe that having several community projects on this very tiny problem domain is goofy.

14:18 cemerick: lynaghk: well, I've turned it on in a org.clojars.cemerick fork, if only to see if chaos ensues

14:18 If only to eliminate the :require-macros crazy, I'll be happy

14:19 though protocol/type impls are brutal at the moment

14:19 lynaghk: the dalap stuff is very different; strictly clj -> cljs, not clj <- cljx -> cljs

14:20 lynaghk: cemerick: in theory shouldn't the cljs compiler itself be able to figure out the require-macros nonsense?

14:20 cemerick: yeah, sure. Still, I'd rather talk with them and see if their needs can be addressed by a modification of cljx and convince them to shut down their project

14:21 cemerick: lynaghk: yeah, almost surely; speculatively require, look up the var, invoke as macro if it's there and marked as such

14:21 lynaghk: cemerick: it seems like their main issue is that they want easier REPL editing and nicer transform rules

14:22 cemerick: That sort of magic seems to be frowned upon in general, witness having to require namespaces and then import types defined therein

14:22 lynaghk: I agree on both points; the former I get around via a cljx nrepl middlware

14:22 middleware*

14:23 lynaghk: cemerick: true. The require-macros doesn't bother me a ton, though it is annoying to have a separate my-project.macros clojure namespace for my ClojureScript projects.

14:23 cemerick: you and your fancy "nrepl" =P

14:23 cemerick: core.logic as the front-end is not super-fun, in the end

14:24 cool, but way more brain work than I'd like in that spot

14:24 lynaghk: cemerick: yeah, I hear you on that---I wouldn't be surprised if I have spent more time fighting/contributing to core.logic in my grammar of graphics project than I've spent with graphics stuff

14:24 cemerick: lynaghk: the require-macros stuff gets really gnarly if the macros are emitting calls to regular fns that really really should just be in a regular ns

14:24 not project.fns-separated-for-no-good-reason

14:25 lynaghk: cemerick: the simplest extension mechanism would be just a user-supplied transformation function that gets any annotated forms?

14:25 dnolen: lynaghk: hehe :)

14:26 lynaghk: dnolen: spent about two hours last night with the new constraint stuff--basically everything gets much more verbose when I try to replace the sketch/hacky partial-maps stuff with proper explicit constraints

14:26 cemerick: lynaghk: approximately; the closer it is to something familiar (macroexpansion), the better

14:26 dnolen: I'd rather just see people fight for feature expressions than continuing to pursue this stuff

14:26 lynaghk: dnolen: I may just end up doing a lot of form-walking of the rewrite rules and then generating constraint maps from that.

14:26 dnolen: yes!

14:27 dnolen: re: feature expressions, we would still need to figure out all of these issues. We're just doing it now via lein plugins on github, which is a lot more efficient than JIRA.

14:28 rplaca: ~.

14:28 clojurebot: Titim gan éirí ort.

14:28 dnolen: lynaghk: right, I wasn't sure unifier was something you would actually use as interface, rather it gives you hook for defining something higher level.

14:28 bbloom: dnolen: I've moved into my new place in NYC. we should get together sometime soon to hack on clojurescript

14:28 dnolen: bbloom: yes!

14:28 lynaghk: dnolen: yep. I'll keep you posted

14:28 bbloom: noooo, now who will I visit to hack cljs when I'm in Seattle?

14:29 bbloom: lynaghk: i'm sure somebody in the clj user group up there does some cljs, ask technomancy who he might know

14:30 dnolen: i'll email you

14:30 technomancy: lynaghk, bbloom: hm, I don't know anyone from Seajure who's using cljs

14:31 oh cbilson showed a little mobile dev demo using cljs and one of those JS cross-platform app thingies once

14:31 not sure if he uses it much or if that was just messing around

14:32 lynaghk: technomancy: oh, I'd be up to chat about that since that's what I've been up to lately

14:34 bbloom: lynaghk: honestly, i hacked up a browser-like environment with Apache Batik's SVG DOM so that I could have faster iteration on clj rather than cljs

14:34 lynaghk: i'm mostly concerned with getting the data representations & algorithms right for what i'm working on

14:34 then i'll port to cljs

14:38 i'm a few weeks behind on progress though... this move sucked away a ton of time....

14:40 llasram: amalloy: Oh yeah, I figured it out, and C-RET works. I just spent a while not knowing what was happening

15:01 cemerick: lynaghk: not sure if you meant it or not, but cljx 0.2.1 hasn't been deployed to clojars

15:06 SurlyFrog: I'd like to split a file into several smaller ones. I can do a `(with-open [rdr ….] (let [seq (line-seq rdr)] …) but I'm trying to figure out how to take n lines at a time, write them to a new file, while maintaining the list of newly created files so I can return it from my function. Any suggestions?

15:07 TimMc: SurlyFrog: You can use a local atom.

15:08 (let [ret (atom [])] (with-open ...) @ret)

15:08 SurlyFrog: TimMc: yeah, I thought about that. Is that the only way given Clojure's laziness?

15:08 lynaghk: cemerick: I did not; must've slipped through the cracks when I was traveling. It's deployed now.

15:09 TimMc: SurlyFrog: It's not so much about laziness as about management of state and mutation.

15:09 This function would be entirely eager, yes?

15:09 lynaghk: bbloom: I've looked at batik, but use too much CSS for it to be worthwhile---maybe when I have time I'll throw all of the appropriate phantomjs bits into a JAR.

15:10 bbloom: lynaghk: the style engine works

15:10 SurlyFrog: TimMc: yes, I need it to process the file, so I have to force evaluation of the lazy-seq returned by `line-seq`

15:10 timcharper: In leinengen 1.x, I remember dependencies being stored local to the project (./lib/*.jar). With leinengen 2.x, they are stored in ~/.m2 . I have a case where uberjar is not working, and an internal maven repository is not easily available to my Amazon EC2 compute cluster. I'd like to run `lein deps` and have it install it local to the project, so I can rsync up my code and all dependencies. Does anyone know if there is an

15:10 plugin to do so ?

15:11 bbloom: lynaghk: it was just a bitch to figure out how to activate it

15:11 lynaghk: bbloom: ohhh, interesting. I'll have to look into it

15:11 TimMc: timcharper: In lein 1.x they were already in m2, just copied from there to ./lib/

15:11 bbloom: lynaghk: just skip the docs and go to the source

15:11 lynaghk: bbloom: also benchmark phantomjs vs. batik for that use case.

15:12 TimMc: timcharper: I'd try really hard to solve the uberjar issue, if possible.

15:12 timcharper: TimMc: okay. Is there an option in lein 2.x to copy from m2 to lib and have it work such that when I invoke the code in the compute cluster it won't attempt to download them?

15:12 bbloom: lynaghk: well phantom is headless & i needed an interactive display. batik has an event model too

15:13 timcharper: TimMc: That's my hunch, but trying to crunch for a deadline tomorrow, so the optimization problem is pushing for immediate results over sustainability right now. :(

15:13 bbloom: lynaghk: haven't really perf tested at all yet, but it's been fast enough for my needs (for now)

15:13 timcharper: TimMc: My hunch being that I should try really hard and fix the uberjar issue :)

15:14 SurlyFrog: Does a `with-open` return anything? If I have a `let` form inside it, will it return the value of my let?

15:15 technomancy: timcharper: you can set :local-repo to a relative path to have it download everything it needs into the project dir

15:15 but fixing the uberjar is a better idea

15:15 amalloy: SurlyFrog: Try It And See

15:16 lynaghk: bbloom: it has an event model too, damn. I guess it basically comes down to the featureset and how much of a pain it is to get phantomjs working and deployed around.

15:16 bbloom: thanks for the infos.

15:16 TimMc: SurlyFrog: According to the source, yes.

15:16 timcharper: technomancy: Thanks! :local-repo sounds like the hack I seek. I'll give uberjar a bit more effort before succumbing.

15:16 lynaghk: bbloom: any of your batik-from-Clojure usage open source?

15:16 SurlyFrog: thanks

15:16 TimMc: timcharper: If it's really a crunch, make sure to give yourself time to get local-repo working, just in case...

15:17 timcharper: Is it an AOT issue?

15:17 timcharper: it's most likely a "I'm a retard" issue.

15:17 TimMc: That's software for ya.

15:17 sh10151: Is it legit to use Clojure agents to make a simple work queue, even though I don't really care about sharing state among the threads?

15:17 bbloom: lynaghk: not yet, but i just pasted the most important file to here: https://www.refheap.com/paste/11180

15:17 timcharper: TimMc: lol

15:19 llasram: sh10151: Depends on the problem you want to solve. The stuff in java.util.concurrent is pretty awesome, so you could just actually use a *BlockingQueue and be done with it

15:20 timcharper: TimMc: I'm specified my :main namespace such that `lein run` will invoke the desired -main function. That works. When I run `lein uber jar`, and then invoke the produced standalone jar with java -jar project-0.x-standalone.jar, I am presented with the following error: Exception in thread "main" java.lang.NoClassDefFoundError: concentro/sim/cor

15:20 sh10151: llasram: That's my initial impression -- I've done a lot of Java. I just don't want to do something that Clojure experts will look at me funny for.

15:20 technomancy: timcharper: are you AOTing the gen-class namespace?

15:21 it used to be magically implied with :main, but that was removed

15:21 lynaghk: bbloom: awesome, thanks. I might rip some of this into the c2po clojure demo (in my copious-amounts-of-spare-time =P)

15:21 timcharper: TimMc: Opening the jar reveals that the namespace concentro/sim/core has been compiled and included

15:21 sh10151: llasram: problem is very standard "listen to a message queue, dispatch workers to process requests but also keep listening for more messages"

15:21 bbloom: lynaghk: feel free

15:21 i've also got a half dozen branches lying around with other things related to this, so let me know if you run into problems

15:22 technomancy: timcharper: so java claims the .class file doesn't exist, but opening the jar claims otherwise?

15:22 llasram: sh10151: BlockingQueue sounds perfect then to me. Heck, clojure.core uses it

15:23 timcharper: technomancy: right, that seems to be the case. I open it and this file is present: concentro/sim/core$_main.class (btw, my error, when pasting, was truncated and was missing the trailing e.)

15:23 java -jar concentro-0.2.0-standalone.jar

15:23 Exception in thread "main" java.lang.NoClassDefFoundError: concentro/sim/core

15:24 technomancy: what about just concentro/sim/core.class?

15:24 timcharper: technomancy: I'm not sure as to whether or not we are AOTing the gen-class namespace, and shamefully, less sure as to what that means.

15:24 technomancy: ok, you should have :aot [concentro.sim.core] in project.clj

15:28 hiredman: technomancy: itym #{concentro.sim.core}, obviously it should be a set

15:29 technomancy: heh; sure

15:31 timcharper: technomancy, TimMc : not in there either. I just asked to my colleague, the author of said project I'm trying to deploy to the cloud, and he said he understands why uberjar isn't working, and that it will be some work to get it working. So I'm going to wave a white flag on uberjar and pursue the hopefully quicker :local-repo option :) Thank you so much for both of your help!

15:33 (he was previously not available, otherwise I would have asked him first :) )

15:34 TimMc: timcharper: Is it an AOT issue? I wrote lein-otf to deal with this kind of thing.

15:34 (You can have an executable jar that compiles on the fly instead of ahead of time.

15:34 )(

15:34 grah)

15:39 timcharper: TimMc: turning on AOT didn't seem to help. My collegue doesn't seem to think that's the problem. :gen-class was not in my target namespace's declaration.

15:39 TimMc: Trying to turn that on now

15:40 and that appeared to be it. lein uberjar is working now!

15:40 TimMc: \o/

15:41 Yep, it's a bit of unavoidable redundancy right now.

15:41 I wonder if kibit could catch some of these scenarios.

15:50 ivan: does anyone use http://gittup.org/tup/ for building Java things?

15:51 mattmoss: I've used it a little for C++, not java.

15:54 ivan: I need some thing for building Java things that is not Maven, or if not that, some way to build all those Maven plugins everyone uses from source

15:54 * ivan finds https://groups.google.com/forum/?fromgroups=#!topic/tup-users/TDkmawwFgqc

15:55 p_l: Gradle seems pretty nice

15:55 llasram: ivan: lein is working for us

15:57 thorwil: does some-> have some problem with anonymous fns?

15:58 TimMc: thorwil: Yes, stitching macros and reader sugar often don't play well together.

15:58 &(macroexpand-1 '(-> 5 #(do)))

15:58 lazybot: ⇒ (fn* 5 [] (do))

15:59 TimMc: &(macroexpand-1 '(-> 5 (#(do))))

15:59 lazybot: ⇒ ((fn* [] (do)) 5)

15:59 thorwil: &(some-> 1 identity)

15:59 lazybot: java.lang.RuntimeException: Unable to resolve symbol: some-> in this context

15:59 TimMc: Well, #(do) is a silly example, but you get the idea.

16:02 brehaut: ha, pythons 'input' function does read eval. how odd

16:02 thorwil: and *poof* goes my ticket to a concise solution. ty

16:05 actually no, all it takes is an extra () around the (fn)

16:05 TimMc: Yep.

16:10 &(->> 5 #'+)

16:10 lazybot: ⇒ #'clojure.core/+

16:10 TimMc: &(->> 5 (#'+))

16:10 lazybot: ⇒ 5

16:11 SurlyFrog: Would somebody like to take a quick look at a small piece of code and critique it?

16:12 gfredericks: clojurebot: list?

16:12 clojurebot: list* doesn't actually make a `list?`

16:12 gfredericks: ^ the '*' points to a footnote: * not actually a list

16:12 TimMc: haha

16:13 seangrove: In emacs, if I have an nrepl session running but I've killed the buffer with the repl input, how can I get it back?

16:13 TimMc: "Some restrictions may apply. Not valid in all VMs. Void where prohibited."

16:13 seangrove: I've just been restarting the whole process so far

16:13 SurlyFrog: It's here if anyone has a moment. http://pastebin.com/KwX6Vyhz The goal is to take a large file, and break it into several new temporary files which can be processed further.

16:16 TimMc: SurlyFrog: I might've used vec + dorun + map myself.

16:16 SurlyFrog: TimMc: how so? `dorun` instead of `reduce`?

16:17 TimMc: (vec (dorun (map #(seq-out % dir) (partition-all count seq))))

16:18 amalloy: TimMc: (vec (dorun ...))?????

16:18 TimMc: erk

16:18 doall

16:18 arkx: Why not (mapv ...)?

16:18 TimMc: &(doc mapv)

16:18 lazybot: ⇒ ------------------------- clojure.core/mapv ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each co... https://www.refheap.com/paste/11183

16:18 amalloy: TimMc: just throw away the doall part: (vec ...) is equivalent but faster

16:18 TimMc: amalloy: Oooh, good point.

16:18 SurlyFrog: I get confused by `doall`, `doseq`, etc.

16:18 TimMc: amalloy is my kibit

16:19 I highly recommend it.

16:19 SurlyFrog: So simply calling `vec` on the lazy sequence created by map will force realization of it?

16:20 amalloy: i don't see where you're suggesting he use vec anyway though, TimMc. in split-file?

16:20 TimMc: amalloy: The last line, yes.

16:21 amalloy: yeah. i guess that line is just (mapv #(seq-out % dir) (partition-all count seq))

16:24 SurlyFrog: amalloy: that works and is a bit easier to read. Thanks, to you and TimMC

16:24 for taking the time to look at it

16:51 cemerick: lynaghk: not sure if you've been following the topic, but this works (gnarly, but produces cljx output with forms on the "correct" lines): https://github.com/cemerick/cljx/commit/079f1c890be1857dc68d4183249dd342712c4ef2

16:52 er, https://github.com/cemerick/cljx/commit/c331257 I mean

16:53 lynaghk: cemerick: have you needed to debug the cljx output very often?

16:53 cemerick: if you think that's useful feel free to push it upstream.

16:54 cemerick: lynaghk: sure; stack traces, certainly. Source maps soon, hopefully.

16:54 frozenlock: Is there any advantages in using cljx instead of lein-cljsbuild crossovers?

16:54 cemerick: I mean, both point to the line number in the .clj/.cljs file fine, but reading the output there is horrid.

16:55 lynaghk: frozenlock: cljx does rewrites to certain protocol names automatically, which is nice

16:56 cemerick: good point re: stacktraces. go for it, and thanks.

16:56 cemerick: frozenlock: and you can write rules to e.g. transform Clojure-style catch/throw forms to something reasonable in ClojureScript

16:56 etc etc

16:57 lynaghk: ok; I'll just need to twiddle the commit order to cherry-pick that bit, and fill in the same treatment for sets, vectors, etc.

16:57 frozenlock: Oh interesting. I'll keep that in mind if I ever need to write clojure code that interops with js/jvm.

17:00 lynaghk: frozenlock: The motivating use case for me was C2, which has a lot of mathy transformation type stuff that wanted to be on both platforms

17:05 gfredericks: is c3p0 (the connection pooling lib used by korma) reputable?

17:08 technomancy: gfredericks: gave me nothing but trouble

17:08 gfredericks: technomancy: dangit.

17:24 tolsen: Hello. I am having trouble doing some println debugging. I can't seem to get the following to print before the exception is thrown: (map (fn [x] (println "HELLO") (throw (RuntimeException.))) (range 1 10))

17:27 dnolen_: tolsen: you need wrap in doall, map is lazy

17:28 tolsen: weird. that feels almost out-of-order lazy as my println comes before the throw in the fn

17:32 morphling: tolsen|away: seems unlikely. You could try to flush the output stream?

17:33 tolsen|away: also, if that helps, println apparently calls prn, which observes *flush-on-newline*

17:36 tgoossens: Hi. I just started planning on organising a clojure meetup in belgium. Any advice?

17:40 frozenlock: tgoossens: Yes, do it in Canada =D

17:40 tgoossens: haha

17:55 ppppaul: frozenlock, already exists

17:55 in toronto, at least

18:06 frozenlock: ppppaul: Any recordings?

20:30 *cricket*

20:33 Hodapp: *wombat*

20:39 rbarraud: *echidna*

20:40 mattmoss: o_O

20:41 Raynes: *hedgehog*

20:42 metellus: none of those animals would wear earmuffs.

20:42 Raynes: I bet Sonic would if it were really cold.

20:44 ivan: *-XX:+PrintCompilation*

20:45 mattmoss: (binding [*hedgehog* 'sonic] (do ...)) ?

20:45 ivan: heard in #jruby the -XX:+TieredCompilation -XX:TieredStopAtLevel=1 settings took another second off the time

21:58 technomancy: lein uses tieredcompilation

21:58 I haven't looked into the other one though

22:00 holy smokes; 0.7s shaved off

22:04 ivan: hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp also suggests some alternate tweaks

22:04 I wonder if TieredStopAtLevel can be raised after it starts

22:13 matthavener: ivan: crazy, just googled what you were talking about

22:14 ivan: jruby guys searching for fastest: https://gist.github.com/teohm/4343392

22:14 ivan: nuts

22:14 -noverify is indeed a big help

22:16 what's -X-C?

22:19 oh, the -X options there are not passed to java

22:22 technomancy: noverify is redundant if you use bootclasspath iirc

22:22 ivan: right, assuming you put everything into bootclasspath

22:22 technomancy: though you might be able to use noverify for the project-level JVM

22:24 hm; doesn't seem to have an effect

22:30 warz: is clutch the suggested couchdb client lib? it looks good, just a few months without any commits, so figure id ask

22:33 ivan: user> (.getDiagnosticOptions (sun.management.HotSpotDiagnostic.))

22:33 UnsatisfiedLinkError sun.management.Flag.initialize()V sun.management.Flag.initialize (Flag.java:-2)

22:33 I was hoping to use that to change TieredStopAtLevel

22:41 djwonk: Hello, does someone remember the business-focused report that recommends adopting Clojure?

22:42 ivan: ThoughtWorks Tech Radar

22:42 djwonk: I can't remember if it was O'Reilly Radar or Garner...

22:42 ivan: thanks! Thoughtworks

22:42 Garner -> Gartner

22:44 SurlyFrog: Is there a Clojure equivalent to Common Lisp's `with-standard-io-syntax`? I want to dump Clojure data into files and read it back, but using clojure.java.io/reader seems to interpret each line as a string.

22:44 epitron: Jennifer Gartner

22:44 ivan: heh

22:45 yogthos: SurlyFrog: something like this ? http://clojuredocs.org/clojure_core/clojure.core/read

22:46 SurlyFrog: yogthos: basically, but I need to be able to move through the file line-by-line.

22:47 yogthos: SurlyFrog: read reads by form since a form could span multiple lines

22:48 SurlyFrog: yogthos: yeah, just saw that…..hmmm, maybe that has to be the way....

22:49 Actually, is there a way to read through two files, line by line? I can do it with a `map` over two line-seqs, but that only works if the two files have the same number of lines. What I need is some sort of loop/recur/cond form.....

22:51 yogthos: SurlyFrog: so what are you trying to do with the contents?

22:51 SurlyFrog: merge them into a single, sorted file.

22:52 yogthos: you could read both then concat and sort

22:52 you could also use reduce

22:52 tomoj: (fn [& seqs] (->> seqs (map #(concat % (repeat nil))) (apply map vector) (take-while #(not-every? nil? %)))) ?

22:52 SurlyFrog: They could be *really* big, so I don't want to read them all into memory.

22:52 yogthos: (reduce (fn [[f1 f2]] ...) [f1 f2])

22:53 you could iterate as well

22:53 SurlyFrog: I haven't looked at iterate, let me check that out...

22:53 cemerick: is anyone else seeing a suspicious 60s delay in the jvm exiting after running `lein cljsbuild once`?

22:54 yogthos: so you'd iterate over the accumulator and the function called at each step could be reading the files

22:55 SurlyFrog: It says the function passed to iterate must be free of side effects. I'd be reading a value from both files, then writing them into a third, sorted file.

22:57 yogthos: if you're just reading and writing without doing anything in memory loop might actually be the way to go

22:58 tomoj: SurlyFrog: to be clear that fn was for you

22:58 SurlyFrog: tomoj: oh, I didn't know that.

22:58 tomoj: &((fn [& seqs] (->> seqs (map #(concat % (repeat nil))) (apply map vector) (take-while #(not-every? nil? %)))) [1 2 3] [4 5] [6])

22:58 lazybot: ⇒ ([1 4 6] [2 5 nil] [3 nil nil])

22:59 tomoj: that's one way to get map but running out at the longest instead of the shortest

23:00 or is that not the problem with using map for that

23:00 yogthos: tomoj: sounds like the data might be to big to keep in memory as well

23:01 tomoj: no problem then, map is lazy

23:03 yogthos: good point, if it got consumed as it maps should be fine

23:04 amalloy: if his plan is to merge two sorted files into a larger sorted file, none of these "one item from each' approaches work at all

23:05 Xorlev: Do you guys have any tips for keeping data structures straight as program complexity grows? In more static languages, types are rather explicit but they're a lot less so in Clojure.

23:05 yogthos: Xorlev: naming conventions help

23:06 Xorlev: for example in the standard lib if a function takes a map it's usually denoted as m, key values as k v, etc

23:07 Xorlev: Pseudo-hungarian approach then... okay, I think I could deal with that. How about things like maps -- what keys does it need to actually be useful? Or is that when you'd define a protocol instead?

23:08 SurlyFrog: tomoj: thanks, that works!

23:08 tomoj: I'm surprised

23:09 I thought amalloy was right

23:09 SurlyFrog: well, it solves the problem I asked about, amalloy just pointed out another issue :-)

23:09 tomoj: ah, yes :)

23:09 yogthos: hehe

23:09 Xorlev: documentation is often used to help figure out what's what, for example https://github.com/ring-clojure/ring/blob/master/SPEC

23:10 SurlyFrog: Is there not a disk-based merge sort already canned someplace?

23:10 amalloy: i mean, the whole thing is easily modeled as (write-to-file "out" (lazy-merge-sort (read-file "in1") (read-file "in2")))

23:11 yogthos: Xorlev: in general it helps to add docs inline to the functions inline as well

23:11 amalloy: all of those functions already exist

23:11 under some name or other

23:11 yogthos: a lot of time solving a problem is a game of finding the right functions to glue together :P

23:12 Xorlev: yogthos: Thanks for the link to the ring docs, that makes a lot of sense :) I'm embarking on my first non-trivial Clojure application. Have a great night/day

23:12 yogthos: Xorlev: good luck :)

23:12 SurlyFrog: yeah….I know, I just haven't found what I was looking for.

23:12 yogthos: Xorlev: my biggest advice is to keep the functions short and readable :P

23:13 Xorlev: That's something I've noticed...Clojure forces you away from monolithic functions.

23:13 Or into catchy hard-to-decompress one-liners. Not sure what's worse.

23:13 yogthos: SurlyFrog: might be useful :) https://github.com/chrismgray/clojure-heap-sort

23:14 Xorlev: you have to have a bit of discipline when writing stuff, if something is hard to read it probably should be refactored

23:15 spjt_: anyone bored and want to do a code review of my first clojure program? :)

23:15 yogthos: Xorlev: while it's often tempting to write really dense code, it's really best not to

23:15 spjt_: could take a look :P

23:15 Xorlev: People make the same mistakes with Scala. Some library authors, even

23:15 SurlyFrog: yogthos: it looks like that does everything in memory

23:16 spjt_: yogthos: http://pastebin.com/g83F3bGF

23:16 yogthos: It's for a school assignment but I've already turned it in.

23:16 yogthos: Xorlev: I find one thing I do is write a solution first, and then refactor it to clean it up after

23:16 spjt_: yogthos: It generates a list of primes between prime-min and prime-max. It's very slow.

23:16 yogthos: Xorlev: with a repl it's pretty natural to do, and because you're working with an AST, you can just rip out nodes and make them into standalone functions

23:17 spjt_: gotcha :)

23:18 Xorlev: yogthos: I'll give that a try. Thank you so much :)

23:18 yogthos: Xorlev: no prob :)

23:19 spjt_: are the agents part of the requirement? :)

23:19 spjt_: yogthos: It has to be multithreaded.

23:20 yogthos: It does "efficiently" distribute the workload over multiple cores, at least in the sense that it heats up the CPU good (all cores running at 100%) but it still takes a long time.

23:21 yogthos: spjt_: generating primes is slow business, hence why encryption still works :P

23:21 spjt_: yogthos: My general question which I've never really seen addressed is the relative efficiency of the different data structures in Clojure (e.g. I use sets for the "small primes" and a list for the "large primes")

23:22 yogthos: It's all anecdotal but the people who used C++ said they got "4 seconds" whereas mine takes around 70 seconds, of course given whatever computer they have and I have, which I have no idea.

23:23 yogthos: spjt_: yeah there's some variation there

23:23 spjt_: also did you run with the -server flag?

23:23 spjt_: and you might want to try multiple runs to let it warm up

23:23 spjt_: I mean within the same jvm session

23:23 spjt_: yogthos: The best I can say is that the clojure program took 70 seconds of wall time and 250 seconds of CPU time on a 4-core CPU :)

23:24 yogthos: you could fiddle with partition sizes as well

23:24 spjt_: yogthos: I did fiddle with that, 100K gave the best results

23:24 yogthos: ah :)

23:25 spjt_: That was part of the problem, I couldn't figure out how to compile it or use -server flags

23:26 i guess i figured out -server

23:26 ivan: how do I call a static method on a package-private class?

23:26 yogthos: spjt_: you can add :jvm-opts ["-Xmx1g" "-server"] in your project.clj

23:27 spjt_: project.clj?

23:27 clojurebot: unquote in project.clj is an escape hatch

23:27 spjt_: server definitely helps

23:27 yogthos: spjt_: if you use leiningen to build https://github.com/technomancy/leiningen

23:28 spjt_: yogthos: I couldn't use leiningen, it had to compile and run from a shell script on a server without clojure installed

23:28 yogthos: spjt_: ah gotcha

23:28 spjt_: yogthos: It runs in 51s with -server, though.

23:29 yogthos: spjt_: some tricks here https://groups.google.com/forum/?fromgroups=#!topic/clojure/yPaQN7JuKFY

23:29 spjt_: significant improvement :P

23:30 spjt_: this should help as well -Xincgc : enable incremental garbage collector

23:30 although that might be enabled by default now?

23:31 spjt_: I probably could have used knowing how to compile without leiningen

23:31 technomancy: spjt_: for wringing the last bits of perf out of Clojure this is a pretty good overview: http://meshy.org/2009/12/13/widefinder-2-with-clojure.html

23:31 if you're I/O bound anyway; for numerics it'll be different

23:32 tmciver: spjt_: you may also want to check out ##(doc pmap)

23:32 lazybot: java.lang.SecurityException: You tripped the alarm! pmap is bad!

23:32 spjt_: I don't think it was IO bound

23:32 tmciver: hmm

23:33 yogthos: technomancy: that's pretty thorough link, I'm bookmarking that for future reference :)

23:33 &(doc pmap)

23:33 lazybot: java.lang.SecurityException: You tripped the alarm! pmap is bad!

23:34 yogthos: aww

23:34 technomancy: lazybot: I am disappoint

23:34 spjt_: my program may not have been the fastest, but I'll bet it was the shortest :)

23:34 nightfly: &(doc #'pmap)

23:34 yogthos: spjt_: and pretty readable to boot :P

23:34 lazybot: java.lang.SecurityException: You tripped the alarm! pmap is bad!

23:35 tmciver: maybe something like (pmap check-prime (range max-prime)) where check-prime could create a map with a key indicating if the value was prime. Then you could filter that.

23:35 spjt_: yogthos: yeah, I could have made it about 1/3 the size by composing all the functions. I also noticed after I wrote it that I could have just wrote 1E7 instead of (Math/pow 10 7) :)

23:37 It's my first clojure program, so I'm not expecting anything too spectacular

23:37 yogthos: tmciver: might be better to partition first (pmap check-primes (partition-all 1000 (range max)))

23:38 spjt_: In my programming languages class we had to give a talk to convince the class to do one language or another, I failed and we're doing Haskell

23:39 yogthos: spjt_: haskell is good for you :P

23:39 tmciver: yogthos: is pmap not parallelized for a single collection. I've never actually used it. :)

23:39 spjt_: Haskell isn't good for me

23:39 yogthos: tmciver: I've used it once in production so far :)

23:40 spjt_: most ideas translate well to clojure, if you get good at haskell you'll grok clojure better as well

23:40 spjt_: I'd think lisp is best for teaching people used to imperative programming how to do functional programming in a controlled environment because there's none of the "what does :!:@-> mean"

23:41 yogthos: spjt_: well lisp does have really simple syntax going for it

23:41 TimMc: spjt_: Don't be too sure. :-P

23:41 ~rest

23:41 clojurebot: rest is easy to write without alphanumerics: https://www.refheap.com/paste/5980

23:41 yogthos: spjt_: I don't know why so many people are averse to it

23:41 TimMc: You can still have line noise in a Lisp!

23:41 tmciver: TimMc: cut it out.

23:41 TimMc: haha

23:41 tmciver: :)

23:42 yogthos: macros can certainly get pretty impenetrable :P

23:42 abp`: That's how I program all day long.

23:42 nightfly: spjt_: Yeah, I had several false starts at learning functional programming with Haskell. Clojure was fairly simple to get into.

23:42 yogthos: TimMc: and that is pretty epic :P

23:42 spjt_: I ended up learning functional programming with Scala because, well, if I couldn't do it functional, I could at least do it.

23:43 yogthos: solvip: I started with Scala, but I found I just kept going back to what I know

23:43 err spjt_ not solvip :)

23:43 spjt_: so then I jumped into deep end with haskell and eventually it started making sense :) after that I moved to clojure and stayed with it :)

23:44 spjt_: My project last summer was to learn a functional language, and Scala ended up winning mostly because I could fall back on imperative when I couldn't figure out how to do it functional

23:45 when I came back to Clojure after that it all made a lot more sense.

23:46 yogthos: spjt_: I find scala to be very busy, it seems to take c++ approach of just throwing every language concept into a cauldron :)

23:47 spjt_: yogthos: yeah, but sometimes that means "I know how to do it in X language, and here it is" :)

23:48 I could definitely see scala in the wrong hands being far, far worse than PHP

23:48 yogthos: spjt_: what I found really neat is that by not making an arbitrary distinction between how you treat logic and data you get all these nice things by default

23:48 spjt_: what I mean is when you have first class functions, you can pass them as parameters

23:49 spjt_: all of a sudden all these visitor patterns, and dependency injection, etc. disappear, you just pass a function in

23:49 spjt_: you can do that in almost any language if you try hard enough

23:49 yogthos: spjt_: nice and simple, by capturing scope and returning functions you can make equivalent of constructors with closures, but you're not introducing any special cases

23:50 spjt_: the worst is anonymous classes in java, they make me want to cry

23:50 yogthos: spjt_: the thing that's appealing is that you just use simple and consistent rules to do all this stuff a lot of languages create special cases for

23:51 spjt_: half the frameworks in java are there to compensate for language deficiencies :)

23:51 spjt: there was an amusing article on that http://www.grahamlea.com/2013/02/a-new-java-library-for-amazing-productivity/

23:52 spjt: we use "java" at my job, i need to convince them to use clojure, after all, "it works with java"

23:52 yogthos: spjt: it can be done, took me 2 years but we actually moved to clojure on my team :)

23:52 spjt: it might take me two years to figure out how to compile clojure

23:52 yogthos: spjt: I found you have to be very patient about it :)

23:53 spjt: leiningen ;)

23:53 spjt: yeah, leiningen probably won't be as much of a problem at work as it is in class

23:54 yogthos: spjt: and if a place is really conservative there's maven :)

23:54 spjt: the thing about that is there's a difference between people writing it and people reading it

23:55 People would see my Scala code and just be? "wtf"

23:55 yogthos: spjt: but there is a really good case to be made, it runs on the same infrastructure, you can use the same build tools, same build servers, same deployment options, even same IDE

23:55 spjt: the only thing that changes is the language

23:55 spjt: bad scala looks like java, good scala looks nothing like it

23:56 yogthos: spjt: scala does seem to be picking up in popularity, I'd certainly rather work with it than java

23:58 spjt: how much of that is java programmers who like not having to put in semicolons

23:59 yogthos: spjt: can hope it's the gateway drug :P

Logging service provided by n01se.net