#clojure log - Aug 14 2015

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

1:28 neo`: hello

1:42 justin_smith: hi

2:37 loke: I have a sorted-map that is keyed on a string. Now, I want to modify a small subset of the values based on some criteria, and I will only know which ones by looking at each value in sequence. In other words: I don't know what the keys are until I inspect each value.

2:37 My question is, what is the most efficient way to do this?

2:37 I can see two options: One is to traverse all values, finding the keys and then do a bunch of update-in on those keys

2:38 The other alternative is to effectivelly rebuilding the entire map using a reduction of conj from an empty sorted-map, modifying the elements that needs modifying

2:38 Is there a better solution?

2:42 Olajyd: Hi @justin_smith

2:46 Seylerius: Olajyd: This is IRC, not Twitter. The convention here is "Hi name", or "name: What was the error message?". Just for future reference.

2:47 TEttinger: yeah, it's funny how @Seylerius has become more common that just Seylerius

2:47 well

2:47 more common than before

2:47 loke: thinking about this...

2:48 loke: My current version does (reduce conj (sorted-map) (map [[k v]] {k (maybe-transform v)}))

2:48 Olajyd: Kindly help me fix this code: (defn my-subs [st from end] (let [f (if (neg? from) (+ (count st) from) from)] (subs st f end)) Thing is when I do this (my-subs -14 3) I get a java.lang.stringoutof bounds, thing is I want it to return an empty string ..

2:48 loke: But it ends up rebuilding the entire thing, and then a typical list contains a few thousand entries and only maybe 5 will need to be changed.

2:49 Olajyd: Am sorry I dont know how to post a code block on IRC

2:49 TEttinger: Olajyd:

2:49 ~pastebin

2:49 clojurebot: pastebin how about refheap? https://www.refheap.com/

2:49 loke: Olajyd: You don't. You use a pastebin.

2:50 Olajyd: Thanks loke

2:50 Seylerius noted :)

2:50 amalloy: loke: are you concerned with the overhead of traversing the whole map, or only the overhead of rebuilding it?

2:50 TEttinger: ,(defn my-subs [st from end] (let [f (if (neg? from) (+ (count st) (mod from (count st))) from)] (subs st f end))

2:50 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:51 loke: amalloy: Rebuilding it. I have to traverse it anyway.

2:51 TEttinger: ,(defn my-subs [st from end] (let [f (if (neg? from) (+ (count st) (mod from (count st))) from)] (subs st f end)))

2:51 clojurebot: #'sandbox/my-subs

2:51 TEttinger: ,(my-subs "string" -14 3)

2:51 clojurebot: #error {\n :cause "String index out of range: -7"\n :via\n [{:type java.lang.StringIndexOutOfBoundsException\n :message "String index out of range: -7"\n :at [java.lang.String substring "String.java" 1911]}]\n :trace\n [[java.lang.String substring "String.java" 1911]\n [clojure.core$subs invokeStatic "core.clj" 4784]\n [clojure.core$subs invoke "core.clj" -1]\n [sandbox$my_subs invokeStatic...

2:51 amalloy: loke: so just use the original map as your reduce's initial value, and a function like (fn [m [k v]] (if whatever m (assoc m k (whatever v))))

2:52 loke: amalloy: ooooh. Stupid me

2:52 Thanks

2:53 amalloy: see also reduce-kv, to make this cheaper

2:53 Olajyd: Tettinger the string for example is “clojurestring”

2:56 TEttinger: hm

2:56 Olajyd: use cases (mysubs -14 3) ;=> Error, (my-subs -13 3) ;=> “clo”,

2:56 TEttinger: ,(defn my-subs [st from end] (let [f (if (neg? from) (max (+ (count st) from) 0) from)] (subs st f end))) ;; if you just want to cap negative indices to 0, this works fine.

2:56 clojurebot: #'sandbox/my-subs

2:56 TEttinger: ,(my-subs "clojurestring" -14 3)

2:57 clojurebot: "clo"

2:57 TEttinger: ,(my-subs "clojurestring" -7 3)

2:57 clojurebot: #error {\n :cause "String index out of range: -3"\n :via\n [{:type java.lang.StringIndexOutOfBoundsException\n :message "String index out of range: -3"\n :at [java.lang.String substring "String.java" 1911]}]\n :trace\n [[java.lang.String substring "String.java" 1911]\n [clojure.core$subs invokeStatic "core.clj" 4784]\n [clojure.core$subs invoke "core.clj" -1]\n [sandbox$my_subs invokeStatic...

2:57 TEttinger: hm...

2:58 Olajyd: what I really want is (my-subs -14 3) ;=> “clo” and (my-subs -1 7) ;=> “ ” (my-subs -7 7) ;=> “ “

2:58 TEttinger: ok but you really should supply the string argument that you expect... I don't really know why there is a space there

2:59 Olajyd: sorry just wanted you to knw its an empty string

3:00 TEttinger: ,(my-subs "clojurestring" -7 3)

3:00 clojurebot: #error {\n :cause "String index out of range: -3"\n :via\n [{:type java.lang.StringIndexOutOfBoundsException\n :message "String index out of range: -3"\n :at [java.lang.String substring "String.java" 1911]}]\n :trace\n [[java.lang.String substring "String.java" 1911]\n [clojure.core$subs invokeStatic "core.clj" 4784]\n [clojure.core$subs invoke "core.clj" -1]\n [sandbox$my_subs invokeStatic...

3:00 TEttinger: sorry

3:01 ,(my-subs "clojurestring" -7 3)

3:01 clojurebot: #error {\n :cause "String index out of range: -3"\n :via\n [{:type java.lang.StringIndexOutOfBoundsException\n :message "String index out of range: -3"\n :at [java.lang.String substring "String.java" 1911]}]\n :trace\n [[java.lang.String substring "String.java" 1911]\n [clojure.core$subs invokeStatic "core.clj" 4784]\n [clojure.core$subs invoke "core.clj" -1]\n [sandbox$my_subs invokeStatic...

3:03 Olajyd: TEttinger (my-subs “clojurestring” -7 3) ;=> should return an empty string

3:03 TEttinger: ah, it's doing this in my code:

3:03 ,(subs "clojurestring" 6 3)

3:03 clojurebot: #error {\n :cause "String index out of range: -3"\n :via\n [{:type java.lang.StringIndexOutOfBoundsException\n :message "String index out of range: -3"\n :at [java.lang.String substring "String.java" 1911]}]\n :trace\n [[java.lang.String substring "String.java" 1911]\n [clojure.core$subs invokeStatic "core.clj" 4784]\n [clojure.core$subs invoke "core.clj" -1]\n [sandbox$eval236 invokeStatic...

3:03 TEttinger: subs may be the wrong thing to use here, oddly

3:04 ,(subs "clojurestring" 6 9)

3:04 clojurebot: "est"

3:04 Olajyd: TEttinger, How the problem is to try and replicate the way python handles substrings

3:04 sorry wanted typing *however*

3:05 TEttinger: so it looks like you need to validate or possibly swap the order of from and end. since subs needs end to be greater than or equal to from

3:05 Olajyd: Teetinger, exactly

3:05 TEttinger: ,(mod -14 7)

3:05 clojurebot: 0

3:05 TEttinger: ,(mod -14 5)

3:05 clojurebot: 1

3:05 TEttinger: hm

3:05 ,(rem -14 5)

3:05 clojurebot: -4

3:06 TEttinger: do you want large negative numbers to loop around from the end of the string more than once?

3:07 Olajyd: if its possible..

3:07 TEttinger: like for the string "don", position 0 is d, position -3 is d, position -6 could be d

3:08 Olajyd: nope position -6 should be equal to 0

3:08 TEttinger: yeah, in don 0 is d

3:09 Olajyd: basically large negative values should start from 0 index

3:10 TEttinger: oh so a clamp?

3:10 so -3 -4 -5 for a length 3 string are all the same?

3:11 Olajyd: TEttiner yes, so when used in the subs, as the starting position it’ll start from 0

3:12 TEttinger: ,(defn my-subs [st from end] (let [f (if (neg? from) (max (+ (count st) from) 0) from) ] (if (<= f end) (subs st f end) "")))

3:12 clojurebot: #'sandbox/my-subs

3:12 TEttinger: ,(my-subs "clojurestring" -14 3)

3:12 clojurebot: "clo"

3:12 TEttinger: ,(my-subs "clojurestring" -11 3)

3:12 clojurebot: "o"

3:13 TEttinger: that look right?

3:13 ,(my-subs "clojurestring" -7 3)

3:13 clojurebot: ""

3:13 Olajyd: sure

3:13 exactly

3:14 TEttinger, please can you take a min to put me through

3:16 TEttinger: oh uh sure

3:17 Olajyd: TEttinger, thanks I really appreciate the help

3:18 TEttinger: (if (neg? from) (max (+ (count st) from) 0) from) ;; so this does mostly what your code did. it just makes sure that it uses the higher number of 0, or the count of the string plus the negative offset. so if it would go negative, 0 is higher than that, so it uses 0.

3:18 Olajyd: TEttinger, I got lost in trying to implement it

3:18 when I was doing it on my own

3:18 TEttinger: (if (<= f end) (subs st f end) "") ;; this is pretty simple and it turns out being the only real missing thing in yours

3:19 it just makes sure that f is less than or equal to end, if it is it gets the substring, if not, returns empty string

3:19 Olajyd: Thanks, I owe you a drink :)

3:19 TEttinger: heh thanks

3:20 if there's anything that I can improve about it to make it more compatible with python-like strings, let me know

3:21 Olajyd: IRC has helped me alot, thanks to TEttiner, justin_smith and oddcully

3:23 TEttinger, is there anyway to find out if you or someone else is online

3:26 jeaye: Olajyd: /whois

3:26 TEttinger: Olajyd: yeah, there's usually a list of people in a channel in most IRC clients. you can also (in almost all clients) use the command /whois TEttinger

3:26 like if I type: /whois Olajyd

3:27 I think he tried "/quit"

3:27 jeaye: haha

3:29 TEttinger: apparently his IP is in Nigeria, which brings the number of countries in Africa with Clojure users to at least 2. Hooray global userbase!

4:54 tgoossens: If a java class uses this (gen-class) file: https://gist.github.com/tgoossens/81915c9d3b47acb677dd. Will parser be slurped everytime I use the static function -run or only once?

5:17 TEttinger: tgoossens: a def is executed once, usually. you may want defonce if you specifically want the file slurped only once, even if the file is required more than once

5:18 I don't really know what circumstances that code gets called when gen-class is involved though

5:19 I would have expected gen-class would only export methods, but now that I think about it... those very often would need defs, and those defs may not be constant, so it must run some code to handle the toplevel def calls

5:20 I really don't know how it works interacting with java. I'd definitely make it defonce if you don't want slurp frenzy potentially

5:20 it shouldn't run every time you call -run though

9:26 jeaye: What's the idiomatic way to run a function over each element of a sequence which matches a predicate?

9:27 Being very new to clojure, I found myself in a doseq and trying to use a continue statement, but that's clearly not the ideal route.

9:29 snowell: jeaye: filter is your friend

9:29 ,(filter even? [1 2 3 4 5 6])

9:29 clojurebot: (2 4 6)

9:30 snowell: Put your predicate as the first arg, doseq over the result

9:33 jeaye: snowell: Ah, yes.

9:33 Thank you.

9:55 Olajyd: Please how can I handle “*” amd “\” as string in the following (last (clojure.string/split “2001/900*34/68” #”*”)) ;=> “34/68”

9:56 chouser: ,(clojure.string/split “2001/900*34/68” #”\*”))

9:56 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: “2001/900*34/68”>

9:56 snowell: Silly fancy quotes

9:56 ,(clojure.string/split "2001/900*34/68" #"\*")

9:56 clojurebot: ["2001/900" "34/68"]

9:57 snowell: Sorry to steal your thunder, chouser. I had the same answer prepped without the fancy quotes :)

9:57 chouser: :-) no problem!

9:59 snowell: Olajyd: You have to escape the * in your regex like so ^

10:12 Olajyd: snowell the “*” string is it a special character

10:12 snowell: In a regex, yes. And the # before the string signifies that it's a regex

10:15 Olajyd: snowell, the # is same as using re-pattern right?

10:16 snowell: Yup

10:17 Well, # is actually better for hard-coded regex patterns. re-pattern is for when you need it dynamically generated

10:25 Olajyd: snowell, lol I’m lost there?

10:26 snowell: Haha it's OK. They do the same thing :)

10:26 Bronsa: Olajyd: do you understand the difference between [1] and (vector 1)?

10:27 that's the same difference between #"foo" and (re-pattern "foo")

10:27 one is a read-time value, the other is a run-time value

10:33 Olajyd: snowell, Lol I actually want to use it like this: (re-pattern “*”) and I’m getting an error

10:34 Bronsa, gotcha

10:34 So how do I go about it

10:36 pbx: interaction on the big screen!

10:36 Olajyd: This is what i want to do: Given (def delim “/“ ) (last (coljure.string/split “foo/bar” (re-pattern delim))) ;=> “bar”

10:36 pbx: oh nm, wrong channel :\

10:37 Olajyd: Thing is `delim` can change to something like (def delim “*“)

10:39 and thus (last (coljure.string/split “foo-bart*bar” (re-pattern delim))) ;=> Error

10:41 cenzhe: hi all. I have nested calls to pmap, i.e., with (pmap f s), inside the f, it also calls pmap

10:42 Like this, the number of threads gets exploded fairly fast, making the load of the system unmanageable

10:42 Do you guys have any suggestions to improve this?

10:43 Creating a thread pool from which the pmap futures runs? I can only find `send-via` has the option to specify a thread pool

11:32 justin_smith: go answer Olayjyd's question he needs (re-pattern "\\*") because "\*" is an illegal string

11:32 despite #"\*" being a legal regex literal

11:46 sdegutis: How can you get a pseudo-random list with even distribution?

11:47 ,(->> (range) (take 3) (cycle) (take 10) (shuffle)) ;; notice it's disproportionate and not evenly distributed

11:47 clojurebot: [1 2 0 2 0 ...]

11:48 sdegutis: Whoops that's a horrible example.

11:49 In fact, I just realized it not only does not demonstrate my problem, it actually solved it.

11:49 Woot.

11:56 justin_smith: cenzhe: I would make a thread pool executor via interop, and use that along with a queue

11:56 cenzhe: justin_smith: yah, I'm reading code from [this link](https://github.com/TheClimateCorporation/claypoole)

11:57 It takes the same logic as you just said

11:57 justin_smith: oh, cool

11:58 cenzhe: :D My functions can block on IO, making things messier

11:58 I was about to use core.async, utilize the go block, but later found go block stops upon seeing function definition

12:00 sdegutis: I found that accidental solution really funny. So I shared it briefly here. Dead silence. Went to tell my wife about it. Blank stare. WHAT THE HELL IS WRONG WITH EVERYONE.

12:03 gfredericks: hiredman: what does "suffer through everyone's edge cases" mean?

12:04 sdegutis: why wouldn't (repeatedly #(rand-int 3)) do what you wanted?

12:06 sdegutis: gfredericks: It might, let me check. But either way, the code I wrote down to demonstrate my problem doesn't actually demonstrate the problematic behavior, it demonstrates exactly what I was trying to do but didn't realize how to.

12:07 gfredericks: sdegutis: I guess it depends on whether you want the same number of everything or a truly random sample

12:07 sdegutis: gfredericks: Oh I see. The code you posted shows the exact behavior I have now.

12:07 gfredericks: e.g., your code will never generate all 0's

12:07 sdegutis: gfredericks: I want the order to be random but the distribution to be even.

12:07 gfredericks: Right.

12:07 gfredericks: so (repeatedly #(rand-int 3)) doesn't work then

12:08 sdegutis: Right. (take 10 (repeatedly #(rand-int 3))) gave me (0 2 1 1 1 1 0 1 1 1) just now and that's what I came here asking how to avoid.

12:08 And in trying to demonstrate the problem, I accidentally wrote down the perfect solution.

12:08 gfredericks: it has a uniform distribution but I don't think that's what you mean by "distribution to be even"

12:08 sdegutis: So it sounds to me like the problem has been all along that I just really suck at communicating.

12:08 gfredericks: it's the hardest part of everything

12:09 except weightlifting

12:09 sdegutis: :)

12:33 {blake}: Actually, getting people to weighlift properly takes a ton of communicating. =P

12:33 But I digress. I'm trying to split a text document up by words and using: (clojure.string/split md #"([A-Za-z'])+")

12:34 But this gets me all the spaces and "\r\n"s as words, too.

12:38 gfredericks: re-seq?

12:39 {blake}: gfredericks: Yeah, that'd...probably work. I swear I had this with a regular split, tho'.

12:48 sdegutis: Where'd technomancy go.

12:48 {blake}: Indonesia?

12:48 tcrayford____: thailand

12:51 amalloy: {blake}: you sure you don't want \b?

12:53 {blake}: amalloy: (clojure.string/split whatever #"\b") appears to return each individual space, all the newlines grouped together, etc.

12:53 amalloy: probably not each individual space, but each group-of-spaces between the words

12:53 it splits on word boundaries, which occur at the beginning and end of every word

12:54 {blake}: That would make sense. And that would be fine but I don't want the non-word stuff.

12:54 gfredericks: {blake}: what's wrong with re-seq?

12:55 it sounds a lot more like what you're describing than split does

12:56 {blake}: gfredericks: Nothing per se. I'm trying to introduce Clojure to some folks and liked the idea of using the clojure.string library as much as possible.

12:57 amalloy: {blake}: re-seq and split both just delegate to java

12:57 one happens ot be in core and the other in string

12:58 justin_smith: ,(re-seq #"[\w]+" "good news, everyone!")

12:58 {blake}: amalloy: Sure. It's not a big deal, I just thought I had it (with split) and then...lost it. =P

12:58 clojurebot: ("good" "news" "everyone")

13:00 {blake}: justin_smith: I'm using (re-seq #"\w+").

13:00 sdegutis: No I mean why isn't he in here.

13:00 justin_smith: oh, of course, that's a silly usage of []

13:00 sdegutis: justin_smith: happens all the time don't sweat it

13:01 ##(group-by identity [:a :b :b :a :c :a])

13:01 lazybot: ⇒ {:a [:a :a :a], :b [:b :b], :c [:c]}

13:01 gfredericks: sdegutis: my guess is he'd rather be doing other things, not to mention I assume it's the middle of the night at the moment

13:03 sdegutis: What's the most majestic way to get the count of every unique element in a seq like [:a :b :b :a :c :a] => {:a 3, :b 2, :c 1}?

13:03 gfredericks: frequencies

13:03 sdegutis: gfredericks: The second reason doesn't explain why he's not on here when it's nighttime for us. The first reason doesn't explain why the rest of you are in here.

13:03 ##(frequencies identity [:a :b :b :a :c :a])

13:03 lazybot: clojure.lang.ArityException: Wrong number of args (2) passed to: core/frequencies

13:03 sdegutis: ##(frequencies [:a :b :b :a :c :a])

13:03 lazybot: ⇒ {:a 3, :b 2, :c 1}

13:04 sdegutis: gfredericks: Very majestic thank you.

13:04 gfredericks: sdegutis: it wasn't clear if you were asking about "right now" or not

13:10 {blake}: ,(clojure.string/split "1234\r\n5678\r\n" #"\n")

13:10 clojurebot: ["1234\r" "5678\r"]

13:11 {blake}: ,(clojure.string/split "1234\r\n5678\r\n" #"\r\n")

13:11 clojurebot: ["1234" "5678"]

13:12 {blake}: Hmmm. But...if we use a reader and line-seq, we don't have to worry whether we've got "\r"s or "\r\n"s.

13:12 justin_smith: ,(line-seq (java.io.BufferedReader. (java.io.StringReader. "hello\nworld\r\nOK")))

13:12 clojurebot: ("hello" "world" "OK")

13:13 justin_smith: next question - do I really type that fast, or am I basically psychic?

13:13 sdegutis: gfredericks: a deviant moron once told me "embrace ambiguity"

13:13 pandeiro: anyone else having issues with calling `clojure-mode` with most recent (melpa) cider/clojure-mode packages?

13:14 I get a File mode specification error: (void-variable defun)

13:14 {blake}: justin_smith: Psychic.

13:14 justin_smith: pandeiro: my voodoo approach is to try deleting all elc files

13:15 pandeiro: justin_smith: good call, i'll try that i guess

13:15 justin_smith: pandeiro: when two releases of an emacs lib are not api compatible, weird things can happen

13:15 pandeiro: i'm using cask so i've already tried deleting .emacs.d/.cask but...

13:15 justin_smith: and clojure-mode / cider often break api

13:16 kwladyka: hmm when reflections (http://clojuredocs.org/clojure.core/*warn-on-reflection*) appear? In one moment i stop need ^long in my code and don't have any idea how it is possible

13:16 justin_smith: kwladyka: the warnings happen during compilation

13:16 that is, when the definitions are created (defn form, etc.)

13:18 kwladyka: justin_smith, yes but.... i didin't change anything important in code from that time

13:18 i guess

13:18 and now i don't need ^long in functions

13:19 i try figure out what changed that

13:19 justin_smith: kwladyka: it could be that the compiler picked up the type from another hint

13:19 kwladyka: but even if i remove all ^long in code...

13:20 sdegutis: Is there a built in Clojure function to generate an evenly distributed list of random elements based on a set of choices for each element?

13:20 justin_smith: were you only warning on reflection, or also warning on numeric boxing?

13:20 hiredman: gfredericks: if you are using anyone else's libraries, your generative testing ends up testing their edge cases too

13:20 sdegutis: Like, if I have [#{:a :b}, #{:a :b :c}, #{:a :c}] then it will choose [:a :b :c]?

13:20 kwladyka: justin_smith, numbering boxing? only on reflection

13:21 sdegutis: I have no idea what this concept is called.

13:21 justin_smith: kwladyka: heres a post about it from puredanger http://insideclojure.org/2014/12/15/warn-on-boxed/

13:21 kwladyka: sdegutis, not really sure what you want to achieve

13:22 sdegutis, maybe there you will find something interesting https://github.com/clojure/math.combinatorics

13:22 hiredman: isn't a problem per se, just a sea of pain

13:28 sdegutis: kwladyka: Honestly I don't know either. Thanks for the link.

13:29 Given a list of sets of choices, I need to pick each choice such that overall it's as evenly distributed as possible.

13:31 I think I know how I could do this imperatively with mutable state. Reorder the sets of choices, most restrictive first. Iterate the list, choosing from each set, and adding to a list. Each choice should be random but biased towards what's least available in the set already. The bias should start out weak but grow stronger over time.

13:31 Now, reduce could probably replace the mutable state and imperativeness.

13:31 kwladyka: justin_smith, i don't understand it. I reset commit to the time when i had warnings about reflections and i don't have them now.......

13:32 sdegutis: So I guess all I'm left with are hard math problems that I don't understand.

13:32 kwladyka: justin_smith, how is it possible?

13:35 justin_smith: kwladyka: are you sure reflection warnings are turned on properly? try adding something to your project that is guaranteed to cause a reflection warning

13:35 (defn date->long [d] (.getTime d)) ; for example

13:51 kwladyka: justin_smith, yes i get a warning

13:52 justin_smith, i did lein clean but is it possible it is cached somewhere?

13:54 so magic...

13:57 shiranaihito: can i extend a protocol to another protocol? :/

14:15 gfredericks: not really

14:17 hiredman: the pain is because you have to weed out their edge cases in the generators? or because you find bugs in their code?

14:48 sdegutis: ##(shuffle #{:a :b :c})

14:48 lazybot: ⇒ [:b :c :a]

14:48 hiredman: gfredericks: both, either

14:49 gfredericks: the machine doing the generating doesn't understand or care about your notions of logical separation and api boundaries

14:50 which can be very brutal when you depend on lots of 3rd parties

14:50 sdegutis: ##(dissoc #{:a :b :c} :b)

14:50 lazybot: java.lang.ClassCastException: clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap

14:51 gfredericks: sdegutis: disj

14:51 sdegutis: Ahh. But why!

14:51 gfredericks: hiredman: I wonder if you're using it in a moderately different style than I do

14:51 sdegutis: Clojure seems so inconsistent. Sometimes it considers sets just like maps, where the key is a key to itself.

14:51 But sometimes they're not considered like maps, like here.

14:51 gfredericks: you can't use assoc with them either

14:52 ,(get #{:a :b :c} :b)

14:52 clojurebot: :b

14:52 gfredericks: ,(find #{:a :b :c} :b)

14:52 clojurebot: #error {\n :cause "clojure.lang.PersistentHashSet cannot be cast to java.util.Map"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHashSet cannot be cast to java.util.Map"\n :at [clojure.lang.RT find "RT.java" 816]}]\n :trace\n [[clojure.lang.RT find "RT.java" 816]\n [clojure.core$find invokeStatic "core.clj" 1470]\n [clojure.core$find invoke "core.clj" -1]\n...

14:52 sdegutis: ##[(contains? {:a 1} :a) (contains? #{:a}) :a]

14:52 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core/contains?

14:52 sdegutis: ##[(contains? {:a 1} :a) (contains? #{:a} :a)]

14:52 lazybot: ⇒ [true true]

14:52 hiredman: gfredericks: could be

14:53 I suspect a lot of it has to do with sort of the granularity of testing too

14:54 gfredericks: hiredman: I often find myself using generators to describe whatever part of the external world is creating inputs to the system

14:54 hiredman: gfredericks: sure

14:54 gfredericks: which often coincides with high-level testing

14:55 hiredman: a better way to phrase the tweet might be something like "generative testing exposes all the ambiguity in the apis you use"

14:55 Bronsa: sdegutis: how does clojure considers set maps?

14:56 sdegutis: Bronsa: I mean sometimes they are both grouped together as similarly functioning things, and sometimes not. Like `contains?` works on both.

14:56 gfredericks: Bronsa: and get

14:56 Bronsa: sdegutis: contains? works on a lot of collections

14:56 sdegutis: ##[(get {:a 1} :a) (get #{:a} :a)]

14:56 lazybot: ⇒ [1 :a]

14:57 gfredericks: hiredman: for me it also forces being explicit about what assumptions are being made

14:57 hiredman: like, I might generating a bunch of data, run it through some kind of analysis, stick the results in some database, then do the same thing with data in memory and compare the results

14:57 to verify the analysis and the database stuff

14:57 sdegutis: ##(for [coll [{:a 1} #{:a}]] (juxt #(get % :a)))

14:57 lazybot: ⇒ (#<core$juxt$fn__4302 clojure.core$juxt$fn__4302@32607988> #<core$juxt$fn__4302 clojure.core$juxt$fn__4302@5bcae98e>)

14:57 hiredman: but of course databases

14:57 Bronsa: ah, you're complaining about dissoc/disj?

14:58 sdegutis: ##(for [coll [{:a 1} #{:a}]] (get coll :a))

14:58 lazybot: ⇒ (1 :a)

14:58 hiredman: gfredericks: yeah

14:58 sdegutis: Apparently I'm drunk today.

14:59 gfredericks: hiredman: databases are ambiguous about what kind of data they accept? I'm having a hard time imagining where this gets hairy

14:59 sdegutis: Bronsa: It seems like dissoc should work on sets yeah.

15:00 hiredman: gfredericks: well, once you are dealing with databases you are generally doing network traffice, and some databases are clustered and replicate data in weird ways, and some datbases are inexact in vague ways about things like counts

15:01 so right, there can be assumptions in the model that just are not valid

15:01 gfredericks: hiredman: is nondeterminism a big part of it?

15:01 hiredman: sure

15:01 gfredericks: yeah that's probably the biggest barrier I see to more elaborate setups

15:02 Bronsa: sdegutis: I think the rationale for it not to work is to maintain the parallel with assoc

15:02 gfredericks: I can't say I've had issues that I felt were inherently related to 3rd-party library use though

15:02 Bronsa: sdegutis: assoc can't work on sets

15:02 hiredman: you have to incorporate the nondeterminism in to the model checking, which gets more complicated

15:04 gfredericks: yeah

15:05 hiredman: well, anytime your code is tested via test.check (or similar), and you are calling code that isn't, you are effectively fuzzing that 3rd party code

15:05 it can get weird

15:06 gfredericks: I found two bugs in goog.math.Integer that way

15:07 which I thought of as a good thing

15:08 hiredman: it depends on the extent of the bug, your relationship with the 3rd party, if you can even decide where the "fault" lies etc

15:09 gfredericks: I suppose whether you consider it a good thing or not depends on the probability that you would have found it in production otherwise

15:10 hiredman: don't get me wrong, generative testing is great, I want it all the time everywhere

15:11 there is just a hint of bitter with the sweet

15:13 gfredericks: :D

15:13 yeah I think I agree with that

15:20 sdegutis: Bronsa: Maybe it could but just take one fewer arg?

15:20 So that (assoc #{} :a) would give #{:a}

15:20 Bronsa: that's conj

15:20 and thus disj

15:20 It'd make more sense to make disj work on maps than dissoc on sets

15:20 sdegutis: Right, but it makes sense with the other terminology more.

15:21 It's just starting to seem like most of the naming and conventions in Clojure were randomly picked out of a hat.

15:22 Bronsa: Most would disagree

15:23 {blake}: I rarely find things that don't make sense. I think "contains?" is a boo-boo, even though it makes perfect sense. That's about it.

15:23 J_A_Work: sdegutis: I do find it frustrating sometimes. It seems like I get ‘surprises’ sometimes. I think it’s partly being used to other Lisps and FP languages. Clojure diverges from convention in seemingly random places (like, assoc is technically wrong in traditional Lisp/Scheme terms)

15:23 clojurebot: Alles klar

15:24 sdegutis: ,(select-keys {} [:a :b :c])

15:24 clojurebot: {}

15:25 Bronsa: J_A_Work: how so?

15:25 sdegutis: ,(get {} :a)

15:25 clojurebot: nil

15:25 Bronsa: sdegutis: select-keys returns a map, get returns a mapped value, nothing surprising

15:26 sdegutis: welp

15:26 J_A_Work: Bronsa: traditional assoc in other lists is a search of an associative list structure, not an add like it is in clj. compare: http://docs.racket-lang.org/reference/pairs.html?q=assoc#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._assoc%29%29

15:26 *other Lisps

15:26 {blake}: Oh, I have one of those.

15:27 Not lisps, but situations that are sort of surprising.

15:27 filter vs. keep

15:27 Bronsa: J_A_Work: well I don't think it's fair to claim that because a name already has a meaning, all other languages using that name must mean the same thing :)

15:28 kwladyka: justin_smith, another mysterious solved. I have warning about reflection only if i use (require). If i use function without require i don't have this warnings

15:28 justin_smith, but why it works in that way....

15:28 Bronsa: J_A_Work: I actually thing assoc makes much more sense as `associate` than as what it means in racket

15:28 {blake}: You end up with languages imitating C's horrible switch/case logic when you copy slavishly. =P

15:28 Bronsa: think*

15:28 J_A_Work: Bronsa: perhaps, but it’s odd if you come from an existing Lisp background. It’s like map or filter, it would be similarly odd for most FP people to find those renamed to something else in a language. I started in CL and then Racket, so the differences can be jarring.

15:29 (already it gets messy from language to another whether it’s reduce or fold and whether there’s both foldl and foldr and … blegh)

15:29 sdegutis: J_A_Work: I haven't really used other Lisps so differences from them are fine with me. I've used Ruby and Python and Haskell more than Lisps.

15:30 I completely forgot about keep.

15:31 J_A_Work: I didn’t know about keep.

15:31 gfredericks: ,(keep next '((1 2 3) (1 2) (1) ()))

15:31 clojurebot: ((2 3) (2))

15:33 J_A_Work: One I still get wrong though, and not because it’s named, is actually filter. XD I often manage to forget that it keeps *true*. Somehow the name always makes me think it’s for ‘filtering something out’ which is what I use it more often for, and then screw up because I forget to negate my fn to get the expected result. XD

15:35 {blake}: Yep. Heh.

15:35 stuartsierra: kwladyka: Reflection warnings are a feature of the compiler, they are printed when you load code, not when you call a function.

15:36 kwladyka: justin_smith, oh i know exactly why. The problem was i used :reload-all (require 'chess-challenge.pieces :reload-all)

15:36 this problem appear only with :reload-all

15:36 without :reload-all i don't have reflections problem

15:37 it looks like some kind of bug or i don't know about something

15:37 justin_smith: kwladyka: without :reload-all require isn't doing anything

15:37 kwladyka: hmm

15:37 justin_smith: require does nothing and returns nil if you have already defined the namespace

15:37 (doc require)

15:37 clojurebot: "([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of Clojure code. Lib

15:38 justin_smith: "skipping any that are already loaded"

15:38 kwladyka: justin_smith, so if i run "lein repl" is chess-challenge.pieces already loaded?

15:40 justin_smith: kwladyka: if you have a :main set up in your project.clj, lein auotmatically requires it, yes

15:40 kwladyka: but it does depend on your project setup, you can turn on reflection warnings via project.clj btw

15:40 kwladyka: justin_smith, oh so it is because i added :main ^:skip-aot chess-challenge.handler to project.clj ?

15:41 justin_smith: yes, that would do it

15:41 kwladyka: here's how you can set up warnings via project.clj as well https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L253

15:41 kwladyka: but anyway how is that when loaded by repl it works without reflections (i know because it is fast), but if i use require :reload-all the problem appear?

15:42 justin_smith: kwladyka: oops, lein I linked to is deprecated, but the one right blow it shows the right way

15:42 kwladyka: I suspect that's not how it is happening at all. I think you fixed your main reflection bottle necks, and the remaining warnings are ones that don't slow down your code as much.

15:44 kwladyka: justin_smith, hmm i feel magic :)

15:45 sdegutis: What's a prestigious way to sort a map by its keys? ##(sort-by {:a 1 :b 2 :c 3} second) ?

15:45 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$second

15:45 sdegutis: Oops ##(sort-by second {:a 1 :b 2 :c 3})

15:45 lazybot: ⇒ ([:a 1] [:b 2] [:c 3])

15:46 sdegutis: Is that a fair assessment?

15:46 gfredericks: you're sorting by values there

15:46 sdegutis: Sorry I meant values.

15:46 Communicating is hard.

15:46 gfredericks: well that definitely works, yeah

15:46 sdegutis: Feels like cheating thou.

15:46 gfredericks: why?

15:46 clojurebot: http://clojure.org/rationale

15:47 sdegutis: It relies on how iterating a map turns each pair them into a vector of [k v]

15:47 Which feels like a weird thing to rely on.

15:47 I'd much rather it work like (sort-by key m)

15:47 gfredericks: use val then

15:47 ,(sort-by val {:a 1 :b 2 :c 3})

15:47 sdegutis: I don't think val will work in that case.

15:47 clojurebot: ([:a 1] [:b 2] [:c 3])

15:47 gfredericks: it's even shorter

15:47 sdegutis: Use ## , is too slow

15:48 I'm surprised that worked. I guess it's not really a vector after all?

15:48 Just looks like one?

15:48 gfredericks: it's both a vector and a mapentry

15:48 sdegutis: (val [:a 1])

15:48 ##(val [:a 1])

15:48 lazybot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

15:48 justin_smith: (vector? (first {:a 0}))

15:48 sdegutis: ah

15:48 justin_smith: ,(vector? (first {:a 0}))

15:48 clojurebot: true

15:48 sdegutis: Haha Map$Entry

15:48 what is this javascript haha

15:48 gfredericks: it's a java inner class

15:49 sdegutis: Right but still

15:49 Is there a way to give a 'weight' to shuffling a seq?

15:49 gfredericks: what would it mean?

15:50 sdegutis: Like, don't shuffle things too far away from each other.

15:51 kangarooo: shocking video about islamic state, must watch: https://www.youtube.com/watch?v=df4KB30K0UU

15:51 gfredericks: sdegutis: you could shuffle by swapping pairs, and vary how many swaps you do

15:52 kwladyka: justin_smith, but i am afraid you are right

15:52 gfredericks: swapping adjacent elements I mean

15:52 kwladyka: justin_smith, perhaps i fixed it in the same time and didn't know about that :)

15:55 oh so great library https://github.com/gtrak/no.disassemble what is the pitty i didn't know about that before

15:56 sdegutis: Wow that is shocking.

15:57 justin_smith: kwladyka: did you find that via the puredanger blog post I linked you to?

15:58 kwladyka: justin_smith, yes

16:18 {blake}: Repeating a string--is it possible without the join/apply stuff?

16:18 It used to be. clojure.contrib.string had its own repeat.

16:19 justin_smith: {blake}: you could do it yourself with a StringBuilder

16:20 {blake}: Sure. Just wondering if clojure.contrib.string/repeat still exists. Doesn't look like it.

16:23 justin_smith: doing it with join or apply str shouldn't be so bad, both will use a StringBuilder come to think of it

16:23 {blake}: justin_smith: Oh, it's not a matter of "bad". It's a matter of sipping from the firehose. I'm trying to introduce people to Clojure, but gently. =P

16:26 gfredericks: I think repeat and apply str are pretty gentle

16:26 you can show the intermediate seq

16:26 ,(repeat 5 "HOOHA")

16:26 clojurebot: ("HOOHA" "HOOHA" "HOOHA" "HOOHA" "HOOHA")

16:26 gfredericks: ,(apply str (repeat 5 "HOOHA"))


16:26 {blake}: gfredericks: Yeah, I like that better than join, thanks!

16:27 Especially because I've already gone over apply.

16:29 justin_smith: ,(str (repeat 5 "HOOHA"))

16:29 clojurebot: "(\"HOOHA\" \"HOOHA\" \"HOOHA\" \"HOOHA\" \"HOOHA\")"

16:29 justin_smith: the difference between that and the apply version should be a nice lesson too

16:29 sdegutis: hahaha

16:29 ##(get {Double/NaN 2} Double/NaN)

16:29 lazybot: ⇒ nil

16:30 sdegutis: Why is that.

16:30 {blake}: NaN's aren't equal to anything, including themselves, I believe.

16:31 ##(= Double/NaN Double/NaN)

16:31 lazybot: ⇒ false

16:33 sdegutis: What is that necessary for?

16:34 gfredericks: I think that's part of the spec for doubles?

16:34 would be interested if there's any language with IEEE doubles that doesn't do that

16:34 sdegutis: What Java code cannot be expressed in a reasonable way except that this rule exists?

16:35 t0by: I suppose they wouldn't be ieee doubles.

16:35 There is a pretty fixed algebra for that.

16:35 Including NaN != NaN

16:36 sdegutis: Given a set #{:a :b} and a list [:c :a :b] what's an amazing way to get the first element in the list which exists in the set?

16:36 Just some?

16:36 t0by: an "amazing" way? :P

16:36 sdegutis: Yes please.

16:36 t0by: it's a meme that's expected of me, I have to use weird adjectives when asking for help or nobody answers

16:37 t0by: Must be fun being you :)

16:38 sdegutis: Goodness no. It's a nightmare.

16:38 Most days I wake up hoping yesterday was all just a bad dream.

16:38 Hmm some didn't work.

16:38 t0by: There was a guy like that in the village I grew up in, as well. He had to use weird adjectives. Then he was committed.

16:38 gfredericks: ,(some #{:a :b} [:c :a :b])

16:38 clojurebot: :a

16:38 sdegutis: Oh wait I think it worked.

16:39 Had the args backwards.

16:39 Thanks gfredericks you're the best person.

16:40 I think this is the first time I've ever used the return value of some more than just for a truthy check.

16:41 t0by: that sounds like the beginning of one of my stories at /u/-sdegutis-

16:42 What's a fantastic way to turn [:a :b :c :d] into [:b :c :d :a] ?

16:43 I can't think of a way to do it without giving it a name.

16:43 gfredericks: (->> coll cycle rest (take (count coll)))

16:43 sdegutis: ##(let [coll [:a :b :c :d]] (->> coll (cycle) (rest) (take (count coll)))

16:43 Yeah that's the only way I could think of. It requires it to be named though.

16:44 ##(let [coll [:a :b :c :d]] (->> coll (cycle) (rest) (take (count coll))))

16:44 lazybot: ⇒ (:b :c :d :a)

16:44 gfredericks: you could put any expression in there it doesn't have to be named

16:44 &(->> (range 5) cycle rest (take (count coll)))

16:44 lazybot: java.lang.RuntimeException: Unable to resolve symbol: coll in this context

16:44 sdegutis: No I mean coll.

16:44 gfredericks: oh for the count, yeah

16:44 sdegutis: Right.

16:44 I was hoping for some kind of weird queue solution.

16:44 gfredericks: well you *can* use a queue if you really want to

16:45 sdegutis: Like this pseudo-code: (->> [:a :b :c :d] (queue) (pop) (push))

16:49 justin_smith: gfredericks: you can queue if you want to .... 'cause your friends don't queue and if they don't queue they aint no friends of mine

17:02 sdegutis: you can leave your queue.. behind?

17:16 numberten: does clojure have a min/max function that uses .compareTo ?

17:17 sdegutis: Is sort-by stable?

17:21 domokato: I'm using an anonymous fn as a Runnable; is there a way to refer to itself from inside the fn? (i.e. "this" in java)

17:23 sdegutis: domokato: letfn

17:24 domokato: sdegutis: oo thx, let wouldn't work, huh?

17:24 sdegutis: (doc letfn)

17:24 clojurebot: "([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."

17:28 sdegutis: (clojuredocs letfn)

17:28 clojurebot: WAKE UP

17:28 clojurebot: It's greek to me.

17:30 justin_smith: domokato: the easy way is (fn some-name [blah] ....)

17:30 ,((fn my-name [] my-name))

17:30 clojurebot: #object[sandbox$eval47$my_name__48 0x42f33dae "sandbox$eval47$my_name__48@42f33dae"]

17:31 justin_smith: returns itself

17:31 domokato: ohhh, i forgot you could do that

17:31 justin_smith: ,(((fn my-name [] my-name)))

17:31 clojurebot: #object[sandbox$eval73$my_name__74 0x1ff66d7d "sandbox$eval73$my_name__74@1ff66d7d"]

17:31 justin_smith: heh, it's a fixed point

17:31 ,(((((fn my-name [] my-name)))))

17:31 clojurebot: #object[sandbox$eval99$my_name__100 0x7146e77a "sandbox$eval99$my_name__100@7146e77a"]

17:44 sdegutis: justin_smith: oh right

17:44 you win

17:44 i always forget that

17:45 hmm mine says: #<main$eval1015$my_name__1016 cleancoders.web.main$eval1015$my_name__1016@2c34b4e>

17:45 hmm your says: #object[sandbox$eval73$my_name__74 0x1ff66d7d "sandbox$eval73$my_name__74@1ff66d7d"]

17:45 broken?

17:45 justin_smith: ,(nth (iterate #(%) (fn me-me-me-me [] me-me-me-me)) 1000000)

17:45 clojurebot: #object[sandbox$eval26$me_me_me_me__29 0x2d082452 "sandbox$eval26$me_me_me_me__29@2d082452"]

17:55 cljnoob2438: hey everyone, just starting clojure. What is the most clojurey way to loop over user input for a command line application? Currently I just have a lein app project that i'd like to run (via lein run or lein trampoline run) and I'd like to be able to interact with user input. Any suggestions? Googling hasn't helped a ton

17:56 justin_smith: cljnoob2438: loop/recur would be a natural choice, using the args to carry any changed state that would come from user input

17:57 you can get user input via *in*

17:59 sdegutis: cljnoob2438: the most Clojure thing to do would be to not write a command line application in Clojure

18:00 cljnoob2438: check out https://github.com/pixie-lang/pixie

18:00 cljnoob2438: Yeah. I was trying to recur an if-let on read-line, but I couldn't get it to work right =/ Still working on it

18:01 Haha no room for scripting in clojure?

18:01 sdegutis: cljnoob2438: the JVM startup time is a killer

18:02 cljnoob2438: Yeah I heard about cljs with node as an option for command line stuff. I guess I should check out that avenue. I'm still gonna try it until I get it to work. It's just for a little programming challenge, but it'd be nice even for a long running systems application that listens for calls from other applications.

18:03 Like a log responder that tails files and runs some function if a certain regex match is hit (using the file as input instead of STDIN)

18:09 justin_smith: cljnoob2438: well, the normal cli thing would be to use *in*, and use piping right?

18:09 but I guess you could open files for tailing too, checkout out java.io.*

18:10 clojure's slow startup time shouldn't be a problem at all for a utility like that (and btw it has nothing to do with the jvm, it's a clojure problem)

18:11 cljnoob2438: justin_smith: ok yeah I could try piping and just pipe echo'd input to it haha thanks

18:11 justin_smith: during development you could use eg. a StringReader

18:12 ,(line-seq (java.io.BufferedReader. (java.io.StringReader. "hello\nworld\r\nOK"))) ; reusing an example from earlier

18:12 clojurebot: ("hello" "world" "OK")

18:12 justin_smith: once you have a line-seq, you can just do a loop/recur calling rest, or even a reduce over all lines

18:13 ,(reduce #(conj % (first %2)) [] (line-seq (java.io.BufferedReader. (java.io.StringReader. "hello\nworld\r\nOK"))))

18:13 clojurebot: [\h \w \O]

18:16 sdegutis: If you change a defmulti's arity, YOU MUST RESTART THE JVM.

18:16 Just FWI.

18:19 justin_smith: sdegutis: or you can just run (def mymulti nil) followed by redefining the defmulti

18:19 sdegutis: now you tell me

18:19 you'd think defmulti would know to do this itself

18:19 justin_smith: sdegutis: that would fuck up a bunch of other things

18:20 the defmulti carries all its methods, imagine what a pain it would be if all your methods disappeared every time a multi was redefined

18:20 just incidentally because you reloaded a file and were not even trying to redefine the multimethod

18:20 sdegutis: justin_smith: presumably if it was redefined so would also be its definitions

18:21 justin_smith: sdegutis: they are in other namespaces

18:21 sdegutis: it should know to reload them

18:21 justin_smith: it should cause namespaces that are upstream on the dep graph to reload? that's just stupid

18:21 sdegutis: I was promised pain-free dynamic changes at runtime and OP did not deliver

19:30 kristof: Common Lisp does not have this problem.

19:39 TEttinger: Lua does not have this

19:39 (it isn't a keyword)

21:06 $seen akeep

21:06 lazybot: I have never seen akeep.

21:06 TEttinger: hm

21:06 he presented something rather neat at a conj

21:43 monsta: Good night

21:44 I having a hard time trying to translate this javascript function to clojurescript, can any body help? http://pastebin.com/S6ndkY21

21:45 gcommer: Whats the issue you're having?

21:46 monsta: Not enough knowledge to write the clojurescript equivalent

21:47 gcommer: To what extent?

21:47 monsta: all

21:47 weel just the loop

21:48 gcommer: Which part of the loop? requestAnimationFrame?

21:48 monsta: I don't know how to write without braking my browser :8

21:48 yes

21:48 gcommer: oh, so you've tried it and had it break your browser

21:48 can you post what you have? and/or error messages you're getting

21:49 (in a pastebin ofc)

21:49 monsta: give me a minute

21:52 Here is what I got so far http://pastebin.com/RfcdBui2, not really know what I am doing ;(

21:53 justin_smith: monsta: that's close

21:53 monsta: not enough

21:54 gcommer: is the code you pasted all in another function?

21:54 i presume not

21:54 justin_smith: a couple simple things - you should be updating delta inside a call to recur, and to call fun, you need to wrap it in parens (fun)

21:54 monsta: ummmm

21:54 justin_smith: monsta: loop does not repeat anything unless you call recur

21:55 gcommer: are you sure you wanna use loop/recur in the cljs version? requestAnimationFrame in the JS

21:55 justin_smith: monsta: and delta should be changing on each step through the loop, so it needs to be reset on each call to recur

21:55 gcommer: oh, good point

21:55 monsta: Oh, I think that in the clojure doc or in a blog post long time ago I saw a example of loop with recur, I though it would work :(

21:56 gcommer: loop/recur is a good strategy for doing loops in clojure

21:56 in general

21:56 justin_smith: monsta: the thing is, your js doesn't have a loop

21:56 gcommer: but requestAnimationFrame is special and should be used for what you're doing in browser-based code

21:56 monsta: ok

21:56 How do a make it a proper loop

21:57 I am connected to figwheel right now

21:57 justin_smith: monsta: just use requestAnimationFrame just like you do in the js version

21:57 monsta: My mind is not a good parser ;(

21:57 justin_smith: monsta: gcommer is right, that would be the way to do a loop, but this code shouldn't be a loop

21:57 monsta: Ok atleas I know that the loop does not suppose to work that way

21:58 justin_smith: ,(loop [i 0] (if (> i 10) i (recur (* 2 i))))

21:58 oops!

21:58 clojurebot: eval service is offline

21:58 justin_smith: ,(loop [i 1] (if (> i 10) i (recur (* 2 i))))

21:58 clojurebot: 16

21:58 monsta: but where the requestAnimation is left?

21:59 justin_smith: monsta: you want something like (fn lp [time] (js/requestAnimationFrame lp) ...)

21:59 I intentionally did not use the name loop, since that is its own thing in clojure

21:59 monsta: what is lp?

22:00 o ok

22:00 immmm

22:00 justin_smith: monsta: a name, you can replace it with any name you'd like to use

22:00 gcommer: such as monstaLoopIsAwesome

22:00 justin_smith: monsta: I changed the name from loop since loop is special in cljs

22:00 sure

22:00 monsta: Ok hmmmmmmmmmmmmm

22:01 I will keep trying, but the insight helped a lot, thanks

22:02 justin_smith: monsta: are you reading a book or doing any simpler exercises?

22:02 because otherwise, this might be a daunting place to start

22:02 monsta: Yes, is a book about game with js

22:02 justin_smith: I mean a cljs book, or some simpler cljs exercises

22:03 monsta: Well no, only the docs

22:03 and blogpost

22:03 s

22:05 justin_smith: monsta: it's entirely up to your judgment, of course, but just be aware it would be a lot easier if you find some good intro cljs materials

22:06 monsta: for example there's the book "clojurescript up and running" from o'reilly

22:06 monsta: Not many around, most of then use Om or some funky libraries that I am not really interested baout

22:06 I will check on that

22:07 justin_smith: monsta: also these tutorials are worth checking out https://github.com/magomimmo/modern-cljs

22:07 monsta: That too

23:00 WickedShell: I have warn on reflection on, and outside of some reflections in dependencies (particularly clj-complete (which I don't even know how it is in the dependency tree)) I'm seeing very large number of java.lang.reflect.Method's build up slowly eating all available memory. Is there a way to track what is causing these at runtime?

23:00 amalloy: lein repl includes clojure-complete

23:01 and tools.nrepl

23:02 WickedShell: Alright, so I can probably safely ignore it, I'm using the lein repl so I shouldn't actually see its effects in builds then. (all though builds do slowly climb to 4million+ instances of java.lang.reflect.Method)

23:02 amalloy: and this persists between GC cycles?

23:03 WickedShell: it's reset between GC cycles, but its causing the GC to run far more often, and problematically on JDK8 on windows I'm seeing total heap size for the JVM grow at every GC until it crashes eventually

23:04 which seems somewhat like an error in the JVM since theres always still 500MB free at the time...

23:05 amalloy: i mean 4M+ seems like a lot to me, but who knows. lots of garbage gets generated by clojure. if you're seeing the heap size grow higher than you want it to go, set a max heap size in the vm parameters

23:05 as long as all the garbage is transient it is likely not worth worrying about

23:06 WickedShell: probably... I'm somewhat worried about performance on low end devices but you're probably right... Can you control VM settings from within java/clojure code? I've only ever set them as launch options...

23:07 amalloy: no

23:07 WickedShell: It just seems to me like I should be able to chase down all the sources of reflcetion fairly easily since its allocating 1MB+ per second (nothing else grows anywhere near as fast)

23:08 amalloy: i presume you could inspect one of the Method values from a heap snapshot to see what method it represents

23:08 well. i guess i assumed you were using a profiler

23:08 if you're not, then you should do that

23:09 WickedShell: I'm using the jvisualvm as the profiler

23:09 took a snapshot from the sampler and I can't inspect... maybe if I attach in profile mode... That's worth checking out

23:11 All it wants to tell me is that no source was found for the class?

23:12 amalloy: you should be able to inspect its members. visualvm isn't the profiler i use, but that information is certainly available

23:13 WickedShell: I'm open to suggestions on other profilers, its just the first one I found (that was free)

23:14 ah, heapdump not snapshot

23:14 * WickedShell headdesk

Logging service provided by n01se.net