2015-08-15
| 00: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" |
| 00:51 | oddcully | mcktrtl: may with meta data? |
| 00:51 | oddcully | ,(let [c (with-meta [] {:very :special})] (binding [*print-meta* true] (pr c))) |
| 00:51 | clojurebot | ^{:very :special} [] |
| 00:55 | mcktrtl | (with-meta (chan) {:very :special}) -> ClassCastException clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to clojure.lang.IObj |
| 00:55 | mcktrtl | am i doing that wrong? |
| 01:12 | amalloy | channels don't support meta |
| 01:12 | amalloy | (is what that error message is saying) |
| 01:18 | mcktrtl | ahh ok :( thanks |
| 01:19 | rhg135 | I'd wrap it in a record/map |
| 01:20 | mcktrtl | like {:writer-ch (chan) :network-ch (chan)} ? |
| 01:22 | rhg135 | Yeah |
| 01:23 | rhg135 | Or a record and define a print-method |
| 01:23 | mcktrtl | oh right, thanks. i guess i should have thought of that since i'm doing it already |
| 01:24 | rhg135 | Np |
| 01: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 |
| 01:26 | rhg135 | It's unfortunate there is no metadata on channels |
| 01: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? |
| 01:58 | amalloy | 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 |
| 01:58 | amalloy | ,(with-meta (atom 0) {:blah true}) |
| 01: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... |
| 01:58 | amalloy | it doesn't work for atoms or refs either, for the same reason |
| 01:59 | amalloy | 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 |
| 02:09 | bacon1989 | so who else is hoping that clojure takes over the COBOL market? |
| 02:10 | bacon1989 | I was thinking of writing an FFI for it, since I think it could probably adopt a lot of interested fellows |
| 02: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 |
| 02:26 | J_A_Work | TEttinger: there is a version of Visual COBOL that runs on the JVM apparently. |
| 06: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. |
| 06:55 | expez | devn: which package does that underlining? squiggly-clojure? |
| 08: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 | justin_smith | ,(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 | justin_smith | 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 | justin_smith | 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 | kwladyka | justin_smith, hmm i don't think it is because hotspot |
| 12:14 | kwladyka | without hotspot it takes agaes, much much worst then REPL |
| 12:15 | justin_smith | kwladyka: lein turns off hotspot |
| 12:15 | justin_smith | 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 | kwladyka | hmm |
| 12:15 | kwladyka | very strange |
| 12:16 | kwladyka | 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 | justin_smith | (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 | justin_smith | 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 | justin_smith | 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 | kwladyka | maybe it has even few seconds more |
| 12:25 | kwladyka | justin_smith, can i ask you what kind of software are you creating? |
| 12:25 | kwladyka | 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 | timothyw | I want to print out a long list - but Clojure ellides some of it |
| 12:26 | timothyw | how can I print an entire list to string / edn |
| 12:26 | timothyw | … 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 | justin_smith | 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 | timothyw | 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 | kwladyka | anyway it is strange REPL works faster then jar without hotspot... |
| 12:33 | kwladyka | 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 | justin_smith | 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 | justin_smith | 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 | sdegutis | sometimes you want to keep true/false but remove nil |
| 15:15 | sdegutis | 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 | sdegutis | (keep identity) == (remove nil?) |
| 15:19 | sdegutis | 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 | sdegutis | 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 | sdegutis | So is (partial remove even?) the same as (remove even?)? |
| 15:42 | gfredericks | nope |
| 15:42 | gfredericks | 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 | sdegutis | 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 | gfredericks | ,(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 | sdegutis | 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 | justin_smith | (inc Bronsa) |
| 15:49 | lazybot | ⇒ 118 |
| 15:49 | justin_smith | yeah, that's the right answer |
| 15:49 | justin_smith | 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 | expez | 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 | justin_smith | 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 | amalloy | ,(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 | expez | (do (inc amalloy) (inc justin_smith)) |
| 16:42 | expez | 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 | justin_smith | 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 | biellls | 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 | biellls | 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 | dfcarpenterak | 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 | TEttinger | Om is likely something you want to look into, it's ReactJS-based |
| 18:55 | TEttinger | 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 | gfredericks | 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 | justin_smith | I still don't know what it would return |
| 20:19 | gfredericks | either {} or nil |
| 20:19 | gfredericks | 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 | justin_smith | 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 | hiredman | :/ |
| 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 | hiredman | which is stored in a record, in a map, in a atom |
| 21:08 | hiredman | so I am not even sure which map level is the one that starts stacking |
| 21:17 | hiredman | 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 | hiredman | 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 | hiredman | 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 | justin_smith | just a guess though |
| 22:01 | gfredericks | just to make charAt fast? |