#clojure log - Aug 15 2015

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

0:41 mcktrtl: is it possible to give an async channel a custom string representation somehow? so like, if I do something like (let [ch (chan)] (println ch)) I'll see something I can identify and not "clojure.core.async.impl.channels.ManyToManyChannel@25f32e46"

0:51 oddcully: mcktrtl: may with meta data?

0:51 ,(let [c (with-meta [] {:very :special})] (binding [*print-meta* true] (pr c)))

0:51 clojurebot: ^{:very :special} []

0:55 mcktrtl: (with-meta (chan) {:very :special}) -> ClassCastException clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to clojure.lang.IObj

0:55 am i doing that wrong?

1:12 amalloy: channels don't support meta

1:12 (is what that error message is saying)

1:18 mcktrtl: ahh ok :( thanks

1:19 rhg135: I'd wrap it in a record/map

1:20 mcktrtl: like {:writer-ch (chan) :network-ch (chan)} ?

1:22 rhg135: Yeah

1:23 Or a record and define a print-method

1:23 mcktrtl: oh right, thanks. i guess i should have thought of that since i'm doing it already

1:24 rhg135: Np

1:24 mcktrtl: i was just putting some logging in to a function that takes a channel as an argument and didn't think of the bigger picture

1:26 rhg135: It's unfortunate there is no metadata on channels

1:57 amalloy: rhg135: it's a little hard to imagine actually allowing it though, right? think of the consequences. (let [c (chan), c' (with-meta c {:blah true})] (go (>! c 1)) (go (<! c)) (go (<! c'))). which of the two reads returns 1? either? both?

1:58 with-meta is supposed to return a value that's indistinguishable from the input, but you can't really do that because channels are mutable objects, not values

1:58 ,(with-meta (atom 0) {:blah true})

1:58 clojurebot: #error {\n :cause "clojure.lang.Atom cannot be cast to clojure.lang.IObj"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Atom cannot be cast to clojure.lang.IObj"\n :at [clojure.core$with_meta__4134 invokeStatic "core.clj" 217]}]\n :trace\n [[clojure.core$with_meta__4134 invokeStatic "core.clj" 217]\n [clojure.core$with_meta__4134 invoke "core.clj" -1]\n [sandbox$eval...

1:58 amalloy: it doesn't work for atoms or refs either, for the same reason

1:59 metadata on channels is such an obvious thing there's no way rich *forgot* to do it; there's got to be a reason why it's no good. i speculate that it's this reason, but maybe it's some other one

2:09 bacon1989: so who else is hoping that clojure takes over the COBOL market?

2:10 I was thinking of writing an FFI for it, since I think it could probably adopt a lot of interested fellows

2:17 TEttinger: bacon1989: how would that work? I don't know if cobol usually runs on the JVM, but if it does then you probably wouldn't even need an FFI

2:26 J_A_Work: TEttinger: there is a version of Visual COBOL that runs on the JVM apparently.

6:46 devn: WickedShell: (set *warn-on-reflection* true). My emacs setup shows me by underlining in yellow the places I'm missing hints. Cursive does something similar IIRC.

6:55 expez: devn: which package does that underlining? squiggly-clojure?

8:52 WickedShell: devn: right I'm familiar with that, however when I actually dump the heap very few of the instances caught by that are actually populating my 4 million instances of reflect (somewhere less then 1 percent). And I can't find enough in the object when looking at it in the heap dump to find it's origin

11:14 joejag: Hello, I'm looking for help trying to figure out a simple way of solving a problem taking text from a collection until a condition is met: https://gist.github.com/joejag/5b19459f05a7cad977ff

11:54 justin_smith: ,(reduce (fn [[s,n]e] (if (pos? n) [(str s (when (not-empty s) \,) e), (dec n)] (reduced s))) ["",2] (clojure.string/split "a,bb,ccc,dddd" #","))

11:54 clojurebot: "a,bb"

11:54 justin_smith: that's a bit verbose, I guess

11:55 ,(clojure.string/join \, (take 2 (clojure.string/split "a,b,ccc,dddd" #",")))

11:55 clojurebot: "a,b"

12:02 gfredericks: hello

12:02 kwladyka: why the same code as jar file has better performance then in REPL?

12:02 justin_smith: because lein is slow

12:02 and so is nrepl

12:02 gfredericks: kwladyka: presumably "better performance" is just startup time?

12:02 justin_smith: the biggest difference you will see is startup time

12:03 yeah

12:03 kwladyka: justin_smith, but i am counting time as (time ...) so startup time doesn't matter? does it?

12:04 justin_smith: the other difference is that lein uses a jvm arg that turns off hotspot

12:04 kwladyka: even more REPL started, load libraries and after then i run some command

12:04 justin_smith: and usually with an uberjar you won't be turning that off, and for some code bases that can make a big difference

12:06 kwladyka: justin_smith, if i run java with -Xint can i check if it is that?

12:08 justin_smith: kwladyka: yeah, that should test it

12:10 kwladyka: anyway i am writing article about how to improve algorithm performance. If you can share with me any interesting article which i can read to make something better will be great :)

12:14 justin_smith, hmm i don't think it is because hotspot

12:14 without hotspot it takes agaes, much much worst then REPL

12:15 justin_smith: kwladyka: lein turns off hotspot

12:15 this is a documented fact

12:15 kwladyka: justin_smith, i understand but when i runed jar without hotspot it takes ages.... i couldn't even wait to finish counting

12:15 hmm

12:15 very strange

12:16 based on that fact extremely strange :)

12:17 justin_smith: kwladyka: you can use :jvm-opts ^:replace ["-server"] to see how lein repl performs with hotspot on

12:17 (that's a config you add to project.clj of course)

12:18 kwladyka: justin_smith, is it equal :jvm-opts ["-Xms4g" "-Xmx4g" "-server"]) ?

12:18 justin_smith: no, your "-server" arg does nothing because you are not using the ^:replace metadata

12:18 kwladyka: ok

12:19 justin_smith: so keep those opts, and throw in ^:replace as a metadta

12:19 kwladyka: the reason is that jvm opts are merged with the lein defaults, and those override the -server options, but ^:replace prevents that

12:21 kwladyka: you know so much about Clojure, are you close to develop clojure.core?

12:21 justin_smith: kwladyka: I haven't really tried

12:21 I'm too lazy

12:22 kwladyka: but you looks like a guy with huge experience about Clojure :)

12:22 justin_smith: yeah, I'm barely (and not really) meeting my deadlines at work though, and clojure.core doesn't even pay money

12:24 kwladyka: justin_smith, running with :jvm-opts ^:replace ["-server" "-Xms4g" "-Xmx4g"] didn't change the time

12:24 maybe it has even few seconds more

12:25 justin_smith, can i ask you what kind of software are you creating?

12:25 justin_smith, yes with -server it is running even longer about few seconds

12:25 justin_smith: kwladyka: a paid app for social media discovery

12:25 timothyw: Quick question

12:26 I want to print out a long list - but Clojure ellides some of it

12:26 how can I print an entire list to string / edn

12:26 … already tried pr , pr-str , etc

12:27 justin_smith: ,*print-length*

12:27 clojurebot: 5

12:27 justin_smith: that value effects all of those printing methods

12:27 if it's set to nil, there will be no limit

12:27 kwladyka: timothyw, and i suggest use pprint <- it is much more readable

12:27 timothyw: a ha

12:27 justin_smith: ,(doc clojure.core/*print-length*)

12:27 clojurebot: "; *print-length* controls how many items of each collection the printer will print. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum number of items of each collection to print. If a collection contains more items, the printer will print items up to the limit followed by '...' to represent the remaining items. The root binding is...

12:28 timothyw: kwladyka: yeah I definitely tried that

12:28 justin_smith: timothyw: you can change the value with set! https://clojuredocs.org/clojure.core/*print-length*

12:29 kwladyka: justin_smith, are you coding only in Clojure or you are polyglot?

12:29 justin_smith: kwladyka: the app is 100% clojure unless you count like sql

12:30 kwladyka: justin_smith, nice

12:30 timothyw: whew - awesome that does the trick

12:30 cheers

12:31 kwladyka: justin_smith, BTW: do you have any idea why REPL is slower then jar? my tests didn't prove it is because hotspot. Even more when i runed jar with -Xint it takes much much longer then REPL.

12:32 justin_smith: no, I don't know what the other difference would be

12:32 kwladyka: ok

12:32 anyway it is strange REPL works faster then jar without hotspot...

12:33 can i check if hotspot is runed in REPL?

12:33 justin_smith: kwladyka: one difference, maybe is that lein does not turn on Xint, it uses the TieredCompilation=0 or something like that

12:33 kwladyka: iirc there is a vm flag that will make any runtime optimization decisions verbose...

12:34 kwladyka: justin_smith, but nothing really appear on screen, but maybe it can affect the time

12:35 justin_smith: -XX:-PrintCompilation maybe

12:36 http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

12:39 kwladyka: justin_smith, i runed with this flag jar file and it doesn't change anything

15:10 sdegutis: (remove nil?) is usually what you actually want as opposed to (keep)

15:12 justin_smith: sdegutis: unless the alternative is (remove nil? (map ...)) because you should just use keep in that case

15:14 sdegutis: justin_smith: false goes away in that case too

15:14 sometimes you want to keep true/false but remove nil

15:15 Like how booleans have three choices (true, false, file not found).

15:15 justin_smith: ,(keep identity [false true nil 1])

15:15 clojurebot: (false true 1)

15:18 sdegutis: Oh right, I misremembered (doc keep). It only does nil.

15:18 (keep identity) == (remove nil?)

15:19 But (remove nil?) expresses intent much more clearly though.

15:19 justin_smith: sdegutis: what else would keep mean other than "I don't want the nil results from this mapping"

15:20 sdegutis: "keep" isn't the problem, "identity" is.

15:20 remove nil? is much more English, keep identity is much more C++

15:20 justin_smith: I mean I don't use (map identity ...) either

15:21 sdegutis: keep identity makes use of more implications, remove nil? is completely straight forward

15:38 gfredericks: ,(doc keep)

15:38 clojurebot: "([f] [f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects. Returns a transducer when no collection is provided."

15:38 gfredericks: haha transducer

15:39 justin_smith: gfredericks: combines map with (partial remove nil?), very useful

15:40 gfredericks: yeah I've used it before; was just curious if it got transducified

15:40 sdegutis: Question: are transducers effectively the same as partial'ing semantically (aside from their better performance)?

15:41 So is (partial remove even?) the same as (remove even?)?

15:42 gfredericks: nope

15:42 they're a moderate haskellian headache

15:42 sdegutis: How are they different? It seems like you could use them the same way.

15:42 Oh?

15:43 gfredericks: (map foo) is a transducer, and a transducer is a function that transforms reducing functions

15:44 sdegutis: Would you use them similarly to how you would with ->> just without the ->> ?

15:45 gfredericks: you can combine them with comp

15:45 sdegutis: I really don't understand transducers, I read the docs and I just don't fully get it.

15:45 gfredericks: ,(->> (range) (map inc) (filter even?) (take 5))

15:45 clojurebot: (2 4 6 8 10)

15:45 Bronsa: sdegutis: transducers have nothing to do with currying

15:45 sdegutis: So instead of (->> (range) (remove even?) (take 3)) you would use ((comp (remove even?) (take 3)) (range))

15:45 gfredericks: (reduce ((comp (map inc) (filter even?) (take 5)) conj) [] (range))

15:45 ,(reduce ((comp (map inc) (filter even?) (take 5)) conj) [] (range))

15:45 clojurebot: [2 4 6 8 10]

15:46 sdegutis: ##(->> (range) (remove even?) (take 3))

15:46 lazybot: ⇒ (1 3 5)

15:46 gfredericks: ^ I had no idea if that would work or not

15:46 sdegutis: ##((comp (remove even?) (take 3)) (range))

15:46 lazybot: ⇒ #<core$filter$fn__4361$fn__4362 clojure.core$filter$fn__4361$fn__4362@3e7b8ad4>

15:46 sdegutis: Ah.

15:46 gfredericks: note how I made the transducer and then called it with conj as its arg

15:46 sdegutis: Ahh.

15:47 gfredericks: conj being the reducing function

15:47 Bronsa: OTOH you shoulnd't use them that way

15:47 gfredericks: :)

15:47 Bronsa: transduce makes it easier

15:47 sdegutis: How?

15:47 gfredericks: yeah there's like three new functions for executing that stuff?

15:47 justin_smith: the major difference with transducers is that you don't make a shitload of lazy-seqs that aren't actually useful

15:47 gfredericks: ~the major difference with transducers is that you don't make a shitload of lazy-seqs that aren't actually useful

15:47 clojurebot: Roger.

15:48 justin_smith: ,(sequence (comp (map inc) (filter even?) (take 5)) (range))

15:48 clojurebot: (2 4 6 8 10)

15:48 Bronsa: (reduce ((comp (map inc) (filter even?) (take 5)) conj) [] (range)) is (transduce (comp (map inc) (filter even?) (take 5)) conj [] (range))

15:48 sdegutis: justin_smith: so it's simply/merely/only a performance boost?

15:48 and serves no other purpos?

15:48 Bronsa: no

15:48 justin_smith: sdegutis: that's not the only purpose no

15:48 Bronsa: sdegutis: read the transducers page in clojure.org

15:49 justin_smith: it also makes it easier to implement the core functions like map, filter, etc. for new data sources (eg. channels in core.async)

15:49 (inc Bronsa)

15:49 lazybot: ⇒ 118

15:49 justin_smith: yeah, that's the right answer

15:49 http://clojure.org/transducers

15:50 sdegutis: Bronsa: I'll read it again but last time I read that it seemed like useless marketing rhetoric

15:51 Bronsa: sdegutis: you must have read a different page than the one I've read then

15:51 justin_smith: sdegutis: can you point out which part of clojure.org/transducers is marketing?

15:51 sdegutis: justin_smith: must be mixing it up with another page

16:04 justin_smith: ,(into [] (comp (map inc) (filter even?) (take 5)) (range)) ; equivalent to Bronsa's transduce

16:04 clojurebot: [2 4 6 8 10]

16:34 expez: If some user does (def foo 1) at the repl. Is there some way to reset this, without knowing the names of the created vars?

16:35 https://github.com/clojure-emacs/cider/issues/1240 I think this user has a pretty weird workflow, but if there's an easy fix to recommend that would be nice.

16:35 justin_smith: expez: you could delete the user namespace. You could use ns-publics or ns-interns to see what all is defined.

16:36 expez: and yeah, like mentioned in that thread, tools.namespace is designed to do that kind of full ns reset

16:36 expez: justin_smith: delete and recreate the namespace? That seems like the simplest thing that could possibly work.

16:36 amalloy: remove-ns is the easy answer, but then you lose the ns mappings to vars in other namespaces

16:37 ,(doc ns-interns)

16:37 clojurebot: "([ns]); Returns a map of the intern mappings for the namespace."

16:37 expez: justin_smith: tools.namespace is limited to undef vars existing in the project, though, right? Anything created at the repl won't be affected?

16:37 amalloy: ,(ns-interns *ns*)

16:37 justin_smith: expez: it restarts namespaces from scratch, removing definitions that are not reflected in the source

16:37 clojurebot: {}

16:37 amalloy: ,(def foo 1)

16:37 clojurebot: #'sandbox/foo

16:37 amalloy: ,(ns-interns *ns*)

16:37 clojurebot: {foo #'sandbox/foo}

16:37 expez: The user reports trying cider-refresh, which calls out to tools.namespace :/

16:38 justin_smith: oh, OK. So yeah, either using ns-interns and selectively ns-unmap to delete bindings, or destroy and recreate the ns

16:39 expez: Can you think of any reason to prefer one over the other? Seems like an easy feature to implement, though I'm not sure it'll get widely used heh

16:40 justin_smith: expez: seems like it wouldn't be hard to implement a function that would take out all definitions and bindings from a namespace, and then use refer-clojure to get the defaults back

16:41 expez: indeed, thanks guys!

16:41 (do (inc amalloy) (inc justin_smith))

16:42 suppose that was too much to ask for, clojurebot :)

16:42 amalloy: justin_smith: if you use ns-interns you won't lose the defaults

16:42 justin_smith: amalloy: but then you also wouldn't unmap required namespaces right?

16:43 expez: lazybot is not nearly so clever, inc is a pseudo-syntax

16:43 amalloy: was that a requirement?

16:43 justin_smith: perhaps only in my imagination :)

16:43 amalloy: in mine it was a requirement to leave them alone

16:44 justin_smith: a full tools.namespace refresh would get rid of any require that wasn't reflected in the ns definition on disk iirc

17:12 biellls: Hi, I've been following the clojurescript tutorial on OS X and I can't get this section (https://github.com/clojure/clojurescript/wiki/Quick-Start#less-boilerplate) to work properly

17:13 I have changed build.clj and index.html as indicated, but i get Uncaught ReferenceError: goog is not defined(anonymous function) @ main.js:1

17:44 arkh: biellis: would you be able to upload what you have so far somewhere?

17:46 biellls: Sure, I will post it on github in a sec

17:53 arkh: Nevermind, I just realized that it was because i had initially added build.clj in src, and my emacs buffer was still saving my edits there even though I had moved the file. Thanks for your help anyways

17:54 arkh: biellls: cool

18:38 dfcarpenterak: Hi everyone, I’m an intermediate javascript developer who made my way to Clojure (also been playing with Elixir as well) through looking into solutions for concurrency/scalability problems with nodejs. Also, I’ve also been using React js + immutable js on the front end and been really enjoying that as well. Anyways, as I slowly become more familiar with Clojure I was wondering if anyone could point me to what are

18:38 considered well designed web-focused open source clojure apps. I’m looking for apps + any reading materials through which I can glean good general architectural recommendations for scalable concurrent clojure apps.

18:54 TEttinger: dfcarpenterak: hm, good question. I don't write web apps, but I think the closest you'll find to an open source _complete_ web app is libraries that have been open sourced from a closed-source commercial venture. I suspect there's not enough motivation to open source a large app and allow a competitor access to your app's internals... there's likely some good architecture advice on dev blogs though.

18:55 Om is likely something you want to look into, it's ReactJS-based

18:55 or was it Rx

18:56 dfcarpenterak: Yeah, I have been playing around with Reagent + reframe also

18:56 TEttinger: I can't keep track of all this stuff I don't use :)

18:56 dfcarpenterak: https://github.com/Day8/re-frame

19:35 domokato: why is there no dissoc-in?

20:04 gfredericks: I think because there aren't obvious semantics for such a function

20:05 but I might be confusing it with something else

20:06 justin_smith: what should (dissoc-in {} [:a :b] :c) return?

20:09 gfredericks: I imagine the call would just be (dissoc-in {} [:a :b])

20:10 justin_smith: oh, right, of course

20:10 I still don't know what it would return

20:19 gfredericks: either {} or nil

20:19 apparently there is such a function in core.incubator wherever that is, so we could go look at it

20:21 justin_smith: https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj#L62

20:25 https://www.refheap.com/108261

20:26 AWizzArd: Maybe something like (update-in m [k1 k2 k3] dissoc :key)

20:26 justin_smith: AWizzArd: on my refheap paste you can see what the version from incubator does

20:42 hiredman: I have this kademlia implementation I am playing with, and it stores some information as a vectors, but that information could just be stored as ByteBuffers, but when I make that change it causes a stackflow where all the frames are at clojure.lang.PersistentHashMap$BitmapIndexedNode.assoc(PersistentHashMap.java:693)

20:43 :/

20:53 Bronsa: hiredman: how does PHM come into play?

21:07 hiredman: the vectors/bytebuffers are stored in a set in a map

21:08 which is stored in a record, in a map, in a atom

21:08 so I am not even sure which map level is the one that starts stacking

21:17 ah, it must be related to bytebuffer's crazy .hashCode calculation, it changes depending on how many bytes are remaining

21:19 amalloy: sounds right to me. using anything mutable as a map key goes wrong pretty fast

21:20 hiredman: yeah, but I often have something is just a chunk of bytes, which is a perfectly fine value, the jvm just doesn't have a great type for it

21:21 bytebuffers are almost not terrible, they have value equality and hashing, but the value is dependent on all the mark and position stuff

21:21 Strings are immutable, but double the storage space and cause lots of copying

22:00 gfredericks: double the storage space?

22:00 justin_smith: gfredericks: bytes stored as utf16 is my guess

22:00 just a guess though

22:01 gfredericks: just to make charAt fast?

Logging service provided by n01se.net