#clojure log - Dec 27 2014

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

1:02 sova: (* 2 3)

1:02 clojurebot: *suffusion of yellow*

1:02 sova: Hahah

1:02 pcn: That makes me so happy

1:02 Let's everyone get a watch

1:03 an i ching calculator watch

1:03 sova: clojurebot can perceive colors

1:03 pdk: after that i'm feeling pretty suffused

2:24 TEttinger: (doc map)

2:24 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

2:24 TEttinger: hiredman, any ideas on what's causing that?

2:38 hiredman: I moved the sandbox over to a new host, upgraded the version of clojure to the latest 1.7-alpha, looks like 1.7 uses some more permissions when just loading the clojure runtime

3:20 profil: Why does a swap! with a map return the entire atoms value? just like this https://clojuredocs.org/clojure.core/swap!#example_542692d5c026201cdc32709f

3:21 thearthur: profil: I'm under the impression that the return value of swap! is only ever the contents of the atom in question

3:21 ,(doc swap!)

3:21 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

3:22 thearthur: the reason it does this (if im understanding yoru queston) is do you can thread the swap through other expressions and have them use the new value

3:23 (-> my-atom (swap! assoc :a 1) :a inc dec)

6:20 __cskksc__: :q

6:27 It is possibly a noob question. Can I use (reset! some-atom @other-atom) in a fn after (for ...) ? So in all (fn (for ....) (reset! ....))

6:27 It does not seem to work. But if do a reset by itself in repl, it works fine.

6:29 thheller: for is lazy, probably better to doseq if you don't need the result

6:31 __cskksc__: Ah, thanks so much. It worked.

6:32 Had'nt considered the laziness of (for)

8:12 SagiCZ1: bbloom: really like your article about Code Density, I am in the situation you describe and I am glad I am probably not as stupid as clojure makes me feel sometimes

8:15 luxbock: SagiCZ1: link to article?

8:15 SagiCZ1: http://www.brandonbloom.name/blog/2013/06/24/code-density/

8:16 luxbock: thanks

8:56 hellofunk: SagiCZ1: i liked that article but i feel like it took me about twice as long to process reading it as compared to, say, a 100K line Java project

9:02 perplexa: mmmh..

9:33 __cskksc__: I'm getting an error between for and doseq. Can anyone please help? http://pastie.org/9800710

9:34 justin_smith: __cskksc__: well, you won't get the error with for, because for won't even run the code, since the result isn't used

9:36 __cskksc__: it seems like somewhere your [] got turned into a (), and you can do assoc-in on a ()

9:37 __cskksc__: Okay yeah it will create a lazy sequence. for works fine in repl though. So i thought if I force eval using doseq it'll work.

9:37 justin_smith: I think it's because somewhere grid or next-grid is being turned into a lazy-seq where it used to be a vector

9:37 you can't assoc-in on a lazy-seq

9:38 that's what that error is saying

9:38 __cskksc__: justin_smi: Thanks :) .Getting back to it.

9:39 justin_smith: also, this style of code isn't the best use of clojure. I think you'll find that rewriting to a functional style will be more clear, and also faster.

9:40 __cskksc__: You mean I could do it without a atom ?

9:40 justin_smith: right, and without globals in general

9:42 I don't see anything in your code that would turn the game state into a lazy-seq, but I still think that is the cause of the error

9:43 __cskksc__: ah okay, ill try doing it without game-state in var.

9:43 justin_smith: __cskksc__: the translation will likely be tricky at first, you may want to solve your current issue before undertaking it

9:45 __cskksc__: justin_smi: yeah. im very new to clojure and functional programming in general :)

9:46 justin_smith: the general "big picture" of it is that you translate the code so that any globals accessed become arguments to the function, and any globals modified become part of the return value

9:47 and then you'll often end up using higher order constructs like map or reduce to describe a series of updates, propagating the results via return value

9:50 __cskksc__: yeah

9:51 justin_smith: also, as a little stylistic thing, a cond with only one condition is better expressed as "when", and a cond with only two conditions is better expressed as "if"

9:54 hellofunk: justin_smith: except that with if there is one test, while a cond with two exprs can have 2 different tests, no?

9:55 justin_smith: hellofunk: I am referring to __cskksc__ 's pasted code, where he uses (cond (q? x) y :otherwise z)

9:55 hellofunk: justin_smith: ok

9:55 justin_smith: hellofunk: of course for that generalized case you still want cond, but he never uses it that way

10:13 __cskksc__: justin_smith: Yeah you're right. an 'if' makes more sense there.

10:16 SagiCZ1: i want to have two optional parameters with zero default values, is this correct?

10:16 [x & {:keys [mag acc] :or {mag 0 acc 0}}]

10:17 luxbock: SagiCZ1: yep

10:17 justin_smith: SagiCZ1: that works, but seriously consider not using varargs keyword params, they are tricky to use

10:18 it's much easier to just take an optional map, that makes composing with other functions easier

10:18 SagiCZ1: i think i saw this kind of usage all over seesaw for example

10:19 isnt this an optional map?

10:19 justin_smith: SagiCZ1: it's optional key value pairs

10:19 [x & [{:keys ...}]] would be an optional map

10:19 SagiCZ1: i see.. then the user has to put { } around the params right?

10:20 justin_smith: &((fn [& {:keys [a b]}] (+ a b)) :a 1 :b 2)

10:20 lazybot: ⇒ 3

10:20 justin_smith: &((fn [& [{:keys [a b]}]] (+ a b)) {:a 1 :b 2})

10:20 lazybot: ⇒ 3

10:20 justin_smith: exactly

10:20 but keeping things in a map is actually convenient in many ways

10:21 SagiCZ1: cool.. didnt know its better

10:21 hellofunk: SagiCZ1: plus if you want defaults, you can just merge the arg map onto a defaults map, any args provided will overwrite the defaults

10:23 SagiCZ1: hellofunk: and i would do that in the funciton body right?

10:23 hellofunk: SagiCZ1: yes

10:24 SagiCZ1: thanks

10:24 hellofunk: SagiCZ1: you might be able to destructure it as well, but i think the body is easier personally

10:29 SagiCZ1: how does this work?

10:29 &(#(read-string (str 2 \r %)) "101010101")

10:29 lazybot: ⇒ 341

10:30 SagiCZ1: &(#(read-string (str 2 %)) "101010101")

10:30 lazybot: ⇒ 2101010101

10:30 Bronsa: ,2r101010101

10:31 clojurebot: 341

10:31 SagiCZ1: ohh..

10:31 Bronsa: SagiCZ1: it's the radix syntax

10:31 SagiCZ1: so its a clojure literal?

10:31 Bronsa: 2rXXX means XXX in base 2

10:31 yeah

10:31 SagiCZ1: thats clever

10:31 Bronsa: 3r23

10:31 ,3r23

10:31 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "23">

10:31 Bronsa: ,3r22

10:31 clojurebot: 8

10:31 Bronsa: etc

10:31 SagiCZ1: thank you

10:32 Bronsa: there's also

10:32 ,1e4

10:32 clojurebot: 10000.0

10:32 hellofunk: and, this time of year, it's nice to catch up with r&r too

10:32 hbccbh: ,4r3e2

10:32 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "3e2">

10:32 hbccbh: ,4r3.2

10:32 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 4r3.2>

10:33 masnun: ,(+ 1 1)

10:33 clojurebot: 2

10:33 justin_smith: it's too bad that doesn't work

10:33 ,(* 4r32 0.1)

10:33 clojurebot: 1.4000000000000001

10:33 justin_smith: not as nice

10:33 clojurebot: No entiendo

10:35 tephra: is it worth getting clojure coockbook given that I already have programming clojure?

10:35 SagiCZ1: cockbook?

10:36 tephra: oops soory

10:36 hellofunk: tephra: each clojure book is a different point of view. absorb them all if you have time and interest

10:38 tephra: hellofunk: thanks, someone told me that it was unnecessary but given that I get it for free i think it should get it then :)

10:39 SagiCZ1: tephra: cant harm

10:39 hellofunk: and how do you get it for free? tephra

10:40 tephra: got a free ebook from oreilly

10:41 hellofunk: tephra: you have the oreilly clojure book by chas and christophe right?

10:41 luxbock: https://github.com/clojure-cookbook/clojure-cookbook

10:42 tephra: hellofunk: yeah programming clojure right? got it when we used clojure in school a year ago, chas, brian and christophe

10:42 SagiCZ1: clojure in school? wow

10:42 tephra: oh it's clojure programming

10:43 SagiCZ1: yeah its a diffrence

10:43 tephra: yeah i got that one (clojure programming)

10:44 SagiCZ1: me too.. liked it

10:44 tephra: SagiCZ1: in our programming language and paradigms course we used it to learn functional programming

10:44 SagiCZ1: tephra: good teachers then..

10:44 tephra: yes it's very good

10:45 SagiCZ1: yes very good, my latest course is learning distibuted and parallel programming in erlang with joe armstrong :)

10:46 SagiCZ1: what school is this?

10:46 bbloom: SagiCZ1: luxbock: glad you guys enjoyed the article! thanks

10:47 tephra: SagiCZ1: stockholm university

10:47 SagiCZ1: bbloom: hi, you're welcome!

10:47 tephra: hah maybe i should finish my masters there

10:48 hlprmnky: So I'm trying to run a REPL inside a Docker container from library/clojure:latest - I have cider-nrepl 0.8.2 as a dependency in my project and in my ~/.lein/profiles.clj (so, one on each side of the host/container divide)

10:48 tephra: SagiCZ1: unfortunetly we don't have any comp sci masters

10:48 :(

10:48 hlprmnky: both are running Leiningen 2.5.0, on Java 1.7.0 (the minor versions of the JDK do differ)

10:48 SagiCZ1: what about cybernetics?

10:48 hlprmnky: and when I try to connect, I get this:

10:49 Connecting to nREPL at 127.0.0.1:12345

10:49 SocketException The transport's socket appears to have lost its connection to the nREPL server clojure.tools.nrepl.transport/bencode/fn--7462/fn--7463 (transport.clj:95)

10:49 I do know that the REPL session is listening on 12345, and that the port is forwarded to the host (verified with 'docker port')

10:50 tephra: SagiCZ1: no sorry, the master is in computer and system science but no programming. security, data mining and bussiness inteligence

10:50 hlprmnky: The last time I ran into an issue in bencode it was because I had leiningen 1.x on one side and 2.x on the other, but that's not the case here

10:50 SagiCZ1: i see

10:50 hlprmnky: google hasn't been super illuminating, I'm hoping someone else here has been in a similar situation and fixed it. :)

10:50 tephra: SagiCZ1: I'm thinking of getting my master from Uppsala since they actually do computer science. Just have my bachelor thesis left :)

10:57 SagiCZ1: tephra: me too, good luck!

10:59 tephra: SagiCZ1: same! where do you study?

11:02 SagiCZ1: in Prague

11:29 how can i get and remove random element from a vector?

11:30 ,(remove #{3} [1 2 3 3 4 5])

11:30 clojurebot: (1 2 4 5)

11:30 SagiCZ1: i need to remove only one.. not all the duplicates

11:31 i will probably have to work with indexes

11:32 AimHere: Well stepping through the collection with loop/recur is an option here

11:32 andyf: SagiCZ1: Do you plan to eventually remove all elements from the vector? If so, you could shuffle it, then pop one element at a time from the end

11:32 masnun: ,(set [1 2 3 3 4 5])

11:32 clojurebot: #{1 4 3 2 5}

11:33 andyf: efficiently

11:33 SagiCZ1: andyf: its complicated.. i need to go through the collection one element at a time and decide if i want to keep it or not

11:33 AimHere: ,(set [1 2 3 3 3 3 4 5

11:33 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:34 AimHere: ,(set [1 2 3 3 3 3 4 5])

11:34 clojurebot: #{1 4 3 2 5}

11:34 andyf: You can either use the built-in vectors, and then removing an element takes linear time, or use core.rrb-vector, where removing an element can be done in log n time.

11:34 hellofunk: SagiCZ1: really depends if you are removing from a specific location (index) in the collection or if you are removing based on a predicate

11:35 SagiCZ1: i dont know how to explain it

11:36 hellofunk: SagiCZ1: well, index vs. predicate should be a simple decision

11:36 SagiCZ1: i just need to go through all of the element.. i dont care about order

11:37 hellofunk: sounds like you are removing based on a predicate

11:37 unless it truly is random

11:37 SagiCZ1: it doesnt have to be random

11:37 AimHere: So each time you pick an element you reduce the number by one? Couldn't you have a map of value counts using frequencies, and just decrease the value of that map by one each time that predicate comes up?

11:38 andyf: Here is one way to remove an element at a specified index from a vector, returning a vector, taking linear time: (defn remove-elem-i [v i] (vec (concat (subvec v 0 i) (subvec v (inc i)))))

11:38 AimHere: Then rebuild the collection with some sort of homegrown invert-frequencies function

11:38 SagiCZ1: AimHere: no, sometimes i decide not to remove the element so the count stays the same, then i need to move on the next element.. as if increasing index by one

11:39 AimHere: What's the main goal here? It sounds like there might be an x-y problem going on

11:39 SagiCZ1: i am implementing iterative optimization described here http://www.cs.cmu.edu/afs/cs/project/jair/pub/volume4/fisher96a-html/node8.html#SECTION00032000000000000000

11:40 i have a collection of n clusters consisting of some number of points.. i need to go through all the points and try to re-assign them to a different cluster if it would improve the overall cluster fitness

11:45 AimHere: My first instinct for something like that would be to use reduce or loop to go through the cluster and rebuild the original cluster without the reassigned ones

11:46 SagiCZ1: i will try some loop magic thanks for ideas

12:10 hellofunk: can unquote-splice be used outside the context of a macro or eval?

12:10 justin_smith: absolutely

12:10 hellofunk: i.e. this works: (eval `(~@(list + 1 2 3))) but this does not: (+ `(~@(list 1 2 3)))

12:11 justin_smith: hellofunk: you just have to use it in a way that makes syntactic sense

12:11 hellofunk: well (+ 1 2 3) is valid syntax, so why doesn't (+ `(~@(list 1 2 3))) do as i'd expect?

12:12 justin_smith: because (+ (1 2 3)) isn't valid

12:12 and that's what you are generating

12:12 hellofunk: ah, i'm getting jumpled in my nesting

12:13 justin_smith: ,(apply + `[1 2 3 ~@[4 5 6]])

12:13 clojurebot: 21

12:13 justin_smith: note how the inner coll is spliced into the one above it

12:13 hellofunk: justin_smith: i can't use apply since i'm actually trying this on ->

12:13 justin_smith: OK

12:14 outside of eval / macros ~@ can only generate a list

12:14 hellofunk: i was thinking i'd could splice into the parent form

12:14 justin_smith: right, yeah, outside a macro that's not really going to work

12:19 arrdem: where is there a good writeup on nREPL middlewares?

12:26 hellofunk: justin_smith: i guess the issue is that backquote must always be followed by a paren, you cannot use ~@ with a ` alone

12:26 SagiCZ1: andyf: thank you for that element removing function, i build the algo around that, its nasty but pretty short and works, thanks

12:26 (inc andyf)

12:26 lazybot: ⇒ 16

12:31 justin_smith: hellofunk: well, paren or some other nesting pair (my example used [])

12:32 &`[1 2 ~@{:a 0 :b 1}]

12:32 lazybot: ⇒ [1 2 [:b 1] [:a 0]]

12:33 justin_smith: &`["test" ~@#{1 2 3}]

12:33 lazybot: ⇒ ["test" 1 3 2]

12:38 AdmiralBumbleBee: a note, O'rielly is offering a free ebook, one of the choices is 'Clojure Cookbook'

12:38 http://post.oreilly.com/rd/9z1zsko8rq94drpmmfel8vj0u6drolp2ihbcme9uljg is the link

12:38 maxigas: rly?

12:38 wow cool

12:38 AdmiralBumbleBee: yes

12:39 java performance, the definitive guide is an option too

12:39 which is an excellent book that's helped my clojure programming a lot.

12:40 maxigas: heh i tried to register and got this

12:40 Error: time_in_future.

12:40 AdmiralBumbleBee: yeah, it appears to be having issues at the moment

12:40 justin_smith: yeah, I got that error when I logged in

12:40 AdmiralBumbleBee: just refresh

12:40 it works eventually

12:42 maxigas: AdmiralBumbleBee: true

12:42 but

12:42 AdmiralBumbleBee

12:42 http://libgen.org/book/index.php?md5=3f6bc98349b3d776640ba6215fc8d9d8

12:42 ^^^ clojure cookbook is already liberated by pirates

12:43 * AdmiralBumbleBee rolls eyes

12:43 maxigas: :P

12:45 kl: how does racket compare to clojure?

12:46 justin_smith: it uses it's own vm - uses less memory, not as fast, is able to tree-shake for generating smaller executables

12:46 has less default usage of immutable / persistent datatypes (though it does have them if you look for them)

12:47 also, racket is part of a system designed for teaching programming

12:47 while clojure is more pragmatic, industry oriented (relatively speaking)

12:50 library interop w/ clojure is via the jvm, and is totally transperent (there is no translation / compatibility layer needed), library interop in racket will be with C libs, and requires ffi wrappers

13:16 hellofunk: here's a weird one ##`{:a 0 ~@[:b 1] ~@[:c 2 :d 3]}

13:16 lazybot: ⇒ {:c 2, :b 1, :d 3, :a 0}

13:16 justin_smith: hellofunk: to see why it is weird, try taking one of those splices out

13:46 SagiCZ1: how do i split coll into n equal parts?

13:46 arrdem: partition

13:46 $grim clojure.core/partition

13:46 lazybot: http://grimoire.arrdem.com/1.6.0/clojure.core/partition

13:46 SagiCZ1: thats splitting it into m n-sized parts

13:48 arrdem: #(partition (/ (count %2) %1) %2), use a real function if you want to assert that %2 divides (count %1) exactly.

13:48 SagiCZ1: arrdem: thanks

13:50 maxigas: hmmm Continuous Enterprise Development in Java is not on libgen

13:50 SagiCZ1: ,(#(partition (/ (count %2) %1) %2) 3 (range 10))

13:51 clojurebot: ()

13:57 arrdem: ##(count (range 10))

13:57 lazybot: ⇒ 10

13:58 SagiCZ1: ,(#(partition (/ (count %2) %1) %2) 3 (range 12))

13:58 clojurebot: ((0 1 2 3) (4 5 6 7) (8 9 10 11))

13:58 SagiCZ1: ,(#(partition-all (/ (count %2) %1) %2) 3 (range 10))

13:58 clojurebot: ((0 1 2 3) (4 5 6 7) (8 9))

14:00 sveri: Hi, is there a way to evaluate every function of a namespace in cursive when it is connected to a repl? All I found is how to load the complete file and then evaluate every form separately

14:03 Hm, I just saw that load file does that, seems like I have a different error in my workflow, nevermind

14:12 hellofunk: ##`{:a 0 ~@[:b 1] ~@[:c 2 :d 3]}

14:13 lazybot: ⇒ {:c 2, :b 1, :d 3, :a 0}

14:13 hellofunk: man how many of these bots do we have for syntax eval.

14:13 ##`{:a 0 ~@[:b 1]}

14:13 andyf: ,(count (available bots))

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

14:14 hellofunk: justin_smith: so the core clojure reader for syntax takes precedence over the reader macros for syntax quote and unsplicing

14:14 andyf: syntax quote is part of the Clojure reader

14:15 hellofunk: andyf: indeed but the map form is read as having too few args before the splicing of the reader has a chance to do its thing... even though the backquote is actually read before the map

14:16 justin_smith: so i concur with you, that is indeed weird

14:17 does anyone regularly run emacs and cider on a running web app on a remote server via ssh?

14:27 maxigas: http://libgen.org/book/index.php?md5=e2d9cadb117ce286f7dae2667158ba84

14:27 ^^^ Continuous Enterprise Development in Java: Testable Solutions with Arquillian

14:34 Hamled: Can someone explain to me why

14:34 andyf: maxigas: Is this relevant to a discussion, or you like to post links to books that have been pirated?

14:34 Hamled: ##(= (short-array [1]) (short-array [1]))

14:34 lazybot: ⇒ false

14:35 augustl: Hamled: see: Java :)

14:35 andyf: Yeah, for the same reason that .equals returns false for those two things in Java

14:35 Hamled: okay

14:36 hmm

14:36 andyf: Clojure's = is true if two immutable values are equal, or if they are not immutable, then if Java .equals is true for them. There may be a few exceptions to that statement, but I think not many.

14:37 maxigas: andyf: sorry it was quite offtopic, now that you made me think about it

14:39 andyf: Java docs for equals method says "The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object"

14:39 Other classes can override that default, but perhaps Java arrays do not.

14:41 Hmm. The docs for the Java Arrays class says that two short arrays are .equals if they are the same length and have equal elements, so now I don't know why you got false ...

14:43 justin_smith: hellofunk: I avoid lein in production, not to mention cider / emacs

14:43 andyf: ah, (java.util.Arrays/equals ...) would return true, but that is a static method in class java.util.Arrays, not the one that you get from doing regular .equals method

15:05 Frozenlock: hellofunk: I do. (cider, emacs, running app, ssh.... )

15:08 kl: justin_smith: thanks for that response re: clojure vs racket there earlier

15:09 Hmm. I can't help but feel I'd absolutely love clojure if it was statically typed.

15:10 kenrestivo: *cough* core.typed *cough*

15:11 kl: kenrestivo: I've not *seriously* looked at it - but is it not a hack, or somehow otherwise badly implemented / ill-advised?

15:12 dnolen_: kl: it's based on Typed Racket research

15:12 kl: That *is* interesting

15:14 profil: thearthur: but it says, "Returns the value that was swapped in.". Shouldnt that mean ":a 1"?

15:14 thearthur: re swap!

15:23 dnolen_: kl: The biggest difference between Clojure & Racket is that Clojure is a production oriented language that targets the JVM & JavaScript and goes out it's way to work well on those hosts, with host libraries, and with host tooling. If these platforms matter to you & you like Lisp then the other factors are considerably less important.

16:08 augustl: anyone using something other than compojure to path match for liberator?

16:08 I fancy myself a path matcher that isn't a list essentially a list of regexps :)

16:13 heeton: Having trouble doing this idiomatically. How do I update values inside a tree? https://gist.github.com/heeton/aafd06e63bfb847f57f6

16:13 I've tried to dig into zippers but am finding them a bit opaque :)

16:17 augustl: heeton: generally I prefer to not store tree structures as deep data structures matching the tree structure, but store by reference instead. I.e. something like {1 {:type "foo" :children [2 3]} 2 {:type "foo"} 3 {:type "foo" :children [4]} 4 {:type "bar"}}

16:17 mearnsh: need a pointer getting this macro to expand recursively (see the last cond case). L11 shows the behaviour i'm looking for: https://www.refheap.com/95469

16:17 augustl: heeton: I like my trees shallow :)

16:19 heeton: augustl: not sure how I could simplify my structure unfortunately, any suggestions?

16:19 (Massive noob here btw)

16:19 (And probably still too stuck in OO mode)

16:20 augustl: heeton: maybe something like {1 {:type "plots" :children [2 3]} 2 {:type "wat" :contains nil} 3 {:type "wat" :contains nil}}

16:20 the downside is of course that invalid states are representable

16:21 TEttinger: :pre conditions may be handy

16:21 augustl: heeton: or if your tree doesn't need to be ordered you can store it as {:plots {1 {:contains nil} 2 {:contains nil}}} and run update-in

16:21 and assoc-in

16:22 heeton: The plots are ordered

16:22 TEttinger: ordered maps may come in handy, there's that lib called ordered

16:22 $google ordered clojure

16:22 lazybot: [flatland · GitHub] https://github.com/flatland

16:22 heeton: TEttinger: thanks, will have a look

16:23 TEttinger: https://github.com/flatland/ordered/tree/develop

16:24 mearnsh: hm, i realize i can just call macroexpand inside my macro

16:24 TEttinger: mearnsh, sounds like wizardry

16:24 heeton: Hypothetically, if I were to reference plots (using a let block or something) and then use update-in on it, will that affect the atom? Or am I creating a copy of the variable or something? (Apologies if naming is slightly wrong)

16:24 TEttinger: update-in returns a new coll

16:24 mearnsh: TEttinger: cf these: https://www.refheap.com/95469 https://www.refheap.com/95470

16:24 TEttinger: to update an atom, you use swap! or reset!

16:25 (doc swap!)

16:25 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

16:25 TEttinger: (doc reset!)

16:25 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

16:25 augustl: heeton: well at any point if you read from the index and then tell the atom to write to that index, you're unsafe since the atom might have changed in the meantime

16:25 heeton: TEttinger: that'll set the value of the overall atom though right? I'm wondering if I can access nodes inside it in the same way

16:25 augustl: s/read from the index/read an index/

16:26 for advanced stuff I would have considered just having some kind of atomic ref and writing my own code that maybe used an executor..

16:26 TEttinger: you may want refs if you want to be sure about multiple transactions overlapping

16:26 heeton: Hmm, so I'm really confused then. What's the recommended way of getting to my goal? I've got my application state which has a few pieces of data, one of which is a list of plots. I'd like to update those.

16:27 I might just bring plots out to be it's own atom

16:27 TEttinger: plots as in graves or plots as in graphing calculator stuff?

16:27 or action movie "plots"

16:28 heeton: Haha, let's assume graves here :)

16:28 Actually for keeping track of plants

16:28 So a plot is a map that has some keys like "planted-at" "contains" etc.

16:29 TEttinger: ,(let [state (atom {:plots [[1 2][1 5]]})] (update-in @state [:plots 0 1] inc))

16:29 clojurebot: {:plots [[1 3] [1 5]]}

16:29 TEttinger: ,(let [state (atom {:plots [[1 2][1 5]]})] (do (update-in @state [:plots 0 1] inc) @state))

16:29 clojurebot: {:plots [[1 2] [1 5]]}

16:30 TEttinger: as you can see, it doesn't change after just calling update-in, but...

16:30 ,(let [state (atom {:plots [[1 2][1 5]]})] (swap! state update-in [:plots 0 1] inc))

16:30 clojurebot: {:plots [[1 3] [1 5]]}

16:30 TEttinger: ,(let [state (atom {:plots [[1 2][1 5]]})] (do (swap! state update-in [:plots 0 1] inc) @state))

16:30 clojurebot: {:plots [[1 3] [1 5]]}

16:31 TEttinger: swap! will change the value of the atom at later reads

16:31 heeton: Ok, thanks, will crack on with it :)

16:31 TEttinger: but most of clojure's collection fns will return new collections (with shared state for efficiency)

16:32 mearnsh: ok, i solved my problem - my code was right, just forgot about macroexpand-all

16:32 TEttinger: oh, and if you want to add something, you can do something like

16:33 ,(let [state (atom {:plots [[1 2][1 5]]})] (do (swap! state update-in [:plots 2] (constantly [3 4])) @state))

16:33 clojurebot: {:plots [[1 2] [1 5] [3 4]]}

16:33 TEttinger: ,(let [state (atom {:plots [[1 2][1 5]]})] (do (swap! state update-in [:plots 3] (constantly [3 4])) @state)) ;; I can't remember if this works, indexes that are larger than the size

16:33 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

16:49 dnolen_: is it possible to set the plugins classpath for leiningen?

16:49 curious about running AOTed plugins

16:50 update my exploration on making cljsbuild run faster http://swannodette.github.io/2014/12/22/waitin/

16:50 basically you can make cljsbuild start 5X faster w/ all my tweaks

16:50 so 1 second to run (and do everything) instead of 5.5 seconds

17:00 hellofunk: cool stuff. i've never been sensitive to a few extra seconds that others complain about with clj and now you say cljs, but dramatic engineering is still captivating to ponder

17:10 justin_smith: Bronsa: maybe you can provide some more insight to this SO question about a failed type annotation? It clearly has something to do with the destructuring, but it would be cool to know more of the details of why that failure happens. http://stackoverflow.com/questions/27671638/why-is-this-type-annotation-failing

17:12 augustl: that structure is known as an adjacency list representation by the way, and it is great because it bridges the gap between cyclical data structures and immutable data, without any laziness hacks

17:13 Bronsa: justin_smith: I don't have a SO account but ^double is an array type hint, [4 5 6] is not an array

17:13 justin_smith: invoking it as (dot3 (double-array [4 5 6]) (double-array [1 2 3])) would do what he expects

17:14 dnolen_: hellofunk: the startup time is fine for REPL based stuff, it's serious bummer for tooling - things you run at the command line

17:15 Bronsa: justin_smith: uhm no, nevermind. let me read that better

17:15 justin_smith: Bronsa: actually it doesn't

17:15 I tried that first :)

17:15 hellofunk: dnolen_: is the performance boost to lein cljsbuild auto for speeding up each automatic compilation? So if it took 1 sec before when you save a file, now it takes much less?

17:16 justin_smith: I think it is some compiler optimization that kicks in (the IFN$OOD inner class) but the destructuring makes it compile in a faulty way?

17:16 Bronsa: justin_smith: I can't reproduce on my repl?

17:16 dnolen_: hellofunk: this is about speeding up incremental compilation, that's already fast

17:16 hellofunk: it's been fast forever

17:16 justin_smith: Bronsa: with warn-on-reflection and hotspot both enabled?

17:16 dnolen_: hellofunk: "this is NOT about speeding up incremental compilation"

17:17 Bronsa: justin_smith: ah.

17:17 justin_smith: it's a bug I fixed that's committed in 1.7 I believe

17:17 justin_smith: Bronsa: https://www.refheap.com/95471

17:17 Bronsa: justin_smith: https://github.com/clojure/clojure/commit/85169b785c5dd59e89c0bd12600eebe5f6172874

17:17 justin_smith: aha, cool

17:17 Bronsa: that would explain why in my repl it works fine

17:18 justin_smith: http://dev.clojure.org/jira/browse/CLJ-887 yup the error seems the same

17:19 justin_smith: very nice to have a decent explanation, thanks

17:19 (inc Bronsa)

17:19 lazybot: ⇒ 81

17:20 justin_smith: that is way too low

17:20 (inc Bronsa)

17:20 lazybot: ⇒ 82

17:23 Bronsa: i wounder how hard it would be to make c.c/destructure understand array type hints

17:23 wonder*

17:23 probably not that hard

17:23 justin_smith: that would be nice

17:36 SagiCZ1: how do i make an inverse matrix and matrix determinant in incanter?

17:37 or should i use clojure.core.matrx?

17:43 oh i guess inverse is called solve in incanter.. so silly

18:05 gfredericks: having a hard time not getting this error when switching to java 8; look familiar?

18:05 Unable to resolve classname: ..proxy$java.lang.Object$SignalHandler$d8c00ec7

18:06 Bronsa: gfredericks: no idea but try applying http://dev.clojure.org/jira/browse/CLJ-979

18:06 justin_smith: gfredericks: I have never seen that

18:07 gfredericks: I wonder if this is a problem with namespaces named .

18:09 justin_smith: gfredericks: I was always surprised that a namespace named . would even work

18:09 gfredericks: turning off my user profile made it work so that might've been it

18:09 the "..proxy" part made me wonder

18:18 TEttinger: oh my god do I need to make another gfredericks meme

18:18 augustl: trying out bidi for the first time. Why does (match-route ["/foo/bar" :bar "/" :root] "/foo/bar") return {:handler :bar} and (match-route ["/" :root "/foo/bar" :bar ] "/foo/bar") nil? I expected both to return {:handler ;bar}

18:22 Figured it out. Seems the vector should only have two items in it.

18:24 justin_smith: yeah, it looks like for multiple routes you want a vector with parent on the left, and a tree (map) of all child routes on the right

18:27 dnolen_: cfleming: fwiw, just encountered the issue again with cljs/closure.clj, all core symbol cannot be resolved

18:33 TEttinger: gfredericks: justin_smith: https://dl.dropboxusercontent.com/u/11914692/gfredericks.png was the first, now there's https://dl.dropboxusercontent.com/u/11914692/gfredericks_on_namespaces.png

18:33 Kristien: lol

18:34 justin_smith: (inc TEttinger)

18:34 lazybot: ⇒ 34

18:34 TEttinger: gfredericks is like the corner case detective

18:35 if there is a minute crack in the facade that is reliable software behavior, gfredericks will apply a liberal dose of plastic explosive

18:37 Bronsa: (inc TEttinger)

18:37 lazybot: ⇒ 35

18:40 akkad: thank you all for making this language soo welcoming

18:40 Hamled: Is there something about the way I've written this test that would cause it to pass even though its condition definitely fails (I can see that when I evaluate it directly) http://hastebin.com/fumiwavixo.clj

18:40 justin_smith: Hamled: you don't call is

18:40 only test/is can cause failures

18:41 Hamled: oh lol of course )

18:41 thanks

18:41 TEttinger: akkad, glad the community is welcoming! so, you're welcome!

18:41 justin_smith: very common mistake, there is a lein plugin called eastwood that will tell you when you have problems like that

18:41 akkad: compared to years of #lisp yes. :P

18:41 TEttinger: heh

18:41 who makes eastwood again?

18:41 Hamled: justin_smith, ah cool I think I saw eastwood before but wasn't sure what it was for

18:41 augustl: akkad: just making up for the bad error messages, that's all

18:42 Bronsa: (inc andyf) ;; TEttinger

18:42 lazybot: ⇒ 17

18:42 justin_smith: "you're more welcoming than #lisp" is kind of like "it tastes better than earwax"

18:43 TEttinger: (inc justin_smith)

18:43 lazybot: ⇒ 163

18:43 Hamled: oh lol I have eastwood in my plugin list I just never thought to use it :D

18:43 TEttinger: damn your karma has gotten significant

18:49 justin_smith: somehow it has. most of the people I end up helping don't even know how karma works

18:51 cfleming: dnolen_: Ok. Closing and reopening the file doesn't work, right? Are other symbols from other files resolved correctly?

18:51 dnolen_: cfleming: yes they are

18:52 cfleming: and no closing/reopening doesn't work

18:52 cfleming: dnolen_: Well that's really weird. Next time it happens can you send a screenshot, and I'll see if I can see anything unusual?

18:52 dnolen_: cfleming: sure thing

18:53 augustl: liberator is such awesome, wow

18:55 SagiCZ1: justin_smith: how does karma work? i started to feel stupid inc'ing everyone who helped, so i rarely do it now which makes me feel a little bad.. like not apprecienting the help enough

18:58 justin_smith: SagiCZ1: it's totally informal

18:59 nothing to feel bad about, or to gloat about

18:59 SagiCZ1: so its just a little fun thing...

18:59 justin_smith: SagiCZ1: meant it as in they don't even use the karma commands

18:59 yeah

19:00 SagiCZ1: oh so otherwise there is something like karma on IRC? maybe thats why it doesnt confuse me

19:01 i started with IRC only because of #clojure

19:01 justin_smith: it's a convention, various channels have bots that keep track of informal karma

19:01 usually via nick++

19:02 SagiCZ1: i see

21:00 thearthur: ,(let [a (atom 0)] (swap! a inc))

21:00 clojurebot: 1

21:01 thearthur: profil: yes you are right the atom it's self is not returned by swap. Could you link ot the context where it was seeming to do so

21:20 gfredericks: justin_smith: my java 8 . problem was apparently caused by putting (ns .) in my [:repl-options :init]

21:20 swapping it out for (create-ns '.) fixes it

21:21 (YOLO)

21:21 justin_smith: haha

21:48 gfredericks: ,(try (re-pattern "\\R") :java-8 (catch Exception e :java-7))

21:48 clojurebot: gfredericks: No entiendo

21:48 gfredericks: &(try (re-pattern "\\R") :java-8 (catch Exception e :java-7))

21:48 lazybot: java.lang.SecurityException: You tripped the alarm! catch is bad!

21:48 gfredericks: ,(re-pattern "\\R")

21:48 clojurebot: #"\R"

21:48 gfredericks: &(re-pattern "\\R")

21:48 lazybot: java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 1

22:13 richardlevan: Hey guys, I’m trying to learn core.async. In a tutorial, I can do the following in a let statement:

22:13 (let [c (chan)]

22:13 (go (>! c "hello"))

22:13 (assert (= "hello" (<!! (go (<! c)))))

22:13 (close! c))

22:13 But if I say (def c (chan)) then (go (>! c “hello”)) it fails. Can someone explain why?

22:15 nuwanda_: what do you mean by fails?

22:15 richardlevan: I get a big stack trace as a result

22:16 I have [org.clojars.trptcolin/core.async "0.1.242.1"] in :dependencies in my project.clj, and I used (require '[clojure.core.async :as async :refer :all]) to get core.async

22:19 Hm, seems pretty quiet here. Anyone know where else I could get help?

22:23 Hey I don’t use IRC often. Am I doing this right? Why are people joining and leaving but no one is speaking?

22:24 andyf: Sometimes people leave automatically because their computer shuts down, or their network connection gets disconnected. They aren't necessarily doing anything manually for it to happen. Same for joining -- for some people it happens automatically when their network connection is restored.

22:24 richardlevan: oh ok thanks

22:24 andyf: Not everyone joined to the room is paying attention right now. Most probably are not.

22:25 richardlevan: Do you know a place where I’d be more likely to get help for my question?

22:25 andyf: Here, next week :)

22:25 richardlevan: haha, yeah I guess Saturday night is a bad time :P

22:25 andyf: Well, Saturday night not always so much like this -- but this is the week between Christmas and New Year's, so lots of people are on unusual schedules and doing other things.

22:26 richardlevan: Ah yeah that makes sense too. Cool, I’ll come back here again in the future

22:26 andyf: You could send a message to the Clojure Google group, or if there is one specifically for core.async, there.

22:27 You are more likely to get help if you include as many details about what you are doing, and error messages you are seeing, as you can.

22:27 richardlevan: Ok nice, thanks for the tips

22:27 andyf: and also if you can break it down to a minimal case that gives the same error.

22:31 ToxicFrog: richardlevan: for future reference, don't just say "I get a stack trace". Pastebin the whole stack trace somewhere and link it, and possibly mention what the exception that caused it is named.

22:32 richardlevan: in my case, both of those examples work fine, as long as I type the second one in from scratch.

22:32 richardlevan: if I copy-paste it, it fails because you use “hello” instead of "hello".

22:36 richardlevan: ToxicFrong: Thanks. I was about to put it in pastebin, but it turns out it was a silly mistake, looking further. I wrote (def c chan) instead of (def c (chan))

23:13 Hamled: Could someone explain why I get a "static field not found" exception when I do (map some.java.Class/staticFunc coll) but (map #(some.java.Class/staticFunc %) coll) works?

23:14 justin_smith: Hamled: methods are not first class

23:15 Hamled: Clojure could have decided to fake it, but instead it reflects the jvm's implementation

23:16 Hamled: ah, seems understandable. Is there some kind of java construct that would work in that scenario, or is the "static field not found" exception just the result of the implementation of map

23:16 like, the exeption seems to imply to me that something perhaps other than a static method would be found if I tried to use that instead? I have no idea what that thing would be, though

23:17 justin_smith: Hamled: I think a java object that was callable / invokable might work as the first arg to map? not certain of that though

23:17 Hamled: ah

23:17 a functor or something

23:17 justin_smith: methods are only usable within forms where they can be resolved to their object

23:18 not just a functor, an fn is an object that is callable / invocable for example

23:18 Hamled: oh

23:18 I suppose that makes sense, where else would you put it

23:19 justin_smith: right, to refer to a thing in java, you need its object - technically we could have done somthing funky with static methods and their class

23:19 Hamled: I don't understand what you mean by "where they can be resolved to their object" -- wouldn't that not apply for a static method?

23:19 oh okay

23:19 justin_smith: right, that's what I was getting at with "technically..."

23:19 Hamled: so the choice was not to special case static methods

23:19 justin_smith: that's my impression, yes

23:19 Hamled: cool, thanks :)

23:20 justin_smith: in general there is a priority in clojure for keeping designs simple

23:20 michaniskin: how would one debug why it takes a really long time to AOT compile certain namespaces?

23:20 justin_smith: michaniskin: are you creating something stateful like a server thread at the top level? that's a common issue

23:21 michaniskin: also, jstack will tell you exactly what each of your threads is doing, and you could run it during compilation

23:21 michaniskin: justin_smith: i'm pretty sure i'm not

23:21 justin_smith: OK

23:21 michaniskin: aha, that sounds like what i need, thanks!

23:21 justin_smith: try jstack and/or jvisualvm, yourkit, any of those can tell you where CPU is being burnt / what a thread is waiting on, etc.

23:22 michaniskin: yeah my cpu is not being utilized at all during the long wait

23:22 it seems like a TCP timeout or something crazy

23:23 justin_smith: michaniskin: creating a URL object? those are resolved when created (which is weird and leads to weird bugs)

23:23 michaniskin: justin_smith: whoa, i did not know that, but it makes sense

23:23 well sort of makes sense, maybe

23:23 justin_smith: it actually makes very little sense that just creating a java.net.URL would do a host lookup, but it does :)

23:25 michaniskin: yeah seems like something that could also be exploited somehow

23:38 andyf: michaniskin: If the wait is about 60 seconds, it could be a side effect of creating a future, or a call to pmap or clojure.java.shell/sh. See http://clojuredocs.org/clojure.core/future

23:42 michaniskin: i think it's repl related, this namespace takes a really long time to compile, and it's like 10 lines of code: https://gist.github.com/df72b821f4347ae9aab1

23:43 justin_smith: michaniskin: yeah, if that's it, I don't see why that would take so long to load, unless reply was doing something weird

23:43 nothing stateful is being created at the top level, clearly

23:45 woah, reply monkeypatches clojure.core

23:45 lol

23:45 https://github.com/trptcolin/reply/blob/master/src/clj/reply/hacks/printing.clj#L39

23:53 andyf: I think reply might depend upon something that creates a future at the top level, IIRC. We saw something similar with this with Leiningen, which depends on reply.

23:53 Let me see if I can find the issue

23:56 justin_smith: in that case you would want to call shutdown agents when compiling? that's terrible though

Logging service provided by n01se.net