#clojure log - Aug 01 2014

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

0:27 andrei: What's the status of clojure debuggers? ritz seems to be dead

0:29 justin_smith: andrei: schmetterling is not complete, and has at least one really annoying bug (an exception inside its inspector causes a lockup requiring a restart) but is otherwise kind of nifty

0:30 andrei: on an exception, you get a browser based UI to evaluate code in the various stack frames where the exception was thrown

0:30 https://github.com/prismofeverything/schmetterling

0:30 andrei: justin_smith: Cool! Thanks. Anything with emacs integration?

0:31 justin_smith: also it was written by the guy who talked me into learning clojure, who is an old and dear friend of mine, so don't say mean things about it

0:31 andrei: hmm

0:31 technomancy: you should mention that in the readme justin_smith

0:31 justin_smith: nothing with nice integration that I know of

0:31 technomancy: otherwise people won't know

0:31 justin_smith: technomancy: I don't have commit rights to the repo!

0:31 technomancy: PR!

0:31 andrei: justin_smith: Thanks!

0:31 One more question, any clojure profilers?

0:31 justin_smith: heh

0:32 andrei: java profilers (including jvisualvm and yourkit) will give slightly obscure class names, but accurate info

0:32 you may not recognize your code at first, but it is hiding in that profile data somewhere :)

0:32 andrei: justin_smith: I've used jvisualvm but it's very poor for clojure. Doesn't integrate with any other tools, startup time is huge

0:34 justin_smith: yourkit gets talked about (and maybe thats not only because it gives you a free license to use it for open source if you mention it in your readme)

0:54 andrei: justin_smith: Thanks, I just tried yourkit. It doesn't seem to be able to print out line numbers, just functions

0:55 justin_smith: ouch

0:55 but at least you get function names I guess

0:56 andrei: justin_smith: Yeah.. it's a pretty lacklustre tool

0:57 justin_smith: andrei: to be frank, I would have contributed to schmetterling, but I find my best route to sort out my clojure code is to keep things small and as purely functional as possible (so that unit testing is trivial or nearly so to set up). Though I have had the good luck not to need to do serious performance profiling.

1:03 andrei: justin_smith: Yeah, that was good back when everything I had was small and performance didn't matter too much. But side effects are important for good performance and applications tend to grow over time

1:07 justin_smith: with any luck I may have that problem some day :)

3:28 arrdem: http://grimoire.arrdem.com:3000/ <- 0.3.0 release candidate. please brake it. <3

3:28 __daniel__: break*

3:28 arrdem: :P

3:28 it's late

3:29 hyPiRion: the brakes

3:29 arrdem: where are inc', dec', +' etc?

3:30 arrdem: hyPiRion: present.. http://grimoire.arrdem.com:3000/1.6.0/clojure.core/inc%27/

3:30 in the functions section of http://grimoire.arrdem.com:3000/1.6.0/clojure.core/

3:30 idk if they're indexed in the cheat sheet. that's andyf's project that I coopted

3:31 hyPiRion: arrdem: oh

3:31 I just did a search and was confused it didn't pop up

3:31 __daniel__: they show up for me when i search

3:32 hyPiRion: __daniel__: the "inc'" function?

3:32 note the trailing quote

3:37 __daniel__: ah no hyPiRion, didn't notice the quote

4:54 michaelr525: hi

4:55 how can I tell emacs to indent clojure code like here: https://github.com/swannodette/om/wiki/Intermediate-Tutorial?

4:56 right now with a function call where the first argument is on the first line, the second line is indented so it aligns with the position of the first argument. and it's a bit too much for "html" type nesting

5:01 oh put-clojure-indent, define-clojure-indent

5:21 dalzony: 안녕하세요. HELLO

5:22 michaelr525: Hello

5:23 dalzony: what lang is that?

5:23 dalzony: that is Korean! :)

5:23 michaelr525: looks interesting

5:24 is that a whole sentence or a single word?

5:24 dalzony: whole sentence, that means "hello"

5:25 michaelr525: haha

5:31 TEttinger: korean is notable for being the only pretty-much-conlang in wide use today, unless you count modern hebrew (pretty different from ancient hebrew)

5:32 the script is like no other script, it was made from scratch, rather than evolving like the latin alphabet (phoenician to greek to latin, etc.)

5:35 dalzony: Korean(called 'Hanguel') was created by King Sejong

6:16 clgv: ,(let [a 1] (eval '(inc a)))

6:16 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>

6:16 clgv: eval does not inherit the local variable scope I guess

6:17 TEttinger: ,(let [a 1] (eval `(inc a)))

6:17 clojurebot: #<CompilerException java.lang.RuntimeException: No such var: sandbox/a, compiling:(NO_SOURCE_PATH:0:0)>

6:17 clgv: ,(let [a 1] (eval `(inc ~a)))

6:17 clojurebot: 2

6:17 TEttinger: there we go

6:18 clgv: well I guess the above is the way to go.

6:18 I have a complicated macro where I need two incarnations that differ only by an additional condition clause...

6:19 trying to get it to work without copy&paste and not too much effort

6:19 Glenjamin: macro-macro!

6:20 clgv: Glenjamin: yeah there are several macrolayers ;)

6:22 ah well, guess I add two other params to the config-map to avoid relying on name capturing

6:31 wizzo: is there a special way to handle functions failing during ->

6:31 or just handle exceptions?

6:34 clgv: wizzo: no only normal exception handling if exceptions are involved. if you functions return nil or false on failure you can use `some->` and `some->>`

6:34 wizzo: oh!

6:34 some-> is exactly what i want. thankyou!

6:36 blunte: I see why my dissoc isn't doing what I want, but I'm not sure what the correct way to do this is:

6:36 ,(let [junk [:a :b]] (dissoc {:a 1 :b 2 :c 3} junk))

6:36 clojurebot: {:c 3, :b 2, :a 1}

6:37 blunte: It tried to dissoc [:a :b] instead of :a and :b

6:37 nathan7: apply!

6:37 ,(let [junk [:a :b]] (apply dissoc {:a 1 :b 2 :c 3} junk))

6:37 clojurebot: {:c 3}

6:38 blunte: Hmm, I thought I had tried that already :). Guess not. map/apply/reduce shouldn't confuse me, but I'm not picking it up quickly for some reason. Thanks!

6:39 nathan7: (apply dissoc {:a 1 :b 2 :c 3} [:a :b]) is the same as (dissoc {:a 1 :b 2 :c 3} :a :b)

6:39 blunte: is it not more like (dissoc {...} :a) (dissoc {...} :b) ?

6:40 as in, calling dissoc one time for each element of the array

6:40 wizzo: is splits the list you give it into separate arguments

6:40 for the one function call

6:41 blunte: ahh I see. I just misunderstood it. Thanks :)

6:41 wizzo: it wouldn't work if dissoc didn't allow multiple keys

6:41 map is more like what you're describing though

6:41 blunte: ah ha

6:43 nathan7: blunte: reduce would do that

6:43 blunte: (apply f [x y z]) is just (f x y z)

6:43 blunte: and (apply f x [y z]) is also just (f x y z), etc

6:43 blunte: nathan7: thanks, very clear example

6:44 nathan7: blunte: in most languages, apply just takes a function and a sequence

6:44 blunte: in Clojure it takes extra args as a convenience

6:45 wizzo: apply takes extra args?

6:47 blunte: I think the x in the example is the "extra" argument

6:47 nathan7: ,(apply list 1 2 [3 4])

6:47 clojurebot: (1 2 3 4)

6:48 wizzo: oooh i see

6:48 neat

6:48 blunte: quite handy

6:51 tac: what is , ?

6:51 nathan7: to tell clojurebot to evaluate it

6:51 tac: ahh

6:51 ,'(1 2 3)

6:51 nathan7: tac: you can also use it inline, like this: ##(apply list 1 2 [3 4])

6:51 clojurebot: (1 2 3)

6:51 lazybot: ⇒ (1 2 3 4)

6:51 nathan7: though that's a different bot

6:51 tac: I see ##'(1 2 3)

6:51 lazybot: ⇒ (1 2 3)

6:55 tac: ,(apply list [1 2] [3 4])

6:55 clojurebot: ([1 2] 3 4)

6:56 tac: ,(list 1 2 [3 4])

6:56 clojurebot: (1 2 [3 4])

6:56 clgv: ,(list* 1 2 [3 4])

6:56 clojurebot: (1 2 3 4)

6:58 TEttinger: ,(list* [1 2] [3 4])

6:58 clojurebot: ([1 2] 3 4)

6:58 nathan7: apply uses list* internally

6:58 tac: So apply then takes a function, hits it with all the supplied arguments, then hits it with any remaining arguments in a list?

7:00 ,(apply + 1 2 [3 4 5])

7:00 clojurebot: 15

7:00 tac: woo

7:01 nathan7: well, the base case is (apply f s)

7:01 (apply f x y z s) is just (apply f (list* x y z s))

7:01 clgv: nathan7: but not literally ;)

7:01 nathan7: clgv: read the source of apply — it is

7:02 tac: list* is a macro then?

7:02 clgv: it's not defined recursively ;)

7:02 nathan7: well, no

7:02 tac: ,(list* + [1 2])

7:02 clojurebot: (#<core$_PLUS_ clojure.core$_PLUS_@163b85> 1 2)

7:02 clgv: it uses (. f (applyTo ...)) in each case

7:02 nathan7: yeah

7:02 tac: crap. I created a closure.

7:03 oh

7:03 clgv: tac: not really ;)

7:03 tac: no I didn't. That just printed the function

7:03 I see now

7:03 clgv: ,(list* '+ [1 2])

7:03 clojurebot: (+ 1 2)

7:03 TEttinger: ,(eval (list* + [1 2]))

7:03 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

7:03 tac: tsk tsk. Trying to eval on a public bot!

7:03 clgv: ,(eval (list* '+ [1 2]))

7:03 clojurebot: 3

7:03 clgv: ;)

7:04 TEttinger: tac, it's a good bot!

7:04 tac: it's pretty neat

7:04 TEttinger: (inc clojurebot)

7:04 lazybot: ⇒ 41

7:04 tac: All the cool languages get bots in their channels nowadays

7:04 TEttinger: we have two

7:04 tac: (get clojurebot)

7:04 err

7:04 TEttinger: $karma clojurebot

7:04 lazybot: clojurebot has karma 41.

7:04 clgv: tac: it's pretty useful to add examples to answers ;)

7:04 (inc 42)

7:04 lazybot: ⇒ 6

7:05 clgv: way to go...

7:05 Glenjamin: i like how it's 6

7:05 TEttinger: why does 42 have 6 karma?

7:05 clgv: should be 23 right? :P

7:05 TEttinger: (inc 42)

7:05 lazybot: ⇒ 7

7:07 hyPiRion: (inc 42) should be.. 43

7:08 tac: ,42

7:08 clojurebot: 42

7:10 TEttinger: ,36rqwerty

7:10 clojurebot: 1626557542

7:11 tac: ,(hd '(1 2 3))

7:11 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: hd in this context, compiling:(NO_SOURCE_PATH:0:0)>

7:11 * tac doesn't know what he's doing

7:11 Glenjamin: TEttinger: what was that :s

7:11 TEttinger: radix 36 number

7:12 Glenjamin: ah

7:12 36r is the prefix?

7:12 TEttinger: ,36rSENTENCE

7:12 clojurebot: 2226111661742

7:12 Glenjamin: ,16rFF

7:12 clojurebot: 255

7:12 Glenjamin: right

7:20 TEttinger: ,(map #(Long/parseLong (clojure.string/replace % #"[^A-Za-z0-9]" "") 36) (remove #{""} (clojure.string/split (doc map) #"\s|\pP")))

7:20 clojurebot: (15 591753 15 433 434 ...)

7:20 TEttinger: ##(map #(Long/parseLong (clojure.string/replace % #"[^A-Za-z0-9]" "") 36) (remove #{""} (clojure.string/split (doc map) #"\s|\pP")))

7:20 lazybot: ⇒ (15 591753 15 433 434 15 433 434 435 15 433 434 435 21303136 59669793928 10 994030 2226294739886 1288290580277164 879 38210 1657447409 879 839609736172 15 1068 38210 36821 879 26070077 31605076 879 666593 591753 1229011460869 430 839609736172 15 1068 38210 36821 879 ... https://www.refheap.com/88807

7:21 TEttinger: ##(clojure.string/join " " (map #(Long/toString % 36) (map #(Long/parseLong (clojure.string/replace % #"[^A-Za-z0-9]" "") 36) (remove #{""} (clojure.string/split (doc map) #"\s|\pP")))))

7:21 lazybot: ⇒ "f coll f c1 c2 f c1 c2 c3 f c1 c2 c3 colls returns a lazy sequence consisting of the result of applying f to the set of first items of each coll followed by applying f to the set of second items in each coll until any one of the colls is exhausted any remaining item... https://www.refheap.com/88808

7:23 Glenjamin: how far can you go with the radix?

7:23 ,64rabc

7:23 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Radix out of range>

7:23 TEttinger: 36

7:23 Glenjamin: oh

7:23 TEttinger: it's a fun trick

7:26 clgv: ,37r1

7:26 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Radix out of range>

7:26 clgv: ;)

7:27 1d6

7:27 clojurebot: 2

7:31 justin_smith: ,(apply + (rest (sort (repeatedly 4 #(inc (rand-int 6)))))) ;rolling up a paladin

7:31 clojurebot: 8

7:31 justin_smith: oh man

7:31 Glenjamin: did you just get an 8 form 4d6?

7:31 justin_smith: 3d6 drop the lowest

7:31 clojurebot: 11

7:31 justin_smith: standard d+d 2e

7:33 ,(zipmap [:str :dex :con :int :wis :cha] (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6)))))))))

7:33 clojurebot: {:cha 7, :wis 14, :int 9, :con 15, :dex 16, ...}

7:33 justin_smith: of all the stats to hide, it had to be str :(

7:34 Glenjamin: ,(set! *print-length* 10)

7:34 clojurebot: 10

7:35 Glenjamin: ,(zipmap [:str :dex :con :int :wis :cha] (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6)))))))))

7:35 clojurebot: {:cha 11, :wis 12, :int 18, :con 6, :dex 13, ...}

7:35 Glenjamin: oh right, key/val is 2

7:35 ,(set! *print-length* 12)

7:35 clojurebot: 12

7:35 Glenjamin: ,(zipmap [:str :dex :con :int :wis :cha] (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6)))))))))

7:35 clojurebot: {:cha 13, :wis 10, :int 11, :con 10, :dex 14, ...}

7:35 Glenjamin: :s

7:37 clgv: 3d6

7:37 clojurebot: 8

7:38 justin_smith: ,(zipmap (reverse [:str :dex :con :int :wis :cha]) (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6))))))))) ; nobody care about cha anyway

7:38 clojurebot: {:str 13, :dex 15, :con 8, :int 8, :wis 14, ...}

7:39 clgv: justin_smith: you can trick the bot via printlength ;)

7:39 ,(str (zipmap (reverse [:str :dex :con :int :wis :cha]) (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6))))))))) )

7:39 clojurebot: "{:str 14, :dex 15, :con 11, :int 13, :wis 18, ...}"

7:39 clgv: ,(binding [*print-length* 100] (str (zipmap (reverse [:str :dex :con :int :wis :cha]) (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6))))))))) ))

7:39 clojurebot: "{:str 4, :dex 11, :con 13, :int 10, :wis 12, :cha 7}"

7:40 justin_smith: oh man, str of 4, that is gonna be a really pathetic cleric

7:40 well, barely qualifies to be a thief also

9:09 XinUmbralis: 8d10

9:09 clojurebot: 39

9:11 clgv: XinUmbralis: pretty average ;)

9:13 justin_smith: ,(apply print (interleave [:str :dex :con :int :wis :cha] (repeatedly 6 (fn [] (apply + (rest (sort (repeatedly 4 #(inc (rand-int 6))))))))))

9:13 clojurebot: :str 15 :dex 8 :con 16 :int 9 :wis 16 :cha 17

9:14 farhaven: heh

9:15 justin_smith: rpgs were my gateway to programming, they are full of algorithmic thinking

9:21 mnngfltg: Do you guys run tests from the repl? If I use `(clojure.test/run-all-tests)`, it gives me: Ran 0 tests containing 0 assertions.

9:22 justin_smith: mnngfltg: have you loaded the namespaces with the deftests in them?

9:22 mnngfltg: Probably because the namespaces are not loaded..

9:22 justin_smith, no I haven't :)

9:23 justin_smith, but surely I don't have to remember all the testing namespaces and manually (require) them?

9:23 justin_smith: mnngfltg: you can make a namespace that requires all the rest to make it easier

9:23 or run "lein test" to do it all from the command line

9:24 mnngfltg: justin_smith, `lein test` must have some way to discover all the testing namespaces, maybe it's exposed to the user?

9:24 justin_smith: usually, I am either double checking the whole repo is good before a push (lein test) or working on a specific namespace / feature (run tests on that feature / in that namespace)

9:24 verma: so I am writing this module which has protocols in it and then a couple of defrecords that define records that satisfy this protocol? is it recommended that these protocol methods mutate the state of the original record and return it, or just modify an internal state (possibly an atom) which is a part of the record?

9:24 justin_smith: mnngfltg: very little info from lein is exposed at runtime, lein is a build tool

9:24 verma: sorry, misplaced "?"

9:24 s/protocol? is/protocol, is/

9:25 justin_smith: verma: how does one mutate the internal state of a record?

9:25 mnngfltg: justin_smith, right, I just thought this part might be handy (find all the testing namespaces in `:test_paths`)

9:25 justin_smith: mnngfltg: lein does not expose :test_paths to you at runtime

9:25 hyPiRion: verma: It's not possible to mutate records, and it's certaintly not recommended to attempt to do so either.

9:25 mnngfltg: alas!

9:26 verma: justin_smith, not mutate really, just modify the record and return the new record, like using assoc etc, sorry incorrect term

9:26 hyPiRion, ^

9:26 clgv: verma: since you use a datatype that is supposed to be persistent you shouldnt mutate the internal state of the current instance. that could lead suprising errors

9:26 hyPiRion: verma: oh yeah, that's completely fine

9:26 justin_smith: verma: a protocol method could return a modified record, it could return a string, it could return a number. Depends what you are trying to do.

9:27 hyPiRion: ,(defrecord Foo [a b])

9:27 clojurebot: sandbox.Foo

9:27 mnngfltg: justin_smith, I'll go with a function in my dev/user.clj that requires all the testing namespaces then

9:27 justin_smith: but yeah, if you want to return a modified version of the record, that is pretty normal

9:27 hyPiRion: ,(assoc (Foo. 1 2) :a :an-a)

9:27 clojurebot: #sandbox.Foo{:a :an-a, :b 2}

9:28 hyPiRion: ,(update-in (Foo. 1 2) [:a] inc)

9:28 clojurebot: #sandbox.Foo{:a 2, :b 2}

9:28 hyPiRion: etc.

9:28 clgv: hyPiRion: how dare you?! :P

9:28 verma: justin_smith, sure, e.g. one of my protocol methods is called become-available, which takes a record and then attaches "being online" related data to it (using assoc) and returns the record back

9:28 justin_smith, hyPiRion, I guess what I am asking is that is this what people usually do

9:28 hyPiRion: clgv: yeah, I'm such a rebel

9:29 verma: yes, this is very normal to do

9:29 clgv: hyPiRion: that's probably it ;)

9:29 verma: hyPiRion, thanks :)

9:29 I guess I can always post the snippet here and get suggetions :)

9:30 hyPiRion: verma: yeah, there's always some person here able to comment on snippets =)

9:31 verma: hyPiRion, nice, thanks :)

9:32 clgv: verma: usually you post them on refheap.com or similar sites ;)

9:33 mdallastella: hola

9:40 verma: clgv, got it

10:34 michaelr`: how to make these colors from cljsbuild show up on windows?

10:37 gtrak: michaelr`: can you successfully develop cljs on windows? I gave up a long time ago.

10:38 easiest path for me was to run a VM and share folders.. also considered having node-webkit on windows host as a brepl talking to the linux VM, but haven't tried that yet.

10:38 rather, I have no idea, I haven't tried to do clojure on windows in 3 years, since before cljs.

10:38 mostly emacs's fault

10:42 stuartsierra: dnolen_: what was the verdict on the Google closure Library release?

10:42 michaelr`: gtrak: yea.. everythink works fine for me more or less :)

10:42 gtrak: what was your show stopper?

10:42 everything

10:44 gtrak: I don't even remember, just the whole hassle with cygwin really.

10:45 I was working on a particular task with git-svn, it was orders of magnitude slower, so at that point I went through the trouble of setting up a linux dev environment.

10:46 michaelr`: heh

10:49 I actually have a linux server where I work sometimes using tramp mode from my crappy laptop

10:58 clojurefan: hey #clojure, if i have a constant defined like (def ^:const foo "bar"), it looks like i can't match against the value of foo in a case statement. is there some way to do this?

11:00 ucb: I know cider replaced clojure-test-mode, though I do miss the ability to switch between a buffer with an ns and it's test counterpart (usually bound to C-c C-t in clojure-test-mode). Has this functionality been ported to cider as well?

11:02 trptcolin: technomancy: got a link handy for your imports-should-use-parens argument?

11:03 BobSchack1: clojurefan: do you mean (case foo "bar" :success :failure) or (case "bar" foo :success :failure)?

11:04 clojurefan: BobSchack1: the latter

11:06 rksm: ucb: C-h m gives you an overview of mode key maps. Cider uses C-c C-t to show a test report page and C-c , to run tests

11:06 BobSchack1: From the docstring "The test-constants are not evaluated. They must be compile-time literals, and need not be quoted." When you try to match foo you are matching the symbol foo not the value foo represents

11:07 ucb: rksm: yes, I am aware of those, I'm just wondering if the buffer-switch functionality had been ported :)

11:07 clojurefan: BobSchack1: right, i saw that, so is there no way to do this? i found cemerick.com/2010/08/03/enhancing-clojures-case-to-evaluate-dispatch-values/

11:08 llasram: clojurefan: Looks like you've found your solution :-)

11:08 clojurefan: llasram: except it's overkill

11:08 i'd sooner not use a case since this is just a small example i'm trying to write

11:08 hlship: I've really gotten to the point where I hate going back to Java, even to code Tapestry. Would rather just stay in Clojure land.

11:09 BobSchack1: clojurefan I've played around with case a lot recently and haven't found a way to do what you want yet

11:09 llasram: Not really. If you need `case` with compile-time evaluation of dispatch values, then you need something other than clojure.core/case

11:09 clojurefan: thanks guys. too bad

11:10 llasram: Using a common-pattern utility function is pretty typical in many cases

11:10 clojurefan: llasram: not sure what that is, do you have a link handy?

11:11 llasram: I just mean "including a copy of a utility function which serves a common need is a common pattern."

11:11 rksm: ucb: C-c , jumps to the test report buffer, dunno if this is what you mean

11:12 ucb: rksm: no, not the test report buffer, but rather the counterpart buffer/file in the test/ directory

11:12 rksm: basically a quick shortcut between code and its tests

11:12 Bronsa: ,(case '(1) (1) 1 2) ;; I always find this counter-intuitive

11:12 clojurebot: 2

11:13 justin_smith: clojurefan: also, :const doesn't really do anything to non-primitive values, so a const string doesn't mean much

11:13 Bronsa: justin_smith: :const will let the compiler inline the value

11:13 justin_smith: or wait, can a String be :const? is it considered primitive for those purposes? my hunch is no but now I am not so sure

11:13 llasram: Bronsa: Agreed. Hmm, I wonder: &(case '(1) ((1)) 1 2)

11:13 justin_smith: Bronsa: ahh, ok

11:14 Bronsa: llasram: sure, that works

11:14 llasram: Oh, right ##(case '(1) ((1)) 1 2)

11:14 lazybot: ⇒ 1

11:14 llasram: There we go

11:14 Cool

11:14 Bronsa: it's just a bit weird

11:14 llasram: But still weird, yeah

11:15 justin_smith: I really don't like the way case handles ()

11:15 single case exceptions suck :(

11:15 llasram: We should just write our `case`s always supplying a sequence of dispatch values for each case :-D

11:15 (case 1 (1) "one" (2) "two" #_else "many")

11:16 Bronsa: justin_smith: also I don't think ^:const can handle primitives at all

11:16 justin_smith: wait, I had it backwards?

11:16 Bronsa: probably, yeah

11:17 justin_smith: do you have a good reference for that annotation (anything more specific than "the source" would be helpful -- ie. a file if you don't have an article:))

11:18 Bronsa: justin_smith: there's probably something in the wiki or in the CHANGELOG, for 1.3

11:22 justin_smith: https://github.com/manutter51/Clojure-1.3-Changes-text#215-const-defs this claims const is only for primitives

11:23 wizzo: why do regular expressions have special syntax instead of just being strings?

11:23 justin_smith: Bronsa: but it is a good example of using a non-primitive to initialize a primitive, at compile time - I hadn't considered that :const could be used that way

11:23 Glenjamin: wizzo: probably so the reader can compile/cache them early

11:23 Bronsa: justin_smith: what's written there doesn't make any sense.

11:24 puredanger: wizzo: b/c you can avoid much of the special escaping required in strings, also b/c they create a different type (Pattern) under the hood

11:24 justin_smith: wizzo: because "\a" is erroneous in a string, but valid in a regex

11:24 rksm: ucb: I see. There is a deprecation of `clojure-jump-to-test' in clojure-test-mode.el: "use projectile or toggle.el instead." I huess it won't be ported then.

11:24 wizzo: oh ok

11:24 justin_smith: Bronsa: oh, so the changelog is innacurate?

11:24 wizzo: i guess that makes sense

11:25 Bronsa: justin_smith: looks like so, or the wording is wrong

11:25 justin_smith: Vars can hold only Objects, not primitive values

11:25 all :const does is allows the compiler to inline the value skipping the .getRawRoot call for every Var access

11:25 puredanger: I think the use of const expanded to collections at a later time

11:26 ucb: rksm: ah, good catch, thanks!

11:26 Bronsa: well that might explain it then

11:26 ah wait, I get it.

11:27 justin_smith: I wish metadata was as easy to look up and as well documented as vars

11:27 Bronsa: if you do e.g. (def ^:const x 1) (let [a x] a), a will be unboxed

11:37 justin_smith: arrdem: a) add documentation for metadata to grimoire b) light blue and gray on white, what the hell were you thinking?

11:54 ahoenigmann: what is best setup for emacs/clojure dev on mac?

11:54 standalone emacs, iterm + emacs?

11:55 had problems yesterday with a few keybindings not being passed from standard mac terminal to emacs

12:05 clgv: ahoenigmann: I heard about aquamacs on macos

12:07 stuartsierra: ahoenigmann: The keybindings thing is a well known problem with terminal emacs in any environment.

12:08 ahoenigmann: yeah

12:09 just want to know what everyone else is doing

12:09 stuartsierra: Emacs compiled with Cocoa bindings via Homebrew.

12:10 justin_smith: ahoenigmann: on Linux I just use the X11 version - that is likely the version a plurality of devs are using too

12:10 ahoenigmann: on osx, when I was forced to use it, I liked emacs under the mac X compatibility environment, but I'm weird

12:12 Jaood: what problemas are you having? did you set the option key to act as +Esc in iterm?

12:13 ahoenigmann: ^^

12:15 michaelr`: has anyone used om-sync yet?

12:16 hmm

12:17 I'm not sure whether I'm missing something, DELETE request is sent to the collection URL and there doesn't seem to be a way to specify the actuall item URL. Such as DELETE /rest/products/1 instead of DELETE /rest/products

12:17 ahoenigmann: hi jaood

12:18 i dont have iterm

12:18 but in mac term i did it

12:18 so the M- works :)

12:19 Jaood: ahoenigmann: iterm gives you more choices for rebinding keys

12:19 ahoenigmann: i see

12:20 Jaood: ahoenigmann: what emacs command didn't pass through?

12:21 ahoenigmann: it was a paredit binding to slurp

12:22 C-)

12:31 Jaood: ahoenigmann: yeah, you'll have to mess with the shortcut keys in iterm, if you don't care about running emacs remotely you should run the gui version

12:54 justin_smith: haha, some of the unit tests in test/clojure/test_clojure/test.clj are commented out

12:55 sdegutis: Is there anything about Clojure that makes it more ideal than Ruby for writing simple web apps?

12:55 Note: I am not trying to start a flamewar. I am just curious. Serious responses only please. Thank you.

12:55 clgv: sdegutis: are you asking that question in both channels? :P

12:55 sdegutis: I am not in any Ruby channel.

12:55 technomancy: no bundler

12:56 clgv: guess you should ^^

12:57 sdegutis: technomancy: Is that a serious benefit? The only problem I remember having with bundle is its speed, which is not much different than using lein (due to Java's library-loading time) for similarly sized projects.

12:57 technomancy: in clojure no one will ever try to redefine the cd function of your shell and fail with hilarious results because you don't use bash

12:57 justin_smith: sdegutis: reliable and repeatable builds

12:57 technomancy: hm; you've never had bundler pull in old versions that don't match your gemspec just because you had them left around on disk?

12:57 justin_smith: technomancy: that sounds like a funny store, got more details?

12:57 sdegutis: technomancy: I've ditched rvm for rbenv years ago, so that doesn't quite hold as a disadvantage anymore. I've also been considering switching to chruby lately.

12:58 technomancy: justin_smith: http://rvm.io

12:58 sdegutis: justin_smith: https://github.com/sstephenson/rbenv/wiki/Why-rbenv%3F

12:58 justin_smith: s/store/story

12:58 technomancy: sdegutis: yes, but there are people in the ruby community who thinks that's an ok thing to do and that you shouldn't go hunt down the people responsible with pitchforks

12:59 sdegutis: technomancy: there are people in the Clojure community who also don't mind rvm.

12:59 technomancy: ~guards

12:59 clojurebot: SEIZE HIM!

13:00 justin_smith: sdegutis: a few apathetic fools can by balanced by a few dedicated zealots. But what if there are no zealots ready to do god's work?

13:00 sdegutis: I won't name names though, on account of the light you've just put them in.

13:01 So, the most compelling reasons for choosing Clojure over Ruby that I can think of are: ring; compojure; hiccup; garden

13:01 technomancy: I haven't actually built a webapp in clojure, so I'll shut up.

13:01 justin_smith: sdegutis: scaling without devops

13:01 technomancy: [over 500 lines]

13:01 justin_smith: (or with much less devops involved)

13:01 sdegutis: What I /don't/ see as particularly advantageous: macros; built-in easier concurrency support; Java.

13:02 justin_smith: sdegutis: clearly you don't pay for the hosting then

13:03 ggreer: hardware is cheap. it's cheaper to pay for a terabyte of RAM per month than to hire another dev

13:03 justin_smith: ggreer: in my experience clojure does not require a larger dev team than ruby

13:03 sdegutis: We've got about 10k LOC according to `cloc`.

13:03 ggreer: I agree. it's just that performance isn't a big deal for me most of the time

13:04 justin_smith: ggreer: and a messier scaling scenario, in practice, often leads to devs messing with deployment issues / scaling hiccups

13:04 sdegutis: And 7k lines of testing Clojure code.

13:04 ggreer: I just like lisp but I want lots of libraries too

13:04 justin_smith: ggreer: which is time being sysadmins when they should be working on code

13:04 technomancy: since you're limiting the scope to "simple web apps" IMO it's not that interesting of a question. simple stuff means there are a lot of different ways you can do it without screwing things up.

13:04 clgv: sdegutis: without macros compojure would suck ;)

13:05 justin_smith: oh yeah, simple

13:05 sdegutis: clgv: I am not entirely sure about that.

13:05 justin_smith: use a static dir w/ apache or something

13:07 technomancy: if you have to write a simple web app, you should go with what you and the people likely to maintain the code in the future know best.

13:07 clgv: sdegutis: well than just have a look at compojure.core ;)

13:07 sdegutis: GET/POST ...

13:07 sdegutis: clgv: I'm not saying it would have the same interface it has now.

13:08 clgv: :GET, :POST would be fine alternatives not requiring a macro.

13:08 clgv: sdegutis: lol what makes it "compojure" if not its interface ? :P

13:08 justin_smith: clgv: maybe the routing? but yeah, its mostly macros

13:08 clgv: sdegutis: with a certain ugly overhead they could be functions yes

13:09 sdegutis: The website I'm working on was written by a single Rubyist who fell in love with Clojure circa Clojure 1.3, and I am now the sole developer, having rewritten 99% of the website myself, still in Clojure, and moved away from Google App Engine with Mongo to AWS with Datomic.

13:09 The original developer probably won't write any more of the code, he's no longer an active developer for the time being.

13:09 justin_smith: so now you are considering switching it to ruby?

13:09 sdegutis: No.

13:10 I'm just reassessing the choice of language.

13:10 Jaood: sdegutis: for sure you will find more libs in the ruby world, the ruby community is very webish

13:10 clgv: sdegutis: not a bad thing to do in general

13:10 sdegutis: Pretty sure the reason he chose Clojure was because it was his new Ruby (he went Java -> Ruby -> Clojure) and it was his honeymoon period.

13:12 justin_smith: sdegutis: my main clojure contributions have all been related to a library (set of libraries) that evolved out of a need to overcome difficiencies my employer saw in ruby (in terms of business costs / resources)

13:12 clgv: is there a lein plugin for clojure code metrics? sexpr count or similar?

13:12 sdegutis: But I'm not seeing many legitimate benefits of Clojure for web apps, over using another language. Compojure and Ring can be done in most other languages without sacrificing too much due to not having macros. But I'm not sure Hiccup can.

13:13 Jaood: I have seen some projects using Bidi instead of Compojure, Bidi doesn't use macros as Compojure

13:13 technomancy: sdegutis: yeah, templating seems like a weak point in the ruby landscape

13:14 way too many people settle for weak sauce stuff like erb

13:14 because it's "standard"

13:14 unless you can stomach haml things seem pretty bleak

13:16 sdegutis: Lately I'm feeling a little bit sketchy about the Clojure setup we have.

13:17 In particular Datomic feels extremely heavy-weight and it feels like it's weighing down the app a significant amount.

13:17 Also it takes quite a long time for the app to start up, and for tests to run, even after a file reloads, which should rerun tests automatically using the testing lib we're using.

13:19 technomancy: I don't get why you would use datomic for a small data set; it's so easy to get all the benefits of immutability and history with a few append-only postgres tables.

13:21 sdegutis: Our product data set is small, but we handle several orders and sell many licenses per day.

13:22 technomancy: recording license sales is already immutable


13:22 sdegutis: We switched to Datomic partially because when using Mongo our database became inconsistent (causing me to spend several days tracking down broken links several times); and because our statistics and reports pages were taking 20 minutes to cache, whereas now that takes only 1 minute.

13:23 technomancy: sure but "look how much better than mongo it is" is pretty faint praise

13:23 sdegutis: (and similarly, individual pages were taking more than 60 seconds, thus hitting the HTTP timeout; now they take a second or two)

13:24 s_kilk: I'm going to concur with technomancy, a postgres setup with append-only tables sounds like it would suit your use-case

13:24 sdegutis: I probably wouldn't disagree.

13:25 s_kilk: wait, 60 second queries with Mongo?

13:25 sdegutis: Though when I tried using the Clojure wrapper for postgres, I ran into too many problems and had to abandon that avanue.

13:25 Yes.

13:25 We we using... an ORM.

13:25 A very inefficient ORM.

13:25 I won't name names.

13:25 s_kilk: yikes, that doesn't sound right at all.

13:25 mthvedt: sdegutis: does it start with h

13:25 sdegutis: Yes.

13:26 mthvedt: How did you know?

13:26 mthvedt: sdeguits: does it end with ibernate

13:26 sdegutis: No.

13:26 So you didn't know :)

13:26 s_kilk: mongo has plenty of faults, but slow queries are usually not one of them :)

13:26 sdegutis: Yeah; to be honest I kind of want to go back to Mongo, just without using that ORM.

13:27 s_kilk: hmm, maybe give the YeSQL library a try with Postgres

13:29 johncash: whats the url to that page with all the transit examples? I think it has a yellow background

13:30 s_kilk: and out of curiosity, why not just use the bare mongo clojure driver?

13:30 technomancy: https://www.panic.com/transmit/#t4numberone

13:32 mthvedt: trying to think of an orm that starts with h and isn’t hibernate

13:33 Jaood: HQL

13:33 itruslove: hyperion?

13:34 sdegutis: s_kilk: If we ever go back to Mongo then I probably would.

13:34 But I pushed hard for the transition from Mongo to Datomic. I imagine my job could be at stake if I pushed to reverse it.

13:35 I like admitting my mistakes and apologizing. I don't like having no income.

13:35 s_kilk: sdegutis: sure :) that's understandable. probably a good move to get away from mongo at least

13:36 Jaood: save your job with rails :D

13:36 s_kilk: *shudder*

13:36 sdegutis: I'm positive he would never allow that.

13:36 Even if we went with Ruby, Rails is out of the question.

13:37 Although to be honest, I like that Rails does a lot of security stuff for you out of the box.

13:37 s_kilk: so what are the upsides of datomic for your use-case? curious to hear what it's like in production

13:38 sdegutis: For one thing, it's really simple to create an in-memory database for use in tests.

13:38 I love that fact a lot. I bet it would be just as easy with Mongo though. But not postgres.

13:39 But I'm on the fence about the immutability. We don't really treat it too immutably, as we shadow the old database value with the new one immediately after a mutating operation, thus effectively making it mutable for our uses.

13:39 technomancy: yeah, being out of process is probably the biggest drag about postgres. especially the apt packaging is clearly meant for production and sucks for development.

13:40 tuft: sdegutis: do you end up using the "what-if" dbvals with a partial transaction applied? i work with a global state style rdbms orm, and having transactions represented as data and a dbval that can reflect part of the changes involved in processing a request is really appealing

13:40 i think i'd miss the postgres extensions like postgis, though -- maybe use elasticsearch+datomic?

13:40 sdegutis: tuft: I think we do that in one place, as a shortcut to extracting a calculation out into another function, to tell whether an order would be completely paid off if we apply the given payments, or something.

13:40 tuft: but to be honest we don't really need that feature at all.

13:41 Also, we don't currently do too much iterating over the database's own history. I think we do for one or two of the reports, but that could easily be replaced by manually creating a history table in Mongo or whatever.

13:41 tuft: tuft: ah ok, interesting. i'm thinking about the problem where one piece of code makes data changes that need to be visible to other code within the same transaction

13:42 sdegutis: sdegutis: I don't think we have any need for that.

13:42 tuft: also i'm starting to use SERIALIZABLE in postgres and it's pretty useful. in datomic this would involve manually asserting the state of the world is still as it was to get the same isolation

13:43 sdegutis: All our transactions are instant and built up within the same file (sometimes via private methods) and applied before the function returns.

13:43 tuft: .. which is surprising given all the great STM in clojure

13:44 ah ok

13:44 sdegutis: Our web app is dead simple btw: we sell licenses to watch training videos about programming.

13:45 That's all we do.

13:45 tuft: anyway, schema, transactions and entities as data and the database as a value is pretty hard to beat. =)

13:46 yeah, i'm doing a toy project with it currently

13:46 haven't hit the limits but just wondering about replacing my go-to tools with it

13:47 gtrak: sdegutis: pretty meta..

13:47 sdegutis: gtrak: quite so.

13:47 It's http://cleancoders.com/ fwiw.

13:48 All the slowness that you see when hitting that page is due to loading all the episode entities into memory.

13:48 justin_smith: gtrak: my best meta moment today was reading the tests in clojure.core for clojure.test

13:48 gtrak: justin_smith: nice!

13:49 cycles are more meta for sure

13:49 tuft: sdegutis: are you the presenter on any of these?

13:50 someone at work brought this site up the other day

13:50 sdegutis: tuft: Not yet.

13:58 s_kilk: surely the episode entities are crazily cache-friendly? how often would they really change?

14:00 sdegutis: Yeah they rarely change.

14:00 That's what's surprising; it should be way faster.

14:01 Honestly I want to just go back to Mongo and use a language that doesn't depend on Java.

14:01 Maybe Lua with some batteries-included language for its simplicity.

14:03 justin_smith: sdegutis: are you doing any cache of the video list results from the db?

14:03 (I mean explicit cache)

14:04 sdegutis: I'm just getting it from the db and letting Datomic cache it for me.

14:04 It is faster than when we used Mongo, for sure.

14:04 Err, using Mongo with an inefficient ORM.

14:04 justin_smith: how local is the datomic server to your web server?

14:04 sdegutis: right next to it; another aws server

14:05 justin_smith: OK

14:05 bbloom_: oh, i probably should come up with an idea for a conj talk, huh? that's kinda due today, isn't it....

14:05 sdegutis: conj talks were always too advanced for me, always felt like I needed a master's in something to understand them

14:05 nickmbailey: bah, who knows how i can get my hudson password for build.clojure.org reset

14:06 sdegutis: so I surely can't present on anything that'll be interesting to anyone there

14:07 bbloom_: sdegutis: were the clj/west talks more your style?

14:07 sdegutis: never seen them

14:07 bbloom_: iirc, the /west talks were more approachable

14:07 xeqi: sdegutis: I'm sure you could. there have been several explain a concept (vars, liberator, etc) talks

14:07 sdegutis: To be honest I'm the wrong person to ask. I never attend talks. I prefer reading something about the topic instead. Much easier to skim and get to the important part that way, and much faster to learn.

14:08 bbloom_: the talks are just something to do in between drinking and chatting with people in the hallways :-P

14:08 xeqi: I mean, if technomancy can give a conj talk on his deathbed anyone can

14:08 +1 to hallway track

14:08 technomancy: haha

14:08 sdegutis: I just assumed the talks were there to be an excuse to go to conferences, and the main point was to socialize with like-minded people and hand out your business cards.

14:09 xeqi: technomancy: did you submit this year?

14:09 sdegutis: If that's universally understood, then I might as well submit a talk that explains how to use Hiccup and just go for it.

14:09 * sdegutis watches technomancy's answer to xeqi carefully

14:09 technomancy: xeqi: no. the lein release task is the only clojure I've written this year.

14:09 sdegutis: ahh.

14:09 well done sir.

14:11 technomancy: eh?

14:11 lpvb: when should I use gen-class and when should I use proxy?

14:12 sdegutis: lpvb: never and never

14:13 lpvb: sdegutis: I need to subclass a swingx model though

14:14 okay..

14:14 aperiodic: lpvb: use gen-class if something demands to be handed a java class *by name*. if you can pase an instance, use proxy

14:14 xeqi: lpvb: if you can create the object and pass it to java then use proxy. Use gen-class if the java code needs to create it

14:14 bbloom_: or if you just need to do it once and it will have a small amount of code in it, just write some java

14:14 lpvb: well I need to pass the model to the java view but within clojure

14:15 is proxy okay for that

14:15 aperiodic: also, before using gen-class, make sure to put an egyptian curse on the author of the framework or library that is making you do this

14:15 yeah, proxy works for that

14:16 bbloom_: if you need to subclass this a lot, one thing you can do is 1) define an interface and 2) write java for a delegation class that takes an instance of that interface to the constructor

14:16 then you can implement the interface in clojure and instantiate the delegation class, rather than subclass from clojure

14:16 much nicer

14:17 lpvb: I'd rather not write java at all

14:18 gives me headaches when I try to develop java in leiningen

14:18 bbloom_: http://www.jetbrains.com/idea/webhelp/generating-delegation-methods.html

14:18 even if there's 379578395 methods, you can just generate all the java in ~5 seconds w/ intellij and then never touch that java code again

14:19 you may have to write the constructor by hand tho :-P

14:19 amalloy: there's an example of bbloom_'s suggestion in flatland.io: https://github.com/ninjudd/io/tree/develop/src/flatland/io/core

14:20 instead of proxying OutputStream or InputStream, you can write (InputStream. (reify InputStreamable ...))

14:21 bbloom_: performs much better than proxy too

14:39 * tuft always has a mini identity crisis when people in #clojure talk about not using clojure anymore. =)

14:41 justin_smith: tuft: tribe member speak of leaving tribe! must stop them for leaving or we lose face!

14:42 tuft: justin_smith: quick! get the spears and block the door!

14:42 justin_smith: ->

14:42 ->>

14:42 Jaood: tuft: I guess is a library problem and the java baggage

14:44 but then, Clojure is not that old

14:45 expez: stuartsierra: do you have any rules of thumb in regards to the size of a component?

14:45 stuartsierra: expez: sorry, busy now

14:45 expez: aight

14:52 Raynes: https://www.refheap.com/62eff49ffcd10438606161986 <-- How to not be a language maintainer.

14:55 justin_smith: Raynes: from ass import problems

14:55 jjido: Did you write that Raynes?

14:56 justin_smith: Raynes: in all seriousness, what a nimrod, I'm glad I didn't spend more than 10 minutes checking that language out

14:58 arrdem: justin_smith: what do you mean "metadata documentation"? this form preserves meta or doesn't?

14:59 justin_smith: arrdem: it was being a bit glib. I meant how various metadata would be used by the compiler.

14:59 rlb: justin_smith: re session, my impression was that peridot handled that for you, but I may well misunderstand.

14:59 justin_smith: in particular we were discussing :const and there was much confusion (not least on my part)

14:59 mdrogalis: Raynes: D'oh

15:00 justin_smith: arrdem: and I realized I didn't even really know where to go to look up what a given metadata like :const would do (not even which source code files to look in)

15:00 arrdem: I decline this request to document the insanities of clojure.core's internals

15:00 justin_smith: arrdem: and for low hanging fruit we could of course document things like :file and :doc etc. etc.

15:00 arrdem: fair enough :)

15:01 arrdem: justin_smith: some stuff, like your macro tutorial, and a reader tutorial may make it in

15:01 expez: why does it make sense that (= (set {:foo :bar} #{:foo :bar}) => false?

15:01 justin_smith: arrdem: surely not mine

15:01 I don't think I ever made one

15:01 arrdem: justin_smith: but especially "compiler significant" metadata is just too insane to be considered stable

15:01 imo

15:01 expez: bah. slight typo making that set literal with the map inside ><

15:02 justin_smith: arrdem: ok, it's just sad to realize I don't know where to look to see what a specific compiler significant metadata will do, not to mention where I would see a rundown of what exists

15:02 arrdem: guess that means I need to read a shitload of code, and write my own docs on the subject

15:03 Jaood: How can I stop reading HN and Reddit?

15:03 Bronsa: justin_smith: there are not many "metadata options" the compiler actually uses though

15:03 justin_smith: Jaood: did you see the thing with the guy who hired someone on craigslist to hang out and slap him whenever he slacked off?

15:04 Bronsa: good news! but I still wish I knew an easy and authoritative source that documents them

15:04 tuft: Jaood: just realize that they are mostly silly hamster wheels

15:05 Bronsa: :tag, :arglists, :const, :inline-whatever, :line, :column and uhm, I can't think of any other

15:05 * justin_smith pastes that in his notes for this project.

15:05 Bronsa: it's :inline and :inline-arities

15:05 well and :macro obviously

15:06 also :once on fn*

15:06 edw: Something I learned reading about Nimrod: Dr Dobb's still exists! Whoa!

15:07 Jaood: I went cold turkey on both a few years ago. Improved my quality of life immensely.

15:07 Bronsa: justin_smith: the issue with user-documenting those is that the official documentation isn't really clear wrt their behaviour

15:08 justin_smith: ,(->> (all-ns) (mapcat ns-publics) (mapcat (comp keys meta second)) (into #{}))

15:08 clojurebot: #{:protocol :added :ns :name :special-form ...}

15:08 justin_smith: Bronsa: OK, so part of the issue here is abstraction leakage, clearly

15:08 Bronsa: oh well, :dynamic :P

15:09 arrdem: justin_smith: essentially. we only have one "definition" structure, so it must expose all kinds of information about the "type" of the definition.

15:10 PigDude: what is the practical difference between (into [] (map f coll)) and (mapv f coll)?

15:10 justin_smith: Bronsa: https://www.refheap.com/88814

15:10 $source mapv PigDude:

15:10 lazybot: mapv is http://is.gd/n1z2gs

15:10 Bronsa: justin_smith: yeah well lots of those aren't used by the *compiler*

15:10 justin_smith: I think that should answer it

15:10 amalloy: expez: because the map {:foo :bar}, when seq'd over, doesn't produce the two elements :foo and :bar, but the single element ("entry") [:foo :bar]

15:11 justin_smith: Bronsa: right, I wasn't trying to correct you or anything, thought maybe that would freshen the memory regarding something

15:11 amalloy: PigDude: no difference at all, just mapv saves some performance

15:11 PigDude: justin_smith: so mapv is faster for the simple case too

15:11 got it

15:12 expez: amalloy: I was surprised, though. When I called (set my-map) I expected the map to end up in the send, not the sequential view of the map. Was wondering if there was some logic behind this, to make it easier to remember :p

15:12 Bronsa: justin_smith: the issue I see is that the current implementation doesn't enforce those metadata options to be consistent, the compiler might crash if you provide a wrong :tag for example, or just ignore it, depending where you use it

15:13 amalloy: expez: (set x) doesn't construct a set containing the single element x, it converts x to a set by seqing over it and adding each element

15:13 ,(hash-set {:foo :bar}) would create a single-element set containing the map {:foo :bar}

15:13 clojurebot: #{{:foo :bar}}

15:14 justin_smith: Bronsa: OK. It's a weird corner of the language, and it would be nice to have some of it be more clear. Even if it was a question of making three lists "these are useful, these other ones are tricky, don't ever use these"

15:14 Bronsa: or :arglists, the compiler doesn't complain if you change :arglists to have a different format than the one used by defn but if you do, the primitive fns optimization will stop working

15:14 expez: amalloy: aha, thanks!

15:16 Bronsa: justin_smith: yeah the thing is that we as users of the language don't really have a way of telling what is considered undefined behaviour vs what is a misuse of a language feature, it's arbitrary until Rich steps in and clarifies it

15:17 amalloy: speaking of rich, did you guys notice that he made the first commit to master snice march today?

15:17 Bronsa: i did

15:19 arrdem: I did

15:20 bbloom_: http://dev.clojure.org/jira/browse/CLJ-1439

15:21 puredanger: surprised it took you guys this long to notice :)

15:21 rlb: If anyone has time to take a look, here's a pared down example of the ring-session issue: https://www.refheap.com/0a7267752bd4bcd8e78d48b61

15:21 These docs made me think the cookies would be preserved: https://github.com/xeqi/peridot#cookies

15:21 amalloy: puredanger: i only noticed because of your comment on aphyr's keyword patch

15:25 Bronsa: justin_smith: btw, I had a bug in tools.analyzer.jvm wrt ^:const handling & primitive vals that I only realized after talking with you about it earlier, thanks :P

15:26 puredanger: would be happy to hear if anyone tries master and has feedback. I see ~2x improvement in cases that do lots of (already cached) keyword construction - like json parsing. General symbol construction should be faster as well (string interning removed).

15:27 justin_smith: Bronsa: heh, np, glad to hear my confusion somehow led to someone else learning something, even if I still feel a bit confused

15:42 dnolen_: Om 0.7.0 is out, in sync with React 0.11.1

15:44 lpvb: if I do (first (filter cond? (map expensive data))) does map stop apply expensive computations after filter and first are satisfied?

15:45 I don't know how lazy clojure seqs are

15:46 justin_smith: lpvb: I always forget the specific rules for chunking, but modulo chunking issues, that sounds right

15:46 jeremyheiler: ,(first (map (fn [x] (println x) x) (range)))

15:46 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n0

15:47 jeremyheiler: 32 per chunk

15:47 bbloom_: subject to (unlikely) change

15:47 lpvb: why does it do chunks?

15:47 ._.

15:47 * tbaldridge makes popcorn

15:47 justin_smith: ,(chunked-seq? (filter even? (map inc (range))))

15:47 clojurebot: false

15:47 lpvb: oh

15:48 justin_smith: dunno if that actually helps much, since you care about map's chunkiness

15:48 lpvb: so when does it decide to chunk?

15:48 Bronsa: ,(first (map (fn [x] (println x) x) (iterate inc 0)))

15:48 clojurebot: 0\n0

15:48 bbloom_: tbaldridge: you seem to eat a lot of popcorn, that can't be healthy

15:48 justin_smith: ,(chunked-seq? (map inc (range)))

15:48 clojurebot: false

15:48 tbaldridge: lpvb: that's a very interesting question, one that may take some time to discover

15:48 ,(chunked-seq? (map inc (vec (range 100))))

15:48 clojurebot: false

15:49 tbaldridge: okay, now I'm confused

15:49 stuartsierra: OK, who had the question about Component?

15:49 Bronsa: , (chunked-seq? (seq (map inc (vec (range 100)))))

15:49 clojurebot: true

15:49 bbloom_: LazySeq doesn't implement IChunkedSeq

15:50 seq will recursively unwrap concrete LazySeq instances to find the deepest head of the ISeq chain

15:50 stuartsierra: expez: ?

15:50 tbaldridge: , (chunked-seq? (map inc (seq (vec (range 100)))))

15:50 clojurebot: false

15:50 bbloom_: ,(supers (class (map inc (seq (vec (range 100))))))

15:50 clojurebot: #{clojure.lang.Obj clojure.lang.Seqable java.io.Serializable clojure.lang.IPending clojure.lang.Sequential ...}

15:50 bbloom_: arg

15:50 argh*

15:51 anyway, it does not include chunkedseq

15:51 IChunkedSeq rather

15:51 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazySeq.java#L17

15:51 tbaldridge: https://github.com/clojure/clojure/blob/c9e70649d2652baf13b498c4c3ebb070118c4573/src/jvm/clojure/lang/LazySeq.java#L54

15:52 that should clear it up

15:52 tbaldridge: bbloom_: yeah, but from my reading of clojure.core/map it looks like map returns chunked seq sometimes

15:52 bbloom_: tbaldridge: no, it's wrapped in the lazy-seq macro

15:52 Bronsa: tbaldridge: it always returns a lazy-seq

15:52 tbaldridge: ah right

15:53 bbloom_: it always returns a LazySeq, but that lazy seq may contain a chunked seq

15:53 tbaldridge: and thus hilarity ensues

15:53 bbloom_: it's kinda generally wonky that map has to think about chunking though

15:54 could be generally made faster & simpler by basing it on reducers (or something like it)

15:54 aka "traversable"

16:02 * Fare hesitates whether to use the State monad some more...

16:02 bbloom_: Fare: have you considered replacing your state monad with lazy seqs simulating the state monad?

16:03 tbaldridge: back me up on this one :-)

16:04 tbaldridge: Recently I've been replacing my state monads with atoms/mutable data structures :-P

16:04 bbloom_: haha even better

16:04 assuming you don't need backtracking or anything like that

16:04 tbaldridge: Do you need backtracking? Do you need to use multiple threads? If the answer to both of those is no, think about mutable data structures.

16:04 Fare: bbloom: what's lazy seqs simulating the state monad?

16:05 bbloom_: Fare: basically instead of accepting/returning a monad, you accept/return a stream of states

16:07 just suggesting reifying the internal structure of the monad as printable/readable data, rather than hiding it behind opaque function objects

16:07 justin_smith: just watch out for chunking!

16:07 j/k

16:08 Fare: so instead of having functions from S to [A S], you have functions from (S...) to [A (S...)] ???

16:08 lazybot: Fare: Yes, 100% for sure.

16:08 tuft: does anyone here do property based testing, and if so is it your predominant testing style or do use more traditional unit tests?

16:08 Fare: not sure what you mean. My state monad state is readable enough.

16:09 bbloom_: Fare: sorry, let me clarify & tailor to your situation

16:09 you need state back tracking for your parser, right?

16:10 if not, definitely just use mutability as tbaldridge says

16:10 tuft: i'm struggling a bit. have some property based tests working, but in other areas it feels like i'll have to reimplement the main code to express the properties. also figuring out how to express generators for all the important scenarios seems harder than manually writing input/actual output/expected output triples

16:11 er input/expected output doubles that is

16:12 Fare: bbloom: my parser is done, though yes, I'll need better backtracking some day to produce usable error messages

16:13 I'm doing scope analysis right now

16:13 I'm also wondering how macros fit in this compiler I'm writing.

16:18 justin_smith: Fare: wouldn't building a vector as you go down the tree, then popping back up that vector as you go up again suffice to document how you got to the syntax error?

16:19 bbloom_: justin_smith: for an eager traversal, yeah that should work

16:20 just a stack of scopes that you push/pop in a try/finally

16:20 Fare: justin_smith, not sure what you mean. My plan was to add some fields to the monad's state to record just how far you got, and what was expected there

16:20 justin_smith: bbloom_: ahh, lazy parsing is a new concept to me

16:21 bbloom_: justin_smith: i don't think he's doing anything lazy, it's just that that's where much of the benefit of functional purity comes in with respect to back tracking

16:21 justin_smith: Fare: does the state not have a concept of going down into a sub expression or coming back up out of it?

16:22 Fare: but right now I'm traversing the parse tree with an environment on the side, and trying to analyse its scoping structure -- though I believe macro expansion should go before that phase, because expansions can modify what's in the scope.

16:22 bbloom_: the push/pop scopes thing makes sense for scope analysis, which he mentioned, but an alternative for that is to just do multiple passes & gather intermediate results in ast nodes

16:22 Fare: justin: when doing analysis, it does

16:23 bbloom_: Fare: have you looked at tools.analyzer or the cljs compiler?

16:23 Fare: and my plan was doing one pass, with a new environment in each scope, and recording the results at the end in the ast node.

16:23 bbloom_: they do something very nice with :env for tracking scope

16:23 Fare: bbloom_, not closely, yet

16:23 python scope analysis is a ugly

16:24 could be worse, though.

16:24 bbloom_: Fare: i imagine it could be done with a single recursive pass over the tree as long as you did some work on both the down and up parts of the traversal

16:25 in a lisp-like, there's a nice invariant that lexicals respect containment of nodes in the ast

16:25 for vars, which have dynamic extent, the various clj analyzers simply use a mutable atom

16:25 which mirrors the semantics of the vars themselves

16:26 but for lexicals in something without binders & with hoisting, you need something more complex

16:26 so in python, i'd imagine you could simply push/pop a stack of scopes and when popping, assoc that scope in to the current ast node as you back out of the recursion

16:28 abaranosky: is the deadline for Clojure /Conj talks the end of today, or was it the end of yesterday?

16:28 bbloom_: formally speaking in terms of attribute grammars, clojure/scheme lexicals are an "inherited" property of the AST and in python, they are a "synthesized" attribute

16:29 alandipert: abaranosky, i think today is the last day

16:29 abaranosky: alandipert: thx :)

16:30 puredanger: today

16:31 bbloom_: Fare: but being a synthesized attribute means that you'd have to do multi-pass to use that info... so you can model it as a "chained" attribute to let you do it in one pass: utilizing state

16:32 puredanger: i feel like i surely could find something to talk about, but i've already procrastinated this long, why not procrastinate until it's too late?

16:33 puredanger: would be happy to see something from you :)

16:33 today

16:33 ;)

16:34 bbloom_: but all my cool clojure projects aren't stable enough to justify standing on a stage and talking about them!

16:34 Fare: bbloom_: well, I do one pass to gather the synthetised attribute, and another to use it, indeed

16:35 bbloom_: Fare: i'm not up on the finer details of python scoping rules, but i *think* you can do it with a chained attribute

16:35 rlb: justin_smith: fwiw, it looks like the code causing the "problem" (assuming it's not just my understanding at fault) is here: https://github.com/xeqi/peridot/blob/6afae7b563ff1521dba6d04a7ec2dca91f807f7b/src/peridot/cookie_jar.clj#L63

16:35 Fare: before I synthetize those attributes, I can't even tell which 'x' a python variable is referring to.

16:36 puredanger: bbloom_: having an upcoming talk tends to help focus the mind on making it stable I find :)

16:36 Fare: i.e. it could be "local", "nonlocal" or "global".

16:36 rlb: peridot drops all the cookies whenever the "Set-Cookie" header is ()

16:36 justin_smith: rlb: yeah, the stuff I use always expects me to explicitly pass the cookies back out again

16:36 Fare: plus the entire function will behave very differently if the "yield" keyword appears in it.

16:36 justin_smith: rlb or maybe I am just doing some conservatively, but it just makes sense

16:37 rlb: wondering if that's intentional -- changing the (dissoc ...) to just cookie-jar "fixes" the behavior.

16:37 Fare: bbloom: is there literature / examples on this "chained" attribute?

16:37 justin_smith: rlb: in that case, how would you clear the cookies from the server end?

16:38 rlb: I'd assume the normal way (though I'm still learning): i.e. "Set-Cookie: ... expires ..."

16:39 bbloom_: Fare: can't find a super simple example, but it appears in the literature under several different names. the other one i recall is "threaded attribute"

16:39 rlb: justin_smith: what do you use/recommend wrt testing?

16:40 bbloom_: Fare: in short: inherited=pre-visit, synthesized=post-visit, and chained=visit-state

16:40 or visitor-state, rather

16:41 justin_smith: rlb: I make a synthetic request map as a literal in my test ns, and pass it to my handler function, and then verify the results I expect to see in the output (ie. there is a cookie in the request coming in, and also in the result coming out)

16:41 just having that unit test on each page endpoint function is a great sanity saver

16:42 Fare: I understand inherited and synthesized, but still not chained.

16:42 bbloom_: Fare: simple example: annotating a tree:

16:42 depth = inherited property

16:43 node count = synthesized

16:43 Fare: http://en.wikipedia.org/wiki/Attribute_grammar has inherited and synthesized

16:43 bbloom_: node index = chained

16:43 where index is a depth first numbering

16:44 Fare: ok, I think I see what you mean, kind of

16:44 bbloom_: a chained attribute is both inherited and synthesized

16:44 but can be done in a single pass

16:44 Fare: it's what in asdf I call sideway dependency vs upward dependency (inherited) or downward dependency (synthesized)

16:45 bbloom: are you providing some infrastructure for attribute grammars?

16:46 bbloom_: Fare: i experimented with them, but there's not much benefit beyond a thought framework if you're doing explicit multipass operations

16:46 recursive functions work just fine for that

16:47 rlb: justin_smith: ok, thanks

16:48 bbloom_: Fare: if you want something more interesting/declarative w/o having to explicitly schedule passes, then there are demand driven (ie lazy) attribute grammars, but then you get in to all sorts of trouble with that & performance

16:48 you need a pretty sophisticated evaluator for those

16:48 ahoenigmann: I have a clojure function that reads some info from a file. Now I want to do that in a separate Thread.

16:48 Fare: yes, I was vaguely thinking of that.

16:49 bbloom_: https://github.com/brandonbloom/ascribe

16:49 ahoenigmann: (It could block)

16:49 Fare: OK, I'll retry naively with a state monad

16:49 and see where it leads me

16:49 bbloom_: i say try an atom :-)

16:49 Fare: and multiple passes, different state every pass

16:49 justin_smith: Fare: asdf?

16:50 Fare: justin_smith, the Common Lisp build system.

16:50 justin_smith: ahh, I figured you might mean that

16:50 Fare: justin_smith, I rewrote it, two or three times, and now it kind of makes sense (to me)

16:50 justin_smith: otherwise I was going to warn you of the naming conflict :)

16:50 bbloom_: i have a super cool UI-in-cljs prototype that is essentially a dynamic attribute grammar, but there's lots of low hanging perf fruit i just haven't put in the hours for yet

16:50 justin_smith: Fare: wait, you wrote asdf?

16:51 bbloom_: Fare: this also mentions chained attributes: http://www.haskell.org/haskellwiki/The_Monad.Reader/Issue4/Why_Attribute_Grammars_Matter

16:51 Fare: no, just rewrote it — if you're interested, I wrote a 26-page essay on it earlier this year.

16:52 For a short comment on whether I wrote it, see the conclusion of this post: http://fare.livejournal.com/176185.html

16:54 justin_smith: Fare: does cybernethics reference Weiner et. all? or just referencing cyber generically? I had a mentor who was one of the last to get a degree in Cybernetics before darpa ruined all that in the '70s

16:56 mikerod: When you define a type - like (deftype MyType [x])

16:56 It is obvious that you have a public field x, so you can do (.x (->MyType 1))

16:56 technomancy: justin_smith: wow, cool

16:56 mikerod: But why does this also work? (.-x (->MyType 1))

16:56 wat

16:57 ,(deftype MyType [x])

16:57 clojurebot: sandbox.MyType

16:57 mikerod: (.-x (->MyType 2))

16:57 ,(.-x (->MyType 2))

16:57 clojurebot: 2

16:57 mikerod: ,(.x (->MyType 2))

16:57 clojurebot: 2

16:57 Bronsa: mikerod: .- is field access syntax introduced in 1.4 IIRC

16:57 stuartsierra: mikerod: That's an artifact of older syntax.

16:57 mikerod: hmm

16:57 justin_smith: technomancy: cybernetics is kind of crazy, in that it gets closer to philosophy / generalism than most science is comfortable with

16:57 xeqi: rlb: looks like your correct, glancing at the http spec and corresponding rack.test's tests indicates it should use "Expires" in the past for clearing

16:58 justin_smith: technomancy: I mean Margaret Mead was one of the members of the founding commitee

16:58 mikerod: So this is an older syntax thing? I'm definitely curious why it exists.

16:58 stuartsierra: mikerod: In Java, field and method names rarely clash, so you could use (.x …) for both. This turned out to be a problem in ClojureScript, so (.-x …) syntax was added specifically for fields.

16:59 Fare: justin_smith, yes, reference Weiner et al., with a twist

16:59 technomancy: I have a copy of the second edition of Cybernetics that I will probably never get around to reading =\

16:59 mikerod: stuartsierra: so which should be used in Java?

16:59 stuartsierra: (.x ..) stil works in Clojure on the JVM for backwards compatibility, but (.-x …) is the standard way to access fields now.

16:59 mikerod: stuartsierra: interesting.. I guess this is implemented somewhere in the compiler?

16:59 stuartsierra: mikerod: yes

16:59 mikerod: stuartsierra: I don't see a field on the Java class

16:59 justin_smith: technomancy: they changed the darpa funding rules in the '70s, no more darpa money unless you could demonstrate "direct military usability" of your research, the cyberneticists dissolved their departments rather than collect the money by making war toys

16:59 technomancy: justin_smith: but the whole idea of metacircularity and runtime compilation seems deeply intertwined with it

16:59 Fare: on my business card I spell it with a ħ

17:00 mikerod: like _x or something

17:00 justin_smith: technomancy: cyberneticists in my experience are totally obsessed with recursion (or as they like to call it, circularity)

17:01 mikerod: stuartsierra: this is a bit interesting that the hyphen variety is the standard now. it would not be a convention that would work if you wanted your deftype'd things to be "Java beans"

17:01 justin_smith: technomancy: and they are a direct root of info theory as we know it today, as well as signal processing among many other examples

17:01 Fare: nice

17:01 mikerod: stuartsierra: like if I'm using my types to interact with an external Java API that will try to find field "x" via a "getX" or a direct public field access

17:01 stuartsierra: deftypes definitely aren't Java beans. All fields are public and there are no getter/setter methods.

17:02 Fare: justin_smith, or "reflection"

17:02 justin_smith: Fare: ?

17:02 Fare: or "autopoiesis"

17:02 mikerod: stuartsierra: Hmm. ok not Java beans. It seems that a lot of libs that do bean stuff will find public fields instead though.

17:02 justin_smith: yes, they like those terms too :)

17:03 mikerod: I guess it is just a specific case. The hyphen thing is just strange to me. I guess it is discussed on a mailing list or something somewhere.

17:03 stuartsierra: mikerod: (deftype Foo [x]) creates a Java class with a field named just `x`. They hyphen is Clojure syntax only.

17:04 mikerod: stuartsierra: yes, I can reflect on that. That's why I think the hyphen variety is the preferred way to access it now.

17:04 That's why I think it is strange*

17:05 stuartsierra: The hyphen is just there to distinguish field-access from method calls. In Java, field access is so rare that it seldom matters.

17:05 dbushenko: hi all!

17:06 how to set default encoding to utf-8 for ring responses?

17:06 mikerod: stuartsierra: I see. This is even documented " The .- form will resolve only as field access (never as no argument public method) and should be preferred when that is the intent."

17:06 @ http://clojure.org/java_interop#Java Interop-The Dot special form now

17:06 rlb: xeqi: ok, thanks -- for now, suppose I can just override merge-cookies

17:06 mikerod: so I guess I should have just stayed up to date on my clojure.org docs! :P

17:07 stuartsierra: thanks for the explanation

17:07 stuartsierra: you're welcome

17:07 rlb: xeqi: i.e. maybe something like this: https://www.refheap.com/d0c2645dd1ec472953cc4c874

17:12 thesaskwatch: Hi, is CIDER the most actual current emacs mode for clojure?

17:13 justin_smith: thesaskwatch: cider is more actively developed, whether to use it (and which version) depends on how you feel about stability

17:14 dbushenko: thesaskwatch, yeah, CIDER is cool!

17:14 xeqi: &(empty? nil)

17:14 lazybot: ⇒ true

17:14 thesaskwatch: justin_smith: I'm a noob, but interested in productivity. For example, is there a way to debug using CIDER?

17:14 xeqi: rlb: you can remove an if ^

17:14 justin_smith: thesaskwatch: are you new to emacs?

17:15 rlb: yeah -- noticed that, but then figured you'd probably clean up any real fix

17:15 xeqi: ^

17:15 xeqi: but something like that.. I'd have to go dive in to remember if the expires code is sufficent for removal

17:15 stuartsierra: dnolen_: Latest Closure Library build has hit Maven Central http://search.maven.org/#artifactdetails%7Corg.clojure%7Cgoogle-closure-library%7C0.0-20140718-946a7d39%7Cjar

17:15 thesaskwatch: justin_smith: not much, can use it for editing text, window management, simple configuration, etc. Also was able to edit and evaluate some clojure code with cider.

17:15 xeqi: I would hope its not sending expired ones

17:16 bbloom_: stuartsierra: does google publish a changelist?

17:16 dnolen_: stuartsierra: great thanks!

17:16 justin_smith: thesaskwatch: if you already have it, may as well try it, but I don't know that it has good stepping / debugging / live process inspection at this point

17:16 stuartsierra: bbloom_: They don't even have versioned releases any more.

17:16 justin_smith: thesaskwatch: I have heard you can do some of that with intellij idea+cursive

17:16 stuartsierra: bbloom_: Just a Git repo at https://github.com/google/closure-library/

17:17 bbloom_: stuartsierra: heh, i dunno what it's like now, but back in 2007, all of google's code was in one giant perforce tree

17:17 thesaskwatch: justin_smith: I have it too, but suspected emacs would be more cannonical tool

17:17 justin_smith: thesaskwatch: and there is a cljs/ browser based inspector for investigating exceptions that get thrown, called schmetterling

17:17 thesaskwatch: more of us use emacs than everything else combined, but only jsut barely

17:18 dnolen_: stuartsierra: just waiting for an executor so that ClojureScript release can build now

17:18 thesaskwatch: ok, one more thing - I"ve heard about autoreloading of code - what tools is the most fashionable now to do it? are you all using this feature? or maybe a different workflow?

17:19 justin_smith: thesaskwatch: it comes with ring, if you are developing a ring based server

17:20 otherwise I like to edit a def, and evaluate, and try a few things, etc. with more of a repl focus

17:20 thesaskwatch: justin_smith: nope, I mean something more general - currently I'm writing a console app. What I want to do it to avoid having to restart emacs from time to time.

17:20 justin_smith: thesaskwatch: why would you have to restart emacs?

17:20 stuartsierra: dnolen_: Oh boy, all the matrix builds are runnnig. This will take a while.

17:20 justin_smith: (require '[some.ns :as alias] :reload)

17:20 dnolen_: stuartsierra: yeah

17:20 stuartsierra: does that normally happen on Friday's?

17:21 thesaskwatch: justin_smith: when I want to be sure that repl has loaded all the code that is on disk

17:21 justin_smith: thesaskwatch: unless you are playing with protocols or defmethods, you shouldn't even have to start clojure

17:21 stuartsierra: dnolen_: It happens every time there's a commit to Clojure. It automatically rebuilds & tests all of contrib.

17:21 dnolen_: ah ok

17:21 thesaskwatch: justin_smith: I don't even know how protocols work yest :)

17:21 justin_smith: thesaskwatch: you require and reload files as you edit them - the repl based workflow is very interactive, I never have multiple files to load - I usually only have one function or definition to update

17:22 Bronsa: stuartsierra: the commit was 5 hours ago, have they been running since then?

17:22 puredanger: yes

17:22 justin_smith: thesaskwatch: that's how I work at least

17:22 puredanger: WHEEE

17:22 Bronsa: wow

17:22 thesaskwatch: justin_smith: is the :reload functionality builtin to clojure?

17:22 puredanger: contribs * jdks * clojure versions = I don't know, a lot

17:22 stuartsierra: Bronsa: probably. 30+ libs, 10+ test builds for each…

17:22 justin_smith: thesaskwatch: also, not only do you not need to restart emacs to get a clean project reload, you can be connected to multiple projects simultaneously

17:23 thesaskwatch: yes, what I showed above was normal clojure syntax

17:23 not cider at all

17:23 thesaskwatch: justin_smith: yeah, I know that. However - is there a way to disconnect from repl?

17:23 stuartsierra: We use the Hudson box to heat puredanger's house.

17:23 puredanger: it's an old 386 I had lying around

17:23 stuartsierra: haha

17:23 justin_smith: thesaskwatch: you can close the process buffer for the connection if you want clojure to continue but not be connected, you can run (System/exit 0) to make the clojure process exit

17:23 thesaskwatch: justin_smith: this :reload thing sounds very nice. Thanks!

17:24 justin_smith: np

17:24 there is also :reload-all for deeper levels of reloading

17:24 stuartsierra: I wonder if Clojure would even run on a 386?

17:24 justin_smith: stuartsierra: haven't people run it on arm?

17:24 puredanger: stuartsierra: occasionally (ok, every time there's a commit to Clojure) I wonder if we push not make all this stuff happen automatically

17:24 s/push/should/

17:25 I'd often rather push that button before I go to bed or something

17:25 stuartsierra: puredanger: a reasonable question. Easy enough: just remove the "build after" from Clojure's Hudson config.

17:25 rlb: xeqi: did you want me to file an issue, or are you good?

17:25 btw

17:25 thesaskwatch: stuartsierra: if jvm runs on 386 (which AFAIK it does) than clojure should too (just guessing)

17:25 puredanger: stuartsierra: yeah, I've considered it

17:25 Bronsa: puredanger: testing the new snapshot after a commit to the contrib lib or before a new release seems reasonable enough

17:27 puredanger: that's separate and already happens

17:27 if I understand you right

17:27 thesaskwatch: this looks useful: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

17:27 puredanger: this is about what happens when there's a commit to clojure itself - right now every commit rebuilds the world

17:28 I'd be happy to do that once a day or week or on demand

17:29 thesaskwatch: shhh stuartsierra is right here! (don't inflate his ego!) :)

17:29 xeqi: rlb: you're welcome to submit a PR with that change if you want an oss commit

17:29 thesaskwatch: puredanger: ok .. actually this doesn't sound very useful ;)

17:29 stuartsierra: puredanger: :P

17:29 rlb: xeqi: by all means, whatever's best for you -- I'm happy either way

17:30 xeqi: rlb: patches welcome :)

17:31 Bronsa: puredanger: yeah, I was agreeing with you, rebuilding the world at every commit to clojure seems unnecessary given that a push on a contrib lib will test the new clojure snapshot anyway; I was suggesting that rebuilding the world before a clojure release just to double-check could be something to consider

17:31 rlb: ok -- will send in a bit -- thanks again

17:32 puredanger: Bronsa: gotcha, yes definitely. And actually I would like a periodic automated build all, but daily or even weekly would be sufficient I think.

17:33 arrdem: clojure-nightly would be nice

17:34 stuartsierra: You can always get the latest -SNAPSHOT from Sonatype, so this would just be for testing I think.

17:34 Bronsa: puredanger: daily seems excessive, that'd mean hudson would be inusable for at least 5 hours a day, every day. more if a commit gets into clojure after the automatic build started

17:34 puredanger: stuartsierra: right, we'd still rebuild clojure itself, just not all the libs

17:35 stuartsierra: yse

17:35 puredanger: but we could do rebuild-all on weekend

17:35 Bronsa: +1 on that

17:36 puredanger: maybe on weekends IFF a commit landed in clojure master during the week

17:36 puredanger: you think we have that kind of technology? :)

17:36 stuartsierra: Our Hudson is old enough to vote.

17:36 andyf_: arrdem: I am ready to commit cheatsheet with updated Grimoire links

17:36 Bronsa: ouch :)

17:36 arrdem: andyf_: send it. I already updated the site.

17:37 puredanger: seriously though, you can specify a crontab for it so that should be sufficient

17:39 andyf_: puredanger: The hudson builds have been done physically in your home since before you were cognitect employee?

17:39 puredanger: that was a joke before :)

17:39 Contegix has been very kind to host the Clojure build box for many years

17:39 and jira and confluence

17:40 although Contegix is here in St. Louis, so….

17:40 andyf_: Ah. It sounded plausible enough that it might be true

17:41 St Louis homes typically don't need extra sources of heat in August, I know from past experience

17:41 puredanger: correct. :)

17:41 Bronsa: speaking of confluence, is the Dashboard broken only for me? it's not showing updates that I can otherwise see if I look at a page history

17:42 puredanger: no, that's perpetually broken

17:42 Bronsa: ah, ok.

17:42 puredanger: there are some background jobs that are supposed to do that indexing but they … don't

17:43 I'm a bit mystified by the admin controls on it and I can occasionally press the right buttons to make it work again, let me try

17:43 bbloom_: this may be a good time to point out this post from july 28: https://github.com/blog/1866-the-new-github-issues

17:43 * bbloom_ ducks

17:43 puredanger: upgrading all of this infrastructure is on my todo list

17:44 including looking at other alternatives bbloom_

17:44 bbloom_: puredanger: i can't hear you, i'm ducking

17:44 puredanger: quack

17:44 * stuartsierra throws a rubber duck at bbloom_

17:44 bbloom_: ow.

17:44 hyPiRion: bbloom_: I read that as "I'm a duckling" for some reason.

17:45 bbloom_: i laughed pretty hard when i saw that they used Microsoft/TypeScript as the project in the post's screenshot

17:45 stuartsierra: Enterprise-grade Emoji

17:46 puredanger: Bronsa: boom, updated index

17:47 andyf_: arrdem: Updated. A few test clicks on symbols with non alpha chars in them worked, so probably all fine

17:47 timsg: I’m having a lot of trouble signing the Clojure contributor agreement. I’ve tried in Chrome, Safari, and Firefox. It’s difficult to enter text in any field, and impossible to even put the Name field in focus. Assuming this isn’t a filter for contributor competence, does anyone know a workaround?

17:47 Bronsa: puredanger: woot thanks!

17:47 arrdem: andyf_: it should be. Really I should just make a "grimoire" org and have a dep you can point to with a version range for the latest munge, but I don't expect to be changing it again.

17:48 puredanger: timsg: the name field is auto-filled by later parts of the form I think

17:48 the signing part that is

17:48 timsg: puredanger: ok I’ll try that, thanks

17:48 bbloom_: timsg: what he's saying is that it is indeed a filter for contributor competence

17:48 timsg: bbloom_ o snap

17:48 stuartsierra: bbloom_: No, that's what JIRA is for.

17:48 puredanger: worst case, you can print and mail it to us - ping me at alex.miller@cognitect.com if you need more help

17:49 bbloom_: haha, no really, i've seen that adobe signature thing before. super confusing

17:49 puredanger: you are all welcome to contribute :)

17:49 bbloom_: don't feel bad timsg

17:49 timsg: did you figure out the clr thing you pinged me about?

17:49 Bronsa: puredanger: that's something that confused a number of folks before, maybe it's worth pointing that out on the /contributing page?

17:49 puredanger: Bronsa: I hadn't seen that, thx

17:50 (the prior confusion that is)

17:50 timsg: bbloom_: It’s okay, I know I shouldn’t feel too bad for not being able to so much as sign the form registering me for contribution to a programming language

17:50 it’s flash, after all

17:50 lpvb: is clojuredocs.org a good website

17:51 timsg: bbloom_: yeah I figured it out. answer is the Clojure-CLR is broken, going to have to fix it. Hence the contributor agreement.

17:51 lpvb: I think it was the out of date one..

17:51 puredanger: in case anyone is curious, we average about 2 new CAs every day

17:52 hiredman: puredanger: there needs to be a chart showing CA's per day on the website

17:52 arrdem: lpvb: I'm biased, but http://grimoire.arrdem.com is in-date and maintained. better is subjective.

17:52 puredanger: hiredman: I'll put that at the top of my list ;)

17:52 hiredman: :)

17:52 stuartsierra: *Which* list, you'll never know.

17:53 lpvb: oh was about to say there was no search

17:53 puredanger: actually, there is programmatic access to that data now, so that's actually feasible

17:53 lpvb: maybe you should move that to the top

17:53 andyf_: lpvb: The doc strings and source code on ClojureDocs are older, but most if not all of the examples are as good as they ever were

17:53 bbloom_: http://crossclj.info/ is pretty interesting too

17:53 arrdem: crossclj is osum. unfortunately they still have munging problems...

17:54 bbloom_: yeah i tweeted at them that clojure.core/< doesn't render correctly

17:54 andyf_: There are definite signs that ClojureDocs may be updated soon, e.g. New version has a test site up and running

17:54 timsg: bbloom_: unless there’s something I’m really really missing. Here’s the relevant thread, actually I’d love your feedback on this issue if you have a minute: https://groups.google.com/forum/#!topic/clojure-clr/YbPhOB-ILSE

17:54 Bronsa: crossclj could be really good, I find it has a somewhat confusing UI though

17:54 bbloom_: Bronsa: agreed

17:55 timsg: isn't this a case of "don't do that"?

17:56 timsg: bbloom_: as in, if everyone agrees not to mutate records, we can pretend they’re immutable?

17:56 bbloom_: timsg: well, i mean, the field (or on the clr, i guess it could be a property) should be read-only

17:56 but... just don't mutate it

17:57 don't use set! unless you know the thign you have is in fact mutable

17:57 Bronsa: deftype/record fields are private in the JVM btw

17:57 bbloom_: yeah, it generates getters

17:57 well getter methods

17:57 on the CLR it may actually generate property getters

17:57 amalloy: Bronsa: record fields are public final, not private

17:58 timsg: bbloom_: there must be some way to enforce privacy, right?

17:58 Bronsa: amalloy: yeah right, I was thinking about mutable fields

17:58 bbloom_: timsg: sure, but it's not "broken" from your perspective

17:58 amalloy: bbloom_: it sure looks like a bug in defrecord to me

17:58 (in the clr version)

17:58 andyf_: timsg: Technically everyone is pretty much agreed on not mutating Clojure persistent data structures in place, too, although it takes more than set! in Clojure to mutate them

17:59 bbloom_: amalloy: yeah, it is

17:59 just saying it's not a problem really, there are plenty of public/mutable things in clojure too that should be private

17:59 but nobody notices

18:00 ,(defn f [x] (* x 2))

18:00 clojurebot: #'sandbox/f

18:00 bbloom_: ,(.__methodImplCache f)

18:00 clojurebot: nil

18:01 bbloom_: ,(set! (.__methodImplCache f) (clojure.lang.MethodImplCache(nil, nil))

18:01 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

18:01 bbloom_: ,(set! (.__methodImplCache f) (clojure.lang.MethodImplCache. nil nil)) ; heh, went java all of a sudden

18:01 clojurebot: #<MethodImplCache clojure.lang.MethodImplCache@70a698>

18:01 bbloom_: ,(.__methodImplCache f)

18:01 clojurebot: #<MethodImplCache clojure.lang.MethodImplCache@70a698>

18:01 bbloom_: hurray! mutation of something that should be private

18:01 sshhh don't tell anyone

18:02 Bronsa: ,(fn [] 2)

18:02 clojurebot: #<sandbox$eval142$fn__143 sandbox$eval142$fn__143@1ddbf6e>

18:02 Bronsa: sandbox$eval142$fn__143/const__0

18:02 ,sandbox$eval142$fn__143/const__0

18:02 clojurebot: 2

18:03 technomancy: haha wait, the electronic CA submission requires flash?

18:04 bbloom_: ,(let [v [1 2 3]] (aset (.tail v) 1 5) v)

18:04 clojurebot: [1 5 3]

18:04 bbloom_: whoops! ^^

18:04 justin_smith: technomancy: it's an adobe conspiracy

18:04 bbloom_: arrays: the largest source of accidentally mutable public APIs in the history of programming!

18:05 timsg: bbloom_: It’s kind of broken. My understanding is that, while strictly speaking you *can* mutate “immutable” data structures, you have to do a weird dance that looks like cheating - hacking some cache, or aggressive reflection stuff, or whatever. That seems an acceptable (though still kind of disturbing) threshold for immutability.

18:05 bbloom_: timsg: see my array example ^^ not very aggressive :-P

18:05 timsg: It should be a lot harder than just set!-ing an incoming value tho

18:05 noobatron: Is there a mute button

18:05 timsg: bbloom_: no it isn’t and I find it quite disconcerting

18:05 bbloom_: timsg: yeah, you're right, it should be immutable. i'm sure they would accept a patch

18:06 timsg: bbloom_: yeah, hence the contrib agreement

18:06 bbloom_: actually you can do the same thing in ClojureScript. Might be a better reason tho

18:06 bbloom_: timsg: well there's nothing you can do about it in cljs

18:06 there's no such thing as private fields

18:07 timsg: bbloom_: maybe something with closures?

18:07 bbloom_: explicit fields perform better than closure fields

18:07 justin_smith: what about freeze? or is that actually usable in js?

18:08 bbloom_: freeze isn't cross browser

18:08 justin_smith: oh, figures

18:08 timsg: bbloom_: hm. tradeoff I guess. And clearly other people aren’t as troubled by this as I am

18:08 dnolen_: justin_smith: bbloom_: it's also slow

18:08 justin_smith: timsg: how many people are actually using clojure-clr?

18:08 arrdem: andyf_: is it reasonable to tweak the cheat sheet to float out to arbitrarily many columns wide?

18:08 justin_smith: dnolen_: the freezing process, or the frozen object, or both?

18:08 bbloom_: timsg: the compiler could (in theory) detect accessibility & mutability for deftypes, or assume fields with a leading underscore are private as a convention

18:08 but it's probably not worth the complexity

18:09 timsg: justin_smith: not sure, but there’s ~40 members on the list

18:09 bbloom_: the rule is: if you're using set!, then you should know what you're doing

18:09 dnolen_: justin_smith: the frozen object, gets deoptimized

18:09 technomancy: what's the word for things that you can just broadly tell everyone they shouldn't be doing, with the knowledge that the people who are OK doing it know enough to ignore your advice?

18:09 timsg: bbloom_: Maybe but there’s a reason you can’t set! eg an element of a persistent vector, right?

18:10 andyf_: arrdem: I don't mind adding options to the generation code for it, as long as I can continue to generate what it does today

18:10 justin_smith: dnolen_: ouch - somehow one would expect the opposite would be possible, good to know

18:10 dnolen_: justin_smith: things that no one uses gets deoptimized

18:10 justin_smith: maybe one day, but not today

18:10 arrdem: andyf_: okay. I'm just looking at https://github.com/arrdem/grimoire/issues/43 and pondering.

18:10 bbloom_: timsg: set! only works on fields and vars

18:10 timsg: but aset worked just fine on tail :-P

18:11 justin_smith: technomancy: o'reilly has an icon for it I think, maybe there is a unicode ☡

18:11 timsg: bbloom_: god you’re right. that’s awful.

18:11 justin_smith: that doesn't look quite right here

18:12 bbloom_: timsg: in cljs, aset works on fields too, btw

18:12 dnolen_: bbloom_: you can enumerate undefined behavior in any language all day

18:12 :)

18:13 bbloom_: dnolen_: a fact i'm trying to convey to timsg :-)

18:14 justin_smith: dnolen_: one of my favorite things about esoteric languages (intentionally hard to use or weird little proofs of concept that are just barely turing complete) is that they can be so small as to be fully defined, or only have one or two cases of undefined behavior. While also being so crappy and small that doing anything at all with them is impressive.

18:15 gfredericks: even BF is pretty ambiguous at the edges

18:15 it's not hard to nail down though, it just wasn't officially

18:16 dnolen_: justin_smith: hrm I don't think I've seen such a thing, there's alway so many edge cases

18:16 definition order, scope, floats etc.

18:16 justin_smith: dnolen_: these are toy languages, most of them don't have floats

18:17 heh

18:17 technomancy: well it helps that they're like 90% stack languages to begin with

18:17 gfredericks: single-threaded

18:17 justin_smith: technomancy: but fungoids!

18:17 dnolen_: justin_smith: someone should do a undefined behavior in esoteric languages, I'm sure it would be eye opening

18:17 even for what appear on the surface to be the most trivial well defined toy langs

18:17 justin_smith: http://catseye.tc/node/Esolang

18:18 dnolen_: indeed - though my suspicion is that unlambda may be without any undefined behavior (I have no proof)

18:18 http://www.madore.org/~david/programs/unlambda/

18:19 bbloom_: basically, the only meaningful language that has ever even attempted to eliminate undefined behavior is Standard ML

18:19 justin_smith: it's a purely functional obfuscated language

18:19 bbloom_: how far did they get with that?

18:20 bbloom_: and the fact that the spec gets revised for an otherwise "finished" language with formal semantics, should basically give you an understanding of how hard it is to eliminate undefined behavior

18:20 justin_smith: technomancy: regarding the whole stack machine thing, the only datatype available in unlambda is functions, no numbers, no stack...

18:20 bbloom_: http://www.typedynamic.com/2012/06/formal-language-semantics.html

18:21 dnolen_: bbloom_: and specs can't do much about the reality of things an implementation may wish to accomplish

18:21 bbloom_: dnolen_: right

18:21 even if you have a machine checked proof of some important property, such as memory safety, you're still bound to have good old fashioned bugs

18:21 not just in your implementation, but in your machine checker too!

18:23 dnolen_: http://sel4.systems/FAQ/#l4v

18:23 timsg: bbloom_, dnolen_: I think I get what you’re saying, that there’s a fuzzy region of tolerable deviations from the presumed spec, and we could all grow old trying to patch them. Still, I don’t think the ability to casually and accidentally mutate immutable data structures lies within that region. On the other hand, the loophole in question seems sufficiently subtle that it hasn’t hurt anyone enough yet for them to patch it, so maybe I

18:23 being too uptight about this

18:23 bbloom_: although, the kframework guys are doing some cool work on generating not-unreasonably-inefficient interpreters from formal semantics, which is cool

18:24 dnolen_: timsg: Clojure-CLR has a bug w/ respect to defrecord that's for sure

18:24 esp. if deftype works correctly

18:25 timsg: dnolen_: deftype doesn’t, nothing seems to generate private fields

18:25 andyf_: timsg: Create a ticket or two on that topic. It may get addressed if the language maintainer agrees

18:25 timsg: andyf_: yep, that’s that plan. Got swept away by this conversation tho :)

18:25 andyf_: Cool

18:26 dnolen_: timsg: so that's a bug too if the CLR can enforce it definitely should

18:26 timsg: that said for conformant Clojure code this mostly a non-issue

18:27 no one is going to port code from Clojure to Clojure-CLR or CLJS that mutates record fields

18:28 timsg: dnolen_: I’ll have a whack at it. This is probably more an issue for Clojure-Unity, which requires a lot of weirdness that wouldn’t come up otherwise

18:28 dnolen_: timsg: this my favorite part - poking at compiler really opens the dark corners of language design

18:31 bbloom_: dnolen_: timsg: i hope you guys aren't in the same room right now

18:31 dnolen_: bbloom_: lol we are

18:31 timsg: bbloom_: :-)

18:31 bbloom_: haha

18:31 you guys up for some beers later?

18:34 timsg: bbloom_: I am! dnolen’s otherwise engaged

18:34 bbloom_: k, i'll msg you

18:34 other nyc clojure folks welcome to msg me :-)

18:35 lpvb: is this ideal (.indexOf (vec (seq (Iterable.))) someObject) ?

18:36 given that I have an Iterable

18:36 the (vec (seq looks a bit off

18:37 justin_smith: lpvb: what about (into [] ...) instead?

18:37 lpvb: what's the difference between that and vec?

18:37 gfredericks: not much

18:38 you probably don't need seq though

18:38 lpvb: well I couldn't do (nth (Iterable.) number) so I think I had to seq

18:39 gfredericks: but vec might do that for you

18:39 justin_smith: vec calls to-array if the argument is not an instance of java.util.Collection

18:39 gfredericks: hmm

18:39 lpvb: oh okay

18:39 justin_smith: to-array may do your magic for you

18:40 oh weird...

18:40 looking at the source for vec, it only calls to-array if the arg is not a java.util.Collection

18:41 dnolen_:

18:41 oops

18:41 justin_smith: then the doc string for to-array says it expects a java.uti.Collection

18:41 something is out of sync here, unless I am out to lunch

18:42 Bronsa: justin_smith: it's the docstring for to-array

18:42 justin_smith: Bronsa: oh, so the doc is out of date? I am looking for the java code now

18:43 Bronsa: ,(instance? java.util.Collection "foo")

18:43 clojurebot: false

18:43 Bronsa: ,(to-array "foo")

18:43 clojurebot: #<Object[] [Ljava.lang.Object;@44b0f8>

18:43 justin_smith: cool, once again Bronsa comes through with the answer

18:43 (inc Bronsa)

18:43 lazybot: ⇒ 34

18:43 justin_smith: (inc Bronsa)

18:43 (missed one)

18:43 lazybot: ⇒ 35

18:45 lpvb: (inc Bronsa)

18:45 lazybot: ⇒ 36

18:45 lpvb: (inc justin_smith)

18:45 lazybot: ⇒ 56

18:45 justin_smith: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L1559 hrmph, looks like to-array won't turn an iterator into a collection (unless I am reading it wrong)

18:46 amalloy: justin_smith: neither will seq, or much of anything

18:46 you can use iterator-seq, if you're keen to do that

18:47 justin_smith: lpvb: ^^^ looks like amalloy has your answer

18:48 amalloy: justin_smith: it looks like he has an Iterable. why would he convert it to an iterator?

18:48 iterators are seqable as normal

18:48 er, iterables

18:49 DomKM: So it looks like Java static fields aren't first-class. https://www.refheap.com/88823

18:49 amalloy: DomKM: indeed not

18:49 DomKM: Is there an idiomatic way to pass them around?

18:49 amalloy: although also that's not a field but a method

18:50 justin_smith: amalloy: d'oh, my confusion

18:50 DomKM: sorry, I don't know much about java

18:50 amalloy: sure. wrap it in a function, as you've done

18:50 DomKM: ok, thought there might be something like memfn

18:50 thanks

18:54 lpvb: amalloy: The iterable object actually extends an abstract class that implements iterable and I get 'nth is not supported on this type' without seq

18:54 justin_smith: lpvb: yeah, that is what he meant by seqable

18:55 lpvb: so if the derived class implemented iterable directly I wouldn't need seq?

18:56 arrdem: andyf_: sorry about the churn :P

18:56 andyf_: this is what happens when you give me free time and coffee

18:56 justin_smith: lpvb: no, it just means seq knows how to turn it into a sequence

18:57 andyf_: Exciting stuff, no apologies needed.

18:59 stuartsierra: dnolen_: I made a Hudson job to do a *staging* release of G.Closure library. We can try it out next time. http://build.clojure.org/job/google-closure-library/

19:04 noobatron: Yes

19:04 everything is working now

19:04 MMM

19:04 FUCK

19:04 >:(

19:08 justin_smith: noobatron: you OK?

19:22 noobatron: Epic crash

19:24 pandeiro: going crazy with 401s from my own archiva instance when trying to `lein deploy releases` to it; anyone familiar with archiva?

20:32 * Fare is surprised to still have bugs to fix in cl-launch, but oh well, here they are.

20:32 Fare: that'll teach me about not running regression tests all the time.

20:33 oops, wrong channel

22:59 how do I get the name of a keyword? .getName ?

23:00 arrdem: is there a writeup somewhere on building clojure.core from source? I'm not finding one.

23:01 justin_smith: Fare: name works

23:01 ,(name :hello)

23:01 clojurebot: "hello"

23:01 Fare: thanks

23:01 (inc justin_smith)

23:01 lazybot: ⇒ 57

23:01 justin_smith: woo, ketchup

23:02 arrdem: it has a pom.xml, have you tried "mvn build" ?

23:02 arrdem: looks like I forgot to run the ant setup script :P

23:02 ant seems to be working now.

23:03 justin_smith: oh, I thought pom.xml meant maven

Logging service provided by n01se.net