#clojure log - Dec 31 2013

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

0:01 alew: rovar: (as-> x (get-in x bar [:users "root" :items]) (vals x) (mapcat vals x) (apply (partial merge-with list) x))

0:01 rovar: not familiar with either of those, I'll go look them up.

0:02 where does one find as-> ?

0:02 justin_smith: clojure 1.5

0:02 rovar: doesn't seem to be in clojure.core, and google isn't much help

0:03 justin_smith: it is in clojure.core in 1.5+

0:03 rovar: ,(help as->)

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

0:03 alew: I used it wrong slightly

0:03 TEttinger: ,(doc as->)

0:03 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

0:03 justin_smith: ,(doc as->)

0:03 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

0:03 rovar: no clojuredocs for 1.5?

0:03 alew: should be (as-> <stuff to thread> <var> ... <forms>)

0:03 justin_smith: the source of as makes it very clear

0:03 $source as->

0:03 lazybot: Source not found.

0:03 TEttinger: clojuredocs hasn't been updated since 1.3

0:03 justin_smith: :(

0:05 rovar: huh

0:05 that's kind of cool

0:06 justin_smith: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6832

0:06 very simple macro

0:06 kind of beautiful actually

0:06 lsdafjklsd: it just allows you to place the argument?

0:06 justin_smith: yeah

0:06 lsdafjklsd: instead of ((expr))

0:06 all the time

0:06 justin_smith: in each step the magic symbol gets a new value

0:07 right

0:07 but it is more verbose, because you have to always explicitly paste the threaded value

0:07 and you always need the full parens because of that

0:09 rovar: mm.. unsupported binding form for (get-in x [:blah])

0:10 justin_smith: as-> expr name

0:10 that trips me up

0:10 ( would expect as-> name expr

0:10 *I

0:11 hiredman: if you want to use as-> in the middle of a -> you need the expr to come first

0:11 radix: is #(identity ...) a common pattern, or is there some more concise spelling?

0:11 seancorfield: because it expects to be used inside (-> ...) ;; yeah, what hiredman said

0:12 radix: I mean, (fn [] ...) is shorter I guess...

0:12 rovar: (as-> (get-in x bar [:users "root" :items]) x (vals x) (mapcat vals x))

0:12 hiredman: radix: your question doesn't make sense

0:12 radix: hm.

0:12 seancorfield: (-> stuff (as-> x (vals x) (mapcat vals x)))

0:12 radix: I found myself writing #(identity ...) and was wondering if that's something that's normally acceptable.

0:13 rovar: om nom

0:13 hiredman: identity requires one arg, args in side #() are always % so #(identity ...) has to be #(identity %) which is just identity

0:13 radix: ummm

0:13 hiredman: the (fn [] ...) you gave doesn't have an arg, so it can't be identity

0:13 radix: I didn't use % anywhere

0:13 so, let me use a more complete example

0:13 #(identity "foo")

0:14 seancorfield: (constantly "foo") perhaps?

0:14 hiredman: ,(doc constantly)

0:14 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

0:14 radix: ok, cool, that helps :)

0:15 TEttinger: hm. before my friend spends countless hours running this code, can anyone tell me if there is something I'm missing about this line? https://gist.github.com/nlacasse/4630592#file-dbpedia-clj-L39

0:15 he wants to run it over a DB of the wikipedia dump

0:15 but (atom (transient {})) shouldn't work if he never calls persistent! right?

0:17 justin_smith: get works on transients, so it should all work from a quick scan

0:17 radix: I'm looking through my code and now I found an #(identity ...) that did use an argument -- what about something like #(identity [:foo %]) ?

0:17 is that pretty normal, or is there a better spelling for that?

0:18 justin_smith: #(vector foo %)

0:18 well make foo a keyworkd, but you know

0:21 hiredman: #(identity [:foo %]) almost certainly means you should be using for instead of map

0:21 TEttinger: justin_smith, just tried it, it does not work because atoms can call in a different thread

0:22 ,(let [id-map (atom (transient {}))] (swap! id-map #(assoc! % :foo "bar"))) ;; this works because they share scope

0:22 clojurebot: #<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@322765>

0:22 hiredman: TEttinger: a transient is a sort of mutable thing, but it inside a reference type doesn't make sense

0:23 TEttinger: yeah.

0:23 that's what I don't understand

0:23 hiredman: TEttinger: so don't do that

0:23 TEttinger: it isn't my code!

0:23 hiredman: so don't use that code

0:24 TEttinger: I'm thinking of enclosing the area that uses that transient in one larger fn

0:25 so it is guaranteed to stay in the same thread and not need an atom

0:27 zerokarmaleft: anyone have an example of mocking an friend/authenticated ring request?

0:29 justin_smith: zerokarmaleft: a ring request is a map, so if you put in the appropriate parameters you should be able to pass that to the handler and verify it responds properly

0:29 the body should be an input stream, you can make one out of a string

0:31 zerokarmaleft: justin_smith: I'm using ring.mock.request, I just added authentication and I'd like to be able to test around that

0:33 justin_smith: test around it as in test the things without the authentication step?

0:33 zerokarmaleft: justin_smith: right, to mock it out

0:33 justin_smith: in that case your best bet is likely to break the code into pure functions where you know their expected inputs and outputs

0:33 and commpose those into your handlers for the app

0:38 zerokarmaleft: I suppose I'm not understanding how friend handles a currently authenticated user

0:40 justin_smith: have you checked if it puts anything in :session ?

0:42 zerokarmaleft: justin_smith: here's a bit more context => https://www.refheap.com/22330

0:44 justin_smith: I see wrap-authenticate defined, and then a call to wrap-authenticated

0:45 zerokarmaleft: sorry, typo pasting it refheap

0:45 justin_smith: and where is request defined? is that ring.mock/request?

0:46 zerokarmaleft: yea, ring.mock...following the trace I'm not sure why current-authentication is called with nil

0:47 or rather, why *identity* is never set to anything

0:47 I suspect it's because I'm bypassing an actual workflow, but I'm not sure

0:48 justin_smith: I've been meaning to figure out how friend works, but frankly I don't get most of it, sorry

0:49 zerokarmaleft: justin_smith: yea

0:50 justin_smith: we should have jackets made

0:50 justin_smith: hah

0:50 the "I don't get friend" gamg

0:54 rovar: ,((apply comp '(inc inc inc inc)) 0)

0:54 clojurebot: nil

0:54 rovar: :(

0:55 what I do wrong?

0:55 justin_smith: ,((apply comp [inc inc inc inc]) 0)

0:55 clojurebot: 4

0:55 justin_smith: ,(map class '(inc inc inc inc))

0:55 clojurebot: (clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol)

0:55 rovar: ah

0:55 right

0:55 justin_smith: ,(map class [inc inc inc inc])

0:55 clojurebot: (clojure.core$inc clojure.core$inc clojure.core$inc clojure.core$inc)

0:56 rovar: ,((apply comp (list inc inc inc inc)) 0)

0:56 clojurebot: 4

0:56 dnolen: ,((apply comp [inc inc inc]) 0)

0:56 clojurebot: 3

0:56 zerokarmaleft: ,(nth (iterate inc 0) 4)

0:56 clojurebot: 4

0:58 zerokarmaleft: @seen cemerick

0:59 justin_smith: $seen cemerick

0:59 lazybot: cemerick was last seen quitting 6 hours and 10 minutes ago.

1:00 radix: hiredman: sorry, missed your response. actually it's in the context of a :content handler in the Lucuma clojurescript library

1:00 but I'll just use (fn)

1:12 jonasen: What's a good clojure library for running shell script (which reads from stdin and writes to stdout)?

1:22 ddellacosta: jonasen: does conch do what you want? https://github.com/Raynes/conch I've found it useful.

1:26 jonasen: ddellacosta: I think so. Thanks!

1:26 ddellacosta: jonasen: any time!

1:27 justin_smith: jonasen: I have had good luck with the ProcessBUilder class

1:27 good fine-grained control of what to do with STDIN STDOUT STDERR of a shell process

1:28 oh, I see he uses ProcessBuilder in conch

1:33 ddellacosta: yeah, it's pretty handy, you can get all the different output and data about the operation in a hash-map if I recall correctly

1:40 jonasen: ddellacosta: justin_smith: conch worked great!

1:40 ddellacosta: jonasen: excellent. :-)

1:43 justin_smith: cool

1:48 marcopolo`: conch looks pretty cool, is there anything like it for cljs+node?

2:56 seriously_random: is this reduce totally wrong? http://pastebin.com/eb6bjVke

3:04 marcopolo`: seriously_random: on line 7 it looks like you are trying to treat the seq returned from my-map as a function

3:05 I think what you want is a loop/recur

3:05 ,(doc loop)

3:05 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

3:06 marcopolo`: This page explains it a bit better http://clojuredocs.org/clojure_core/clojure.core/loop

3:10 andyf: seriously_random: The first one in my-map-one, or the second one?

3:11 If the first, my guess would be that since concat is lazy, it would either cause very deep stack usage if called on a long sequence, and even if it did not blow up the stack it might use O(n^2) time

3:13 The second reduce seems like it cannot do what you wish it to (i.e. cause f to be called with 2 or more arguments), because the call to (my-map f a-seq) will always call f with 1 arg.

3:15 seriously_random: andyf, reasonable would to write f for two sequences?

3:25 turbopape: Hi guys,

3:25 Sorry If I already asked,

3:25 But did anyone use http-kit as a heavy load reverse proxy ?

3:29 chinmoy: How can i make parallel http requests in clojure?

5:20 bitemyapp: TimMc: what is a "string" to a TCP socket?

5:21 TimMc: if I pass the straight binary of a "string" from a Golang client directly into a TCP socket to a Java TCP server, what happens?

5:28 Clome: what does N mean in clojure, example 3N

5:28 TEttinger: Clome, BigInteger

5:28 or BigNumber

5:29 ,(class 1N)

5:29 clojurebot: clojure.lang.BigInt

5:29 TEttinger: ,(class 1M)

5:29 clojurebot: java.math.BigDecimal

5:29 Clome: tnx

5:29 TEttinger: BigDecimal is very handy when you use with-precision

5:30 ,(with-precision 4 (/ 2M 3))

5:30 clojurebot: 0.6667M

7:20 seriously_random: need some hints for why the nestedness is happening: http://pastebin.com/Jn04vE19

7:27 justin_smith: (cons (f (first seq-1) (first seq-2)) (my-map-two f (rest seq-1) (rest seq-2)))

7:28 it conses the result of the function on the first two, to the recured value

7:28 I think that would do it

7:30 sbhuiyan: hello, got an interesting issue trying to use not-any? in a REPL, if I try (not-any? nil? ("test" nil)) I get false which is as expected. But if I have a (def account nil) and try (not-any? nil? '("test" account)), I get true

7:30 justin_smith: ,(map class '("test" account))

7:30 clojurebot: (java.lang.String clojure.lang.Symbol)

7:30 justin_smith: a quoted list does not get its contents evaluated

7:31 try (list "test" account) or ["test" account]

7:32 sbhuiyan: great

7:34 Thanks Justin. I was going for a list but guess didn't understand '() vs list. I do now

8:05 seriously_random: justin_smith, excuse my impatience, but where did I make a mistake here: http://pastebin.com/Y9sxySRT

8:12 justin_smith: (f (first-of-all seqs)) should likely be (apply f (first-of-all seqs))

8:18 seriously_random: justin_smith, I seem to have hit infinite loop.

8:21 light table is kinda buggy with stopping infinite loops

8:24 justin_smith: seqs in my-map-helper won't be empty

8:24 (empty? [() () ()])

8:24 ,(empty? [() () ()])

8:24 clojurebot: false

8:24 justin_smith: that is the case you are missing

8:25 seriously_random: changed to (empty? (first seqs)), still hitting nullpointer

8:26 justin_smith: well, clearly we fixed one bug and hit another!

8:28 also, just a little thing - (defn my-map-one [f a-seq] (reduce #(conj % (f %2)) [] a-seq))

8:28 much simpler, does the same thing

8:30 seriously_random: justin_smith, the bug has to be something simple http://pastebin.com/RSzBPHQ5

8:32 justin_smith, looks like end condition is incorrect

8:32 justin_smith: very likely, yeah

8:33 are you familiar with let?

8:33 using let to break things down into steps can help

8:35 Clome: Nested :keys destructing is not allowed on a map?

8:35 pyrtsa: Clome: How would you nest it?

8:36 mrhanky: anybody tried iterating with a for-loop over js localstorage on window.load ?

8:37 Clome: [{:keys [{:keys [x1 y1 z1]} v1 v2 v3]} triangle] something like this ?

8:37 seriously_random: justin_smith, my base case should be if rest-of-all is empty. But that doesn't explain why vector works

8:37 pyrtsa: Clome: But what key would x1, y1 and z1 be found on?

8:38 Clome: x1 y2 z1

8:38 [{:keys [{x1 y1 z1} v1 v2 v3]} triangle] or at least something like this?

8:38 pyrtsa: Oh, I see. That doesn't seem like nesting, more like merging to me.

8:38 justin_smith: ,(let [{{a :a} :b} {:b {:a 0}}] a)

8:38 clojurebot: 0

8:39 Clome: i meant [{:keys [{x1 y1 z1} v2 v3]} triangle]

8:39 justin_smith: :keys is not written in a way that would make that work

8:39 Clome: ok

8:39 justin_smith: but you can use regular map destructuring, as I show above

8:40 or you could destructure in steps

8:40 Clome: but it is tedious :/

8:41 pyrtsa: Clome: What does triangle look like, as a data structure?

8:41 justin_smith: ,(let [{:keys [b]} {:b {:a 0}} {:keys [a]} b] a)

8:41 clojurebot: 0

8:42 Clome: (defrecord Triangle [v1 v2 v3]) (defrecord Vertex [x y z r g b a s t p])

8:43 justin_smith: there is also get-in, as another option

8:43 pyrtsa: (let [{{x1 :x y1 :y z1 :z} :v1, :keys [v2 v3]} triangle) ...)

8:44 You can only use :keys if the local names end up being the same as the names of the keys. But in your case the keys are :x, :y, and :z, and you want to use the bindings x1, y1, and z1.

8:45 justin_smith: ,(get-in {:b {:a 0}} [:b :a])

8:45 clojurebot: 0

8:46 seriously_random: justin_smith, fixed. http://pastebin.com/N4jFUNBn

8:46 Clome: oh right, I will try that

8:47 pyrtsa: Clome: Another option: (let [[x1 y1 z1] (select-keys (:v1 triangle) [:x :y :z]), ...] ...)

8:48 Or simply (let [{x1 :x, y1 :y, z1 :z} (:v1 triangle), ...] ...)

8:48 And likewise for :v2 and :v3.

9:06 Clome: How come a protocol name is not a verb instead of a noun? Fly => Flying ? Does not sound better? It is a protocol about flying after all.

9:07 justin_smith: Fly is a verb

9:07 Flying is a conjugated verb

9:07 pyrtsa: Fly is a noun too. :)

9:07 llasram: A... participle even?

9:07 justin_smith: actually it is the adjectival form

9:08 pyrtsa: I doubt in that context Fly is being used in its noun form, though a codebase where every protocol was the animal exemplifying its action may be fun to see

9:08 pyrtsa: :)

9:09 justin_smith: (defprotocol HoneyBadger [] (not-give-a-shit ...))

9:09 ddima: damn, I also thought about badger, but a WildBadger ;)

9:09 pyrtsa: Flies may be related to zippers too. :)

9:09 justin_smith: lol

9:09 true enough

9:11 I guess a zipper, or a button, or a velcro could all implement the Fly protocol

9:12 pyrtsa: I'm experimenting with a stuartsierra'esque REPL setup, and one trouble I think I managed to solve is that a protocol gets replaced, while I've still got a "defonce" instance of it I'd like to clean up after the reload.

9:13 justin_smith: so you want defonce to be more like def-when-reload?

9:13 pyrtsa: The way I managed to get around it was by wrapping the defprotocol inside another defonce: (defonce App (defprotocol App ...)). But on a scale from zero to one, how stupid or dangerous this might be?

9:14 Well, the problem was that the protocol defined a (stop [this]) method, and calling (stop app) after the reload errors telling that app doesn't satisfy the protocol (which is right, because it's a different protocol now).

9:14 justin_smith: it is definitely a hack

9:14 pyrtsa: Yep

9:14 justin_smith: maybe you could look at the source of defonce and construct do-once out of it?

9:14 pyrtsa: At least Sam Aaron was playing with the hack like decades ago: https://groups.google.com/d/msg/clojure/SYYYwZIrFiY/xm_0CaARLywJ

9:15 justin_smith: At least that'd make it even more explicit, with little benefit though.

9:16 justin_smith: the trick with do-once would be making a unique identifier that would be the same identifier on each reload

9:16 I think explicitness is a huge benefit

9:16 Clome: so no points for me for "conjugated verbs" :)

9:16 pyrtsa: justin_smith: Me too.

9:16 justin_smith: the only drawback of the above is the non-conventional usage of defonce where the thing defined is a throwaway

9:16 pyrtsa: I'm just thinking defonce is pretty explicit already.

9:17 justin_smith: maybe add throw-away or place-holder to the name of the thing defonced :)

9:17 the problem is def is being used in a weird way there, and do-once would more clearly describe the intention of the code

9:18 pyrtsa: Ah, I see what you mean.

9:35 justin_smith: pyrtsa: maybe something like this? https://www.refheap.com/22340

9:42 mrhanky: ,(for [res ["a", "b", "c"]] (println res))

9:42 clojurebot: (a\nb\nc\nnil nil nil)

9:44 mrhanky: whats wrong with the above one? works in my web repl but not in compiled cljs files Oo

9:44 justin_smith: ,(dorun (for [res ["a", "b", "c"]] (print res \space))) ; slightly cleaner for bot interaction

9:44 clojurebot: a b c

9:44 justin_smith: mrhanky: for is lazy

9:44 ,(do (for [res ["a", "b", "c"]] (print res \space)))

9:44 clojurebot: (a b c nil nil nil)

9:44 justin_smith: erm...

9:44 mrhanky: oh

9:45 hyPiRion: use doseq instead, if you only do side effects

9:45 justin_smith: anyway, because it is lazy, if you don't use the result, it shouldn't be counted on to do anything

9:45 ,(do (for [res ["a", "b", "c"]] (print res \space)) nil) ; actually showing laziness this time

9:45 clojurebot: nil

9:45 justin_smith: the value was not used, so nothing was done

9:47 mrhanky: still not working in compiled code

9:47 justin_smith: mrhanky: a common beginner (and even sometimes intermediate) mistake in clojure is forgetting that the repl's print stage forces laziness, whereas your code may not

9:48 mrhanky: did you try doseq or wrapping the for in dorun?

9:49 mrhanky: ah

9:49 dorun does the trick

9:50 justin_smith: replacing the for with doseq should work too, in most cases

9:51 and doall instead of dorun will return the results of whatever you do (if you care for those)

9:55 mrhanky: i dont get it Oo

9:55 (dorun (for [res ["consize.clj", "bootimage.txt", "prelude.txt"]] (io/file-read (str "consize/" res))))

9:55 what am i doing wrong?

9:55 jcromartie: mrhanky: "dorun" is strictly for side effects, "doall" is for evaluating and returning the whole seq

9:55 mrhanky: oh

9:56 jcromartie: dorun doesn't return anything

9:57 I'd rewrite that as: (doall (map #(io/read-file (str "consize/" %)) ["consize.clj", "bootimage.txt", "prelude.txt"]))

9:57 but for is nice too

9:58 the fact that it's called "for" is a little confusing though :)

9:58 justin_smith: (doall (map (comp io/read-file (partial str "consize/")) ...)) would work too

9:58 jcromartie: it's not our fault all the algol family languages do for the wrong way :P

9:59 in all seriousness yeah, given everyone learns an algol language first, for is a bad name choice

9:59 jcromartie: though I can't think of a better name :|

9:59 justin_smith: cartesian

10:00 jcromartie: a-la-descartes

10:00 justin_smith: ,(do (def cartesian for) (cartesian [a [0 1 2] b [3 4 5]] [a b]))

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

10:00 justin_smith: mmm

10:00 jcromartie: :P

10:01 but I know what you mean

10:02 I don't think clojurebot likes defn or defmacro

10:02 does it?

10:02 ,(do (defmacro cartesian [& args] `(for ~@args)) (cartesian [a (range 3) b (range 3)] [a b]))

10:02 justin_smith: ,(do (def a 0) a)

10:02 clojurebot: 0

10:02 ([0 0] [0 1] [0 2] [1 0] [1 1] ...)

10:02 jcromartie: hey, cool

10:02 that's pretty permissive :)

10:03 justin_smith: jcromartie: that is what I was going for, thanks man

10:03 jcromartie: for a bot

10:03 justin_smith: (inc jcromartie)

10:03 lazybot: ⇒ 6

10:05 justin_smith: it is pretty permissive, I think there is a full env reload on some timer

10:05 jcromartie: now how about a macro that aliases a macro the way you wanted to

10:05 justin_smith: so better to put your def and the code that uses it in one do block

10:05 hmm

10:11 rovar: justin_smith: did you work on jiraph?

10:11 justin_smith: ,(do (defmacro alias-macro [new old] `(defmacro ~new [& args#] `(~'~old ~@args#))) (alias-macro unless when-not) (unless false (print "OK")))

10:11 clojurebot: OK

10:12 justin_smith: rovar: nope

10:12 jcromartie: I think I wrote that macro, see above

10:12 first time I have ever had to use `(~'~ in my code

10:12 rovar: that looks dirty

10:13 justin_smith: it's just nested syntax quote

10:13 I always liked the name unless better than when-not

10:14 mdrogalis: tbaldridge: Your Conj talk was awesome. :)

10:16 rovar: when-not is generally more clear for most people than unless

10:16 i'm used to unless because I coded in ruby for a bit

10:16 ddellacosta: happy new years everyone

10:16 rovar: ddellacosta: right back atcha

10:17 ddellacosta: rovar: :-)

10:17 mullr: Happy conj-ing in the happy new year!

10:17 jcromartie: justin_smith: nice

10:17 justin_smith: (swap! year inc)

10:17 jcromartie: justin_smith: mine was way uglier

10:17 mullr: (inc justin_smith )

10:17 lazybot: ⇒ 1

10:18 mullr: TIL the current year is mutable

10:18 justin_smith: heh

10:18 til my name has a space in it :)

10:18 (inc inc)

10:18 lazybot: ⇒ 5

10:18 justin_smith: (inc inc )

10:18 lazybot: ⇒ 1

10:18 mullr: woah

10:19 (inc justin_smith)

10:19 lazybot: ⇒ 24

10:19 mullr: better

10:19 justin_smith: ta

10:19 $karma juxt

10:19 lazybot: juxt has karma 4.

10:19 justin_smith: (inc juxt)

10:19 lazybot: ⇒ 5

10:19 justin_smith: I could swear I had already done that

10:19 jcromartie: lazybot just revealed his dirty little secret: he's actually written in Perl and is just a massive collection of nasty regexes

10:20 justin_smith: so it seems

10:20 ddellacosta: that would be so hilarious

10:20 justin_smith: the only known instance of cljprl

10:21 $@&clj

10:21 something like that

10:22 ddellacosta: $_ =~ eval(/()/${func_name}()/) or something

10:22 forgotten all my perl

10:22 mercifully

10:22 justin_smith: well that would be a funny name for a clojure port, but it is appropriate

10:23 * justin_smith is being intentionally dense

10:26 jcromartie: how extensively do you all use pre/postcondition maps in your defns?

10:26 I am finding myself using them a lot in important functions, but there's some discussion about turning them on or off in production etc.

10:26 justin_smith: jcromartie: really often I find the need to level up from a precondition to an assert

10:26 jcromartie: I don't see any reason to turn them off

10:26 justin_smith: especially since assert has an optional string as the last arg, helps quite a bit

10:26 jcromartie: hm, yeah

10:26 I see

10:27 justin_smith: ,(assert false "this always fails")

10:27 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: this always fails\nfalse>

10:27 jcromartie: but a lot of times the precondition is explanation enough

10:27 justin_smith: assertions can also be turned off

10:27 jcromartie: yeah

10:27 but why?

10:27 unless you were talking about really performance sensitive code

10:28 justin_smith: I guess some people use assertions in real code instead of unit tests

10:28 hyPiRion: that's like, the whole reason why. Sometimes assertions are expensive

10:28 justin_smith: sometimes the property you want to assert is expensive to verify

10:28 jcromartie: suer

10:29 sure

10:29 so long as I don't use expensive assertions though

10:29 or if it's for rarely-used functions, like data model functions or external API calls

10:29 justin_smith: and there is always "(when (bad-state?) (Throw (Exception. "WTF")))

10:29 "

10:29 jcromartie: that's 99% of where I use them now: interfacing with external systems or for posterity

10:33 justin_smith: ,(when false (throw (Exception. "WTF")))

10:33 clojurebot: nil

10:33 justin_smith: ,(when true (throw (Exception. "WTF")))

10:33 clojurebot: #<Exception java.lang.Exception: WTF>

10:35 justin_smith: so when you really need to check some state you can use a when / throw type combo, and assertions are more for dev time code correctness

10:35 which is a little odd I think, but the ability to turn assertions off kind of forces the issue

10:36 zerokarmaleft: ,(dec zerokarmaleft)

10:36 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: zerokarmaleft in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:36 zerokarmaleft: (dec zerokarmaleft)

10:36 lazybot: You can't adjust your own karma.

10:36 zerokarmaleft: bargle

10:36 justin_smith: $karma zerokarmaleft

10:36 lazybot: zerokarmaleft has karma 1.

10:36 justin_smith: yo uwant that dec'd?

10:36 zerokarmaleft: it's only fitting :P

10:36 justin_smith: (dec zerokarmaleft)

10:36 lazybot: ⇒ 0

10:37 justin_smith: $karma zerokarmaleft

10:37 lazybot: zerokarmaleft has karma 0.

10:39 gdev_away: (inc zerokarmaleft )

10:39 lazybot: ⇒ 1

10:40 zerokarmaleft: $guards

10:40 lazybot: SEIZE HIM!

10:41 gdev: (dec zerokarmaleft )

10:41 lazybot: ⇒ 0

10:42 justin_smith: man that sucks, lose all your karma and ascend to etherial enlightenment, only to have it be put on you again

10:42 oh good, he is back in his nirvana

11:27 (dec netsplit)

11:27 lazybot: ⇒ -1

11:27 mdrogalis: ~anaphoric

11:27 clojurebot: I don't understand.

11:28 justin_smith: ~anaphora

11:28 clojurebot: <rhickey> anaphora == bad

11:29 gfredericks: clojurebot: anaphoric |are| &env and &form

11:29 clojurebot: You don't have to tell me twice.

11:29 justin_smith: ~it

11:29 clojurebot: it is for clojure.pprint/cl-format :)

11:29 gdev: whatis anaphora

11:29 justin_smith: clojurebot: it is anaphoric

11:29 clojurebot: 'Sea, mhuise.

11:29 mdrogalis: I just want to make clojurebot talk about barking spiders again. :/

11:29 gdev: lazybot, whatis anaphora

11:29 lazybot: anaphora is "the use of an expression the interpretation of which depends upon another expression in context"

11:29 patrickod: anyone here use sqlkorma and transactions with their test suite? having trouble using use-fixtures with transactions at the moment

11:30 gfredericks: patrickod: what's the trouble?

11:31 patrickod: gfredericks I have a fixture that wraps the test in a transaction, and another which is used in *some* tests that adds a row to a table such that the test can use it

11:31 but the second one fails on teh second run because it violates a unique index on insert

11:32 gfredericks: you're rolling back at the end of the test?

11:32 patrickod: I guess I could make it into a :once for these tests instead of :each now that I think about it

11:32 gfredericks: in a finally?

11:32 patrickod: gfredericks https://gist.github.com/patrickod/3acf16cd1b1f1807046a like so

11:33 gfredericks: a bit safer to do (try (t) (finally (rollback))), but if you first test isn't throwing anything that shouldn't be your problem at the moment

11:35 patrickod: the exception that's stopping the test suite is thrown by the second fixture

11:35 rovar: ,(help defalias)

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

11:35 rovar: ,(where defalias)

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

11:36 rovar: clojurebot: I never liked you.

11:36 clojurebot: I don't understand.

11:36 rovar: clojurebot: how could you understand? you're not real.

11:36 clojurebot: It's greek to me.

11:37 rovar: It would have never worked between us.

11:37 justin_smith: rovar: doc

11:37 (doc defalias)

11:37 clojurebot: Gabh mo leithscéal?

11:37 justin_smith: ,(doc defalias)

11:37 clojurebot: Pardon?

11:37 justin_smith: weird

11:37 ,(do (use 'clojure.repl) (doc defalias))

11:37 clojurebot: I don't understand.

11:37 patrickod: gfredericks unless I've misunderstood though, it should be possible to have multiple fixtures set to :every?

11:38 rovar: it's not in core or contrib

11:38 patrickod: s/every/each

11:38 gfredericks: patrickod: yep; they probably run in the order they're added

11:38 rovar: i'm trying to figure out where tf it is

11:38 gfredericks: patrickod: use-fixtures is variadic even so you can do it in one call

11:40 patrickod: maybe it's that the first fixture only wraps the test and not the second fixture?

11:40 justin_smith: https://groups.google.com/forum/#!topic/clojure/LhidPSlvX_Q rovar

11:41 gfredericks: patrickod: that sounds plausible

11:41 easy to figure out the ordering w/ debug msgs

11:42 rovar: so instead of making a proper defalias macro they just complained about it and left it out.

11:48 patrickod: huh they overwrite each other apparently, using multiple (use-fixtures :each) in the same namespace

11:48 rovar: (seen amalloy_ )

11:59 is there some sort of moral equivalent to cond-let around?

12:00 I guess with lazy collections, it's not that horrible to simply build all of the potential cases and then use cond..

12:05 tommo_: i'm new to clojure and im having a bit of a problem, why does this not work? (def myfuture (.bind bootstrap 8080))

12:05 mocker: Holy crap, finally solved 4clojure #22: https://www.refheap.com/22346

12:05 Not pretty, but it works

12:06 tommo_: Cannot cast java.lang.Long to io.netty.channel.ChannelFuture

12:06 by that logic .bind would evaluate to a long would it not?

12:08 mocker: How should something like https://www.refheap.com/22346 be indented? Or should it just stay on one line?

12:09 ddellacosta: mocker: a bit simpler way-- ,(reduce (fn [i _] (inc i)) 0 '(1 2 3 3 1))

12:09 whoops

12:09 ,(reduce (fn [i _] (inc i)) 0 '(1 2 3 3 1))

12:09 clojurebot: 5

12:10 mocker: ,(reduce (fn [i _] (inc i)) 0 "Hello World)

12:10 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

12:10 mocker: ,(reduce (fn [i _] (inc i)) 0 "Hello World")

12:10 clojurebot: 11

12:10 mocker: Nice

12:11 ddellacosta: mocker: yeah, although, for 4clojure the struggle of doing it yourself is definitely very useful

12:11 mocker: ddellacosta: But implementation aside (because I know mine isn't great) should it be indented?

12:11 ToBeReplaced: mocker: the important step in the thought process needed to be "i'm looking at a sequence, what can i do to operate on a sequence?"

12:11 ddellacosta: where? I think your formatting was fine

12:11 mocker: Ok, just not sure in clojure where/when to put newlines at.

12:12 justin_smith: I often like to line up the args to reduce

12:12 since it has an optional arg that is not the last arg

12:13 ddellacosta: mocker: yeah, for something like that, if you find it is reasonable on one line it's fine. Usually if my reduce function starts getting complex it's a smell that I should just break it out into a separate function.

12:14 justin_smith: also, while the replace / map {} thing is a bit silly, you can do it more succinctly (though just as silly) with (comp {nil 1} {})

12:14 (map (comp {nil 1} {}) (range))

12:14 ,(map (comp {nil 1} {}) (range))

12:14 clojurebot: (1 1 1 1 1 ...)

12:14 ToBeReplaced: mocker: indentation https://www.refheap.com/22348

12:15 ddellacosta: justin_smith: nice

12:15 oh, wait

12:15 hmm

12:15 justin_smith: it is of course effectively (constantly 1)

12:15 mocker: justin_smith: I started w/ solving the '(1 2 3 3 1) by taking each one (+ 1 (* 0))

12:15 justin_smith: the whole thing is silly, like I said

12:15 mocker: And it just was a downward spiral from there to get a sequence of 1s from a string.

12:15 justin_smith: right

12:16 mocker: ToBeReplaced: Thank you.

12:16 TimMc: bitemyapp: http://clojure-log.n01se.net/date/2013-12-30.html#23:49

12:16 justin_smith: mocker: also that call to vec doesn't do anything

12:17 map already forces its last arg to a seq

12:17 mocker: Oh, nice.

12:19 justin_smith: ,(apply str (map (comp char inc int) "hello"))

12:19 clojurebot: "ifmmp"

12:21 justin_smith: ,(apply str (map (comp char inc int) "IBM"))

12:21 clojurebot: "JCN"

12:21 justin_smith: err

12:21 ,(apply str (map (comp char inc int) "HAL"))

12:21 clojurebot: "IBM"

12:21 justin_smith: that's what I meant

12:23 lsdafjklsd: If I want to keep my route definitions and dispatch constrained to a namespace.routes file, what is the best way to include / initiate that into a namespace.core file?

12:24 have one public function that i call in the core file?

12:24 and that function sets everything up

12:28 mocker: Crap, I've been doing the 4clojure stuff by number and not by order on the site.

12:28 I wonder if doing them in site order would prepare me better for upcoming questions.

12:35 whomp: is there any way to see what line of my source code caused the problem? the stack trace is difficult to parse

12:36 justin_smith: whomp: if the function was defined in a file, it will show the file/line

12:36 whomp: ohh i see it, it was in yellow lol

12:36 ty

12:36 justin_smith: whomp: first thing I do is look for namespaces that are mine

12:36 reading a clojure stack trace is basically a new language you have to learn

12:36 a sucky one

12:45 pandeiro: how does one iterate over list items with om?

12:45 zerokarmaleft: http://java.dzone.com/articles/reading-clojure-stacktraces <= a good post on mentally filtering the noise

12:46 whomp: ^

12:46 whomp: zerokarmaleft, thanks!

12:46 this channel is awesome lol

12:59 dnolen: specify is sweet https://github.com/clojure/clojurescript/commit/f55bb020fd27c140011fef1bd1f0c933a1719dd3

13:00 bbloom: dnolen: got it working?!

13:00 dnolen: an optimization would be to allow specify to use earlier defined functions, would save function allocations, but at 1000000 allocations ~130ms, ain't slow

13:00 bbloom: already released 2138 has it

13:01 ior3k: dnolen: nice exchange with Avdi Grimm on twitter

13:01 lsdafjklsd: dnolen: no idea what JS fusion reactors are.... but I like it!!

13:03 dnolen: ior3k: it's always interesting to see smart OO folks poking around at FP, puts things into perspective

13:03 lsdafjklsd: heh, just that JS engines can optimize such patterns

13:03 lsdafjklsd: would be hard to make that work on the JVM

13:04 ior3k: dnolen: at least they're not dismissing it outright. Well, some of them aren't

13:04 pandeiro: dnolen: can you point me to info on "Each child in an array should have a unique key prop"? I'm trying to use om/build-all to iterate over and output a list of buttons... Probably doing it wrong?

13:05 lsdafjklsd: dnolen: nice! that's exciting as a JS dev who's work targets the browser... I mainly use clojurescript

13:06 dnolen: pandeiro: React wants a key, opts can take :key option to use something in your data as the key, for example :id or whatever

13:09 pandeiro: I suppose I could support :keyfn which would take the index and you can generate one based on that

13:09 pandeiro: if you don't want to invent one on the data itself.

13:09 pandeiro: the other option is to just generate for if you not supplied

13:09 s/for if you/for you

13:10 pandeiro: dnolen: no the :key :whatever in the final arg is fine for me...

13:11 but iteration being such a basic thing maybe this should make it to the README?

13:11 (just a suggestion)

13:11 dnolen: pandeiro: no there yet

13:11 pandeiro: and probably won't be for a while

13:12 maintaing docs for this is the pits

13:12 pandeiro: still stabilizing stuff first i imagine

13:12 dnolen: so for now the goal is for the code to be approachable

13:12 users can read it, it's not that complicated :)

13:12 pandeiro: sure, and it is; i was just impatient

13:12 btw docstrings for cljs in cider would be great

13:22 whomp: how can i view output from println? i don't see any buffer which has it

13:30 zerokarmaleft: whomp: are you using emacs?

13:30 whomp: zerokarmaleft, yes

13:30 zerokarmaleft: with cider?

13:34 that may not matter...I believe depending on which thread is writing to stdout, nrepl will send stdout to the repl buffer or *nrepl-server ...*

13:41 whomp: zerokarmaleft, i am using cider and i checked all of the buffers (nrepl, nrepl-server, nrepl-connection, messages, etc.) and didn't find anything

13:41 lsdafjklsd: whew, set my OM project up with austin, half the day gone :D

13:44 pandeiro: lsdafjklsd: austin is the browser repl thing?

13:45 lsdafjklsd: pandeiro: ya

13:45 noncom: can anyone recommend a library to fuzzy-search strings? i've googled a few, but it maybe someone has some personal experience with any?

13:45 lsdafjklsd: pandeiro: I made a lein template to get it up and going

13:45 pandeiro: lsdafjklsd: nice what's it called?

13:46 i am finally working through the om examples for the first time

13:47 dnolen: there's a tiny bug in 'counters', just one missing (put! ...) on one of the button handlers

13:47 lsdafjklsd: pandeiro: it's not published on clojars, but you can clone it and install it locally here https://github.com/lsdafjklsd/haywood-austin

13:47 i spent like, 3 hours just studying the counters code :-P

13:47 sad

13:48 pandeiro: lsdafjklsd: i'm on hour one but 3 sounds about right :)

13:48 lsdafjklsd: pandeiro: haha, good stuff!

13:51 dnolen: pandeiro: where?

13:52 pandeiro: the '-' button's click handler

13:52 dnolen: ^

13:52 (put! (:last-clicked chans) (.-path data))

13:52 dnolen: pandeiro: what's wrong w/ that?

13:52 lsdafjklsd: I figured that was deliberate

13:52 pandeiro: it's missing on mine

13:52 lsdafjklsd: it only counts if you do plus

13:52 pandeiro: + has it, - doesn't

13:53 yeah, ah is that deliberate?

13:53 dnolen: pandeiro: oh right

13:54 pandeiro: thx fixed

13:55 pandeiro: dnolen: :onChanged only works if you implement some protocol yeah?

13:55 dnolen: pandeiro: what do you mean?

13:55 pandeiro: (om/component (dom/h1 #js {:onChanged #(js/alert "hi")} "hello")) <- should alert?

13:56 dnolen: pandeiro: onChanged doesn't work on h1 tags

13:57 pandeiro: dnolen: sorry maybe something else tripping me up; but dom/button with :onChange should 'just work' right?

13:58 dnolen: pandeiro: I don't think onChange applies to buttons either

13:58 pandeiro: onChange is only for changeable form elements

13:58 input, textarea, select

13:58 pandeiro: https://github.com/swannodette/om/blob/master/examples/counters/core.cljs#L25

13:58 dnolen: pandeiro: that's *onClick*

13:59 pandeiro: gah

13:59 man

13:59 sorry

13:59 dnolen: pandeiro: np

13:59 lsdafjklsd: dude, you blew it

14:02 pandeiro: lsdafjklsd: was lein cljsbuild auto <build-id> broken for you with the examples btw?

14:02 lsdafjklsd: pandeiro: no

14:02 pandeiro: let me try again

14:02 pandeiro: 'once' works but 'auto' is entering a crazy loop

14:03 just curious, no big

14:04 lsdafjklsd: pandeiro: yea just tested again, lein cljsbuild auto counters worked fine

14:04 jcromartie: PROTIP: Rebind your Mac's command key to be meta and option to be option so you can input funky unicode chars in Emacs again

14:05 (setq mac-command-modifier 'meta) (setq mac-option-modifier nil)

14:07 technomancy: putting meta somewhere that isn't next to space is just asking for RSI

14:08 gfredericks: PROTIP: rebind OSX to linux

14:08 pandeiro: lsdafjklsd: are you using r2138 by chance?

14:08 jcromartie: gfredericks: I'm with you on that one

14:08 this is my work machine :)

14:08 lsdafjklsd: pandeiro: in my current project?

14:08 gfredericks: yeah I got forced into a mac @work too

14:09 it's like the new windows

14:09 lsdafjklsd: pandeiro: I'm using 2134

14:09 pandeiro: lsdafjklsd: no with the cljsbuild auto issue?

14:09 jcromartie: I can't complain that they gave me a $3K laptop but I have a soft spot for Fedora on my Thinkpad…. need to spend more quality time with it

14:09 my $400 craigslist computer runs Clojure just as fast as the beastly MBP

14:10 pandeiro: gfredericks: i did too and struggled 2 days to put archlinux on it; loving it

14:10 lsdafjklsd: pandeiro: nope, using cljs 2134.. that's what you're asking right?

14:10 gfredericks: pandeiro: I've been using virtualbox for over a year now but I intend to try vmware

14:11 pandeiro: gfredericks: why not dualboot?

14:11 technomancy: I have a work mac too =(

14:11 gfredericks: pandeiro: I'm a wuss?

14:11 pandeiro: gfredericks: is it a macbook air?

14:11 technomancy: luckily they only make me use it for HR type stuff

14:11 gfredericks: lol

14:11 the HR machine

14:12 pandeiro: pro

14:12 I use OSX mostly for printing

14:12 technomancy: well it also works well for checking my hair on account of the glossy screen

14:12 handy for right before a video conference

14:12 pandeiro: i see; i have a step-by-step org-mode file for how i got it working; just need to post it to github one of these days... but it's for a 2013 air setup w/ os x and arch dual booting

14:12 technomancy: yeah the gloss is incredible on these things

14:13 technomancy: it's a real face-palm

14:13 lsdafjklsd: LOL

14:13 technomancy: remember when computers used to get better all the time?

14:13 lsdafjklsd: (inc technomancy)

14:13 lazybot: ⇒ 88

14:13 pandeiro: just smudge it up with sweaty palms

14:13 kinda works

14:14 technomancy: i dunno i'd say it's the best machine i ever had, even with its issues

14:14 battery life is 3x what the equivalent lenovo gets

14:14 that alone puts it in a different category for me

14:15 technomancy: ah. I just got a thinkpad with a low-voltage chipset.

14:16 pandeiro: technomancy: how many hrs battery?

14:16 jcromartie: mine lasts about 3 hours on a good day :)

14:16 i7

14:16 technomancy: did you get the latest Intel chipset?

14:16 pandeiro: jcromartie: yeah that's what i was used to... my air is getting 8

14:16 technomancy: jcromartie: "just" meaning "in 2009" in this case

14:16 jcromartie: I really just use it around the house though

14:17 technomancy: pandeiro: 5 hours with the 6-cell battery, then I swap in the 9-cell battery and haven't ever run that one all the way down. =)

14:17 pandeiro: technomancy: swappable ftw, that's great

14:18 technomancy: yup, that's why I haven't upgraded to an X1

14:18 pcn: The new macbook pros with ssds, etc will last an entire workday running a few virtualbox VMs (though not cranking them the whole time)

14:18 pandeiro: technomancy: my ideabook isn't swappable either :( sucks

14:18 pcn: SSDs make a huge difference.

14:19 pandeiro: ...but it has a great non-reflective screen

14:19 pcn: yeah ssd must be helping; i do have a small issue with the computer "freezing" though and i suspect it has to do with the ssd

14:23 whomp: zerokarmaleft, any ideas about the println issue?

14:24 Greduan: Hi! Anybody available to help me out with CLJS + Node.js integration?

14:24 rovar: anyone feel like code golf?

14:24 https://www.refheap.com/22351

14:24 is there a better or more idiomatic way to do this?

14:25 Greduan: what do you need exactly?

14:26 lsdafjklsd: rovar: there is a monad that you can use which protects against nils in each step of a -> macro

14:26 rovar: derp, nm

14:27 Greduan: rovar: I've been trying to figure out how to integrate CLJS + Node.js + node-webkit in a way that works, but I've been having trouble just with integrating CLJS and Node.js. What's an updated way to call Node.js from CLJS? All I've found is old blog posts...

14:27 dnolen: ,(doc some->)

14:27 clojurebot: "([expr & forms]); When expr is not nil, threads it into the first form (via ->), and when that result is not nil, through the next etc"

14:27 rovar: lsdafjklsd: sort of like a apply-not-if-nil or something

14:28 dnolen: Greduan: hrm, that's a pretty specific question, obviously possible since that's how LightTable works

14:28 Greduan: you may want to ask that on the ClojureScript mailing list too if nobody can respond at the moment.

14:28 Greduan: dnolen: Right. I would like to study Light Table but the source isn't available yet.

14:28 dnolen: Will do. Thanks. :)

14:28 zerokarmaleft: whomp: sorry, no ideas beyond that :(

14:28 rovar: dnolen: that's not exactly what I want, I wish to have a list of candidate objects against which I wish to run a function, when I find the first non-nil, I stop.

14:28 seangrove: dnolen: Are javascript fusion reactors a thing, or just something that sounds cool?

14:28 jcromartie: rovar: don't you just want to call the first non-nil function?

14:29 dnolen: seangrove: just a funny phrase from one of the ex-core V8 devs

14:29 seangrove: mraleph

14:29 seangrove: Phew, ok

14:29 Thought maybe they were something generator-related

14:29 jcromartie: (runverb (first (filter not-nil? verbs)))

14:29 er I mean the first non-nil value

14:30 seangrove: or just (remove nil? verbs)

14:30 rovar: fusion reactors sounds like something that would run a list of event handlers in haskell.

14:31 jcromartie: that'll do. I keep forgetting filter is lazy

14:31 jcromartie: lazy or not, it'd do the same thing

14:31 justin_smith: or a thread pool that mutates every var in your vm if you don't monitor it closely

14:31 rovar: well no need to recreate an entire list if you're going to run the first item

14:32 jcromartie: rovar: sure

14:32 laziness is usually a boon, but sometimes a bane

14:32 :P

14:34 rovar: I like clojure's balance.

14:34 lazy collections, strict everything else, also a few options for synchronization points.

14:34 so far I've not had the problems with laziness that I had with Haskell sometimes.

14:35 e.g. I've not blown the heap with thunks yet :)

14:37 lsdafjklsd: dnolen: Whats the recommended way to share `app-state` between cljs files e.g. router.cljs / core.cljs

14:38 dnolen: lsdafjklsd: lift it up into a higher namespace probably simplest

14:39 lsdafjklsd: dnolen: yea, like state.cljs which has the atoms for the app and require them in the files

14:39 dnolen: lsdafjklsd: yep

14:39 lsdafjklsd: dnolen: thanks

14:39 rovar: IMO people seem to like to complain about namespaces in clojure. Frankly I don't see the problem. I've got a few dozen namespaces in my app and they don't seem to cause me problems :)

14:40 not yet at least..=

14:41 Clome: Happy new year and happy coding :D

14:44 rovar: (for [x '(happy)] [y '(new-year coding)] prn x y)

14:44 ,(for [x '(happy)] [y '(new-year coding)] prn x y)

14:44 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (5) passed to: core/for>

14:44 rovar: ,(for [x '(happy)] [y '(new-year coding)] (prn x y))

14:44 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/for>

14:45 rovar: ,(for [x '(happy) y '(new-year coding)] (prn x y))

14:45 clojurebot: (happy new-year\nhappy coding\nnil nil)

14:45 rovar: meh

14:45 justin_smith: ,(doseq [x '(happy) y '(new-year coding)] (prn x y))

14:45 clojurebot: happy new-year\nhappy coding\n

14:46 justin_smith: ,(doseq [x '(happy) y '(new-year coding)] (pr x y))

14:46 clojurebot: happy new-yearhappy coding

14:49 dnolen: rovar: people like easy, I don't have a problem with them either

14:51 justin_smith: I think usually the complaints about namespaces come from an idea (which I will withold judgement about) that the API provided to users of a library should be arbitrarily distinct from the structure of the implementing code

14:51 gdev: it's funny when I was teaching Clojure to some Java devs at my company namespaces totally threw them for a loop until I told them they were less like class definitions and more like package definitions

14:52 they were trying to organize their project like (ns myapp.person) (get-name [person] ...)

14:53 we've come a long way since then though

14:55 also, the beauty of being a Java developer when I was learning Clojure is that I wasn't used to things being easy so to me Clojure was simple and easy. My friends who were ruby devs had a harder time

14:55 bbloom: gdev: that package vs class distinction is a big hurdle for a lot of folks

14:56 gdev: you should totally write up your experiences w/ whatever magic words made it click for people :-)

14:56 algal: I think what's tricky about namespaces, for people new to the language, is that you're not learning just about namespaces. You learn about namespaces while also learning the distinction between name vs symbol vs var vs value. And that's actually subtle.

14:56 And then there's load vs require vs use.

14:56 justin_smith: (inc algal)

14:56 lazybot: ⇒ 1

14:56 log0ymxm: algal: the key is to start with something horrendous like elisp so you don't have to worry about namespaces

14:56 justin_smith: very good point

14:56 algal: So there are a lot of distinctions flying around there, like bats.

14:57 whomp: lol if you want to cheat at clojure, just have a rand-nth function with the solutions to the unit tests

14:57 after about 6 tries you'll get it right

14:57 *4clojure code golf

14:58 gdev: bbloom, funny you should say that because that's what I'm trying to do. I want to at least do a lightning talk about it at one of the big conferences

14:58 zerokarmaleft: whomp: iirc, chouser had something similar where he gamed the tests, so one solution would work for every problem

14:59 whomp: haha nice

14:59 algal: gdev: There's a pretty good video on line about namespaces, but I can't remember the title. I think it ended with "oh my".

15:00 gdev: But I think what would REALLY explain them all well is just a big honking diagram, with arrows clearly showing the mappings.

15:00 zerokarmaleft: whomp: that would usually be considered self-defeating, but he's kind of been around awhile => http://clojure-log.n01se.net/date/2008-02-01.html

15:01 gdev: algal, yeah I was thinking of doing an experience report style talk. what worked, what hasn't. I haven't had luck with diagrams yet

15:01 algal: The REPL does "name" to symbol to var to value for you, so it's easy to miss the intuition that there's a sequence of differnet kinds of dereferencing going on under the hood.

15:01 zerokarmaleft: that early exchange always makes me chuckle

15:03 gdev: Once I'm done implementing this pharmacy system in datomic I'm going to take another crack at my clojure-quest game. I think I have a good design for a HUD that shows everything that is going on in the background of the repl

15:03 whomp: haha nice

15:04 algal: gdev: Clojurequest? HUD? background of the REPL? Is this cruel practical joke designed to drive me wild with curiosity, or a real thing?

15:04 gdev: algal, it will be a real thing in the Spring of 2014

15:04 watch this repo https://github.com/gdeer81/clojure-quest

15:06 it was originally my Lisp in Summer Projects project, but I had a rough summer to say the least, so I didn't make it past the hammock phase

15:07 algal: I guess the hammock phase is at least a step beyond the mattress phase.

15:09 gdev: that's the only drawback to hammock driven design. you need a clear head

15:10 justin_smith: gdev: free idea - make a map of the world that is a 1:1 projection of the project source code

15:10 function calls being exits to access other places

15:11 gdev: justin_smith, yeah that's what I had in mind, thanks

15:12 justin_smith: throw statements as traps

15:12 what would treasure / monster be...

15:13 gdev: justin_smith, my original idea was "escape from the dungeon of nouns" the only reward is that by the end of the game you're thinking at a more functional level

15:14 algal: Is the Monad an enchanted mirror? Because everyone looks at it and thinks it looks like something different?

15:14 gdev: like literally level one is pulling yourself out of the muck of java interop

15:14 seangrove: ~monad

15:14 clojurebot: monad is functors that map a category to itself.

15:14 philed: Endofunctors?

15:14 seangrove: clojurebot: monad is VERBOTEN!

15:14 clojurebot: Ok.

15:14 seangrove: ~monad

15:15 clojurebot: monad is "yea, though I should walk in the valley of imperative code, I shall fear no evil, for your monad comforts me" - seen in #haskell

15:15 gdev: no, monads will be burritos that you can eat, but it takes two weeks to digest

15:15 unless you have a youtube powerup

15:15 and find some stackoverflow scrolls

15:17 then it only takes like week to digest the burrito

15:18 justin_smith: gdev: and when you are done with digesting the burrito you are cursed to rewrap your poop as a new burrito and make others eat it

15:19 scratch that, too gross, sorry

15:19 there must be some way to represent the monad curse though

15:20 gdev: justin_smith, it might just be an abstract idea like something that delays your progress

15:20 there will be a lot of yaks along the way

15:20 justin_smith: yaks should hand out fedex quests

15:21 gdev: like if you're on level one and you try to learn emacs, that's gonna set you back a few weeks

15:21 algal: :)

15:21 gdev: the goal is to also make it out of the dungeon in 20 weeks

15:21 err months rather

15:29 man my youtube app is letting me down, four videos were posted to clojuretv and I didn't get a single notification.

15:48 lazybot, whatis Buddha

15:48 lazybot: Buddha is "Ping-ting comes for fire!"

15:48 gdev: I am enlightened

15:57 jcromartie: comes *from* fire

15:57 no?

15:57 clojurebot: no is tufflax: there was a question somewhere in there, the answer

15:58 jcromartie: oh my

16:09 gdev: jcromartie, no Ping-tang comes *for* fire

16:12 jcromartie: got it

16:23 algal: clojuretv! didn't know about this! cool.

16:25 gdev: algal, infoq.com and skillsmatter have some good videos as well if you haven't seen those

16:26 algal: Those I knew, but the UIs a pita on those pages sometimes.

16:28 asdf1: Nonetheless, STOP spamming your site on HackerNews

16:31 gdev: is Zeder not open source yet?

16:32 technomancy: they need to start making that a qualification for accepting talks

16:32 if it's not OSSed when the talk is submitted, it needs to be at least before the talk ends

16:33 given that this has happened twice already

16:33 gdev: technomancy, what was the other one?

16:34 technomancy: gdev: longbottom and chas's bayesian lib

16:38 gdev: well +1 for only OSS talks

16:38 technomancy: I don't mind talks about internal things as long as they're up-front about it

16:40 gdev: or the library should at least be available to use even if its closed

16:40 I can't find source or binary for Zeder 0_o

16:47 andrew-dean: quit

16:53 gdev: gah I was told to go home 4 hours ago. Clojure gives you a notion of time, but you sometimes lose your sense of time

17:04 coventry: It seems as though in a compojure defroute the output from println statements and the like don't go to the repl. Is there any way to change that, or should I just spit to a file?

17:09 gdev: coventry, i think that's called logging which is usually preferred over printing

17:12 coventry: Yeah, using a logging framework is definitely better than spitting to a file, but both are a bit heavy when you're just exploring how something is working.

17:12 gdev: coventry, agreed. didn't mean to sound snarky =)

17:13 technomancy: coventry: they'll probably go to the root binding of *out*

17:13 gdev: coventry, so you're calling println inside of defroutes?

17:14 coventry: gdev: Not anymore, since it didn't work. :-)

17:14 technomancy: Yes, *out* is set to a different value. Thanks.

17:15 gdev: coventry, if you want to see whats going on, macroexpand your defroute form

17:16 technomancy: io has nothing to do with defroute; the same thing would happen with any arbitrary ring handler

17:49 jacksonn: given (1 2 3) (4 5 6) what would be the most idiomatic way of getting ((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6)) ?

17:50 Bronsa: ,(for [a [1 2 3] b [4 5 6]] [a b])

17:50 clojurebot: ([1 4] [1 5] [1 6] [2 4] [2 5] ...)

17:50 jacksonn: thanks

17:54 dnolen: Om Time Travel - http://swannodette.github.io/2013/12/31/time-travel/

17:55 red00: does anyone know if there is a simple openid auth (google) that works well with luminus template?

17:56 CaptainLex: Is this an appropriate venue for clojurescript discussion? #clojurescript is almost never active

17:56 red00: nope, not using clojurescript, purely clojure

17:57 CaptainLex: red00: Sorry, that was not directed at you!

17:57 That sounded terribly passive aggressive, I'm very sorry!

17:57 And sadly I do not know an answer for your question

17:58 ToBeReplaced: CaptainLex: yeah, lots of cljs discussion in here -- i'd try first in #clojurescript though -- seems like we should be pushing more for that

18:00 CaptainLex: Okay, cool. So, are there any resources for a good, like, general overview of front-end architecture best practices? I'm not sure if I'm asking the question clearly...

18:00 zerokarmaleft: red00: take a look at friend-oauth2

18:00 oh, sorry, openid

18:01 red00: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/openid.clj

18:01 coventry: CaptainLex: No, people are still feeling their way through those questions.

18:01 jacksonn: I am getting back to clojure after some abstinence. is emacs + slime still the prefered way of doing programming in clojure?

18:01 CaptainLex: coventry: How compelling!

18:01 ToBeReplaced: CaptainLex: take a look at dnolen's blog posts-- he covers a lot of ground and i found it very helpful

18:01 zerokarmaleft: jacksonn: most emacsen use nrepl/cider these days

18:01 justin_smith: jacksonn: nope, now it is cider (or nrepl, some of still use that)

18:02 jacksonn: thanks, checking it out

18:02 CaptainLex: jacksonn: What they have said, but I wouldn't overlook LightTable if you are interested in experimenting

18:02 red00: thanks for the help!

18:02 coventry: CaptainLex: There are a lot of exciting approaches, but no best practices at this point.

18:07 CaptainLex: coventry: What a fun time to be involved with a language!

18:13 UltimateEyePatch: AimHere, ping

18:13 * AimHere pongs.

18:14 UltimateEyePatch: AimHere, so ehh, what do you think of Clojure's macro system

18:14 It isn't fullyy hygienic like scheme's right?

18:14 AimHere: Nah; but there's ways in which hygiene is encouraged

18:15 I seem to recall that for anaphoric macros you have to quote and unescape the variable, to keep you honest, and stuff of that ilk

18:16 justin_smith: in practice making macros that capture is a bit harder, by default symbols get namespaced in quasiquote forms

18:17 KeithPM: I am having a problem with a helper function I am writing to count up frequencies of occurrence of elements in a sequence. May I post the code for comments? It's about 6 lines of code

18:17 justin_smith: KeithPM: did you know that frequencies is already a function?

18:18 KeithPM: use refheap or a github gist

18:18 KeithPM: : justin_smith yes. I am writing my own as an exercise

18:19 OK... I'll have to figure those out, are there instructions somewhere?

18:19 UltimateEyePatch: AimHere, is it possible to get full hygiene that can't ever be broken with them though

18:19 justin_smith: they are just paste sites

18:19 KeithPM: OK... Cool thanks

18:19 UltimateEyePatch: Like, scheme doesn't enforce it but you can get full referential transparency that can't ever be broken

18:19 justin_smith: KeithPM: you can upload your code into a paste, and then share the URL here

18:20 KeithPM: OK thanks justin_smith

18:22 Here is a link to the code https://www.refheap.com/22356

18:23 UltimateEyePatch: AimHere, hmm, sweetie?

18:23 justin_smith: KeithPM: if you use recur instead of a self-call, it will still work, and be faster / use less stack space

18:24 AimHere: I'd be inclined to use 'reduce' instead of loop/recur, meself

18:24 UltimateEyePatch, yes, what is it now?

18:24 KeithPM: OK, thanks...

18:24 justin_smith: KeithPM: also you could avoid the inner if statement by using the optional "not found" arg to get

18:24 UltimateEyePatch: AimHere, like I asked, is it possible to get full hygiene

18:25 AimHere: UltimateEyePatch, I'm sure it's possible to tweak the clojure code to do that; but it's not something I'd be equipped to do myself in a hurry

18:26 justin_smith: KeithPM: that is to say (freqs a-key) is the same as (get freqs a-key) and you can add a default / not found value of 1 as an extra arg

18:26 ,(get {} :a 1)

18:26 KeithPM: Right... Are you saying that if I perform a get on freqs and item is not found, I can perform the insertion?

18:26 clojurebot: 1

18:26 justin_smith: ,({} :a 1)

18:26 clojurebot: 1

18:26 justin_smith: you would insert either way

18:26 the switch is that it either returns the current count, or 1

18:26 actually, you want 0

18:26 because you would inc it :)

18:27 AimHere: To get rid of the (if ... (assoc ) (assoc)), I'd likely do (merge-with freqs {a-key 1} inc) instead

18:27 KeithPM: Oh cool, I did not know that, I thought it just 'returned' that default value

18:27 UltimateEyePatch: AimHere, are you not the worlds most renowned expert on clojure.

18:27 THen point me to who is.

18:27 KeithPM: Wow, cool... That sounds interesting

18:27 the merge

18:28 AimHere: UltimateEyePatch, sadly I am not. There's a bloke called Rich Hickey who claims to know more than anyone else, feel free to troll him instead!

18:28 justin_smith: AimHere: I think you mean (merge-with {a-key 0} freqs)

18:28 you want the pre-existing to override if it is there

18:28 AimHere: That's just 'merge' you're talking about isn't it?

18:28 KeithPM: Yes that is correct justin

18:29 justin_smith: AimHere: could be I am confused

18:29 AimHere: merge updates the second; I want to increase the pre-existing one if there's a clash

18:29 So 'inc' might be (fn [a b] (inc a)) in what I did

18:30 UltimateEyePatch: AimHere, you always call me a troll.

18:30 We have known each other for years now

18:30 and you still call me a troll

18:30 justin_smith: AimHere: yeah, it gets two args

18:30 UltimateEyePatch: I will tell molly about this

18:30 AimHere: I don't know who Molly is, I figure she might know you're a troll too!

18:31 KeithPM: Wow there's so much opportunity for style in this language.

18:32 Let me try to get rid of the inner if and to use recur or starters. I am interested in the 'reduce' approach as well ( I think I am more comfortable recursing up than down, it's closer to mathematical induction :) )

18:33 UltimateEyePatch: AimHere, you know molly right?

18:33 As in, molly`

18:33 AimHere: The name is only vaguely familiar

18:35 justin_smith: ,(update-in {:a 1} [:b] (fnil inc 0)) ; AimHere, KeithPM

18:35 clojurebot: {:b 1, :a 1}

18:36 justin_smith: ,(update-in {:a 1} [:a] (fnil inc 0))

18:36 clojurebot: {:a 2}

18:36 UltimateEyePatch: AimHere, why does everyone always think me to be a troll?

18:37 AimHere: I'd guess it's because you turn up in random places on IRC and accost people with interminable and irrelevant conversations for your own amusement; but you'd have to ask the other guys what they think to be sure about that.

18:42 UltimateEyePatch: AimHere, how is it irrelevant in clojure to ask about its macro systems?

18:42 You wound me madam

18:42 KeithPM: justin_smith: update-in looks interesting

18:42 AimHere: I think the vast bulk of this conversation hasn't been about clojure macro hygiene!

18:43 UltimateEyePatch: AimHere, because you refused to answer and called me a troll

18:43 thereby insulting mine honour.

18:43 I have told people about this you know.

18:43 I have friends in high places.

18:43 KeithPM: the get seems to have gotten rid of the innermost if. I am using 0 as the default since the inc is accepting the value before passing to assoc.

18:45 UltimateEyePatch: KeithPM, you stand idly by as AimHere insults my honour?

18:45 bbloom: UltimateEyePatch: if you are a troll, you're a pretty bad one, so give up now. if you're not a troll, you might want to take stock of your style of communication and think about why people perceive you as a troll. b/c quite frankly, you seem like a troll to me

18:46 KeithPM: LOL... Sorry guys, I was a little consumed with my challenges...

18:51 UltimateEyePatch: bbloom =(

18:51 I have been an upstanding member of this channel for 5 years.

18:52 I was here when Chousuke still posted

18:52 And you treat me like dirt.

18:53 AimHere: Familiarity breeds contempt!

18:54 UltimateEyePatch: AimHere, I have been here longer than you

18:54 Or Molly

18:55 justin_smith: let's make a version of IRC /ignore that turns someones words into gibberish instead of just making them disappear

18:55 UltimateEyePatch: It's actually better

18:56 Because it doesn't look like others are talking to nothing

18:56 Anyway, explain to me exactly the operative model of clojure's macro system

18:56 because I don't get it

19:08 SegFaultAX: UltimateEyePatch: What don't you get?

19:09 UltimateEyePatch: Macros are something like compile-time functions in the sense that they take *uncompiled lisp forms* as arguments and return new lisp forms as values.

19:10 As an example, if I have a macro foo, the expression (foo (+ 1 2 3)) is evaluated at compile time, and foo receives exactly (+ 1 2 3), not the /result/ of (+ 1 2 3).

19:11 technomancy: https://twitter.com/mukeshsoni/status/417917145180147713 kind of a good point

19:12 gdev: technomancy, that's like saying whoever named automobiles "cars" is responsible for my hernia because they are definitely not cariable

19:12 SegFaultAX: technomancy: The term is confusingly overloaded in this case. Vars aren't variable in the same way as other languages.

19:12 justin_smith: gdev: carriage, duh

19:13 SegFaultAX: But they are still variable.

19:13 justin_smith: or does carriage come from carriable somehow, hmm...

19:13 gdev: justin_smith yes probably because it carries the riders

19:13 justin_smith: nope, carriable seems to come from carriage actually

19:13 yeah, there we go

19:14 anyway, that is just pedantry, my appologies

19:14 technomancy: why not call them yeah-you-can-reload-your-code-you-can-thank-me-for-avoiding-ml-forward-change-visibility-only-later

19:15 SegFaultAX: technomancy: I'd RT that. :)

19:15 technomancy: brb opening a jira

19:16 gdev: you could just write a macro that lets you use that long name and then creates a var under the covers

19:17 technomancy, that's going to get rejected for being goofy

19:26 UltimateEyePatch: SegFaultAX, yeah, I know that,

19:26 I don't get how the hygiene works

19:26 the whole 'qualifies symbols with namespace'

19:26 Like ehh

19:26 Say I have a macro which uses + in its form and I use it inside (let [+ 3] ... )

19:26 Does that break the macro?

19:27 hiredman: ,`(+ 1 2)

19:27 clojurebot: (clojure.core/+ 1 2)

19:27 hiredman: ,(= '+ 'clojure.core/+)

19:27 clojurebot: false

19:28 AimHere: ,(= + clojure.core/+)

19:28 clojurebot: true

19:30 technomancy: tias?

19:30 clojurebot: tias is try it and see

19:32 technomancy: tl;dr: the problem that hygenic macros are intended to solve do not happen in CLojure unless you go out of your way to perform variable capture

19:35 marcopolo`: I'm playing around with core.matrix, and it's not letting me multiple a 2x1 with a 1x2, anyone have any experience with this?

19:36 UltimateEyePatch: hiredman, that doesn't actually answer me though

19:36 But ehh

19:36 Nonon, that doesn't work

19:36 marcopolo`: s/multiple/multiply

19:37 UltimateEyePatch: AimHere, how about a yes or no, say I have a macro which uses + and I use it inside (let [+ 3] ...), does it break or not?

19:40 arrdem: (inc bitemyapp) ;; fastmail just worked

19:40 lazybot: ⇒ 14

19:41 arrdem: ... what happened to lazybot? technomancy has karma 0. the end has come.

19:42 justin_smith: $karma techonmancy

19:42 lazybot: techonmancy has karma 0.

19:42 justin_smith: overflow?

19:43 arrdem: I doubt it... everyone I checked is zeroed. except for bitemyapp.

19:44 justin_smith: $karma justin_smith

19:44 lazybot: justin_smith has karma 24.

19:44 * justin_smith is secretly a karma vampire

19:44 arrdem: what the whaaaa....

19:45 there's something funky going on... looks like lazybot lies in /msg

19:45 UltimateEyePatch: hiredman, hmm?

19:45 justin_smith: I noticed earlier that lazybot had forgotten I inc'd juxt

19:45 arrdem: $karma justin_smith

19:45 lazybot: justin_smith has karma 24.

19:45 arrdem: $karma arrdem

19:45 lazybot: arrdem has karma 12.

19:45 justin_smith: $karma technomancy

19:45 lazybot: technomancy has karma 88.

19:45 arrdem: okay it's a /msg related issue

19:45 justin_smith: I had a typo above

19:45 arrdem: interesting.

19:45 justin_smith: (inc juxt)

19:45 lazybot: ⇒ 6

19:47 marcopolo`: for posterity: http://stackoverflow.com/questions/19982466/matrix-multiplication-in-core-matrix

19:47 gdev: arrdem, I knew we needed to deploy our own irc bot just for karma. Cloutjure is never gonna happen is it?

19:47 arrdem: gdev: shhhhh

19:48 gdev: I had the realization that if we could put together a generic karma source API that half of our architecture problems go away :/

19:48 gdev: then we just hammer out a source specific client exposing a standard api

19:48 gdev: no need to do crazy crap with a single sentient, omnicient graphdb

19:49 gdev: yeah cloutjure may not happen until the next clojure cup tho :/

19:50 gdev: arrdem, I'm getting better at Datomic so that will be an option by the time clojure cup comes around again =)

19:51 arrdem: gdev: I see all this cool stuff about datomic and datalog floating around... sooner or later I'm gonna break down and do something with it myself

19:51 but until then I'm content writing hardware simulators :P

19:54 alew: is clojure cup like ludum dare for clojure?

19:54 gdev: alew it doesn't have to be a game though

19:54 alew its more like rails rumble or node knockout

19:55 alew: Ah ok

19:55 sounds fun

19:55 gdev: alew it is if you have a good team

19:55 alew: Sounds like you had a bad experience :P

19:55 arrdem: having worked with the people before is a huge pluss

19:56 alew: it coulda been worse :P

19:56 gdev: also not having to drive an hour to meet your team helps

19:56 arrdem: gdev: that's your own darn fault :P

19:57 alew: Oh wow, significant prizes

19:57 gdev: there were prizes?

19:57 lol I didn't even notice that part

19:57 arrdem: gdev: thanks for the ride again tho, it was fun that you made it up

19:57 alew: link? I knew there were prizes but I didn't know what...

19:58 gdev: arrdem, although I think next year a game might be a better option

19:59 arrdem: gdev: really? oh right you were talking about a windjammers clone

19:59 alew: http://clojurecup.com/prizes.html

20:00 arrdem: daaaaang

20:00 I knew that there were bragging rights on the table, but I woulda lost some more sleep if I'd known the prizes were that good :P

20:01 gdev: oh cool that means Normand and his team got a Raspberry Pi board

20:01 wow the public favorite awards are better than 2nd and 3rd place

20:02 arrdem: gdev: do me a favor.. ping io@arrdem.com

20:05 gdev: arrdem ping timed out on port 25

20:06 * arrdem feels silly

20:06 arrdem: gdev: I meant email.

20:07 * gdev knew what you had meant

20:08 arrdem: $google urban dictionary ping

20:08 lazybot: [Urban Dictionary: ping] http://www.urbandictionary.com/define.php?term=ping

20:13 gdev: http://clojurecup.com/blog lol arrdem we're the first picture

20:14 arrdem: pffft

21:19 philll: A recent cljs announcement said "Implement specify, instance level protocol extension for ICloneable extenders"... what's that mean?

21:34 gdev: philll, js objects are fully dynamic and clojurescript had no mechanism to exploit that for protocol implementation

21:35 philll, the specify macro does something similar to what extend-type does in Clojure

21:36 philll: ah. protocol extension worked on prototypes? Now I get it. Thank you. Hopefully natural language algorithms aren't training on cljs release announcements.

21:40 gdev: philll, Jira usually has the most details

21:44 philll:) http://dev.clojure.org/jira/browse/CLJS-414

21:45 lol if you look at the open and close date of that issue, it took exactly one year

22:49 cheesus: Woah big channel

23:11 justin_smith: I just mentioned HDD to a friend, who naively assumed it must involve a hammock for each function you write

23:11 mapping 1:1 with TDD of course

23:13 zerokarmaleft: that's a lot of naps

23:14 justin_smith: seriously

23:14 though, really, I do think I could do it!

23:15 * justin_smith gears up for the challenge.

23:17 cheesus: HDD?

23:17 justin_smith: hammock driven development

23:18 a period of inactivity involving hard thinking, and sleeping on it, before realizing a design

23:18 best thing to come out of the clojure community, or best thing ever? you decide

23:19 ddellacosta: sometimes, for practices, I just take naps in a hammock

23:19 *practice

23:20 it really helps build your skills

23:27 KeithPM: Hi justin, I was abe to get the my-frequencies-helper to work using reduce but for some reason the recursive method ends up returning an empty map. Any ideas? I actually tried the update-in and had it work one time through.

23:28 justin_smith: KeithPM: have you edited the original paste / made a new one?

23:29 KeithPM: I made a new one, once sec...

23:30 This one works https://www.refheap.com/22358

23:32 justin_smith: the equivalent update-in for that assoc is (update-in counts [x] (fnil inc 0))

23:32 I think

23:33 I think reduce is better than recur when it is possible anyway, but it couldn't hurt for learning purposes to see what went wrong with the looping version

23:33 KeithPM: https://www.refheap.com/22364 Here is one with update-in that fails

23:34 Yes. I was happy with the reduce, that is actually how they implement frequencies in the code. But I am uncomfortable with this failure though.

23:34 justin_smith: you have some extra parens there that don't make any sense

23:34 KeithPM: Lemme check... I have been messing around so much...

23:35 justin_smith: remember that unlike an algol family language, you cannot just add an extra () around any set of statements to group them

23:36 KeithPM: The extra pair around the update is to form the else portion for the if... I need to call the function again.

23:36 justin_smith: '() always creates a sequence, () stands for an empty sequence, (foo) calls foo

23:36 maybe you want do

23:37 two things: (do ...) groups a sequence of things by doing each one and returning the result of the last

23:37 TEttinger: ,(doc do)

23:37 clojurebot: Gabh mo leithscéal?

23:37 TEttinger: (doc do)

23:37 clojurebot: Cool story bro.

23:37 TEttinger: what

23:37 justin_smith: update-in does not change its argument, it makes a new thing with the update

23:37 TEttinger: &what

23:37 lazybot: java.lang.RuntimeException: Unable to resolve symbol: what in this context

23:37 TEttinger: ##(doc do)

23:37 lazybot: ⇒ "Special: do; Evaluates the expressions in order and returns the value of\n the last. If no expressions are supplied, returns nil."

23:37 justin_smith: if you do not use the return value, it is gone

23:37 KeithPM: OK lee me have a look... So do to form a 'block'

23:38 justin_smith: but I think you actually want let here

23:38 KeithPM: AH... THAT is probably the problem there... That is the behaviour I am seeing

23:38 justin_smith: because you have the update-in and you need to use or bind the result somehow

23:38 let is a binding form followed by an implicit do

23:38 ,(let [a 0 b 1] a b)

23:38 clojurebot: 1

23:39 justin_smith: it assigns some values to symbols, and returns the last thing in the body

23:39 TEttinger: so do forms a block for something like if, where you need one form (like the then form or else form) and can't have more

23:39 justin_smith: right

23:39 but the next step is that update-in does not mutate the input

23:39 so you need to bind the result of update-in somehow to use it

23:40 which is where let comes in

23:43 KeithPM: Yes I have used the let to bind. Let me try to bind the updated map then recurse with that

23:44 justin_smith: you didn't know it but you were already using do - both fn (defn) and let have an implicit hidden do at the end

23:52 KeithPM: OK... hidden in the macro somewhere? :)

23:53 justin_smith: basically

23:58 come to think of it, in common lisp or scheme the form would evaluate to have a do in it after all the expansions, but it may not actually do that in clojure - but regardless, it acts that way

23:59 KeithPM: If I use the let to bind, I think that also allows me to execute multiple expressions right?

23:59 justin_smith: of course

23:59 each binding has an expression, and you can have any series of forms in the body

Logging service provided by n01se.net