#clojure log - Jan 01 2015

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

1:05 zophy: it is very good for you to have me wishing you a happy new year !!

1:39 rhg135: I dont know yall well but i love you all and heres to even better code in 2015

1:50 woort: Hey what is the command character for clojurebot?

1:51 rhg135: , i think

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

1:51 jwm: happy newyear

1:51 woort: nice, thank you

1:51 ,(+ 1 1)

1:51 clojurebot: 2

1:52 rhg135: ,(-> #'map meta)

1:52 clojurebot: {:ns #<Namespace clojure.core>, :name map, :added "1.0", :file "clojure/core.clj", :static true, ...}

1:52 rhg135: Grr

1:53 ,*clojure-version*

1:53 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

1:54 rhg135: why is it a dynamic var tho?

2:45 kenrestivo: does core.async get upset when some consumers/producers of channels are go loops and others are jvm threads?

3:08 rhg135: kenrestivo: no which is great

3:09 kenrestivo: thanks. trying to troubleshoot deadlocked/stuck threads in a production-sized app is not fun.

3:09 even converting everything to go loops, still something somewhere is locking up channels.

3:10 * kenrestivo starts on rewrite #3

3:10 rhg135: id avoid threading till needed. Core.async wont care

3:26 Good night #".+"

4:07 dagda1_: this comparison returns false (= [["dog"] ["cat"]] [["cat" "dog"]]) is there a way to compare that would compare irrespective of the order of the elements?

4:07 I mean this (= [["dog"] ["cat"]] [["cat"] ["dog"]])

4:09 this works (= (set [["dog"] ["cat"]]) (set [["cat"] ["dog"]]))

4:18 cfleming: Is it possible to macroexpand but to retain the line and column metadata?

4:18 I can't get it to work.

4:19 .(binding [*print-meta* true] (pr-str (read (LineNumberingPushbackReader. (StringReader. "(let [x (+ 2 3)] x)")))))

4:19 ,(binding [*print-meta* true] (pr-str (read (LineNumberingPushbackReader. (StringReader. "(let [x (+ 2 3)] x)")))))

4:19 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: LineNumberingPushbackReader, compiling:(NO_SOURCE_PATH:0:0)>

4:19 cfleming: Bah

4:20 Anyway, that returns "^{:line 1, :column 1} (let [x ^{:line 1, :column 9} (+ 2 3)] x)" as expected

4:21 * cfleming However (binding [*print-meta* true] (pr-str (clojure.walk/macroexpand-all (read (LineNumberingPushbackReader. (StringReader. "(let [x (map nil nil)] x)"))))))

4:21 cfleming: Produces "(let* [x (map nil nil)] x)"

4:22 Sorry, "(let* [x (+ 2 3)] x)", rather

4:22 All the line and column data has been stripped off

4:24 It seems that I can add metadata, but any metadata added to lists is removed - I guess this is because lists are always replaced with their macroexpansions?

4:27 amalloy: cfleming: the compiler ordinarily sets the metadata itself, but macroexpand isn't the compiler

4:28 cfleming: amalloy: But in this case it's not preserving metadata that I've set either

4:28 amalloy: I can set ^:test on the arg vector or the binding symbol, but if I set it on (+ 2 3) it gets lost

4:29 amalloy: This also happens with riddley, which surprised me

4:29 amalloy: clj-865 iirc is one that mentions this

4:29 $google clj-865 jira

4:29 lazybot: [[#CLJ-865] Macroexpansion discards &form metadata - Clojure JIRA] http://dev.clojure.org/jira/browse/CLJ-865

4:29 amalloy: i guess not, really. but related

4:30 cfleming: I was going to say that's the most surprising thing I've seen lately, but there are so many...

4:30 What a PITA

4:31 amalloy: oh wait, you used clojure.walk/macroexpand-all?

4:31 man, just never use that function

4:31 it gets the easy cases right-ish, but misses a lot of subtleties

4:32 cfleming: amalloy: This also happens with riddley

4:32 Which is what I tried first

4:33 amalloy: riddley maps over lists, as i recall

4:33 because it has to look for macros inside the list to expand

4:33 and of course map doesn't preserve metadata

4:34 cfleming: amalloy: https://www.refheap.com/95637

4:34 No, riddley isn't using map as far as I can see

4:35 It has its own walking function

4:36 amalloy: i was thinking of https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L228, cfleming

4:36 its walking function uses map

4:37 but anyway your example is a weird one, because the list you provided doesn't even exist in the output at all, so it's kinda not that surprising that the metadata you put on it doesn't appear

4:38 cfleming: Right, but intuitively it seems like you would want the metadata for a macro form to be preserved on the expansion

4:38 Maybe that's not intuitive, I dunno - it seems like it to me

4:49 zophy: i should be able to map println over a persistent list, correct ?

4:50 amalloy: yes, zophy, but it will all end in tears

4:51 ~map

4:51 clojurebot: map and the other sequence functions used to be lazy, but with the advent of chunked sequences, may or may not be lazy, consult your local ouija board

4:55 SagiCZ1: zophy: i think you are looking for doseq

4:55 ,(doseq [e (range 5)] (println e))

4:56 clojurebot: 0\n1\n2\n3\n4\n

5:04 zophy: SagiCZ1, and amalloy, thanks, i can get it to work with doseq :)

5:06 heh, map worked for this in the cider-repl...

5:09 SagiCZ1: map does work but it is lazy so you have to force the evaluation with doall.. and it collects the result thus wasting memory

6:18 zot1: happy 2015! any other lively nerds in here?

6:18 i'm playing with misaki, and have never seen the #- form before — what does it do?

6:19 or is this perhaps part of his dsl in some way i can't yet track down?

6:20 wagjo: zot1: cljx maybe?

6:21 zot1: could be — i've never touched cljx

6:22 wagjo: zot1: feature expressions, so that yhou can use same source file for both CLJ and CLJS

6:23 zot1: interesting

6:23 (inc wagjo)

6:23 lazybot: ⇒ 1

6:26 wagjo: thanx

6:51 mi6x3m-alt: hey llasram, I managed to fix the issue

6:51 by delaying the initialization of the decorator

6:52 I moved it to a method called initialize() which is invoked after the instance is constructed

10:21 zophy: ~seq

10:21 clojurebot: Titim gan éirí ort.

10:25 zophy: pog mo thoin

10:36 mi6x3m: hey llasram, you here by any chance?

12:15 dagda1_: if I have a set like this (def a #{["cat" "man"] ["man" "snake"] ["spider" "cat"]}) then why is (first a) ["man" "snake"]

12:16 mfikes: Try (seq a)

12:16 adulteratedjedi: or ffirst

12:17 mfikes: (The order is not defined, right, so any other element could be first in the seq)

12:19 dagda1_: mfikes why is it always ["man snake"

12:20 even (first (vec a)) returns ["man" "snake"]

12:20 mfikes: dagda1_: For that particular literal, the hash codes produced will be deterministic, but undefined. (Not truly random.)

12:20 dagda1_: mfikes: ah right, the hashcodes determine it, that makes snese

12:50 andyf: dagda1_: There is a set implementation in a library that preserves items in the order they were added, if that is useful to you. Also several ordered map variants that sort on insertion order, by values, or by a specified list of keys. See the cheatsheet for links to them: http://jafingerhut.github.io

12:53 justin_smith: dagda1_: maybe it's helpful to know that a hashset #{} is implemented as a tree, sorted by the hashcode

12:53 dagda1_: justin_smith: yes, that makes sense

12:53 justin_smith: ,(hash ["cat" "man"])

12:54 clojurebot: 12869706

12:54 justin_smith: ,(hash ["man" "snake"])

12:54 clojurebot: 1160122883

12:54 justin_smith: I guess there's still something I don't get, because I would have expected the "first" item to be the one with the smaller hash code

12:55 clearly it's not that simple

12:57 dagda1_: justin_smith: no, it can't be size, but there is a consistent algorithm

13:07 andyf: justin_smith: Even for sets with the same set of elements, and are thus equal, the seq orders may be different, because hash collision items are put into linked lists in order of addition to the set.

13:07 i.e. it is possible (fairly rare) to have (= s1 s2) but (not= (seq s1) (seq s2))

13:14 seangrove: Can anyone help point out the problems in cljs (and tooling) that come from not having reified namespaces?

13:14 cemerick ^^

13:17 mi6x3m: andyf: sounds fairly possible to me

13:27 irctc: should I use deftype, records, or zippers to represent trees in clojure?

13:27 quad trees to be specific

13:27 mi6x3m: why not vectors or normal sequences?

13:28 irctc: mi6x3m: how would you recomend they be structured

13:29 arrdem: irctc: what problem are you trying to solve and why do you feel that a quad tree is in order

13:30 irctc: arrdem: looking for clusters of points in 2d space

13:31 arrdem: most of my points should be spread out in a path

13:32 arrdem: but occassionaly there may be clusters with a certain patter, I thought if the quad tree has a certain depth it indicates that there is more activity there

13:34 arrdem: so I don't think that bringing a deftype in will actually help you here

13:36 the advice I usually see given here is that you want to prototype with a map or some other easy to work with structure and then once you get that nailed down switch to a class generating thing which is a little less flexible.

13:37 irctc: arrdem: what class generating thing? records?

13:39 arrdem: irctc: deftype and defrecord both emit a customized class which can cause problems when you're working at a REPL

13:40 hiredman has been quoted repeatedly steering people away from those, not that they don't work they just have pitfalls.

13:41 irctc: yeah i was trying to avoid them, but all the examples for trees in clojure are using these two

13:41 when defining custom data structures, (like quad trees or whatever) I don't need to make it a new type

13:41 andyf: As was mentioned earlier, you can make trees with nested maps.

13:41 irctc: right?

13:43 andyf: If you want different types of "nodes" in your tree, you can have a :kind or :type key with a value that tells you what 'type' it is.

13:43 irctc: arrdem: I actually did that, adding stuff blows up the stack though, I could try switching the recursive calls to loop/recur, but it seemed like zippers would help

13:44 arrdem: this is what i had

13:44 http://pastebin.com/1GFqvxj6

13:48 andyf: irctc: There is a call to add-points with the wrong number of args in there, yes?

13:50 irctc: andyf: oh there might be

13:53 andyf: You never have x or y coordinates the same as in other points? If you do, next-quad will return nil

13:55 It seems like how balanced this quad-tree is depends heavily about the value of :len, and how spread out the points are that you are adding.

13:56 Seems you could easily end up with a long skinny tree with very little or no branching.

13:56 s/heavily about/heavily upon/

13:57 I haven't implemented a quad tree before, or looked at what variants exist, but I'd bet there are rebalancing variants that are more complex to implement, but guaranteed to avoid that problem regardless of the order in which points are added.

13:59 justin_smith: andyf: a quick search tells me for balancing you want k-D trees, which are a superset of octrees, which are a superset of quadtrees

14:01 but it is trickier than regular balancing via rotation, because these trees have extra invariants that a linear tree does not

14:01 andyf: that wouldn't surprise me.

14:02 justin_smith: that is, you can see a normal red-black tree as a balanced 1d tree, where a quad tree is a unbalanced 2d, octree unbalanced 3d, k-d-tree balanced n-d

14:03 "The algorithm checks whether there could be any points on the other side of the splitting plane that are closer to the search point than the current best. In concept, this is done by intersecting the splitting hyperplane with a hypersphere around the search point that has a radius equal to the current nearest distance."

14:03 andyf: I also wouldn't be surprised if there is a rebalancing quad-tree for 2d that avoids some of the complexity of higher dimensions.

14:04 justin_smith: could be, but k-d generalizes both up and down

14:21 irctc: andyf: that's probably true

14:21 andyf: yeah, i didn't account for edges

14:23 rritoch: Does anyone know how to fix a multiline regex so it doesn't break the java stack if there's no end to the match? https://github.com/rritoch/lein-sablecc/blob/master/src/leiningen/sablecc/compile.clj#L33

14:24 I made this code to strip out block comments so it would ignore any Package declarations in comments, but if there's a '/*' in the grammar, and no comment to close it /* */ I get a java stack error.

14:38 kenrestivo: huh, i've run into a situation where async/alts! locks up hard, even if there's a timeout, the timeout never fires.

14:38 (async/alts! [kill-chan ins (async/timeout timeout)])

14:39 according to tools.trace, alts! gets called, but never returns.

15:10 ticking_: I wonder why clojure allows for nil in collections while it disallows it in chans. Hindsight?

15:15 godd2: ticking_ perhaps because in a channel, you can be waiting for the next thing. You wouldn't shove nil through a channel, because empty space is simply waiting for the next thing to process. however in a collection, the space between members is discrete, so the only way to represent empty space between members is with nil.

15:16 since the default is "sit there and do nothing" for a channel, it's redundant to send a message which tells it to not do anything

15:16 ticking_: godd2: good explanation, but I wonder if :custom/nothinghere elements would be cleaner

15:17 godd2: Well I mean, if you think of the real world, sure, you can always send someone an empty box.

15:17 justin_smith: ticking_: checking for truthy vs. falsey is more concise than checking for :custom/nothinghere

15:18 godd2: but it doesn't make sense to, let's say in a restaurant, send a cook an order with nothing on the ticket.

15:18 ticking_: nil to me is the value of "something nonsensical" so a collection with elements of a certain problem domain should contain the placeholder elements of said domain

15:18 justin_smith: maybe the empty message could just be :yo/sup

15:18 hellofunk: i'd enjoy any tips on making this little algorithm more elegant, which i'm sure is possible: https://gist.github.com/hellofunk/caf3de6b465d6e2ab2f6

15:18 godd2: ticking_ ah, well I'd say that nil isn't "nonsense", its just not anything else

15:19 its the answer to the question "what is a number which is even and odd?"

15:19 the question isn't nonsense, the answer is that there aren't any

15:20 ticking_: justin_smith: yeah but I would rather dispatch on my custom element than have an ambiguous (first []) (first [nil]) :/, maybe it's just a matter of taste though

15:21 borkdude: how to check for byte-array with prismatic/schema?

15:22 ticking_: godd2: you mean as in (and (even? x) (odd? x)), but the answer to that is ironically false :P

15:22 ,(and (even? 0) (odd? 0))

15:22 godd2: no, that's the answer to the question "is this number even and odd"

15:22 clojurebot: false

15:23 borkdude: got it (Class/forName "[B")

15:23 godd2: which is different from what I stated previously

15:24 ticking_: godd2: if you mean that the answer to "what is a number which is even and odd?" is nil, I'd disagree to

15:24 godd2: ticking_ oh? you have a different answer?

15:25 ticking_: godd2: ah good I understood correctly now :), yeah because nil is not a number

15:25 godd2: :P

15:26 now, in the restaurant example, if the cook came up and asked the servers if there was any work to be done, then nil would make sense, but that wouldn't be a channel anymore

15:27 ticking_: godd2: In the restaurant example I would expect the waiter to return a collection

15:27 godd2: same goes for the ticket of work to be done

15:27 godd2: clojure separates nil from '() for that reason right?

15:28 godd2: ticking_ right. its the difference between "give me the number which..." and "give me the list of numbers which..."

15:28 because an empty list has properties which nil does not

15:28 for example, you can put things into an empty list, but you can't put anything in nil

15:29 ticking_: I think a lot of bugs could be prevented if (conj [] nil) would be the identity

15:29 godd2: ticking_ perhaps, but you might also introduce other bugs

15:29 ticking_: ,(conj nil 1)

15:29 you think so ? ;P

15:29 clojurebot: (1)

15:30 ticking_: godd2: nil is the end of seqs as well as the empty map

15:30 godd2: ,(cons nil 1)

15:30 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

15:31 ticking_: at least when it comes to operations that take them

15:31 ,(cons 1 nil)

15:31 clojurebot: (1)

15:31 godd2: ,(cons '() 1)

15:31 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

15:32 ticking_: ,(cons 1 '())

15:32 conj and cons have reverse arguments

15:32 godd2: yeah, but I wonder how we'd code if we didn't live in the constant fear of a nullpointer exception like the haskellers

15:32 clojurebot: (1)

15:32 AimHere: Maybe we'd code like the haskellers

15:33 godd2: ticking_ well I mainly code in Ruby, so I don't have that fear ;)

15:33 ticking_: AimHere: is that good or bad in you opinion :D

15:44 godd2: A nice side effect would be that map could filter and assoc could dissoc, so no longer a need for the non existent dissoc-in

15:44 godd2: the biggest downside I see is that (assoc [0 1 2] 1 nil) is inefficient in the current vector implementation

15:44 borkdude: can you collect "normal" args in a list like (defn f [x y :as z] z)?

15:46 simon: Aloha!

15:47 Im quite new to clojure and are writing a blackjack game, and I represent a hands value as a list of lists since Aces can be either 1 or 11. I wanna define a function that calculates the set of possible values of a set and needs a way to combine a lists of lists to all the different lists that can be combined from them.

15:48 That is probably a bit confusing.

15:48 But in explenation.

15:48 [[10] [9] [10]] -> [[10 9 10]] , [[5] [1 11]] -> [[5 1] [5 11]], [[1 11] [1 11]] -> [[1 1] [1 11] [11 1] [11 11]]

15:48 andyf: Cross product, or Cartesian product, are two names for that.

15:48 simon: Using the returned lists I wanna map a + reduce to get the different values.

15:49 Yeah, im using cartesian product to generate my deck.

15:49 But I dont relaly know how to do it for a list of lists, if that makes sense?

15:49 andyf: If you want a library to help with that, with source code you can look at, math.combinatorics has it.

15:50 simon: Okok, thanks.

15:50 andyf: Library in general: https://github.com/clojure/math.combinatorics The particular function: https://github.com/clojure/math.combinatorics/blob/master/src/main/clojure/clojure/math/combinatorics.clj#L117

15:51 That isn't necessarily a beginner-level function to read and understand easily, necessarily.

15:52 department of redundancy department -- the number of times I reuse words in a sentence that I don't re-read and edit is alarming.

15:52 simon: :)

15:55 Sweet! Clojure is so neat. (apply ../cartesian-product (into () [[5] [1 11]])) -> ((5 1) (5 11))

15:55 TEttinger: that shouldn't work, should it?

15:55 .. is already a symbol

15:55 simon: clojure-blackjack.core> (apply combo/cartesian-product (into () [[1 11] [5]]))

15:55 TEttinger: (doc ..)

15:55 simon: ((5 1) (5 11))

15:56 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

15:56 simon: I didnt want to write out the library name.. :P

15:56 TEttinger: heh

15:57 ,(for [a [5] b [1 11]] [a b])

15:57 clojurebot: ([5 1] [5 11])

15:58 TEttinger: ,(for [a [5] b [1 11]] (list a b)) ;for completeness

15:58 clojurebot: ((5 1) (5 11))

15:58 simon: Hmm, im a bit confused, the (into () ..) bit is uneccecary. So how how does (apply ../cartesian-product [[1 11] [5]]) work?

15:58 So you can apply functions to a sequence I guess and not just lists?

15:59 TEttinger: (into () [[5] [1 11]]) is the same as (list [5] [1 11]) and usually you don't need to ever use lists, vectors work in most of the same places

15:59 simon: Neato.

16:00 Ent_: (repeat 10)

16:00 andyf: simon: cartesian-product is written to take a variable number of sequences as arguments

16:00 simon: andyf: yeah, that I understand.

16:00 TEttinger: it's called the seq abstraction in a lot of stuff that talks about clojure

16:00 andyf: If it had instead been written to take a sequence *of* sequences, then apply would not be needed there.

16:00 simon: Its the apply that boggles my mind now. :)

16:01 Ent_: (take 1 (repeat "Hi"))

16:01 andyf: As maybe a simpler example, + is written to take a variable number of arguments:

16:02 ,(+ 1 2 3 4 5)

16:02 clojurebot: 15

16:02 Ent_: ,(take 1 (repeat "Hi"))

16:02 clojurebot: ("Hi")

16:02 Ent_: ,(repeat 10)

16:02 clojurebot: (10 10 10 10 10 ...)

16:02 andyf: but you can't get a useful result calling it with 1 sequence:

16:02 ,(+ '(1 2 3 4 5))

16:02 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number>

16:02 andyf: If you have a sequence of numbers, and want to add them up, one way is to use apply:

16:02 ,(apply + '(1 2 3 4 5))

16:02 clojurebot: 15

16:02 simon: My mental image of apply is that it just moves in the function into the list. i.e (apply str '(1)) => '(str 1) => (eval '(str 1))

16:03 But from the implementation of apply its clear thats not how it works.

16:03 justin_smith: simon: ##(apply + 1 2 3 [4 5 6])

16:03 lazybot: ⇒ 21

16:03 Ent_: ,( #(+ %) '(1 2 3 4 5))

16:03 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number>

16:03 andyf: The implementation of apply is a bit lower-level code than most Clojure

16:03 for performance reasons.

16:04 There are other ways to write it that would look more like the way you described it in words.

16:05 If you have a number of arguments that is known when you are writing the code, there isn't much reason to use apply. It is necessary to use apply in cases where you have a sequence of arguments at run time, and you don't know how long it is.

16:07 simon: So, an implementation using apply is not idiomatic in this case you say?

16:07 Ent_: ,( #(+ %) [1 2 3 4])

16:07 simon: http://pastebin.com/1C384QqL hand-value, at the end of the file.

16:07 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentVector to java.lang.Number>

16:07 justin_smith: Ent_: what are you trying to do?

16:07 andyf: The example of (apply + '( 1 2 3 4 5)) I would never write that way except as an example. I would write it (+ 1 2 3 4 5)

16:08 Ent_: seeing if I can do `apply` without using apply

16:08 ticking_: (fold + coll) for really large cols ;)

16:09 justin_smith: yeah, you can use reduce instead of apply for things like +

16:09 ,(reduce + [1 2 3 4 5 6])

16:09 clojurebot: 21

16:09 justin_smith: ticking_: assuming by fold you mean reduce

16:09 kenrestivo: i wonder if the universe will explode if i do somthing to the effect of (async/go-loop [] (let [res (async/<! c)] (async/>! c (do-stuff res))))

16:09 Ent_: Ah that makes more sense

16:09 thanks

16:10 ticking_: justin_smith clojure.reducers/fold

16:10 justin_smith: ahh

16:10 kenrestivo: especially since do-stuff can block

16:11 justin_smith: kenrestivo: locking vs. blowing?

16:11 kenrestivo: um, blowing?

16:11 justin_smith: up

16:11 kenrestivo: locking up, is what i've been experience

16:11 ticking_: simon, who said it was not idiomatic :)? sorry I missed the start

16:12 kenrestivo: i'm starting to think this message bus idea was very, very stupid.

16:12 but it's hard to do this with discrete channels since there are circular relationships betwen the various components that need to communicate. a "network-like" bus with routing is optimal.

16:12 ticking_: btw does someone know of a clojure lib that takes two edn datastructures and returns a Om style assoc-in able diff?

16:13 kenrestivo: i feel like i'm trying to make core.async do stuff it was not designed to do.

16:14 justin_smith: kenrestivo: a good pattern is to take coordination vs. work that may block for a while, and put them in separate contexts, so there is always a quick response time from the coordinator

16:15 kenrestivo: that might work, a central router rather than a bus topology.

16:16 justin_smith: the router can even split into more than one parallel unit, as long as none of them lock up on long running tasks

16:17 also, Java Concurrency in Practice is a surprisingly good book, one of the items on the "Clojure reading list", worth looking at even if you aren't doing Java

16:17 kenrestivo: yeah, i feel like part of the problem is i do not have a deep understanding of what-all is going on under the hood in the jvm.

16:18 ticking_: I domt thi

16:18 I dont think the people writing the jvm have that

16:19 Muonic: kenrestivo: I've only just started looking at core.async, but it doesn't feel well suited to functioning as a message bus

16:20 kenrestivo: thanks for the sanity check.

16:20 Muonic: mostly since multicasting doesn't fit in the model

16:20 kenrestivo: well there's pub/sub

16:20 and mult/tap

16:22 SagiCZ1: whats the cure for a function that takes too many arguments?

16:22 ticking_: Yeah they seem to handle multicast reasonably well, even though some buffering is required

16:22 Muonic: i was thinking, in the sense you mayw ant multiple recievers to get the same message

16:22 it becomes awkward trying to use mult/tab + pub/sub to acheive that effect

16:22 ticking_: Muonic, yeah that is what mult is for

16:24 really? hm, but creating a chan and tabing with it seema like its equivalent to a bus subscribe right?

16:25 SagiCZ1, depends, an opts map?

16:27 SagiCZ1: cfleming: it would be nice to have some support of (:require [... :reger [list-of-symbols]]) ... for example if i already have some there, i would like to have new ones added automatically with alt+enter.. and if the caret is in the list-of-symbols, it could show all available symbols for refering on ctrl+space

16:29 cfleming: and other cool thing would be a better support of variable extraction (default ctrl+alt+v) which doesnt work well and doesnt work at all in repl console.. just throwing it out since i always forget these

16:29 kenrestivo: ticking_: there's some ceremony with pub/sub, less so with mult/tap

16:30 and the ceremony of pub/sub with mix becomes quite cumbersome. makes me think i'm Doing It Wrong.

16:30 cfleming: SagiCZ1: Yes, the better support for refer is definitely on the cards

16:31 SagiCZ1: Do you have examples of the variable extraction not working?

16:31 SagiCZ1: it does work but i dont think i understand how can it help me.. it just replaces the selected sexp or value with the symbol 'value'.. i would expect it to be defined in the let or in root via def if there is no enclosing let

16:32 ticking_: kenrestivo: hm, yeah such a tight feedback loop with a channel feels a bit weird, but on the other hand if one imagines a channel as a queue it's not that strange

16:33 feels like a infinite computation, but there are things hidden in our code everywhere just not as obvoous and scary

16:33 cfleming: SagiCZ1: When you do the extract, you have to select two things, the expression to extract, and where to extract it to

16:33 SagiCZ1: At the point that you tell it to extract to, you'll get a new let binding

16:34 SagiCZ1: If you select an existing let binding as the extract point, it will be added to that.

16:34 lxsameer: hey guys, how much clojure-android is slower than java on android ? is it noticeable ?

16:34 cfleming: SagiCZ1: I think what you're running into is a bug if you try to extract to the same point you're extracting from

16:35 SagiCZ1: cfleming: oh! it does work.. i didnt read the tooltip.. i thought it wanted me to select what i want to extract, which is something intellij does for java sometimes.. so i was choosing the lowest possible insertion which just replaces it with "value" .. but choosing enclosing let works fine

16:35 cfleming: SagiCZ1: Great - yeah, I need to fix that bug, it's almost never what you actually want to do but it's easy to do by mistake

16:36 SagiCZ1: cfleming: ok, but in repl the shortcut does nothing.. maybe its shadowed by something by my own settings

16:36 cfleming: SagiCZ1: I'll test that, it may be that it doesn't work - the REPL editor is subtly different in annoying ways

16:36 Ent_: @lxsameer I think it's quite slow. Atleast the time it takes for the app to start is quite long.

16:36 cfleming: SagiCZ1: If it doesn't work I'll fix for the next drop

16:37 lxsameer: Ent_: damn, thanks ,

16:37 SagiCZ1: cfleming: alright.. thanks for the info :)

16:37 cfleming: SagiCZ1: No worries!

16:37 Ent_: Yep, sure

16:39 cfleming: SagiCZ1: BTW for the extraction point selection I'm planning to add support for using ctrl-up/down to select only existing let bindings, since that's often what you want to do

16:40 SagiCZ1: cfleming: good idea, i am excited about this feature, i use it all the time in java

16:40 cfleming: SagiCZ1: Yeah, it's really useful

16:41 SagiCZ1: I'll be adding extract method too sometime soon

16:41 SagiCZ1: BTW inline binding works too, which I also use a lot

16:41 SagiCZ1: cfleming: what is that?

16:42 cfleming: SagiCZ1: If you no longer need a variable as a local binding, you can inline it and the uses will be replaced with the binding body, like inline variable in Java

16:42 SagiCZ1: cfleming: so thats basically extracting variable backwards?

16:43 cfleming: SagiCZ1: exactly

16:43 SagiCZ1: cfleming: hey this is way cool, i didnt know about this one, never used it.. smart

16:44 this will save some time too\

16:50 justin_smith: Ent_: some folks have addressed the startup time on android issues by compiling clojurescript (which has minimizing / tree shaking compilation via google closure)

16:51 Ent_: justin_smith: Oh. Guess the video I saw discussing it is now outdated.

16:54 justin_smith: oh, oops, meant to address that to lxsameer

16:55 lxsameer: justin_smith: clojurescript ? I thought we use clojure itself

16:56 justin_smith: lxsameer: the point is clojurescript can load much faster / use less of the device's ram

16:56 (though it won't likely perform as well for a long running / computation heavy process, but that isn't the only kind of process you have in a mobile app)

17:00 mfikes: lxsameer: Sam Beran has been investigating this. It involves ClojureScript -> JS -> Java bytecode -> Dalvik. I put together a little repo making it easy to try the sequence up to the Java bytecode: https://github.com/mfikes/cljs-cl

17:02 lxsameer: I was exploring whether Sam's approach can also be used to make "Clojure" command-line apps that run with low start-up time

17:04 Ent_: mfikes: Would you say as it stands, clojure-android is decent for making apps?

17:05 mfikes: Ent_: I don't have any real experience with it. I've been focusing on ClojureScript on iOS.

17:05 arohner: I have lein fighweel finally working, but now how do I make the (Om) page re-render?

17:05 Ent_: ok

17:05 arohner: ...re-render when fighweel determines that the code reloads, that is

17:07 mfikes: Ent_: Sam Beran's approach resulted in ridiculously fast launch time, FWIW. (I can't recall, but I think it was on the order of 100 ms or so.)

17:08 Ent_: mfikes: Cool. Will have a look at it.

17:09 mfikes: Ent_: His tweet about it: https://twitter.com/samberan/status/523929208595025920

17:10 sameerynho: justin_smith: clojurescript ? I thought we use clojure itself

17:12 Ent_: mfikes: Thanks. going through google results for Sam & clojure-android stuf

17:13 mfikes: Ent_: I bet the real challenge with Sam's approach is host interop with the Android stuff. For example, with the command line stuff, I had to do this funky call to print (via JS into Java): https://github.com/mfikes/cljs-cl/blob/master/ClojureScript/print-fibs/src/print_fibs/core.cljs#L6

17:16 Ent_: mfikes: Given that Dalvik VM is different from JVM, is there any other way to do it? I wonder if we just have to sit down and reimplement the whole thing.

17:17 mfikes: Ent_: Perhaps you could embed a JavaScript engine in our Android app. That's what I do on iOS.

17:19 Ent_: Or wait for Clojure to get faster (tree shaking, or whatever they are doing in the fastload branch?)

17:22 Ent_: mfikes: Is the overhead of embedded JS engine within acceptable range or are you still working on optimising it?

17:28 mfikes: Ent_: It is fine on iOS. There's the phase where it parses and loads the JS and this takes 386 ms (I think this was on an iPod touch). That will only get faster. After that, the CPU and memory effects during normal app usage haven't been something I've been able to notice, when comparing to other native apps I've made.

17:34 justin_smith: mfikes: as I understand it fastload is just lazy about loading definitions (and ends up being slower for longer processes because it needs to check whether things are loaded before running them)

17:35 mfikes: arrdem can tell us more about the details, but simplistically speaking since eval is defined to be present in clojure at runtime, you need a modified language definition to get tree shaking that works properly.

17:37 mfikes: justin_smith: Interesting dilemma. I have no eval calls anywhere in any of my application-level code.

17:39 justin_smith: I guess I like all of the flexibility during dev, but it would be interesting to have all sorts of semantics-bending whole-program optimizations for deployment. But everything is fast enough for me. Simpler is better :)

17:44 SagiCZ1: when i call (take-while pred (iterate ... )) the pred is called twice before calling fn in iterate.. is that because of chunking?

17:44 the function i iterate can never return nil.. but the predicate sometimes gets nil as an argument.. i dont understand how is that possible

17:47 cant replicate it on a simpler example

17:48 AimHere: So presumably the problem is something to do with whatever's in the ellipsis

17:49 What' the function in the iterate?

17:49 SagiCZ1: it just returns an updated vector.. nothing fancy

17:49 the predicate checks whether the vector passes a condition

17:50 take-while:(0.5893322273289112 -0.014178434390894584 0.8908398415838613)

17:50 iterate:(0.5893322273289112 -0.014178434390894584 0.8908398415838613)

17:50 take-while:(0.5788656395366827 -0.11356364514133756 0.8944496094541826)

17:50 take-while:(0.5893322273289112 -0.014178434390894584 0.8908398415838613)

17:50 take-while:nil

17:52 i dont get it

17:53 AimHere: Again, not enough info to go on

17:53 SagiCZ1: the predicate gets called when its not supposed to

17:54 or maybe i dont understand how this construct works

17:54 iterate should create lazy seq of elements.. which get passed to the predicate in take-while as one argument right?

17:54 AimHere: Yes

17:55 What happens if you '(take 100 (iterate inc ..))'?

17:55 Is there a nil thrown up ever?

17:55 SagiCZ1: nope

17:55 that one works fine

17:56 AimHere: Is the predicate recursive?

17:56 SagiCZ1: the predicate is #(neg? (first (mmult (trans %) point class)))

17:58 so strange

17:58 justin_smith: and trans gets nil as an arg?

17:59 SagiCZ1: yes.. after random number of iterations

17:59 but (take 100 ... ) works

18:00 feels like all of my code is correct but the take-while iterate logic is acting up

18:01 justin_smith: iterate and take-while are really extensively used and debugged...

18:02 SagiCZ1: what can force the take-while predicate to be evaluated several times in a row without the iterated fn being called?

18:02 justin_smith: I think it's more likely your tracing logic is flawed than that happened

18:02 SagiCZ1: its like: iterate->pred->iterate->pred->iterate->pred->pred->pred->exception

18:03 yeah ok, its just println

18:03 not sure how to debug it

18:03 maybe i will dust off the debugger

18:15 ok, it was my mistake of course.. the nil was coming from the initial iterate value

18:27 how would i return the first positive number in collection?

18:28 [-4 -8 -9 -5 -9 10 13 46] --> 10

18:28 i think there might be a better way

18:28 ,(last (last (take-while #(some neg? %) (partition 2 1 [-4 -8 -9 -5 -9 10]))))

18:28 seangrove: What are the advantanges of reified, first-class namespaces, and the disadvatanges of cljs' current implementation?

18:28 clojurebot: 10

18:28 seangrove: dnolen_: ^^ just in general

18:28 Nothing too detailed

18:29 hipsterslapfight: SagiCZ1: `(first (filter pos? collection)` maybe?

18:29 SagiCZ1: thats way better, thanks

18:29 (inc hipsterslapfight)

18:29 lazybot: ⇒ 1

18:30 hipsterslapfight: np

18:30 AimHere: I keep thinking that 'some' does that job, but it just gives the truthy value instead

18:32 Frozenlock: AimHere: That's because of 'pos?', not 'some'.

18:32 ,(some #(when (pos? %) %) [-4 -8 -9 -5 -9 10 13 46])

18:33 clojurebot: 10

18:33 AimHere: Yeah, I know

18:33 You can write the predicate to make some do that job, but then the first/filter dance becomes prettier

18:36 Frozenlock: That's kind of sad in a way... I would love to have filter/some behave in the same way.

19:08 justin_smith: Frozenlock: instead of when, you can use and (which helps emphasize it's a value, not a side effect)

20:24 SagiCZ1: I just realized there is this one too: ##(first (drop-while neg? [-4 -8 -9 -5 -9 10 13 46]))

20:24 lazybot: ⇒ 10

20:26 ajmccluskey: Anyone know an easy way to print a transient map the same way a regular one is printed?

20:27 rhg135: i guess you could redefine print-method

20:27 ajmccluskey: rhg135: right. I guess I'm really checking if there's an existing function or something quick and dirty.

20:28 rhg135: not that im aware of, ajmccluskey

20:28 but wait for them smart folks

20:28 ajmccluskey: haha, thanks :)

20:30 rhg135: ajmccluskey: also this is quick and very dirty

21:52 justin_smith: http://stackoverflow.com/questions/27736719/core-async-machine-that-loops-until-a-fx-returns-true what this guy is doing looks smelly, but I don't know the right answer

22:19 kenrestivo: a weird side-effect of using core.async is, i've noticed, it pushes me toward writing imperative code. loops, and so on.

22:19 looks like that guy got the disease too. "oh, i'll just busy-wait"

22:20 i find the more i use core.async, the less functional my code is.

22:20 maybe i should get on the transducer tip.

22:21 jonasen: kenrestivo: which isn't surprising since core.async isn't a functional construct

22:21 AWizzArd: justin_smith: why did this guy not install an onload handler for the body? This function gets called by the JSVM when the body was loaded.

22:21 <body onload="myFunction()">

22:22 kenrestivo: i'm tempted to say "use om or reagent", but that's too dismissive and proabbly unnecessarily heavyweight for what he's trying to do.

22:27 justin_smith: it kind of begs the question: "why or what is creating that element, and why can't it do that (.start f) once it does?

22:30 rhg135: core.async is meant to do the communication

22:30 hence the c in csp

Logging service provided by n01se.net