#clojure log - Feb 28 2015

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

2:55 lvh: Hm

2:58 So, I am rebinding a dynamic var using a fixture that lives in a different namespace; that namespace then calls the original namespace back, and by the time I get there, the var is unbound again :-(

2:58 at first I thought it might be some threading shennanigans, but I get the same behavior with with-redefs

3:04 Ah. Turns out I didn't know how use-fixtures works :)

3:07 niac: user=> (import PiratePhrases)

3:07 ClassNotFoundException PiratePhrases java.net.URLClassLoader$1.run (URLClassLoader.java:372)

3:08 but there is a PiratePhrases.class

3:08 without package

3:26 SagiCZ: i am making java desktop application and i have decided to use clojure to write the gui part.. swing and javafx seem both pretty constricted where it comes to design, i would like to develop the design simliary to web pages, is it possible in clojure? maybe run it in a bundled web browser? i dont know where to start though

3:30 niac: is there any way to use a local java file without lein in clojure

3:33 devll: you can checkout reimport here. niac https://github.com/zcaudate/vinyasa/tree/master/src/vinyasa

3:35 niac: devll: thanks

3:40 sveri: Hi, I wonder if there is an abstraction for korma that let's me insert and update many-to-many entities? It seems like korma itself does not support this usecase

3:42 devll: https://github.com/friemen/aggregate

3:43 I am using yesql ,but aggregate might do what you want sveri

3:47 sveri: devll: uh, another nice library I never heard of, this looks promising, thank you

3:49 devll: :D

4:18 noncom: hi, anyone using ccw here ?

4:37 Eremox: How do I set a distinct documentation string for each arity of a function?

4:39 noncom: Eremox: i think there is no way to do that. if you look at the core clojure functions, they all just describe the arities verbally in a singal description

4:40 Eremox: ok to bad.

4:40 noncom: Eremox: not really, this goes hand-in-hand with the notion that a single function must have a single responsibility and arity overload must not seriously affect the functionality of the function

4:40 Eremox: so, ultimately, this limitation is for the greater good

4:42 Eremox: I understand but i think it makes the code clear. (I defined a macro.

5:33 SagiCZ: I am trying to add a couple of clojure files to my all java project in intellij but Cursive does not recognize any symbols, what am I doing wrong?

5:34 oh i know.. i didnt set the directory as source in the project structure.. nevermind it works now

5:34 cfleming: SagiCZ: Do you have Clojure added as a library dependency to your module? And are your Clojure files under a source root?

5:35 SagiCZ: Snap, there you go.

5:35 SagiCZ: I'm planning to add a popup in the editor when you don't do that, especially for cljs

7:06 SagiCZ: cfleming: thanks!

7:07 whats the best way to send two state parameter to a function?

7:07 lets say i have a function that can draw something on TOP or BOTTOM

7:08 i could do something like (draw x y z true) where true would mean TOP and false would mean BOTTOM.. but i dont like that

7:08 what about (draw x y z :top) and (draw x y z :bottom) is that a misused keyword?

7:19 raspasov: SagiCZ: have two separate functions? :)

8:22 devll: Hi, after deleting a file in my project,(refresh-all) gives FileNotFount Exception.

8:22 *Found

8:32 doing remove-ns does not help.

8:32 how can I remove this error?

8:33 restarting repl will do it,but it is too costly.

8:43 triss: hey all. am I right in thinking there are no pre and post conditions for defmethod?

8:48 Bronsa: triss: you can add them to the dispatch function

8:49 triss: or even to every defmethod

8:50 ,(defmulti m class)

8:50 clojurebot: #'sandbox/m

8:50 Bronsa: ,(defmethod m Object [x] {:pre [(string? x)]} x)

8:50 clojurebot: #<MultiFn clojure.lang.MultiFn@6ea5b634>

8:50 Bronsa: ,(m "foo")

8:50 clojurebot: "foo"

8:50 Bronsa: ,(m 1)

8:50 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (string? x)>

8:51 triss: brilliant thanks Bronsa... doesn't look documented to me? http://clojuredocs.org/clojure.core/defmethod

8:52 Bronsa: dunno, I read the impl

8:52 triss: hah. might hve o try nad ge used to that.

8:53 ^ have to try and get used to that

11:17 crazydiamond: Hi. Can anyone suggest math/functional programming book with theory and/or exercises for development of functional way of thinking (with Clojure flavour)?

11:17 subhashgo: crazydiamond: I don't know about books, but 4clojure.com is a good resource for clojure exercises

11:24 crazydiamond: subhashgo, thanks

11:25 justin_smith: crazydiamond: have you looked at clojure for the brave and true, and clojure from the ground up?

11:34 gfredericks: clojure {for,from} the {brave,ground} [and] {true,up}

11:37 crazydiamond_: :D

11:37 btw, is e.g. lambda calculus useful to know for functional programming?

11:37 justin_smith: ,(str "clojure " (rand-nth '[from for]) " the " (rand-nth '[ground brave]) (rand-nth [" and " " "]) (rand-nth '[true up]))

11:37 clojurebot: "clojure from the brave true"

11:38 justin_smith: ,(str "clojure " (rand-nth '[from for]) " the " (rand-nth '[ground brave]) (rand-nth [" and " " "]) (rand-nth '[true up]))

11:38 clojurebot: "clojure from the ground and up"

11:38 gfredericks: crazydiamond_: not in too much detail

11:38 crazydiamond_: an, other fields of math?

11:38 *and

11:38 justin_smith: crazydiamond_: the lambda calculus is for fp kind of like knowing a machine language (optionally turing tape being that language) is for imperative

11:38 ,(str "clojure " (rand-nth '[from for]) " the " (rand-nth '[ground brave]) (rand-nth [" and " " "]) (rand-nth '[true up]))

11:38 clojurebot: "clojure from the brave and up"

11:39 crazydiamond_: so far no matches with "for", btw

11:39 justin_smith: ,(str "clojure " (rand-nth '[from for]) " the " (rand-nth '[ground brave]) (rand-nth [" and " " "]) (rand-nth '[true up]))

11:39 clojurebot: "clojure from the brave up"

11:39 justin_smith: ,(str "clojure " (rand-nth '[from for]) " the " (rand-nth '[ground brave]) (rand-nth [" and " " "]) (rand-nth '[true up]))

11:39 clojurebot: "clojure for the ground up"

11:39 crazydiamond_: there it is

11:40 justin_smith: finally - that last one is for pigs that want to learn how to program after they become sausage

11:46 gfredericks: (inc justin_smith)

11:46 lazybot: ⇒ 199

11:46 * gfredericks omg omg omg omg omg

11:49 justin_smith: haha

12:04 hyPiRion: (inc justin_smith)

12:04 lazybot: ⇒ 200

12:04 hyPiRion: do I win something

12:06 justin_smith: you got to be an important part of a very special moment

12:06 gfredericks: ~200 is a number made up of only smallish primes

12:06 clojurebot: Ik begrijp

12:07 gfredericks: ,(* 2 2 2 5 5)

12:07 clojurebot: 200

12:08 justin_smith: ,(filter #(zero? (rem 200 %)) (range 1 200))

12:08 clojurebot: (1 2 4 5 8 ...)

12:09 justin_smith: ,(clojure.string/join \space (filter #(zero? (rem 200 %)) (range 1 200)))

12:09 clojurebot: "1 2 4 5 8 10 20 25 40 50 100"

12:18 TEttinger: ,(clojure.string/join " " (filter #(zero? (rem 200 %)) (range -200 0)))

12:18 clojurebot: "-200 -100 -50 -40 -25 -20 -10 -8 -5 -4 -2 -1"

12:18 TEttinger: nice

12:19 justin_smith: remainder is handy that way

12:21 SagiCZ: does anybody know how could i change the way seesaw button is painted? i know its JButton and in java i would extend it and overwrite the paint method, how to do that in clojure/seesaw?

12:26 emaczen: I need to use the for macro and for some reason this is not visible in my current namespace -- I see that it is part of clojure.core.

12:27 nvm I figured it out

12:28 but what does :refer all do in a require form?

12:28 SagiCZ: it should be :refer :all

12:29 nuwanda_: it means you get every function in the namespace, as opposed to :refer [functions you want]

12:29 SagiCZ: and it refers all the symbols

12:29 and yeah.. 'for' should be available everywhere

12:29 emaczen: SagiCZ: What's wrong with omitting :refer :all (it seemed to import the for macro)

12:29 SagiCZ: emaczen: what was before the refer all? what namespace>

12:29 ?

12:30 emaczen: clojure.core

12:30 SagiCZ: you dont need to require clojure.core thats automatic

12:30 delete the whole statement

12:30 (ns my-namespace)

12:30 emaczen: But I can't use the for macro otherwise

12:30 SagiCZ: (for [x (range 10)] x)

12:30 emaczen: unlikely

12:31 what editor do you use?

12:31 emaczen: emacs

12:31 justin_smith: SagiCZ: clojure.core is not referred if you use in-ns to create a namespace

12:31 emaczen: I'm user cider

12:31 justin_smith: emaczen: did you use in-ns to switch to a namespace that did not exist yet?

12:31 emaczen: justin_smith: I am switching namespaces

12:31 I believe that it exists

12:31 justin_smith: how did you create the namespace?

12:32 I bet the ns code had an error, so the namespace was not created

12:32 just a guess

12:32 then when you used in-ns you created a namespace that did not have (refer-clojure)

12:32 emaczen: justin_smith: It does have an error -- I am editing it...

12:32 justin_smith: that's literally all you need to do to rescue your repl

12:32 (refer-clojure)

12:32 it's done implicitly by ns

12:34 emaczen: justin_smith: good to know, thanks

12:34 SagiCZ: in proxy macro how do i mimick super.method() call?

12:36 gfredericks: ,(apropos "super")

12:36 clojurebot: (clojure.core/proxy-call-with-super clojure.core/proxy-super clojure.core/supers)

12:36 gfredericks: I'd check those first two

12:37 SagiCZ: it has no doc.. gosh i hate core

12:38 justin_smith: (doc proxy-super)

12:38 clojurebot: "([meth & args]); Use to call a superclass method in the body of a proxy method. Note, expansion captures 'this"

12:38 justin_smith: SagiCZ: ?

12:40 SagiCZ: proxy-call-with-super has no doc

12:40 justin_smith: it's a helper function used in implementing proxy-super

12:41 SagiCZ: i see.. well it at least works so thats nice

12:43 i would like to use "this" in the proxy too..

12:44 justin_smith: SagiCZ: that's what proxy-super says - you can use "this" inside the body

12:44 as long as that is the name of the object in that scope, it will work

12:45 I don't like that it is a magic name used by the macro, but at least it's usable

12:45 you're just required to bind to the name "

12:45 SagiCZ: yeah.. that is super weird.. it works though

12:45 justin_smith: this" in the enclosing scope

12:45 right

12:54 devll: why I can't see the full deps tree with lein?

12:54 justin_smith: devll: is something missing from "lein deps :tree" ?

12:54 devll: I am having an issue with clj-http.

12:55 justin_smith: so what's wrong with the deps tree printing?

12:55 devll: I am using elastic search too which uses clj-http, but lein deps :tree does not show this.

12:56 justin_smith: devll: if it's not in the tree, how do you know the dep is present?

12:56 devll: I searched for the error

12:56 then I got the info from github.

12:57 I also verified from ClojureSphere

12:57 justin_smith: are they pulling in the dep via their declared deps, or resolving it and compiling it in when packaging?

12:57 devll: *it

12:59 justin_smith: devll: are you talking about elastich? their handling of the clj-http dep is super weird https://github.com/clojurewerkz/elastisch/blob/master/project.clj#L21

12:59 devll: yes.

13:00 justin_smith: devll: you can only have one version of a dep loaded. Likely clj-http is being loaded under another dep

13:00 if it's not present in the tree at all, that's seriously messed up

13:00 if you need a specific version, you should explicitly depend on that version rather than relying on transative deps

13:02 devll: in my case,deps tree are missing info.

13:02 justin_smith: can you post your deps tree output?

13:02 not in here, on refheap or something, of course

13:03 devll: ok

13:03 wait for a minute

13:05 http://pastebin.com/0in6rjmQ

13:06 justin_smith: devll: clj-http is right there, it's a top level dep

13:06 line 78, that's the version you have

13:08 devll: [clj-http "1.0.1-SNAPSHOT"]

13:08 justin_smith: snapshot gets translated into a date specific version

13:08 [clj-http "1.0.1-20140913.231842-1"] is what 1.0.1-SNAPSHOT gets today

13:09 that may change tomorrow

13:09 that's how snapshots work

13:09 devll: got it. lein deps :tree | grep -i clj-http

13:09 this only showed one line.

13:09 my bad.

13:09 thanks

13:10 justin_smith: no problem

13:16 SagiCZ: cfleming: any reason why cursive cant see my Java classes? the plugin itself can find them because it autoimported them but REPL says ClassNotFoudException when trying to load the clojure file

13:18 TEttinger: SagiCZ: loading a clojure file that itself imports java classes?

13:22 SagiCZ: yes

13:23 clojure file with (:import (myPackage MyClass)

13:23 fails

13:24 devll: WARNING: update already refers to: #'clojure.core/update in namespace: clj-http.client, being replaced by: #'clj-http.client/update

13:25 I am getting this warning .

13:26 gfredericks: devll: hopefully newer versions of clj-http don't have that?

13:26 devll: what does this mean? how can I resolve this?

13:26 I updated everything.

13:26 no luck.

13:29 justin_smith: devll: someone needs to update clj-http to be compatible with clojure 1.7.

13:29 the warning doesn't mean anything is broken though

13:29 it just means they gave something the same top level name as something in clojure.core

13:29 AlwaysBCoding: does anyone know what \_ means as a character in Clojure? It’s coming from an api where a &nbsp was in a string and the string in clojure just has a weird _ character in it. When I do (seq (char-array string)) it shows up as \_ … what is that character and how could I regex it out?

13:30 justin_smith: ,(type \_)

13:30 clojurebot: java.lang.Character

13:30 SagiCZ: AlwaysBCoding: its a clojure literal for the underscore symbol "_"

13:30 justin_smith: oh, that may be something different

13:30 devll: I cant use clj-http. it eventually throws an error.

13:30 justin_smith: ,(int \_)

13:30 clojurebot: 95

13:31 justin_smith: AlwaysBCoding: that's a normal underscore - is that copy pasted from the original?

13:31 the-kenny: devll: that warning isn't a big issue. It just says you import a function named 'update' which overrides the clojure function with the same name.

13:31 justin_smith: AlwaysBCoding: use int to find out it's numerical value, that will be unambiguous

13:31 devll: - Attempting to call unbound fn: #'clj-http.client/update

13:31 AlwaysBCoding: it shows up in emacs/cider as a yellow underscore, but if I regex on an underscore it doesn’t match

13:32 godd2: ,(str \h \e \l \l \o)

13:32 clojurebot: "hello"

13:32 the-kenny: devll: Either import qualified [... :as http] or refer only the functions you need: [... :refer [fn1 fn2 ...]]

13:32 devll: I got this error too.

13:32 the-kenny: AlwaysBCoding: \_ is a char, not a string.

13:32 justin_smith: AlwaysBCoding: OK, in the context where you have that string, map int across the string

13:32 the-kenny: ,(first "_")

13:32 clojurebot: \_

13:32 justin_smith: AlwaysBCoding: get the actual code point

13:32 devll: I delete all the (:use ) today.

13:32 deleted*

13:32 AlwaysBCoding: int value is 160

13:33 justin_smith: devll: I think that has to do with the fact that your libs require like 80 different versions of clj-http

13:33 devll: I exclude all

13:33 justin_smith: devll: likely the one you are providing does not define the function one of your libs needs

13:33 devll: d

13:33 justin_smith: devll: exclude does not help when they call a function not defined in the version of the lib you pull in

13:33 that's the problem

13:33 devll: I downgraded Clojure to 1.6.0

13:33 then it is OK.

13:33 justin_smith: devll: that won't fix your probelm

13:34 really?

13:34 ...

13:34 devll: yes.

13:34 the-kenny: justin_smith: 1.6 doesn't have clojure.core/update

13:34 only clojure.core/update-in

13:34 AlwaysBCoding: the int value of a normal underscore is 95 it seems, then what the hell is 160? wtf haha this is tripping me out

13:34 justin_smith: the-kenny: his actual problem is something in his code calls clj-http/update and it does not exist

13:34 godd2: AlwaysBCoding the \ is used to denote a single character. So "h" and \h are pretty much the same thing, as are "_" and \_

13:34 justin_smith: godd2: but not everything that prints as _ is _

13:35 AlwaysBCoding: unicode 160 is non breaking space http://www.fileformat.info/info/unicode/char/00a0/index.htm

13:35 that's your issue

13:35 &nbsp translates to that unicode symbol

13:35 lazybot: java.lang.RuntimeException: Unable to resolve symbol: nbsp in this context

13:35 justin_smith: lazybot: shutup

13:36 AlwaysBCoding: justin_smith: awesome. how can I regex out that character from strings?

13:37 justin_smith: AlwaysBCoding: I'd use clojure.string/replace to replace nbsp with regular space maybe

13:38 godd2: does \s not match nbsp?

13:39 or refer to it by its unicode \u00a0

13:39 AlwaysBCoding: justim_smith: how though? like it doesn’t match &nbsp or anything

13:39 justin_smith: AlwaysBCoding: looks like godd2 is on the right track there

13:39 AlwaysBCoding: ok got it. It looks like it matches if you do '\xa0'

13:39 the-kenny: doesn't clojure.string/replace also work on char/char replacements? Just specify nbsp as second arg, space as third.

13:40 AlwaysBCoding: godd2: \u00a0 works also, awesome

13:40 godd2: coolio

13:43 justin_smith: /me loves it when a plan comes together.

13:44 great work, team!

13:46 godd2: (synergize [:team_member1 :team_member_2 :team_member_3 :team_member_4])

14:12 erik``: why does

14:12 slipset: ,(+)

14:12 clojurebot: 0

14:12 slipset: but not

14:12 ,(-)

14:12 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->

14:13 justin_smith: ,(/ 2)

14:13 clojurebot: 1/2

14:13 slipset: and one could expect

14:13 godd2: slipset subtraction doesnt have a left-associative identity

14:13 slipset: ah!

14:14 justin_smith: godd2: well, it won't until we invent anti-zero

14:14 slipset: So then there might be a (good) reason why

14:14 ,(max)

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

14:15 justin_smith: ,(min)

14:15 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/min>

14:15 justin_smith: ,(*)

14:15 clojurebot: 1

14:15 slipset: one could imagine (max) return something very small :)

14:16 godd2: slipset think about what reduce does

14:16 slipset: godd2, that's actually what I'm trying to think about

14:16 (reduce max [1 23 8 2 ])

14:17 justin_smith: ,(max Double/NEGATIVE_INFINITY)

14:17 clojurebot: -Infinity

14:17 hyPiRion: ,(reduce max []) ;; ???

14:17 lazybot: hyPiRion: Oh, absolutely.

14:17 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max>

14:17 slipset: (reduce and [])

14:17 ,(reduce and [])

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

14:17 slipset: d'oh!

14:18 ,(and)

14:18 clojurebot: true

14:18 hyPiRion: and is a monoid though

14:18 godd2: the identity of addition is 0, so reducing [1 2 3] is (+ (+ (+ 0 1) 2 ) 3), but for subtraction, (- 1 2) doesnt equal (- (- 0 1) 2)

14:18 slipset: ,(or)

14:18 clojurebot: nil

14:18 hyPiRion: max and min aren't

14:18 justin_smith: godd2: right, which is why I suggested we need anti-0

14:18 slipset: hyPirion: max and min aren't monoids, or aren't monoids in Clojure?

14:19 * slipset is way out on a limb here

14:19 slipset: I only do crud

14:19 godd2: justin_smith but then we'd have to prove uniquness and that all just too much hassle

14:19 justin_smith: godd2: why prove something when you can axiomize it?

14:19 "the value that is the left-associative identity for subtraction"

14:20 done, it's unique

14:20 hyPiRion: slipset: They could be monoids for floating point values, but not for any other numeric type

14:20 godd2: justin_smith I think you may run into a contradiction from commutativity.

14:20 hyPiRion: Well, I mean, they *could* be for any type, but I'm not sure if it makes sense

14:21 justin_smith: godd2: oh god

14:21 right

14:21 slipset: hyPirion: the question sortof arises from one of @ctfords tweets this evening.

14:21 he had a function somewhat like

14:21 justin_smith: godd2: hrm, wait - no - it would be similar to i I think

14:21 godd2: justin_smith you might be right, I'm just speculating

14:21 justin_smith: godd2: it introduces a new kind of "complex number" anti-zero+n

14:21 slipset: (defn f [l] (->> :foo (max)))

14:22 (defn f [l] (->> l :foo (max)))

14:22 it should be

14:22 godd2: justin_smith and the anti-identity matrix

14:22 slipset: which fails when the list he passes in is empty

14:22 justin_smith: right, right

14:22 slipset: sorry, my brain is not on

14:22 (defn f [l] (->> l (map :foo) (max)))

14:23 hyPiRion: slipset: I think you forgot a reduce or apply there

14:23 justin_smith: yeah, definitely forgot an apply

14:23 hyPiRion: (->> l (map :foo) (reduce max))

14:23 slipset: hyPirion: you're right

14:23 (defn f [l] (->> l (map :foo) (apply max)))

14:23 but this fails when the list is empty

14:23 since max is not a monoid

14:23 but

14:24 (defn f [l] (->> l (map :foo) (reduce 0 max)))

14:24 works

14:24 as would wrapping the whole thing in a (if ...)

14:24 hyPiRion: slipset: sure, but that assumes the lowest value in the list is 0

14:24 justin_smith: slipset: that works if at least one arg is positive

14:25 slipset: which I guess is a pre-condition to this function

14:25 justin_smith: slipset: use Double/NEGATIVE_INFINITY instead maybe?

14:25 or just not provide an anitial value and let reduce use the first value as the inditial

14:25 hyPiRion: Actually, I just retract my statement about max/min being monoids. They simply can't be.

14:25 ,(max Double/NaN Double/POSITIVE_INFINITY)

14:25 clojurebot: NaN

14:25 slipset: justin_smith: sure, in the general case, but in this specific case, 0 is known to be the smallest possible value

14:26 hyPiRion: ,(= Double/NaN Double/NaN)

14:26 clojurebot: false

14:26 justin_smith: slipset: why not use the general solution?

14:27 slipset: justin_smith: I guess if it were my code, I'd wrap the thing in a (if (seq l) ... 0)

14:27 emaczen: What is the difference between atoms and agents? All I can tell is that they both are asynchronous.

14:28 justin_smith: emaczen: agents don't retry, for one

14:28 and they have a queue, rather than speculative execution

14:29 emaczen: So an agent seems more like the traditional asynchronous execution that I would think of.

14:29 slipset: would it be correct to say that you send someting off to an agent to happen at some time, whereas a change to an atom happens quite immediatly?

14:29 * slipset is hedging with the 'quite immediatly'

14:29 justin_smith: emaczen: if you know contention will be low (the normal case) an atom will be faster. If you know it will be high (or if retries would be disasterous) agents are definitely better.

14:30 slipset: change to an atom happens when it is done with the computation you use, plus all relevant retries (if any)

14:30 slipset: justin_smith: and while updating an atom you block, right?

14:31 emaczen: justin_smith: can you define or point me to contention?

14:31 slipset: whereas updating an agent is non blocking.

14:31 ?

14:31 justin_smith: emaczen: two overlapping updates to the same atom

14:31 something else changed it while you were using it

14:32 emaczen: justin_smith: cool!

14:32 justin_smith: swap! will restart with the new value, if any change happened after it started and before it commited

14:32 which is why swap! + side effects is bad news

14:37 emaczen: oh, another big difference is that if you get an exception when doing a swap! on an atom, you get it in your calling context, but an exception on a send or send-off to an agent will be handled by the agent's exception handler (or via explicit calls to agent-error and restart-agent later)

14:39 emaczen: Is retrying by the atom the major difference? It makes sense to me to use agents over atoms when contention is high due to the retrying.

14:39 justin_smith: atoms have less coordination overhead, and you can deal with exceptions / get the result transperently in the calling context

14:56 gfredericks: emaczen: I think switching to agents due to contention only makes sense if the contention is due to the update function being slow

14:56 threads still have to contend to get stuff into the agent's queue

14:57 justin_smith: gfredericks: isn't it a decent sized queue though? and queue insertion should't be a wide target for contention

14:58 gfredericks: I wasn't referring to queue size just the coordinated operation

14:58 justin_smith: aha, yeah

14:58 gfredericks: what do they use some kind of j.u.c.QueueThinger?

15:00 justin_smith: gfredericks: https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/Agent.java#L24

15:00 gfredericks: an AtomicReference to an ActionQueue

15:00 justin_smith: yup

15:01 gfredericks: what on earth is line 40 about?

15:01 is that an initial value for an instance variable?

15:01 emaczen: doc isn't working in the "user" namespace for me, what is going on?

15:01 justin_smith: emaczen: (use 'clojure.repl)

15:02 gfredericks: emaczen: dunno that's complicated, I recommend using lein-shorthand and not investigating further :)

15:02 justin_smith: emaczen: likely lein added clojure.repl to your "main ns", whichever that is

15:02 emaczen: use is the same as require right?

15:03 justin_smith: gfredericks: it's declaring an instance field on Agent, with some misleading indentation

15:04 emaczen: kind of, it's the same as (require 'foo :refer :all)

15:04 emaczen: I'm looking for a function like common-lisps make-list or make-array where you can specify the number of entries to be in the sequence and the initial argument.

15:04 justin_smith: emaczen: checkout conj.io

15:04 emaczen: justin_smith: Ok, so you can pick a subset of the stuff that you want to import

15:04 what is conj.io?

15:05 gfredericks: justin_smith: I didn't think instance fields could have initial values set at the top level

15:05 like

15:05 what does that even?

15:05 justin_smith: emaczen: a cheatsheet of useful clojure functions

15:05 gfredericks: I'm gonna go write some java code to try this out.

15:05 justin_smith: gfredericks: ahh, good point

15:06 emaczen: justin_smith: is conj.io as website or something?

15:06 justin_smith: emaczen: anyway, the function you want is on conj.io, and is called repeatedly

15:06 emaczen: yes

15:06 emaczen: I'm googling it, and not finding anything

15:06 justin_smith: http://conj.io

15:06 ,(repeatedly 3 :a)

15:06 err

15:06 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a>

15:06 justin_smith: sorry

15:06 ,(repeat 3 :a)

15:06 clojurebot: (:a :a :a)

15:06 justin_smith: much better

15:07 emaczen: http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/repeat/

15:08 emaczen: anyway, most of the interesting functions in clojure are on that page (http://conj.io aka grimoire), and it is updated pretty regularly

15:08 emaczen: sweet! Thanks for the resource

15:09 Can you get a vector instead of a list from repeat?

15:09 gfredericks: justin_smith: looks like java lets you do it and just runs the expression every time you initialize something

15:09 justin_smith: gfredericks: so it's like constructor code that is not inside the constructor

15:09 TEttinger: emaczen, sure

15:10 ,(vec (repeat 5 "whee"))

15:10 clojurebot: ["whee" "whee" "whee" "whee" "whee"]

15:10 * whee

15:10 TEttinger: sorry, didn't realize that nick was in use

15:10 emaczen: hah okay thanks TEttinger -- I thought it might have been a keyword argument to repeat

15:10 TEttinger: that's rare in clojure, usually things return seqs

15:10 gfredericks: justin_smith: yep I believe so.

15:11 I'll check whether it runs before or after constructor.

15:11 runs before

15:11 TIL about java.

15:11 justin_smith: ~java

15:11 clojurebot: java is a mutable basket case

15:11 justin_smith: ~clojure

15:11 clojurebot: clojure is the bestest programming language available.

15:11 gfredericks: ~a mutable basket case

15:11 clojurebot: excusez-moi

15:24 justin_smith: ~java

15:24 clojurebot: java is nuts

15:24 justin_smith: more of that mental illness theme, I see

15:24 ~nuts

15:24 clojurebot: excusez-moi

15:25 justin_smith: from a pm: 12:24 <clojurebot> ☕

15:29 crazydiamond: Hi. Is there "loop version" of walk/postwalk?

15:29 TEttinger: (identity justin_smith)

15:29 lazybot: justin_smith has karma 200.

15:29 TEttinger: gasp!

15:29 you reached it justin_smith!

15:29 justin_smith: I couldn't have done it without the help of all the little people

15:29 TEttinger: haha

15:29 justin_smith: meaning the leprechauns who help me answer clojure questions

15:30 it's a great day in fake internet points for me, to be sure

15:31 let's just hope technomancy doesn't figure out I was stealing his points while he wasn't looking

15:31 (identity technomancy)

15:31 lazybot: technomancy has karma 162.

15:33 justin_smith: woah, does anyone else see a "run code snippet" button on this? http://stackoverflow.com/questions/28786376/how-can-i-use-a-unsigned-64-bits-variables-in-bits-operations-in-clojure

15:34 gfredericks: yep

15:34 justin_smith: I have never seen that feature before

15:34 gfredericks: I clicked it and it just printed the code

15:34 justin_smith: it appears to be totally broken

15:34 gfredericks: unformatted

15:34 justin_smith: but it looks like a new feature

15:35 perhaps it will even work soon, that would be cool

15:35 gfredericks: maybe it assumes all code is a language wherewithin everything evaluates to itself

15:35 or rather itself without newlines and in a variable-width font

15:36 justin_smith: reminds me of this messed up language I tried once called html

15:37 kryft: Hmm, I tried to set :friend/redirect-on-auth? to false, but I still seem to get redirection upon successful login

15:38 TEttinger: justin_smith: gfredericks: it looks like that code snippet doesn't have highlighting, maybe they didn't set the language

15:38 justin_smith: aha, I will edit it!

15:38 kryft: If I have (:require [cemerick.friend :as friend]), then :friend/redirect-on-auth? should be the same symbol as ::redirect-on-auth? in the cemerick.friend ns, right?

15:38 justin_smith: TEttinger: oh, I reloaded, someone else set the language

15:39 Bronsa: kryft: ::friend/redirect-on-auth

15:39 justin_smith: TEttinger: maybe it was a java related feature? (or chess or bitboard...)

15:39 TEttinger: haha

15:39 kryft: Bronsa: ...ah, thanks

15:39 justin_smith: TEttinger: ahh! the button was there because it had been set as lang-html http://stackoverflow.com/posts/28786376/revisions

15:39 kryft: So :friend/redirect-on-auth would be ::my-current-ns/friend/redirect-on-auth :P

15:39 justin_smith: and they switched it to java which is way silly

15:40 Bronsa: kryft: no :friend/redirect-on-auth is just :friend/redirect-on-auth

15:41 kryft: Bronsa: Ok, I'd better reread the docs on that, thanks :)

16:54 lvh: is there a shorthand for "apply, except for macros"?

16:55 E.g. if I have a list [1 2 3 4], I want to be able to easily do (are [whatever] some-expr ~@that-list) in a test

16:55 except without the ~@ I guess

16:56 justin_smith: lvh: I think it would need to be another macro

16:57 lvh: justin_smith: Indeed it would; I was hoping that'd be a macro someone already wrote ;)

16:57 justin_smith: actually, it may be hard to do without eval...

16:57 arohner: lvh: there's apply-macro floating around

16:58 justin_smith: https://github.com/clojure/clojure-contrib/blob/73accf597eafb8dfcb642702a3b98b057bbdbbdf/src/main/clojure/clojure/contrib/apply_macro.clj#L34

16:58 arohner: lvh: I'm on slow internets right now, you'll have to google for it. It was in old contrib, not sure if it got re-released

16:58 justin_smith: like I thought, eval :(

16:58 lvh: arohner: Found it; thanks :)

16:58 arohner: lvh: but I'd be cautious about using it. It's not really idiomatic

16:58 and ~@ works just fine in most cases

16:58 justin_smith: "This is evil. Don't ever use it. It makes a macro behave like a function. Seriously, how messed up is that?"

16:58 lvh: heh

16:58 arohner: `(are [whatever] some-expr ~@that-list)

16:59 lvh: Yeah :-)

16:59 I might also just use is and give up on are's magic

17:00 maybe that's slightly suboptimal because I'll get pretty terrible error message out when a test fails

17:13 hq1: hi, noob here. I'm having trouble getting cljfmt to work. `lein cljfmt check src/foo/core.clj` works, but I'm having classpath issues when running `lein repl` and trying to (require `cljfmt.core) throws FileNotFoundException. My lein version is 2.5.1. Profile: https://gist.github.com/aerosol/2b2da25ec3bf72f21d59

17:15 Running `lein classpath` doesn't include any of the cljfmt packages. Is that supposed to be handled automatically or do I need some extra configuration?

17:16 arohner: hq1: that's a lein profile issue

17:17 hq1: as in, the profile is misconfigured?

17:17 arohner: if you try to require at runtime, it needs to be in the standard deps. I'm assuming cljfmt, when loaded as a plugin, puts itself in the :dev profile

17:18 hq1: oh ok, let me look that up

17:20 arohner: hq1: :plugins are code that is loaded into the lein process. :dependencies are loaded into your app's process. Some plugins add dependencies.

17:21 hq1: lein-cljfmt is the lein plugin. [cljfmt "0.1.7"]. is the runtime code. I bet lein-cljfmt adds cljfmt as a dependency. If you don't go through that path, cljfmt doesn't get loaded, and you can't require from repl

17:22 so the way to fix it is just add [cljfmt "0.1.7"] as a dependency. You probably want to put it in your :dev profile, like {:profiles {:dev {:dependencies [[cljfmt "0.1.7"]]...

17:22 hq1: thanks arohner

17:24 emaczen: can someone here help me with cider? #clojure-emacs is very quiet

17:24 hq1: arohner: brilliant, it works as expected now.

17:24 arohner: ~ask

17:25 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

17:25 emaczen: when I start a cider-repl, I am now seening warnings

17:25 1) WARNING: CIDER requires nREPL 0.2.7 to work properly

17:25 2) WARNING: The following required nREPL ops are not supported:

17:25 apropos classpath complete eldoc format-code format-edn info

17:25 inspect-start inspect-refresh inspect-pop inspect-push inspect-reset

17:25 macroexpand ns-list ns-vars resource stacktrace toggle-trace-var

17:25 toggle-trace-ns undef

17:25 Please, install (or update) cider-nrepl 0.9.0-SNAPSHOT and restart

17:25 CIDER

17:26 WARNING: CIDER's version (0.9.0-snapshot) does not match

17:26 cider-nrepl's version (not installed)

17:26 scottj: uh oh

17:26 emaczen: All I did was install cider via MELPA

17:26 justin_smith: emaczen: what it is saying is that your clojure process needs a cider-nrepl dep to work properly with cider

17:27 emaczen: the two halves are distributed and installed separately, but their versions must match

17:27 emaczen: justin_smith: where do I get this nrepl plugin?

17:27 justin_smith: usually it will be installed via a plugin in profiles.clj

17:27 emaczen: justin_smith: can I put it in project.clj?

17:27 justin_smith: emaczen: declare a dep for cider-nrepl with the version string it asks for under the dev profile

17:28 it's better off in ~/.lein/profiles.clj unless you only plan to use cider with one project

17:29 arohner: emaczen: putting it in project.clj is good if you're planning on starting nrepl at runtime, i.e. in production. Otherwise put it in profiles

17:30 emaczen: thanks guys!

17:33 So I am still getting some warning messages that aren't clear to me

17:34 WARNING: CIDER requires nREPL 0.2.7 to work properly

17:34 {:user {:plugins [[cider/cider-nrepl "0.8.2"]]}} -- I put this in profiles.clj

17:34 justin_smith: why did you pick that version?

17:34 the error message told you exactly the version it wanted

17:35 emaczen: That's the version which is in Melpa

17:35 cider 0.8.2 installed Clojure Integrated Development Environment and REPL

17:35 justin_smith: emaczen: something's fucky

17:35 your cider thinks it is 0.9.0-SNAPSHOT

17:36 and that's the version of cider-nrepl it is asking for

17:36 emaczen: what is the difference between the two warnings:

17:36 WARNING: CIDER requires nREPL 0.2.7 to work properly

17:36 WARNING: CIDER's version (0.9.0-snapshot) does not match cider-nrepl's version (0.8.2)

17:36 I also get the 0.9.0-SNAPSHOT warning

17:36 arohner: emaczen: I bet you have multiple cider.el's loaded in emacs

17:36 justin_smith: nrepl is a dep that cider-nrepl needs

17:36 emaczen: arohner: That's probably valid -- I'll remove them and then restart emeacs

17:37 justin_smith: the version of nrepl, and the version of cider-nrepl, are both not usable by your version of cider

17:37 ~cider

17:37 clojurebot: cider is Try #clojure-emacs for more help with Cider

17:37 justin_smith: ~cider

17:37 clojurebot: cider is Cider is unstable and broken right now, most things don't work. Use the last stable version of nrepl.el for now.

17:39 emaczen: arohner: AMAZING! It works! FINALLY!

17:40 arohner: emaczen: great!

17:40 emaczen: arohner: Now I will play with company-mode and the extra jazz :)

17:40 is there a recommended way to reload your .emacs file?

17:41 I either M-x eval-buffer or M-x load-file [.emacs]

17:41 arohner: not that I know of. The bigger problem is there isn't a convenient way to unload the effects of an old file

17:42 emaczen: Yeah ...

17:42 justin_smith: if only we had component.el

17:42 haha

17:49 gfredericks: has anybody written clojure.el yet?

17:51 emaczen: what do you guys use for clojure completion?

17:51 gfredericks: something terrible

17:54 scottj: gfredericks: have you seen dash.el?

17:55 gfredericks: yeah

17:59 avshalom: emaczen: company

18:00 emaczen: avshalom: do you know of a way to rebind the up and down arrow keys for selection of a completion in the scroll bar?

18:01 avshalom: emaczen: not sure how to do that. are you talking about company mode?

18:18 emaczen: avshalom: I figured it out if you want the code

18:19 chipf0rk: Hi, could anyone familiar with cider/cider-nrepl help me out? I've upgraded cider in emacs to the latest version and the cider-nrepl version in my profiles.clj is 0.9.0-SNAPSHOT, but cider seems to think it's both 0.9.0snapshot and 0.8.1 at the same time...

18:20 emaczen: chipf0rk: I might have just had this problem

18:20 chipf0rk: WARNING: CIDER's version (0.8.1) does not match cider-nrepl's version (0.9.0)-snapshot) - yet it says "CIDER 0.9.0snapshot" one line above

18:20 emaczen: You may have multiple versions of cider loaded into emacs

18:20 I just rebooted

18:20 and it was fine

18:20 chipf0rk: rebooted or restarted emacs?

18:20 because I've tried the latter

18:20 emaczen: restarted emacs

18:21 the lateset in elpa is 0.8.2 for me

18:23 chipf0rk: hold up, `killall emacs` might've done the trick

18:23 sigh

18:23 clojurebot: Excuse me?

18:25 chipf0rk: "CIDER 0.9.0snapshot (package: 20150228.1306)" btw

18:25 so 0.9.0snapshot seems to be in my package repos

18:26 emaczen: it has to match what is in profiles.clj

18:26 chipf0rk: I'm aware of that

18:26 emaczen: why not use 0.8.2

18:27 chipf0rk: good question - mainly because I saw that I had emacs upgrade to 0.9.0

18:27 how do I downgrade a package?

18:27 maveneagle: hi guys, I was trying to understand the reducers in clojure. Just wanted to know if i understand it correctly.. when i create a reducer for map and reduce it, the specific collection (vec, list et all) will reduce itself "sequentially"? but the same reducer if i try to fold it will use the fork/join approach to parallelise the reduction?

18:27 chipf0rk: to a specific version

18:27 Zardoz: So ~/.lein/profiles.clj has the right plugin version?

18:27 chipf0rk: welp it has 0.9.0-SNAPSHOT atm

18:27 emaczen: So 20150228 in my *packages* buffer is from melpa

18:28 Usually there is a melpa archive and a marmalade archive

18:28 the marmalade archive lists the version and the latest for cider was 0.8.2

18:28 unless it changed in the last 30 minutes

18:29 chipf0rk: i'm reinstalling the cider package I guess

18:29 Zardoz: Can confirm, mine is "20150228"

18:34 arohner: maveneagle: I don't think reducers specify an order. in fact I think they explicitly don't

18:34 maveneagle: though transducers are explicitly fold-left

18:34 chipf0rk: well that's interesting, it installed the same version, now that warning's gone

18:35 however it now tells me it needs nrepl 0.2.7

18:35 arohner: maveneagle: there's also https://github.com/aphyr/tesser

18:35 Zardoz: Oh yeah, that's annoying

18:36 Make sure your profiles.clj looks like this:

18:36 {:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]

18:36 :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}

18:36 emaczen: chipf0rk: I had the exact same errors before but the restart just worked for me

18:36 chipf0rk: doesn't for me sadly :(

18:36 hold on I can specify deps in profiles.clj? oh

18:37 emaczen: Can anyone link me to a resource about OO design and clojure? I'm seeing a lot about just using values and datastructures (I like the idea of just using a map everywhere but I want to see the other options as well)

18:39 maveneagle: arohner: thanks, will have a look at it

18:39 chipf0rk: Zardoz: Seems to have done the trick. Thanks a bunch!

18:39 Zardoz: You're welcome =D

18:40 I ran into the same thing last week

18:47 justin_smith: emaczen: regarding when to use maps etc. http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

18:47 emaczen: you won't be let down by that flowchart

18:49 emaczen: regarding OO, OO in clojure is mostly about keeping things modular by definining functions that work on interfaces / protocols, and then extending those interfaces / protocols to the types you need (starting with the persistent datatypes like map, vector, list, set etc.)

18:50 also see multimethods, and derive, between those you can do some interesting OO things

18:50 emaczen: justim_smith: cool, I am somewhat familiar with multi-methods but not derive

18:50 justin_smith: emaczen: multimethods respect the heirarchies created via derive for dispatch

18:51 finally, information hiding isn't as important when your data is not mutable

18:53 emaczen: justin_smith: What can you tell me about lazy evaluation?

18:53 justin_smith: what about it?

18:53 emaczen: I think I have a good question that will clarify my understanding thus far for you.

18:55 If I have a nested map expression, in common-lisp it must finish evaluating the nested map expression before the outer-expression can be evaluated

18:55 justin_smith: emaczen: clojure lazy-sequences are always evaluated in order

18:56 but they are not always realized

18:56 emaczen: I thought in Clojure, the outer sequence would begin to be evaluated as soon as the inner one had "returned" an element

18:57 justin_smith: emaczen: it really depends. I'm putting together an example.

18:59 contrived example:

18:59 ,,(let [counter (atom 0)] (nth (map (fn [i] (map #(swap! counter + %) (take 3 (repeat 1)))) (iterate inc 0)) 1000))

18:59 clojurebot: (1 2 3)

19:00 justin_smith: emaczen: notice that I get the 1000th element from the outer map

19:00 but the inner map is the first of the inner maps to be realized

19:00 the rest, being lazy, have not been generated yet, because they were not accessed

19:06 emaczen: justin_smith: I don't know enough clojure yet to follow it to a tee -- but what I think you are getting at is that the nested-maps will only evaluate till they get the 1000th item. Is that right?

19:07 justin_smith: emaczen: (iterate inc 0) gets the integers starting with 0

19:07 ,(iterate inc 0)

19:07 clojurebot: (0 1 2 3 4 ...)

19:08 justin_smith: actually - let me simplify it, one moment

19:10 ,(let [counter (atom 0)] (last (repeatedly 1000 (fn [] (map #(swap! counter + %) (repeat 3 1))))))

19:10 clojurebot: (1 2 3)

19:10 justin_smith: that's equivalent, and hopefully easier to read

19:10 so, it's a lazy seq of evaluating that function 1000 times

19:10 and we are just taking the last item and returning it

19:11 the item is generated by mapping an increment of the atom across [1 1 1]

19:11 in fact I should have written [1 1 1] instead of (repeat 3 1)

19:12 what's to be noted, is that for each realized element of that 1000 item sequence, the atom is incremented 3 times

19:12 maveneagle: I was watching Rich hickey's talk on reducers, I just want to understand how this line performs efficient compared to the old map & reduce -> (time (reduce + (r/map inc (r/filter even? v))))

19:12 justin_smith: but you see at the end, it only got incremented 3 times total, even though we got to the 1000th item

19:12 maveneagle: i do understand fold is optimsed due to fork join

19:13 emaczen: what is the %?

19:14 justin_smith: emaczen: oh, that's a shortcut for anonymous functions

19:14 ,'#(+ % %)

19:14 clojurebot: (fn* [p1__54#] (+ p1__54# p1__54#))

19:14 emaczen: it looks like a placeholder

19:14 justin_smith: it just means "first argument"

19:16 emaczen: so why aren't all the elements "realized"

19:16 justin_smith: emaczen: they are lazy, and were not accessed

19:16 which is why typically you really want referentially transperent functions generating lazy sequences

19:17 I intentionally made a contrived, non-transperent function (closing over the mutable atom) to demonstrate the behavior

19:18 emaczen: Yeah, I would think the values would be 2998 2999 3000

19:18 If you count from 1

19:19 Which you aren't so subtract 1 from what I wrote above

19:19 justin_smith: the first swap! returns 1

19:19 so it does count from 1

19:19 emaczen: oh ha

19:19 justin_smith: swap! returns the new value, and you added 1

19:20 well, not you, but anyway

19:20 emaczen: Can you tell me what happends under the hood? A contrived example is just telling me that the first portion of the list is not evaluated?

19:20 justin_smith: under the hood a lazy seq is a thunk

19:21 emaczen: thunk?

19:21 justin_smith: a function of no arguments returning the next element of the list

19:21 or, actually, returning a next element, followed by a "rest" that is a thunk

19:21 which is in turn the same

19:21 until one of them has an empty rest

19:25 emaczen: justim_smith: It would probably be very educational to play with a thunk -- I've done this before in scheme. I'll have to look into it again but more in depth

19:26 justin_smith: emaczen: thunks are just how lazy-seqs are implemented

19:26 typically you don't need to use them directly

19:26 though we have delay, for doing similar things with explicit deref

19:26 emaczen: I just remember using "force" or something in scheme

19:26 To actually get the next element

19:31 justin_smith: Isn't the implementation of lazy sequences a starting value and a function to get you the next element?

19:31 justin_smith: a function that gets you next element and next function

19:31 emaczen: And when you actually want to get the next value, you just apply this function with the current value?

19:31 justin_smith: because that first function can only give you the first element

19:32 no

19:32 you get a new lazy-seq at each step

19:32 or nil (empty)

19:46 maveneagle: why is the second line faster than the second line here (https://gist.github.com/anonymous/19702a4efdac2cedae97) I understand why the 3rd line is faster though

19:47 * second line faster than first line

19:47 justin_smith: maveneagle: lazy-seqs have an overhead that r/map and r/filter do not

19:48 maveneagle: justin_smith: ahh.. thanks! forgot about that

19:48 justin_smith: maveneagle: as I was just describing to emaczen, the thunk created for each item

19:48 maveneagle: r/map does not need to create that for each element

19:49 bbloom: gfredericks: i think i solved my irc time traveling problem

19:50 justin_smith: maveneagle: for more info, you would likely find it informative to look at transducers. They solve a similar performance problem in a more generalized way.

19:50 gfredericks: bbloom: omg omg omg

19:50 bbloom: gfredericks: solution was to switch ISPs by moving across the country

19:50 gfredericks: bbloom: oh right of course

19:50 obvious in hindsight

19:50 maveneagle: justin_smith: sure, I am gonna watch rich's talk on transducers

19:50 justin_smith: maveneagle: whereas reducers specialize map, filter, etc. for reduce, transducers generalize them to be efficiently used for any source / sink of data generally

19:51 bbloom: gfredericks: if i start time traveling again, you let me know so that i can move back before i test another solution. we want to be scientific about this

19:52 gfredericks: bbloom: I bet if you had called the IRC call center they would've made you try that before anything else

19:52 justin_smith: bbloom: my guess was that you were in a weird spot in respect to the infrastructure of the Internet that would cause you to be separated in multi-jump netsplits from most of us

19:52 bbloom: i always refuse to unplug it and plug it back in again

19:53 gfredericks: ~bbloom is in a weird spot in respect to the infrastructure of the Internet

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

19:53 enn: So Clojure Autodoc, Marginalia, and Codox all generate fairly fancy multi-column layouts for the documention. Can anyone recomment a tool that generates something more basic?

19:54 emaczen: in core.match, can a pattern be a predicate? I'm pretty sure I've seen this functionality in elisp's pcase.

19:55 bbloom: emaczen: https://github.com/clojure/core.match/wiki/Basic-usage#guards

19:58 crazydiamond: Hi. Are there data structure processing algorithms that require state by definition? I have solved my idea with a bit of imperative code, but not sure that I can turn it into pure functional

19:59 justin_smith: crazydiamond: there is a proof that any mutation can be refactored into extra args / return values that are threaded through the code

19:59 this is very easy to do with loop

19:59 clojurebot: Roger.

19:59 justin_smith: clojurebot: I wasn't talking to you

19:59 clojurebot: Cool story bro.

19:59 crazydiamond: justin_smith, interesting

20:00 justin_smith: crazydiamond: of course where this gets tricky is if you had multiple mutations within one loop

20:00 then you need to refactor things so there is one threading of the updated values from top to bottom

20:00 crazydiamond: so, my example: I have DS like this [[1] [[1]]]. I want to take out common parts [1]

20:01 there's it solved in imperative way with Python: 4

20:01 [(0, 1), (1, [0]), (2, [1]), (3, [2]), (4, [1, 3])]

20:01 i.e. 4 is list (say, vector) with 1 and 3:

20:01 [0_] [2_]]

20:02 justin_smith: I have no idea what any of this means, sorry

20:03 crazydiamond: well... imagine (clojure.walk/postwalk f some-data-structure)

20:03 where (defn f [x] (do (println x) x)))

20:03 i.e. prints and returns the value

20:04 bbloom: crazydiamond: if you need state over a traversal, idiomatic clojure is to simply use mutable state

20:04 crazydiamond: and I want to gather that values instead of returning them

20:04 bbloom: crazydiamond: unless you need something more advanced, like the ability to backtrack or go down multiple traversal paths in a non-standard order or something

20:04 crazydiamond: however, if you are interested in how you'd do this more functionally just b/c, then may i suggest looking at zippers

20:05 gfredericks: ~zippers |are| the lenses of monads

20:05 clojurebot: c'est bon!

20:06 crazydiamond: well, traversal, when I visit each node-by-node

20:06 i.e. next node knows about what happened when visiting all previous

20:07 in typical traversal it knows only about it's parents

20:07 not siblings

20:07 justin_smith: crazydiamond: what about just using tree-seq

20:07 crazydiamond: I should check that out

20:08 justin_smith: and having a reduce over the tree-seq that carries the state you care about in the accumulator

20:08 bbloom: crazydiamond: do you care about the context of the tree? ie parents/siblings, or do you only care about the state threaded through the traversal?

20:08 if just the state, yeah tree-seq is what you want

20:08 if actual parents/children/etc, then look at zippers

20:08 crazydiamond: state, yes

20:08 bbloom: in both cases, it's just a "left fold"

20:08 crazydiamond: how to say that...

20:09 bbloom: the idea is to flatten the traversal of the tree in to something like a list, then reduce over the list + some state

20:09 crazydiamond: I have structure with huge amount of repeating parts

20:09 I want to achieve the same goal what "let" is for

20:09 say that

20:10 emaczen: is there a flat-map function in clojure?

20:10 In CL I did reduce #'append

20:10 justin_smith: emaczen: apply concat

20:10 crazydiamond: [[1] [[1]]] become (let [a [1]] [a [a]])

20:10 emaczen: I'd rather use something like flat-map though

20:10 justin_smith: or mapcat

20:10 bbloom: ,(reduce (fn [acc x] (update-in acc [x] (fnil inc 0))) {} (tree-seq vector? seq [[1] [1 [1] [1]]]))

20:10 clojurebot: {[1 [1] [1]] 1, 1 4, [1] 3, [[1] [1 [1] [1]]] 1}

20:10 bbloom: crazydiamond: something like that ^^

20:11 justin_smith: ,(frequencies (tree-seq vector? seq [[1] [1 [1] [1]]])))

20:11 clojurebot: {[[1] [1 [1] [1]]] 1, [1] 3, 1 4, [1 [1] [1]] 1}

20:11 justin_smith: :)

20:11 bbloom: justin_smith: yes, but that won't teach him how to use reduce to emulate state

20:11 :-P

20:12 justin_smith: of course

20:12 crazydiamond: uhm, that's exciting anyway

20:12 thanks!

20:12 Uncle Bob was talking "with state monad you may have state when you haven't"

20:12 so this must be the case

20:12 justin_smith: crazydiamond: bbloom: I finally realized that weird vector of numbers and vectors above was probably just "frequencies" over subtrees

20:13 crazydiamond: the one where I was just like "wait, I don't even know what that is supposed to be"

20:13 emaczen: Is there a mutable version of map like forEach?

20:13 bbloom: ,(reduce (fn [acc x] (update-in acc [x] (fnil inc 0))) {} (tree-seq vector? seq [[:x] [:x [:x] [:x]]])) ; clearer

20:13 clojurebot: {[:x [:x] [:x]] 1, :x 4, [:x] 3, [[:x] [:x [:x] [:x]]] 1}

20:13 justin_smith: doseq

20:13 emaczen: ehh nvm

20:13 bbloom: emaczen: in clojure 1.7 there will be run!, but yeah, doseq is what you have to use otherwise

20:14 emaczen: what is run!

20:14 bbloom: ,*clojure-version*

20:14 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

20:14 bbloom: ,(run! prn [1 2 3])

20:14 clojurebot: 1\n2\n3\n

20:14 bbloom: ,(doc run!)

20:14 clojurebot: "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil"

20:23 emaczen: how do you refer to a function without the (fn [x] ...)

20:23 sorry let me restate

20:24 Instead of (fn [x] (some-function(x)))

20:24 Can you do #'some-function?

20:24 Bronsa: emaczen: assuming you mean (fn [x] (some-function x)), that's equivalent to some-function

20:25 timvisher: emaczen: what are you trying to achieve?

20:25 Bronsa: emaczen: and more or less equivalent to #'some-function too if you don't take into account var redefinition

20:25 timvisher: given your nick, are you thinking that passing a function to another one requires special quoting like it does in elisp?

20:25 emaczen: I got it -- in common-lisp often you will write (mapcar #'some-function some-list)

20:25 In clj you can just write the function

20:25 timvisher: yeah, in clojure that's just (map func ...)

20:26 yep

20:26 Bronsa: emaczen: #' in clojure doesn't mean what it means in cl

20:26 emaczen: I was trying all of these weird # combos

20:26 timvisher: emaczen: glad you're sorted out :)

20:26 justin_smith: but funny enough it will sometimes look like it is

20:27 ,(map #'inc (range))

20:27 clojurebot: (1 2 3 4 5 ...)

20:31 emaczen: thanks for all the help today guys -- getting spun-up on Clojure from common-lisp is really fun!

20:32 justin_smith: Empperi: I think it'll grow on you as well

20:36 vas: datomic is really cool

20:43 crazydiamond: can "loop"s be nested?

20:44 justin_smith: yes

20:44 the recur will work going to the innermost loop in the context

20:45 crazydiamond: is there "depth" function with signature like tree-seq's one? :D

20:49 gfredericks: what would it return?

20:50 the depth of the input?

20:50 crazydiamond: yes

20:50 * gfredericks tries to hack tree-seq to do that

20:50 crazydiamond: I have written one, though (but simpler one)

20:51 http://dpaste.com/1MENVQ7

20:53 gfredericks: ,(defn tree-depth [branch? children root] (let [walk (fn walk [node] (if (branch? node) (inc (reduce max (map walk (children node)))) 0))] (walk root)))

20:53 clojurebot: #'sandbox/tree-depth

20:53 gfredericks: ,(tree-depth 4)

20:53 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/tree-depth>

20:53 gfredericks: ,(tree-depth coll? seq 4)

20:53 clojurebot: 0

20:53 gfredericks: ,(tree-depth coll? seq [4])

20:53 clojurebot: 1

20:53 gfredericks: ,(tree-depth coll? seq [4 [1]])

20:53 clojurebot: 2

20:53 gfredericks: ,(tree-depth coll? seq [4 [[4] 1]])

20:53 clojurebot: 3

20:54 gfredericks: somethinglikethat

20:54 I think it crashes on an empty collection so good luck

20:54 crazydiamond: cool, thanks

20:56 gfredericks: I don't know what an empty collection means in terms of depth anyhow

20:56 crazydiamond: either +1 or +0 :D

20:56 gfredericks: yeah one of those

21:03 arohner: when using #'proxy, is there a way to proxy the constructor?

21:10 crazydiamond: ,(defn tree-depth-check-empty [branch? children empty root] (let [walk (fn walk [node] (if (branch? node) (let [children (children node)] (if (empty? children) empty (inc (reduce max (map walk children))))) 0))] (walk root)))

21:10 clojurebot: #'sandbox/tree-depth-check-empty

21:10 crazydiamond: ,(tree-depth-check empty coll? seq 4)

21:10 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: tree-depth-check in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:10 crazydiamond: ,(tree-depth-check-empty coll? seq 4 0)

21:11 clojurebot: 0

21:11 crazydiamond: ,(tree-depth-check-empty coll? seq 4 1)

21:11 clojurebot: 0

21:11 crazydiamond: ,(tree-depth-check-empty coll? seq [4] 1)

21:11 clojurebot: 0

21:11 crazydiamond: ,(tree-depth-check-empty coll? seq 0 [4])

21:11 clojurebot: 1

21:11 arrdem: o/

21:11 crazydiamond: LOL

21:11 so many arguments so easy to mess up

21:14 * crazydiamond wishes he had rainbow braces in REPL

21:50 mistaBIZ: Wow its deep

22:03 devll: hi, I deployed a clojar from the latest source,but I am getting this error

22:03 Caused by: java.lang.IllegalArgumentException: Can't define method not in interfaces: with_meta, compiling:(clj_http/headers.clj:105:1)

22:04 code is here. https://github.com/dakrone/clj-http/blob/master/src/clj_http/headers.clj#L120

22:05 how can I resolve this?

22:06 arrdem: devll: what's the full stack trace and what else are you using/doing?

22:06 devll: just that isn't enough to go on besides telling you to open an issue on the clj-http bugtracker.

22:06 and even that may not be in order depending on what you're up to..

22:08 devll: this is a known issue for long

22:09 clj-http 1.0.1 does not support clojure 1.7

22:09 which is the latest version for clj-http

22:10 arrdem: https://raw.githubusercontent.com/dakrone/clj-http/1.0.1/project.clj

22:10 devll: http://pastebin.com/1Ld4D8Q7

22:10 full trace here

22:11 arrdem: clj-http 1.0.1 doesn't depend on any version of Clojure. In fact it explicitly excludes any specific version of clojure from its transitive deps. You're probably trying to use 1.7-alphaN which doesn't work.

22:12 devll: yes.

22:14 arrdem: what are we on... alpha4 right now?

22:14 doesn't look like there's a matching issue on jira..

22:14 devll: compability fix has been merged into clj-http master.

22:14 there is but closed

22:15 alpha5

22:16 arrdem: devll: what commit fixes this? I'm not seeing one but still looking.

22:17 devll: https://github.com/dakrone/clj-http/commit/ccd4f10ce9fc748a882b27d57408145cb3e3b057

22:17 arrdem: that shouldn't fix the issue you posted a stacktrace for...

22:18 devll: it fixes another issue

22:18 arrdem: right.

22:18 but not the one you seem to care about.

22:18 enn: I'd like to find a way to figure out whether a certain function is anywhere on the call stack. I thought I'd be able to do this by examining the JVM stacktrace, but I've run into a wall.

22:19 If I have a function: (def foo [] (map bar some-sequence)), and I look at the stacktrace (with (.. Thread currentThreat getStackTrace)) from within bar, foo doesn't appear anywhere, because by the time the sequence is realized foo has already completed.

22:20 devll: using clj-http 1.0.1 causes "update" related issue. using the latest build throws the error above

22:20 arrdem: devll: my gut is that you've found a bug in the alpha and should probably report it.

22:20 devll: OK

22:20 enn: So I guess what I'd like is a way to get the "logical" call stack. Does such a thing exist?

22:21 devll: I am downgrading to 1.6.0

22:21 arrdem: enn: no, Clojure keeps no "logical" call stack.

22:21 devll: for this though

22:21 or my online app will not work.

22:21 enn: arrdem: well, shoot. OK, thank you.

22:21 arrdem: enn: so you're hitting an issue with lazy evaluation.

22:22 devll: thanks arrdem as well

22:22 enn: yeah

22:22 arrdem: enn: if you _really_ want to see foo in your stack, try mapv (which is strict) or use doall

22:22 $grim clojure.core/doall

22:22 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/doall

22:22 arrdem: $grim clojure.core/mapv

22:22 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/mapv

22:23 enn: arrdem: unfortunately this is in the context of instrumenting arbitrary code, so I can't really banish lazy sequences altogether

22:25 I guess plan B is, alter-var-root on the function I'm looking for (foo) so that it dynamically binds some flag, which I can then check for in bar

22:26 arrdem: enn: I guess that could work..

22:26 I think dynalint and some other tools do some similar var introspection hackery to build a logical call stack.

22:26 tracer...? it's been a long time since I used it last.

22:27 https://github.com/xumingming/tracer

22:27 https://github.com/clojure/tools.trace

22:28 I'm pretty sure both of those do var poisoning akin to what you're after... as does technomancy/radagast

22:28 amalloy: enn: dynamically binding a flag will have exactly the same problem

22:29 foo has finished by the time you realize the results of map, so of course the flag will no longer be dynamically bound either

22:29 enn: amalloy: yeah, I just discovered that. Damn.

22:31 What I'm trying to do is implement something like tools.trace, with an option to only trace function bar when it is called down-stack of foo. (This is a shameless copy of the :wherein option to SBCL's trace, http://www.sbcl.org/manual/#Function-Tracing.)

22:31 But it sounds like this is not possible in the general case in Clojure.

22:31 clojurebot: 'Sea, mhuise.

22:31 gfredericks: oh because of laziness?

22:31 enn: Yeah

22:32 gfredericks: maybe if you modified the lazy-seq macro, but that sounds sooper hairy

22:32 i.e., it could save your dynamic bindings before executing the thunk

22:32 or something I mean youseewhatimsayin

22:33 I think modifying the lazyseq macro like that might be damn near impossible though w/o forking clojure

22:34 enn: yeah, I'd be worried about things breaking

22:53 arrdem: I assume that the string "RELEASE" as a lein version specifier refers the latest release?

22:54 Just trying to grok how this works https://github.com/lshift/cloverage/blob/master/lein-cloverage/src/leiningen/cloverage.clj#L9

23:02 WonkyWombat: Hi all, I'm a Clojure-N00b and get it power in using the JVM platform but can Clojure operate on it's own in a desktop or server, *not* using the JVM for delivery?

23:03 gfredericks: not clojure the jvm language, no

23:04 WonkyWombat: gfredericks: right, does Clojure have access to libs or frameworks for TCP/IP-systems frameworks?

23:05 gfredericks: only inasmuch as Java does

23:05 for questions like that you can consider Clojure to be just a java library

23:05 WonkyWombat: gfredericks: that puts it into perspective

23:06 So it may not be the best choice for writing a tool that can almost forensically examines, reports and backups a web site/application?

23:07 * gfredericks not sure

23:08 WonkyWombat: gfredericks: thanks for the candour, I'll read further on Java's ability for networking

23:08 gfredericks: np

23:08 juggernot: WonkyWombat: it might be since that seems like a long running process

23:09 is there a particular reason you want to avoid Java/JVM?

23:09 WonkyWombat: juggernot: Have this perhaps incorrect view that Java is second rate with networking compared to Python etc

23:11 juggernot: oh i see... well there's always the ClojureScript on nodejs route if you dont have any qualms about nodejs

23:12 WonkyWombat: juggernot: k, aware but have not read up

23:47 Did we have a net split or something? Awful lot of In/Out

Logging service provided by n01se.net