#clojure log - Oct 22 2014

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

0:27 justin_smith: rritoch: in clojure eval always compiles

1:23 numberten: is there any reason that core's implementation of the 'take' function has a lazy-seq around the outter most sexpr?

1:24 I'd have imagined that the second argument to cons would be wrapped in 'lazy-seq'

1:24 the second argument being the recursive call

1:26 justin_smith: numberten: otherwise it would realize the first n elements

1:27 ,(do (take 10 (map println (range))) nil)

1:27 clojurebot: nil

1:27 Balveda: Any simple ways to check if a character is a number in clojurescript?

1:28 justin_smith: ,(do ((fn tk [n coll] (when (pos? n) (when-let [s (seq coll)] (cons (first s) (lazy-seq (take (dec n) (rest s))))))) 10 (map println (range))) nil) ; numberten

1:28 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n

1:28 justin_smith: thanks to chunking, it even realizes more than the first 10

1:29 numberten: i see

1:29 dbasch: justin_smith: you want to replace take by tk probably

1:29 numberten: thanks :)

1:29 justin_smith: dbasch: good point :)

1:29 dbasch: in the recursive call of tk

1:30 justin_smith: dbasch: it leads to the same result, but may as well demonstrate

1:30 ,(do ((fn tk [n coll] (when (pos? n) (when-let [s (seq coll)] (cons (first s) (lazy-seq (tk (dec n) (rest s))))))) 10 (map println (range))) nil) ; numberten

1:30 dbasch: but if you use a large number it will blow the stack

1:30 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n

1:31 numberten: shouldn't it have only printed the first element? in the case where you accidentally called take instead of tk?

1:31 justin_smith: numberten: chunking

1:31 numberten: i see

1:31 justin_smith: notice it is printing more than 10 elements too

1:32 it just grabs and processes the next chunk, but returns the count you asked for

1:32 numberten: yeah

1:32 i see

1:32 so chunks come in blocks of 32

1:32 it looks like

1:32 justin_smith: side effects inside a lazy operation are a bad idea for this reason, better to feed a lazy input to your side effecting function

1:32 numberten: alright

1:32 justin_smith: doseq was designed for this case

1:33 dbasch: I still don't always get when a given lazy-seq will blow the stack or not - do you know of a good book chapter or blog post covering it in some depth?

1:36 numberten: wouldn't processing a lazy-seq use O(1) space as long as you don't maintain a reference to the head?

1:37 egghead: i'm pretty sure it happens inside a for loop in most cases

1:38 i got bored and implemented a subset of clj in js, lazy seqs was one of the things

1:39 justin_smith: egghead: I have seen stacks blow up from combinations of reduce / concat

1:39 Balveda: Anyone? Not sure how to handle this

1:39 egghead: but both of those should be happening inside of a while loop iirc justin_smith :/

1:40 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj#L72-L77

1:41 but ya, guess there are many ways to skin a cat...

1:42 vIkSiT: Hi all

1:42 when using a simple compojure app, I'm getting empty params {}

1:42 I can see the query string contains my params

1:43 https://gist.github.com/viksit/15464b3bbd6b70b7478d

1:43 Any idea what the hell is going on?

1:43 safety: */

1:43 nvm

1:44 vIkSiT: both /sample and /posts in that route show empty params

1:46 egghead: hm vIkSiT

1:47 usually I use (compojure.handler/site routes) instead or `wrap-params`

1:48 dbasch: justin_smith: in that particular case, it’s just the recursive calls that create new stack frames for every call

1:48 egghead: but recursive calls to lazy seqs don't happen on the stack

1:48 vIkSiT: egghead, I didnt know that existed - trying to pieece together that!

1:48 egghead: since the recursion happens in a closure

1:49 vIkSiT: so you're saying I use instead of the (-> routes wrap-params) a simple (c.h/site routes)

1:49 dbasch: oh, lazy seqs, never mind

1:49 vIkSiT: I thought compjure.handler was deprecated in 1.2 though

1:49 as per their docs

1:50 egghead, still no luck

1:50 egghead: vIkSiT: that is just because it was moved here: https://github.com/ring-clojure/ring-defaults/blob/master/src/ring/middleware/defaults.clj#L79

1:50 vIkSiT: egghead, hrm so I'm very new to compojure

1:51 egghead: vIkSiT: :( - the example you posted looked fine to me tbqh

1:51 dbasch: justin_smith: in your example you’d removed the lazy-seq

1:51 vIkSiT: what is the easiest way to get my params as a map from the request?

1:51 egghead: why not try {:as req} and inspect the request object itself?

1:51 maybe something funny is happening, who knows

1:51 vIkSiT: how so?

1:51 oh I did that

1:51 see /posts?

1:52 dbasch: justin_smith: actually you hadn’t, you’d moved it inside

1:52 vIkSiT: if I do : http://localhost:9000/posts?author=viksit&title=foo

1:52 I see {:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, .... }

1:52 and :query-string "author=viksit&title=foo"

1:53 egghead: vIkSiT: i just do 'lein new compojure my-app-name'

1:53 and then stuff usually works :shrugs:

1:53 condolences :p

1:53 justin_smith: dbasch: I put it inside the cons call, because that was the case numberten was describing / asking about

1:54 dbasch: justin_smith: yes, it wouldn’t blow the stack, my bad

1:57 speaking of stack overflow, I’m running into this bug (apparently) when trying to serialize a large PersistentHashMap http://bugs.java.com/view_bug.do?bug_id=4152790

1:58 justin_smith: woah, that sucks

1:58 dbasch: convert to /from an adjacency list representation?

1:59 dbasch: it’s a map of pairs word -> vector of words

1:59 I can try making it a vector and see if it changes anything, or turn it into a java util hashmap

2:00 justin_smith: or even an array of two element arrays

2:00 yeah

2:00 no need for something that fancy if it's shallow

2:02 piranha: anybody using prismatic's schema here? I've updated to 0.3.1 and coercer returns an arraymap (like {:error [:smth is-wrong]}), which is not considered error by schema.utils/error? - is this a known issue?

2:34 hm, 'lein clean' resolved problem :)

2:39 justin_smith: piranha: ahh, yeah, should have thought of that

2:39 piranha: :)

2:39 justin_smith: library upgrades and cached compiled stuff don't mix nicely

2:42 piranha: yeah, unfortunately

2:42 I thought that's a problem mostly for clojurescript, but I was wrong apparently :)

2:53 justin_smith: regarding caching of compiled artifacts: http://33.media.tumblr.com/2f62641ff71d2ff0178d630549959903/tumblr_ncjpycT0Yj1s71q1zo1_1280.png

3:28 mearnsh: lol

3:31 kenrestivo: personal pet peeve: committing compiled artifacts into git.

4:21 dysfun: what's the easiest way to locally redefine a function for purposes of testing?

4:35 sveri: dysfun: maybe this one? http://clojuredocs.org/clojure.core/with-redefs-fn

4:43 dysfun: that looks perfect, thanks

4:57 hrm. how about redefining macros?

4:59 i want to do a macroexpand-1 to test a macro which calls a function, but of course i need to recompile the macro

5:05 sveri: dysfun: well, I know nothing about macros, sry

5:06 dysfun: heh. it's a fairly unusual thing i'm doing. i expected to run into some difficulties

5:07 clgv: dysfun: what exactly do you mean? you can redefine macros as you can redefine functions

5:08 dysfun: or do you want to rebind a name to a macro in a local scope?

5:08 dysfun: yes

5:08 clgv: the latter?

5:09 dysfun: well, what i actually want to achieve is 'recompile the function with the same source so as to pick up the new version of the function you depend on'

5:10 clgv: well, functions are looked up through the symbols when you call them directly, so you always get the latest definition in that case.

5:11 dysfun: can you provide a small example demonstrating the problem/feature?

5:14 dysfun: no, it works, and i've figured out why

5:15 it's because of where the metadata is attached

5:15 it's all working now

5:16 clgv: well, fine. no idea what the problem was, though

5:23 dysfun: it was more i anticipated one where there wasn't one :)

5:24 i've been doing this job for too long :)

7:01 martinklepsch: what could be going wrong when it takes a long time for an alts! to pick up a value from a channel?

7:02 I'm sure the value has been put on the channel but it still takes seconds for the alts! block to start handling it

7:04 (oh and the channel where the value has been put on is a pipeline-async channel, so it's not actually THE channel I use alts! on. (if my understanding of pipeline-async is correct))

7:04 SagiCZ1: ,(meta cons)

7:04 clojurebot: nil

7:04 mosdd: what is the current status for using clojure for creating small, short-running command line utilities that need a fast startup? how fast can we clojure program to start, and what would it take?

7:04 SagiCZ1: ,(meta 'cons)

7:04 clojurebot: nil

7:04 SagiCZ1: why does it return nil, when the function clearly has meta data?

7:05 cursork: ,(meta #'cons)

7:05 clojurebot: {:ns #<Namespace clojure.core>, :name cons, :added "1.0", :file "clojure/core.clj", :static true, ...}

7:05 SagiCZ1: cursork: thank you

7:05 why is that necessary?

7:06 hyPiRion: 'foo refers to the symbol, whereas, #'foo refers to the var

7:06 #'foo is sort-of shorthand for (resolve 'foo)

7:06 martinklepsch: mosdd: I'm not sure if there's a right way of doing this. I always like to believe that cljs might work well it that spot but never tried

7:06 hyPiRion: ,(meta (resolve 'cons))

7:06 clojurebot: {:ns #<Namespace clojure.core>, :name cons, :added "1.0", :file "clojure/core.clj", :static true, ...}

7:06 SagiCZ1: hyPiRion: thank you

7:07 and how could i just see docs for something?

7:07 ,(doc #'+)

7:07 clojurebot: #<CompilerException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)>

7:07 SagiCZ1: ,(doc #'cons)

7:07 clojurebot: #<CompilerException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)>

7:07 SagiCZ1: (doc cons)

7:07 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

7:07 SagiCZ1: ,(doc cons)

7:07 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

7:07 SagiCZ1: my repl cant find the doc function

7:09 hyPiRion: are you using `lein repl` ? Clojure by default doesn't ship doc

7:09 SagiCZ1: ,clojure.main/repl-requires

7:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: repl-requires in class clojure.main, compiling:(NO_SOURCE_PATH:0:0)>

7:09 hyPiRion: Clojure as in `clojure`, `lein repl` contains doc

7:09 SagiCZ1: yeah its lein repl

7:10 hyPiRion: well then, that's strange. doc should be included there

7:10 cursork: SagiCZ1: Changed namespace?

7:10 SagiCZ1: cursork: yes

7:10 cursork: wait so thats the problem?

7:10 thats why it works SOMETIMES

7:11 cursork: SagiCZ1: Yep. Lein just does a (use 'clojure.repl) for you

7:11 hyPiRion: ooh, yeah

7:11 SagiCZ1: damn im stupid.. thank you

7:13 clgv: mosdd: not optimal. you can speed up via "drip" or "grenchman" for leiningen

7:14 jsanda: hi all. i am using the << (string interpolation) fn from clojure.core.strint. can someone tell me how to pass a variable to it?

7:14 mosdd: clgv do you know the start up of hello world if you tested it?

7:14 jsanda: i try unquoting like, (<< ~myvar), but that just evaluates to

7:15 mosdd: +time

7:15 jsanda: "(clojure.core/unquote myvar)"

7:15 clgv: mosdd: easy to check, just write one an aot compile it ;)

7:15 scottj: jsanda: (<< "This trial required ~{v}ml of solution.")

7:16 jsanda: http://clojure.github.io/core.incubator/clojure.core.strint-api.html

7:16 SagiCZ1: whats wrong with this function, that doc keeps returning nil for it? https://www.refheap.com/92146

7:16 mosdd: lol ok, I hae to find out what aot is first

7:16 jsanda: scottj: i want to pass a var

7:17 (def myvar "This trial required ~{v}ml of solution.")

7:17 (<< ~myvar) ;; does not work though

7:17 noncom: is it possible to modify a loaded java class bytecode in runtime? are there any clojure libs for that ?

7:18 TEttinger: SagiCZ1: docstring goes before arglist

7:18 clgv: jsanda: probably because the macro `<<` expects a string literal

7:18 SagiCZ1: TEttinger: ohh... missed that, thank you

7:18 clgv: $source clojure.core.strint

7:18 lazybot: Source not found.

7:19 jsanda: clgv: ok, thanks

7:20 clgv: jsanda: well the implementation is pretty strange

7:20 jsanda: https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/strint.clj#L49

7:21 martinklepsch: mosdd If you're familiar with javascript I'd recommend to evaluate that as well

7:21 jsanda: clgv: looking...

7:22 mosdd: recur is used when you have tail recursion and direct recursion otherwise?

7:22 clgv: jsanda: I think that might be a reason why it did not make it into clojure, yet

7:23 jsanda: hmm...any suggestions on an alternative string interpolation fn?

7:24 martinklepsch: http://gearon.blogspot.de/2013/03/clojurescript-and-nodejs.html

7:24 clgv: jsanda: you can just use that one with literal strings

7:24 jsanda: or are the string constants you tried to use mandatory?

7:24 hyPiRion: jsanda: cl-format?

7:24 clgv: jsanda: you can use `interpolate` directly instead of `<<` when using constants

7:25 jsanda: clgv: string constants don't work for me. i'm trying to pass in string that are loaded from files

7:25 clgv: jsanda: ok, use `interpolate` directly

7:25 hyPiRion: ,(require '[clojure.string :as s])

7:25 clojurebot: nil

7:25 jsanda: ok, thanks

7:25 TEttinger: ,(format "This trial required %1ml of solution." 10)

7:25 clojurebot: #<UnknownFormatConversionException java.util.UnknownFormatConversionException: Conversion = 'm'>

7:25 hyPiRion: ,(s/cl-format nil "~d duck~:p and ~d pig~:p" 13 1)

7:25 clojurebot: #<CompilerException java.lang.RuntimeException: No such var: s/cl-format, compiling:(NO_SOURCE_PATH:0:0)>

7:25 clgv: jsanda: ah lol that one is private...

7:26 jsanda: I usually just use clojure.core/format

7:26 hyPiRion: oh, derp

7:26 TEttinger: ,(format "This trial required %dml of solution." 10)

7:26 clojurebot: "This trial required 10ml of solution."

7:26 clgv: jsanda: not exactly the same use case...

7:27 jsanda: eyah

7:27 yeah

7:27 clgv: hyPiRion: isn't that part of clojure.pprint?

7:27 hyPiRion: clgv:

7:27 yeah

7:27 ,(require '[clojure.pprint :as pp])

7:27 clojurebot: nil

7:27 hyPiRion: ,(pp/cl-format nil "~d duck~:p and ~d pig~:p" 13 1)

7:27 clojurebot: "13 ducks and 1 pig"

7:27 hyPiRion: ,(pp/cl-format nil "~r duck~:p and ~r pig~:p" 13 1)

7:27 clojurebot: "thirteen ducks and one pig"

7:27 TEttinger: :p is pluralize?

7:28 hyPiRion: TEttinger: yeah, pluralize last arg

7:28 TEttinger: ,(pp/cl-format nil "~r radius~:p and ~r pig~:p" 13 1)

7:28 clojurebot: "thirteen radiuss and one pig"

7:28 TEttinger: hm

7:28 hyPiRion: have to use ~[~] for special cases

7:28 clgv: well it isn't really gramar aware ;)

7:28 TEttinger: it's majjyyk

7:28 clgv: *grammar

7:29 hyPiRion: TEttinger: http://www.gigamonkeys.com/book/a-few-format-recipes.html if you're interested

7:31 SagiCZ1: files in clojure are sequencible? how about buffered readers?

7:31 clgv: SagiCZ1: what?

7:32 SagiCZ1: i thought i read that somewhere

7:32 TEttinger: (doc file-seq)

7:32 clojurebot: "([dir]); A tree seq on java.io.Files"

7:32 SagiCZ1: yeah

7:32 clgv: ah well that explains more with fewer words ;)

7:32 SagiCZ1: well i need to read from buffered reader using readLine.. do i need loop for that?

7:33 clgv: SagiCZ1: you may also do it lazyly but with the problem that you dont know then too close the file

7:33 s/then/when/

7:33 martinklepsch: anyone an idea regarding my core.async pipeline delay issue?

7:33 SagiCZ1: its not a file.. i need to read line from the stream and put it in a blocking queue

7:35 Chaze: Hi there. Does clojure have a macro for "uncurrying" in the sense of putting its arguments into a vector?

7:35 clgv: SagiCZ1: well you could just have a thread in an endless loop doing that - but depends on your scenario if that is ok

7:36 SagiCZ1: cglv: but there is no while (true) in clojure, right?

7:36 Chaze: so, lets say i have a (def foo [x y]) and i want a macro that instead makes it a (def bar [[x y]])

7:36 clgv: SagiCZ1: interestingly there is

7:36 ,(doc while)

7:36 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

7:36 SagiCZ1: Chaze: apply ?

7:36 clgv: oh

7:37 Chaze: SagiCZ1: nope, because i want to pass the "uncurried" function as an argument

7:37 clgv: SagiCZ1: so (future (while true ...)) might be an option. better: (future (while @continue ...))

7:37 Chaze: I can't say (map (apply foo) col) for instance

7:37 SagiCZ1: clgv: thank you

7:38 Chaze: Oooh. I can do (map (partial apply foo) col)

7:38 SagiCZ1: clgv: where continue is an atom flag right?

7:38 Chaze: SagiCZ1: thanks for the hint

7:40 clgv: SagiCZ1: yeah, for example an atom

8:02 SagiCZ1: ,(+ 5 3)

8:02 clojurebot: 8

8:02 SagiCZ1: ,*1

8:02 clojurebot: #<Unbound Unbound: #'clojure.core/*1>

8:03 SagiCZ1: ,1*

8:03 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 1*>

8:03 SagiCZ1: ,*1*

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

8:11 TEttinger: &*1

8:11 lazybot: ⇒ #<Unbound Unbound: #'clojure.core/*1>

8:11 TEttinger: hm, looks like these don't fully act as REPLs

8:15 hyPiRion: They're more like REP

8:48 zapho53: Anyone using Yesql?

8:49 defqueries keeps giving me a java.io.FileNotFoundException

8:51 jonathanj: hrm, if i add aleph to my deps and run lein repl i get:

8:51 #<CompilerException java.lang.RuntimeException: No such namespace: d, compiling:(manifold/deferred.clj:721:7)>

8:52 and i can't require anything that depends on manifold

8:52 what gives? :(

8:52 nonrecursive: zapho53: can you share the full defqueries form you're using and the filesystem location of your queries file?

8:54 zapho53: nonrecursive: (defqueries "/Users/gmac/clj/db2/sql/db2.sql"). Exact file location.

8:57 nonrecursive: zapho53: hmm I'm not sure that would be on your classpath?

8:58 zapho: I have my queries in "src/queries" and use e.g. (defqueries "queries/select/route.sql")

8:58 zapho53: I just tried using the full filesystem path as well and got the same error as you

8:59 zapho53: nonrecursive: I'll try under src

9:00 dysfun: so i've volunteered to teach a friend of mine to program, but he uses windows. is it easy to get going with clojure and lein under windows?

9:00 clgv: dysfun: lighttable, counterclockwise and cursive are options to do that, easily

9:00 zapho53: nonrecursive: (defqueries "src/sql/db2.sql")

9:01 ... same Excetion

9:01 dysfun: hrm, i'd prefer something that

9:01 nonrecursive: you'll want to use

9:01 dysfun: wasn't tied to an IDE

9:01 nonrecursive: zapho53: (defqueries "sql/db2.sql")

9:02 jonathanj: looks like there was a bug in manifold-0.1.0-beta2 and unfortunately aleph-0.4.0-alpha4 depends on that

9:02 zapho53: nonrecursive: That worked. Thanks. Maybe the docs should make all this a bit clearer.

9:02 jonathanj: sigh

9:03 zapho53: nonrecursive: Instead of "some/where/users_by_country.sql"

9:03 nonrecursive: zapho53: the reason is that "src" is included in your classpath, and yesql looks up paths relative to the directories in your classpath

9:04 zapho53: yeah I had to fiddle with it a bit myself the first time I used yesql, I agree it could be a bit clearer

9:04 zapho53: nonrecursive: Some libraries also work with absolute paths so it needs to be made clear.

9:04 roelof: I cannot understand this :

9:04 I have a function divides which looks like this : (defn divides? [divisor n] (=(mod n divisor)0))

9:05 when I do (divides? 400 4) I see false

9:05 but when I do ( mod 400 4) I see the output 0

9:05 why does divides still says false ?

9:08 clgv: dysfun: you need an editor and a repl (best when the editor can interact with the repl). all 3 options I listed provide that

9:14 agarman: quick question on using dependencies installed in local .m2

9:15 dysfun: clgv: actually, i was thinking those plus midje. and editor rather than ide

9:16 joegallo: agarman: proceed

9:16 roelof: no one who can help me ?

9:16 agarman: what is a good way of changing the class path for a mvn dependency that is only installed locally? pomegranate?

9:17 dysfun: roelof: you have the arguments the wrong way around

9:17 joegallo: agarman: installed locally in your .m2?

9:17 agarman: yes,

9:17 roelof: dysfun: what do you mean ?

9:17 dysfun: roelof: you executed (mod 4 400), not mod (400 4)

9:17 agarman: joegallo: have a java project that only installs local and want to pull it in as a dependency, but lein & alembic can't find

9:18 roelof: dysfun: thanks, I will change it

9:18 joegallo: agarman: then something is slightly off, leiningen is totally cool with local only stuff in your .m2 -- i think

9:19 (i've used it for testing new versions of things in development across different projects, for instance)

9:20 agarman: yeah, I'll fiddle some more with groupids etc

9:24 joegallo: needed to add :extension "pom" to dependency

9:24 (inc joegallo)

9:24 lazybot: ⇒ 5

9:28 roelof: dysfun: thanks, finally get this one working

9:28 any midje expert here ?

9:39 Can I somehow test only 1 function with midje instead of the whole namespace which happens with lein midje ???

9:39 lazybot: roelof: How could that be wrong?

9:41 roelof: I do not understand the answer which lazybof gives. What is wrong with my question ?

9:41 llasram: Does lazybot give a silly response to questions with lots of question marks???

9:41 lazybot: llasram: Yes, 100% for sure.

9:42 roelof: llasram: thanks

9:42 llasram: roelof: With an editor-connected REPL you can send the form for just one test to be run

9:43 The Emacs midje extension has/had explicit support for that

9:43 Running just one test e.g. from the command line is pretty much impossible though

9:43 The fundamental mode of midge is that it runs tests at what is normally Clojure "compile time"

9:43 roelof: oke, I wokr now with codio.com so I do not think they have a editor connected repl

9:43 llasram: Which is one reason that I dislike it

9:44 (midje, not codio.com -- no idea what the latter even is)

9:44 roelof: llasram: thanks for the answer. Codio.com is a online solution to work with clojure

9:55 puredanger: martinklepsch: on your pipeline-async thing, it's important that you conform to the doc sentence: "The presumption is that af will return immediately, having launched some asynchronous operation (i.e. in another thread) whose completion/callback will manipulate the result channel." - are you?

9:56 zot: anybody have a suggestion for a more idiomatic-yet-clean way to do this? https://gist.github.com/anonymous/3d335b876c7303d9e687

9:57 i did it with reduce and an anon function over [:a :b :c], but it wasn't very readable, imo, seeking something better. (this is a toy example, of course… longer list in real life.)

9:59 roelof: I need the help of the experts once again. What is wrong here : (defn do-a-thing [x] ( let [double_x (+ x x )] (Math/pow double_x double_x))) I see a this error message : unable to resolve symbol: x in this context

10:00 puredanger: ,(defn do-a-thing [x] ( let [double_x (+ x x )] (Math/pow double_x double_x)))

10:00 clojurebot: #'sandbox/do-a-thing

10:00 BRONSA: zot: there's not something much better than (defn finish [mtrx] (reduce #(update-in % [%2] finish-child) mtrx [:a :b :c]))

10:01 puredanger: ,(do-a-thing 5)

10:01 clojurebot: 1.0E10

10:01 zot: BRONSA: tnx :)

10:01 BRONSA: zot: 1.7 will have `update` so you can write (update a b f) instead of (update-in a [b] f)

10:06 jonathanj: how do people do async network io with Clojure?

10:06 (like writing custom protocol handlers, etc.)

10:07 puredanger: jonathanj: I haven't done it, but should probably look at Netty http://netty.io/

10:09 scottj: puredanger: do you know if there has been a decision whether fastload will make it into 1.7? is there an issue I should follow?

10:09 puredanger: scottj: will not be in 1.7

10:09 scottj: ahh, bummer

10:10 puredanger: scottj: might not be in ever - it has pros and cons

10:10 part of fastload is a class cache which is being evaluated vs Zach's patch in http://dev.clojure.org/jira/browse/CLJ-1529

10:10 BRONSA: puredanger: how about the direct stuff?

10:10 puredanger: I think one or the other of those will be in 1.7

10:11 Bronsa: will not be in 1.7, I would consider it experimental/research atm

10:12 scottj: puredanger: is there anything in writing about the major cons of fastload?

10:13 puredanger: scottj: I have written about it here in the past. the major one is that while it makes vars faster on load, it makes them slower forever after that

10:13 BRONSA: iirc fastload was class cache + direct + lazy fn loading

10:13 it'd look like lazy fn loading is the problematic one

10:13 puredanger: Bronsa: no, direct is a separate thing

10:14 BRONSA: puredanger: ah, I thought direct got merged into fastload at some point

10:14 puredanger: the class cache part is just perf tuning and is independent (hence hopefully will be in 1.7)

10:14 Bronsa: direct is a branch from fastload branch

10:14 BRONSA: puredanger: I see, my memory got messed up then

10:15 puredanger: fastload does not change usage of anything; it just affects how vars are loaded and called

10:15 csd_: Is Company mode really flakey for anyone else? Sometimes it works, othertimes it inexplicably doesn't

10:15 puredanger: direct compiles new static invocation paths and opens up many possible decision points every time you compile about whether you use static or dynamic invocation

10:16 potentially on a per-var basis

10:16 this has big usage ramifications in terms of what knobs you make available

10:17 neither fastload nor direct actually made a significant difference in runtime performance though for most stuff I tested with

10:17 BRONSA: I'd have thought direct would have a significant impact

10:17 puredanger: you would think so

10:17 but most hot cpu loops typically don't have var invocation in them anyways

10:19 direct doesn't affect protocol invocation either as that's a different path

10:19 BRONSA: right

10:20 puredanger: I think Ghadi's experiments with indy are far more interesting - they have the potential to get the benefits of both fastload and direct without most of their costs

10:20 scottj: puredanger: do you have a link to this?

10:20 puredanger: to what?

10:21 scottj: ghadi's experiments with indy

10:21 puredanger: he's doing a talk at the conj, not sure if he's written anything up anywhere

10:21 scottj: ok

10:21 puredanger: I've mostly just talked to him about it

10:22 I gave him some invocation benchmarks I've used and he's seeing good numbers

10:22 scottj: fwiw on startup speeds for hello worlds I saw time decrease to 1/2 or 1/3 of normal with fastload.

10:22 BRONSA: puredanger: speaking about callpaths, I don't recall if I opened a ticket about that but the compiler generates an unused method for every fn w/ keyword-invokes

10:22 ah I did

10:22 http://dev.clojure.org/jira/browse/CLJ-1351

10:23 puredanger: scottj: I did not find anything close to that with real programs

10:23 Bronsa: yeah, I did my part on that, Rich has never looked at it

10:27 scottj: fastload makes every var invocation about 50% slower (post-inlining) for the rest of the time your program runs too. You mostly won't notice that as it's rarely the bottleneck but kinda sucks

10:28 alexherbo2: Hi

10:31 puredanger: indy has support for switchpoint method handles so you can delay loading on invocation, then switch to the new path without the check after it's loaded, which gives you the deferred loading + avoid the cost of the check after load

10:31 BRONSA: that's nice

10:32 EvanR_: its a beautiful day in the neighborhood

10:32 puredanger: Bronsa: I believe it was designed for this kind of use case

10:41 mearnsh: BRONSA: HELLO

10:45 SagiCZ1: can we dump threads in repl?

10:53 puredanger: sure

10:54 depends on what repl of course. ctrl-\ dumps it in *nix if you're in the jvm process started from command line, but that's not going to work in many setups

10:55 you can produce it via external means with jstack

10:56 SagiCZ1: ok

10:56 puredanger: and you can call through the jvm jmx beans too

10:58 you can get it as data with (.dumpAllThreads (java.lang.management.ManagementFactory/getThreadMXBean) true true) - not sure what gymnastics you'd need to print that usefully though

11:00 johnwalker: ping GFREDERICKS

11:00 puredanger: (pprint (seq (.dumpAllThreads (java.lang.management.ManagementFactory/getThreadMXBean) true true)))

11:00 does an ok job

11:00 GFREDERICKS: johnwalker: halooo

11:00 johnwalker: are you feeling uppercase today

11:01 GFREDERICKS: BRONSA started it

11:01 johnwalker: i kind of wish there were only one case

11:02 anyway, i wondered if you wanted me to take TCHECK-46 with TCHECK-47

11:02 GFREDERICKS: yeah I think -46 is subsumed by -47

11:02 johnwalker: ok, and i also wanted to ask if that was the right procedure in jira

11:02 i have never clicked the assign button

11:02 GFREDERICKS: yeah I believe so

11:02 reid pointed it out to me after I started on it because I'm not used to paying attention

11:03 johnwalker: ahh

11:03 reiddraper: GFREDERICKS: HELLO

11:03 johnwalker: well, in that case i'd be happy if you took it

11:04 clgv: all caps day? :P

11:04 johnwalker: it's up to you. i was planning on starting today, but if you already have some work done then thats a different story

11:04 EvanR_: known fact that the romans went around yelling at each other on a regular basis

11:05 johnwalker: oh god ecci romani

11:06 CookedGryphon: ecce*

11:07 romanes eunt domus!

11:07 johnwalker: it's been a while

11:10 llasram: I wonder if Roman-era biblio-archaeologists get annoyed at people typing in whispers all the time


11:12 johnwalker: just check if e. e. cummings has haters

11:12 teslanick: Romans used to read everything aloud


11:14 llasram: teslanick: huh. TIL

11:14 /Space Between Words/ looks like an interesting read

11:21 GFREDERICKS: johnwalker: reiddraper: https://github.com/gfredericks/test.check/commit/6fbb6bcecd89817774682406ffe84e470f2ccf10

11:22 reiddraper: GFREDERICKS: much appreciated

11:22 GFREDERICKS: I don't know if I got all of them yet, I quit as soon as reid pointed out the ticket-assignment

11:23 BRONSA: GFREDERICKS: it's capslock day!

11:25 GFREDERICKS: https://twitter.com/timbaldridge/status/524904211037683712

11:26 johnwalker: nice

11:26 what is line 467 ?

11:28 GFREDERICKS: johnwalker: I guess I quit in the middle of a line

11:29 johnwalker: the only one that i notice missing is sample-seq

11:29 GFREDERICKS: reiddraper: I converted a (def ... (partial ...)) to a (defn ...) so I could have more consistent error reporting

11:29 johnwalker: that one doesn't have the delayed-error problem though does it?

11:30 johnwalker: i'm not sure.

11:30 reiddraper: GFREDERICKS: no argument here

11:34 GFREDERICKS: there are a lot of three-letter acronyms without wikipedia pages

12:01 justin_smith: technomancy: I found this image, and am convinced you will find many an amusing context to invoke it http://i.imgur.com/MdbUlkO.png

12:02 EvanR_: is there a update-in that does not create a key if it isnt there already

12:02 SagiCZ1: can i make a string literal containing double quotes?

12:02 EvanR_: ,"\"\""

12:02 llasram: &"\"sure\""

12:02 lazybot: ⇒ "\"sure\""

12:02 clojurebot: "\"\""

12:03 justin_smith: EvanR_: not that I know of, but you can make something with the help of contains?

12:03 SagiCZ1: and if i didnt want to use the backshlash?

12:03 llasram: EvanR_: What would it return in the non-extant case?

12:03 mdrogalis: EvanR_: I don't think so, no.

12:03 EvanR_: llasram: it would return the original map

12:03 justin_smith: ok

12:03 SagiCZ1: ,\"

12:03 clojurebot: \"

12:03 llasram: EvanR_: Hmm. Sounds like a good source of bugs to me :-)

12:04 BRONSA: EvanR_: get-in is probably going to be more useful than contains? in this case

12:04 technomancy: justin_smith: <3

12:04 BRONSA: you can (get-in my-map [p a t h] ::not-found) but you can't (contains? my-map p a t h)

12:05 EvanR_: sounds good to me

12:07 "adjust-in"

12:08 SagiCZ1: EvanR_: can i somehow quote the entire string? tell the reader that this string will contain some double quotes and ignore them?

12:08 ,<special_symbol>"ignore " the " inner " quotes " please "

12:08 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: <special_symbol> in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:09 EvanR_: !"what language is this"!

12:09 llasram: SagiCZ1: If you're looking for something like a here-doc or Python's """-quoted strings, I am afraid you are out-of-luck

12:09 SagiCZ1: You can always `slurp` in an external resource file though

12:09 EvanR_: theres no reader macro for this?

12:09 SagiCZ1: thats too bad

12:10 llasram: No

12:10 You could hack one in by modifying the reader's syntax table, but that is "frowned upon"

12:10 EvanR_: the only issue with get-in and update-in so far are they nil may mean the key was not there, or it did and the value is nil

12:11 technomancy: ugh nil =\

12:11 justin_smith: EvanR_: my attempt at update-in only if already present https://www.refheap.com/92164

12:12 llasram: EvanR_: You can provide default value to `get-in`, but yeah -- not `update-in`. With the latter you generally only allow `nil` for not-found and wrap the update function in `fnil`

12:12 But doing something explicitly monoidal would definitely be nicer for some things

12:12 EvanR_: justin_smith: i see, so it somehow checks that the key is there

12:13 andyf: llasram: is someone particular being quoted in "frowned upon" ?

12:13 EvanR_: llasram: what default value would help?

12:13 noonian: ,(get-in {:foo nil} [:foo] :not-found)

12:13 clojurebot: nil

12:14 justin_smith: EvanR_: that the "place" of the final key is there, and that place is associative so that you can even do lookup on it

12:14 llasram: andyf: Nah, I was being jokey. I mean, it's more "so crazy no one has done it except to show that it can be done and anyone who did do it in a library would be shunned"

12:14 (imho)

12:14 arrdem: BRONSA: you're capital today?

12:15 BRONSA: arrdem: capslock day

12:15 EvanR_: noonian: should work, most of the time

12:15 justin_smith: arrdem: it's caps lock day. This is an important part of our culture.


12:15 arrdem: oh. right. PLT_HULK must be going nuts

12:15 llasram: EvanR_: Well, if the update function were treated as an explicit monoid, attempting to add an absent value would first call it's 0-arity version get the identity value

12:15 noonian: EvanR_: yeah looking at the source it calls seq on it and goes through the k,v pairs

12:15 llasram: EvanR_: If that's what you were asking?

12:15 technomancy: "I don't have a caps lock key you insensitive clod"

12:15 arrdem: ^ that

12:15 I just have a spare control key

12:15 llasram: Me too :-(

12:16 EvanR_: llasram: nope

12:17 :not-found is what i was looking for

12:17 llasram: Ah

12:17 Oh, yeah I meant "default return value if not found"

12:17 Which may be a bit of a stretch :-)

12:19 EvanR_: this is what i have http://lpaste.net/113034

12:19 not really par with std lib but good enough

12:20 BRONSA: EvanR_: (m) doesn't really make sense to me

12:20 clojurebot: excusez-moi

12:20 EvanR_: ,(m)

12:20 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:20 BRONSA: EvanR_: also I'd prefer ::not-found instead of :not-found

12:21 arrdem: oh we're namespace qualifying trash values now?

12:21 BRONSA: EvanR_: you're invoking your map with no args, that should be `m` not `(m)`

12:21 ::arrdem

12:21 arrdem: why not just have done with it and use a full contract...

12:21 justin_smith: ,({}) ; this is what (m) in your code does

12:21 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap>

12:21 justin_smith: EvanR_: ^^

12:21 EvanR_: ah, i really wrote that

12:22 ,::not-found

12:22 clojurebot: :sandbox/not-found

12:22 EvanR_: ,:::not-found

12:22 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :::not-found>

12:22 EvanR_: two colons ?

12:22 justin_smith: EvanR_: it's a shortcut for namespaced keywords

12:22 EvanR_: man

12:23 justin_smith: EvanR_: which helps ensure you are not shadowing the same keyword used for a different purpose

12:23 EvanR_: this is a lot of work for a get-in that returns an option type or something

12:24 BRONSA: I wouldn't call a 2-line function a lot of work

12:24 arrdem: "line"

12:24 challenge accepted

12:24 EvanR_: was talking about namespaced keywords to interpret whether a map has a key

12:25 justin_smith: EvanR_: mental work, sure, but it's a one-time cost if you plan on using clojure again :)

12:26 EvanR_: my function works, though im unsure on the exact semantics of the ::not-found value

12:26 arrdem: &(get {} :foo ::not-found)

12:26 lazybot: ⇒ :clojure.core/not-found

12:26 EvanR_: does it have the same problem, map happens to contain the value ::not-found

12:26 BRONSA: EvanR_: you just need to get used to it, it gets obvious once you see it enough times :)

12:26 arrdem: if you ever (assoc ::not-found), wtf m8

12:27 justin_smith: EvanR_: sure, but someone in a namaspace other than yours using a keyword in your namespace is asking for trouble anyway

12:27 BRONSA: EvanR_: sure but the probability of somebody sticking in a map :not-found vs :your.namespace/not-found is different

12:27 EvanR_: alright then...

12:27 so we cut the probability in half

12:27 good stuff

12:27 justin_smith: "half"

12:27 BRONSA: EvanR_: if you want to be 100% sure that function will work even if your users are assholes, use a sentinel value

12:28 justin_smith: ::not-found, in any namespace other than yours, is not equal to ::not-found in your namespace

12:28 BRONSA: (let [sentinel (Object.) value (get-in m path sentinel)] (if (identical? value sentinel) ..))

12:28 EvanR_: .oO(method to check if a key exists in a map or not)

12:28 jonathanj: is there an IRC channel for aleph and so forth?

12:28 justin_smith: EvanR_: that's contains?

12:28 jonathanj: i'm apparently missing something crucial with aleph.tcp.client

12:28 EvanR_: justin_smith: ah ok

12:29 justin_smith: EvanR_: as seen in my paste prior

12:29 EvanR_: yeah yours probably is better

12:29 jonathanj: the wiki talks about `tcp-client`: https://github.com/ztellman/aleph/wiki/TCP

12:29 BRONSA: EvanR_: the issue w/ contains? is that it only works on a single level, not on multiple level paths like get-in/update-in

12:29 justin_smith: EvanR_: the check for ILookup is because contains? errors on things you can't lookup on

12:29 BRONSA: I address this in the code I am referencing

12:30 EvanR_: still seems more solid

12:31 BRONSA: justin_smith: yeah but it's a lot more work than using get-in w/ not-found value

12:32 EvanR_: i was initially going to be ok with a crap value being now impossible to use in a map, but if im going to start splitting improbabilities, ill just do it right

12:32 justin_smith: https://www.refheap.com/92164 updated. BRONSA: a lot more?

12:35 EvanR_: justin_smith: you have literal tabs in your code?

12:35 or is that just the pastebin

12:36 justin_smith: EvanR_: odd, whitespace-mode doesn't show any tabs

12:37 EvanR_: I don't see tabs in my original code, or in copy pasting from my code back into my editor

12:37 BRONSA: justin_smith: ok, I was unfair

12:37 EvanR_: must be my

12:37 technomancy: justin_smith: check whitespace-style

12:38 justin_smith: technomancy: is that from a package?

12:38 technomancy: no, it's a builtin defvar

12:38 justin_smith: ahh, right

12:38 technomancy: defcustom

12:38 dagda1_: can anyone help me out with my understanding of this generic consume function https://github.com/suprematic/ascent.repl/blob/master/src/cljs/cdtrepl/util.cljs#L12. I can't quite work out what the kill channel is for

12:38 EvanR_: it obviously has no tabs in the pastebin, its a weird quirk of my vim setup

12:39 dagda1_: my idea of what a kill channel was is one where I destroy existing channels

12:39 justin_smith: technomancy: I just periodically turn on whitespace-mode and fix things that are red or yellow

12:40 dagda1_: or maybe it just avoids the channel being null

12:40 llasram: justin_smith: Just leave it on all the time. It's a great way to be constantly slightly annoyed at other people.

12:40 justin_smith: llasram: hah

12:40 dagda1_: a kill channel is a channel that kills you

12:40 also known as a poison channel

12:42 dagda1_: in that context, you can see that any input from the kill-ch will make the loop fail to recur

12:42 dagda1_: justin_smith: ha and kill the channel

12:42 justin_smith: no, kill the go loop

12:43 the channel is fine (though likely soon to be collected)

12:43 dagda1_: justin_smith: so I would stil need to call close! to destroy the channel

12:43 justin_smith: or just don't hold onto it

12:43 gc

12:44 dagda1_: justin_smith: I'm trying to come up with the best plan for killing channels in clojurescript.

12:44 justin_smith: dagda1_: put a nil value in it

12:44 this kills the channel

12:44 hashpuppy: i'm looking at some clojurescript code and i see (map (constantly true)) being passed to an arglist, where it is consumed with let [out (apply async/chan 1 args)]. i'm trying to figure out what's going on. is (map (constantly true)) returning a partially applied function? but when i key that into the clojure repl i get an error saying wrong number of args were passed. is this something clojurescript specific? or what's going on?

12:45 dagda1_: justin_smith: I thought close! kills the channel

12:45 justin_smith: hashpuppy: it's a clojure 1.7 thing

12:46 dagda1_: justin_smith and it would not be GC'd unless close! was called

12:46 hashpuppy: thanks, justin. so what's being returned there?

12:46 justin_smith: dagda1_: I'll have to let someone else weigh in on that

12:46 hashpuppy: a reducer

12:46 *transducer

12:46 sorry

12:46 dagda1_: justin_smith: thanks

12:46 hashpuppy: oh... ok. thanks

12:47 EvanR_: i didnt know you could do (map f) by itself

12:47 hashpuppy: how are you guys installing clojurescript on a mac? with brew? or just via source?

12:47 EvanR_: i have (partial map f) over here in a lot of places

12:47 noonian: EvanR_: thats new with transducers

12:47 hashpuppy: i meant clojure

12:47 justin_smith: hashpuppy: don't install clojure, install lein

12:47 noonian: hashpuppy: if you have clojure installed you just list clojurescript as a dependency in project.clj

12:48 justin_smith: noonian: need lein for project.clj

12:48 noonian: hashpuppy: and when i say have clojure installed i really mean leiningen

12:48 justin_smith: :)

12:48 hashpuppy: so i have lein installed. how do i update clojure to 1.7. it's on 1.6

12:49 virmundi: Hello, when using fixtures in clojure, is it encumbant upon the fixture to try/finally around the function passed in to make sure the cleanup occurs.

12:49 justin_smith: hashpuppy: in project.clj, you should see a clojure dep

12:49 noonian: if you create a project, just change the version on the clojure dependency in project.clj; if you don't have a project yet type 'lein new my-project' to get one

12:49 justin_smith: hashpuppy: you can update that to a 1.7 version

12:50 EvanR_: justin_smith: your function cleaned up a lot of my code and the output, thx

12:50 justin_smith: np

12:50 hashpuppy: ok, so silly question. i have (def x (map (constantly true))) how can i apply a list to that? (x [1 2 3])???

12:50 lazybot: hashpuppy: Oh, absolutely.

12:51 noonian: in this case lazybot is right

12:51 justin_smith: ,(sequence (map (constantly true)) [1 2 3]) ;; hashpuppy:

12:51 clojurebot: (true true true)

12:51 noonian: er

12:51 BRONSA: EvanR_: (map f) is not (partial map f)

12:52 EvanR_: ,((map (constantly true)) [false false false])

12:52 clojurebot: #<core$map$fn__4341$fn__4342 clojure.core$map$fn__4341$fn__4342@1695c8c>

12:52 EvanR_: ,((partial map (constantly true)) [false false false])

12:52 clojurebot: (true true true)

12:52 BRONSA: EvanR_: read the docstring for map, (map f) returns a transducer

12:52 EvanR_: ah

12:53 BRONSA: EvanR_: a transducer can be passed to transduce/sequence/into/chan and a bunch of other functions

12:53 EvanR_: a lot of sequence functions now can return a transducer in their n-1 arity but don't confuse that with partial application

12:53 Balveda: Anyone run a Hoplon app on a server?

12:55 EvanR_: when everything is something, nothing is obviously wrong ;)

12:55 hashpuppy: so feeding the transducer into sequence turns it into a sequence?

12:56 justin_smith: ,(doc sequence)

12:56 clojurebot: "([coll] [xform coll] [xform coll & colls]); Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields (), When a transducer is supplied, returns a lazy sequence of applications of the transform to the items in coll(s), i.e. to the set of first items of each coll, followed by the set of second items in each coll, until any one of the co...

12:56 justin_smith: I probably would have named that something dumb like transmap or mapduce

12:57 BRONSA: hashpuppy: it turns it into a lazy sequence, if you don't want the lazy behaviour you can use (into [] x [1 2 3])

12:57 hashpuppy: thanks

12:58 EvanR_: mapdeuce

13:05 in doc strings can i highlight a variable name

13:05 justin_smith: EvanR_: it's just a string, there is no formatting layer defined

13:06 EvanR_: whats the convention for talking about the params

13:06 justin_smith: I mean you can put html in there if you want, but people don't have an html renderer attached

13:06 EvanR_: gross

13:06 looks like it starts with an arity list

13:07 (gross: html)

13:07 justin_smith: that's something the clojure.repl/doc function throws in there yeah

13:07 puredanger: you can override that with meta

13:07 justin_smith: so you can refer to parameters by the same name they are named in the args list, and that context will be present

13:08 puredanger: yeah, that too

13:08 EvanR_: in vim, is there a combo for "enclose selection in quotes"

13:09 justin_smith: EvanR_: this is worth figuring out, but a bit weird at first https://github.com/vim-scripts/paredit.vim

13:09 structural editing

13:10 EvanR_: im using vim-sexp at the moment

13:10 justin_smith: ok, it likely has a command for what you are describing, or at least a very concise way to do it

13:10 EvanR_: nah

13:11 only for ( [ {

13:11 so maybe i picked the wrong horse

13:13 and now i get to either convert a giant map into a giant nested java object, or fiddle with existing code which applies a giant map to a preexisting java object for the same purpose

13:13 joy

13:37 justin_smith: EvanR_: for what consumer?

13:38 EvanR_: im using camel

13:40 justin_smith: EvanR_: have you seen this? http://codeabout.blogspot.com/2010/06/using-apache-camel-from-clojure.html

13:41 or even this - https://github.com/hmanish/clj-camel

13:42 EvanR_: good to know

13:45 CookedGryphon: does anyone know why the buffer protocol in core.async changed from full? remove! add!, to full? remove! add!*

13:47 EvanR_: justin_smith: i am having some difficulty getting a trace of intermedia values between elements in a -> macro

13:48 justin_smith: (doc doto)

13:48 clojurebot: "([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"

13:48 justin_smith: ,(-> 5 (doto println) inc (doto println) inc)

13:48 clojurebot: 5\n6\n7

13:49 EvanR_: alrighty

13:49 justin_smith: for values of "trace" where trace = print at least :)

13:49 EvanR_: yes

13:49 technomancy: doto prn instead

13:50 justin_smith: technomancy: yeah, that is a good idea

13:50 (doc prn) ; for the uninitiated

13:50 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

13:50 justin_smith: (doc pr)

13:50 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

13:51 justin_smith: ,(prn "hello")

13:51 clojurebot: "hello"\n

13:51 justin_smith: ,(println "hello")

13:51 clojurebot: hello\n

13:51 EvanR_: i was actually going to use pprint

13:52 justin_smith: that works too :)

13:52 virmundi: What is the guidance on using function names that are in clojure.core? I want to load collections from a document db. The method name is (load [ctx]). I have (:refer-clojure :exclude load). Is this acceptable?

13:53 justin_smith: virmundi: I think it should be (:refer-clojure :exclude [load])

13:53 virmundi: Sorry, typo in the box. But is that idomatic clojure, to overload/re-reference a function from core?

13:54 justin_smith: well, I think it should be more a question of using it's name

13:54 since you are not modifying anything by doing that

13:54 EvanR_: what about commenting out a piece of a ->

13:54 justin_smith: and using its name is fine, but I'll probably hate you if I am reading your code and you exclude def and replace it with something totally different

13:55 for example

13:55 virmundi: I envision the api being (col/load [ctx])

13:55 Go on.

13:55 justin_smith: EvanR_: #_

13:55 ,(-> 5 #_ whatever inc)

13:55 clojurebot: 6

13:55 EvanR_: i thought that made it take the value of nil

13:55 or thats only comment

13:56 justin_smith: virmundi: yeah, it would only be an issue if it makes your code hard to read, so you are probably fine

13:56 EvanR_: it means skip the next form

13:56 EvanR_: (comment ...) returns nil, that just makes the next thing not be in your compiled code at all

13:57 ,(#_#_#_ it nests, too + 1 1)

13:57 clojurebot: 2

13:57 justin_smith: don't do that in real code, it is evil

13:57 virmundi: Thanks

14:06 poushkar: does anybody has experience working with RoR as backend and Clojurescript + Om/Reagent as frontend? How do you set it up?

14:06 *have

14:07 SagiCZ1: is there a better way to do this? (swap! atom #(new-value)) if i just want to set a new value to the atom?

14:07 justin_smith: SagiCZ1: reset!

14:07 SagiCZ1: thank you

14:11 EvanR_: how do i print a constant string in the middle of a ->

14:12 ,(doc doto)

14:12 clojurebot: "([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"

14:12 GFREDERICKS: reiddraper: I wrote some documentation for my test.check fork: https://github.com/gfredericks/test.check

14:12 EvanR_: now i have no idea how doto was working with (doto pprint)

14:13 i think i need to eat lunch

14:13 noonian: ,(-> "foo" (doto println) (str "bar"))

14:13 clojurebot: foo\n"foobar"

14:13 csd_: anyone here use the data.json package?

14:15 llasram: cheshire 4 eva

14:16 justin_smith: (inc cheshire)

14:16 lazybot: ⇒ 3

14:16 mgaare: EvanR_: (-> "a" ((fn [x] (println "static string") x)))

14:17 justin_smith: mgaare: yeah, I was looking for something more concise than that...

14:18 mgaare: couldn't think of anything

14:18 justin_smith: ,(-> 5 (doto ((constantly (println "OK")))) inc)

14:18 clojurebot: OK\n6

14:18 justin_smith: maybe

14:18 still ugly, probably merits writing an actual function

14:18 mgaare: that's a little nicer

14:19 although I think the explicit function is a bit easier to follow

14:19 justin_smith: ,(defn do-print [x str] (println str) x)

14:19 clojurebot: #'sandbox/do-print

14:19 justin_smith: (-> 5 (do-print "hello") inc)

14:19 ,(-> 5 (do-print "hello") inc)

14:19 clojurebot: hello\n6

14:20 justin_smith: I think that writing that small helper function is the right way to do it

14:20 noonian: ,(-> 5 (doto (do (println "a string)))

14:20 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

14:20 noonian: ,(-> 5 (doto (do (println "a string")))

14:20 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

14:21 noonian: ,(-> 5 (doto (do (println "a string"))))

14:21 clojurebot: a string\n5

14:24 borkdude: with transducers are things like mapv now also obsolete? (into [] (map inc) (range 10)) instead of (mapv inc (range 10)) ?

14:26 sdegutis: Hi. What's a good Vim plugin for Clojure?

14:27 Thanks in advance, and God bless.

14:28 borkdude: sdegutis fireplace maybe?

14:28 sdegutis: borkdude: Thank you sir, I'll investigate it.

14:29 Oh tpope created it, who also created fugitive. Nice.

14:32 borkdude: what does it mean that a transducers is independent of its "context" (whatever in the blogpost)

14:33 puredanger: borkdude: transducer functions do not know where input values come from or where output values are going to

14:33 sdegutis: I have not looked into "transducers" yet. I heard it's the new big thing though.

14:33 puredanger: as opposed to seq functions which explicitly assemble outputs by creating new lazy seqs (for example)

14:33 borkdude: puredanger right. I sensed that "independent of input" and "independent of whatever" were overlapping

14:34 sdegutis: Is http://clojure.org/transducers the best way to get started?

14:34 puredanger: sdegutis: I think watching Rich's talk that's linked there is a very good intro to the ideas

14:35 https://www.youtube.com/watch?v=6mTbuzafcII

14:35 sdegutis: Are transducers worth learning for someone who reluctantly uses Clojure in production and has no interest in pushing the envelop of computer science?

14:35 CookedGryphon: sdegutis: totally

14:36 they make so much stuff easier in my day to day work

14:36 and faster as an added bonus

14:36 puredanger: borkdude: re mapv, that example is probably one where the into version may be faster esp if you are composed with other ops

14:37 borkdude: puredanger will mapv be rewritten using a transducer then

14:37 puredanger: dunno, there are many questions like that still to be answered in the future

14:37 at the moment, transducers are almost entirely additive - they don't change the behavior of stuff that already exists, just add new capabilities

14:38 borkdude: puredanger were things like transducers and core.async more or less planned, or happy accidents that make clojure even cooler?

14:39 puredanger: transducers were a result of the work done in reducers and the (re-)work being done in core.async that led to the idea of factoring those parts out of applying transformations

14:41 borkdude: CookedGryphon how does it make stuff easier?

14:41 CookedGryphon: composability

14:42 being able to combine bits of operations together in different ways

14:42 I make use of core.async a lot, and it's meant I can just get rid of 90% of my go loops

14:43 I just pipe things about with transforms, which are composable, when go-loops are hideously boilerplatey

14:43 puredanger: CookedGryphon: are you using the new pipeline fns?

14:43 CookedGryphon: not yet, it's possible I should be

14:44 borkdude: puredanger what are the new pipeline fns?

14:44 CookedGryphon: but I wasn't sure how stateful transducers would behave given that parallelism seems obligatory

14:44 puredanger: borkdude: https://clojure.github.io/core.async/#clojure.core.async/pipeline

14:44 CookedGryphon: so I just stuck to chans with xforms and old fashioned pipe for now

14:44 borkdude: CookedGryphon do you also "return" transducers from functions where you would return a lazy sequence before?

14:45 CookedGryphon: borkdude: yeah, that sort of thing

14:45 again it's biggest win is in core.async

14:45 meant I could take the core.async :require out of a lot of namespaces entirely

14:45 they just return the transformation that they were doing in a go loop before

14:46 *and* as a bonus, testing is ridiculously simple, I just apply the same transform to a coll in, coll out

14:46 as opposed to nasty test setups where I'd need to make chans, onto-chan my data, then read the data back out and see if it was doing the right thing

14:48 borkdude: CookedGryphon ah right, you can unit test without using core.async

14:48 CookedGryphon: precisely

14:50 so yeah, totally worth it, and really not complicated. Use them about as much as normal function composition...

14:50 technomancy: is there any benefit vs normal composition if you're not using core.async?

14:50 other than speed

14:51 CookedGryphon: and memory usage

14:51 puredanger: less gc, faster, clearer separation of algorithm

14:51 mgaare: debuggability perhaps

14:52 borkdude: mgaare I don't see how this helps debuggability, I would say the opposite, because it's more difficult to inspect the intermediate stuff with println for example?

14:52 hiredman: technomancy: benefit to transducers?

14:52 technomancy: to me it kinda sounds like core.async has created its own world where different rules apply, and this feels like a workaround for that

14:52 hiredman: yeah

14:52 mi6x3m: hey clojure, if I have something like (let [x y z w] [1 2 (throw blabla) 4] will the bindings up to z be established ?

14:52 hiredman: technomancy: yeah, lots

14:52 mi6x3m: is this behaviour even defined?

14:52 puredanger: there are more pert-related improvements coming as well that aren't in 1.7 bucket http://dev.clojure.org/jira/browse/CLJ-1499 http://dev.clojure.org/jira/browse/CLJ-1515 for example

14:53 mgaare: borkdude: To be more precise, I was really thinking of stacktraces not containing n-levels of lazy seqs

14:54 CookedGryphon: technomancy: map/reducing over collections that are bigger than memory is useful

14:54 hiredman: technomancy: tranducers can avoid lots of extra overhead

14:54 technomancy: CookedGryphon: it sounds like you're just using different words to say "performance" over and over =)

14:55 amalloy: mi6x3m: do you mean (let [[x y z w] [1 2 (throw) 4]])?

14:55 CookedGryphon: :P well is performance such a bad thing?

14:55 mi6x3m: amalloy: mmm, yep

14:55 hiredman: technomancy: have you looked at reducers at all? how reducers get subsumed in to transducers seems to be up in the air, but the reducers work provides for a very compeling way to handle resources

14:56 puredanger: I do not expect that reducers will be subsumed into transducers

14:56 technomancy: CookedGryphon: I didn't say it was bad; I was asking if performance is the main point

14:56 hiredman: puredanger: oh, really?

14:56 CookedGryphon: technomancy: but I don't even mean reduced overhead when I'm talking about bigger than memory, I'm talking about being able to map+reduce over a collection where the *source* data is bigger than you could fit in ram

14:56 puredanger: technomancy: I think the main point is separating transformation from application

14:56 CookedGryphon: which is an entirely new thing, not just a performance improvement

14:56 amalloy: mi6x3m: have you tried macroexpanding that? it's pretty clear what happens, really

14:56 hiredman: puredanger: why not?

14:57 CookedGryphon: and that's a practical limit that I have hit before, which even reducers couldn't cope with

14:58 puredanger: I don't think they'll be removed but I don't think there will be attempts made to retrofit it in any way. it's more likely that we will gain new core functions that use transducers in parallel (i.e. preduce) that leverage the same underlying FJ fold over vectors/maps

14:58 hiredman: ok

14:58 subsumed rich style

14:58 puredanger: :)

14:58 technomancy: CookedGryphon: you can already map and reduce over collections bigger than your memory can hold though.

15:00 CookedGryphon: not so, certainly not in a composable way. Say you want to get a line-seq on a 400gb file, split the line into words, concatenate that into a list of all the words, filter from a list of stop words and then track the frequencies of the remaining words

15:00 sdegutis: go on

15:01 hiredman: technomancy: how do you create a for comprehension over the results of two sql queries that don't fit in memory?

15:01 * technomancy stares blankly

15:01 hiredman: with lazy-seqs it is hard because you don't just have the lazy seq, you have some database connection resources to manage

15:02 technomancy: like, if you (with-query-results ...) whatever you get a lazy seq of results, but those are only valid for the life time of the result set, so if you haven't forced it before you leave the with-query-results the seq isn't valid

15:03 technomancy: sure

15:03 hiredman: technomancy: I am using that particular api as an example of resource management around collections

15:03 (not claiming it is great or anything)

15:03 CookedGryphon: with transducers, you can do that as a (transduce (comp (mapcat tokens) (filter stop-words)) add-word-to-count (line-seq file)) and it won't hold the head of the seq

15:03 and I just plain couldn't do it before, try as i might

15:04 hiredman: so (for [x (with-query-results ...) y (with-query-results ...)] [x y]) is going to fail, unless you force the results inside the with-query-results

15:04 but for the sake of argument your result set is to large to fit in memory

15:04 so you can't

15:04 CookedGryphon: without writing the whole thing as a single reduce with no mapping, but that changes the problem, and you're basically reimplementing what transducers do under the hood anyway, so it may as well be readable

15:05 hiredman: with the reducers library you can formulate something that does that

15:06 technomancy: so it helps with managing scopes of resources

15:06 hiredman: sure

15:06 http://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html#sec-2-2

15:08 now the reducers library is not the same thing as this new transducer stuff, but it seems like transducers will be superset of reducers functionality

15:08 (even if the reducers namespace sits around for all time and #clojure has to constantly explain to people thay they should be using transducers instead)

15:08 puredanger: :)

15:09 technomancy: like clojure.core/partition

15:09 or clojure.core/list?

15:09 hiredman: exactly

15:09 also filter

15:09 err

15:09 flatten

15:09 puredanger: whew, I thought I was behind :)

15:10 llasram: hiredman: As the face of reducers for resource-management, you may appreciate this: https://gist.github.com/llasram/e75c6bbd9b8567e96681

15:11 hiredman: llasram: the irony is whene I tried to bring in reducers for resource management at work it got rejected on code review

15:11 llasram: whaaaa

15:11 hiredman: very conservative organization

15:11 llasram: It's such a great pattern though.

15:12 Also "very conservative" :: "using Clojure"

15:12 hiredman: well, we've been using clojure since before 1.x was released, so continuing to use clojure is a conservative choice :)

15:13 llasram: Fair enough!

15:13 hiredman: uh, actually

15:13 technomancy: is that right? since before 1.x was released? I don't remember

15:13 technomancy: hiredman: yeah totes

15:14 nov 2008 was when I started; right when AOT and atoms were added

15:14 GFREDERICKS: which have a lot of letters in common

15:14 smoat

15:14 TimMc: Are we doing uppercase names today?

15:15 arrdem: apparently

15:15 TIMMC: oh no it is catching

15:15 GFREDERICKS: is karma case sensitive?

15:15 (inc TIMMC)

15:15 lazybot: ⇒ 74

15:15 ARRDEM: it would seem not

15:16 GFREDERICKS: (dec TIMMC) ;; didn't earn that one

15:16 lazybot: ⇒ 73

15:16 TIMMC: hiredman: Do you want typo corrections on that piece?


15:16 ARRDEM: TIMMC: dude this isn't common lisp

15:20 justin_smith: (𐌶𐌽𐌺 𐍄𐍇𐌼𐌼𐌺)

15:20 GFREDERICKS: what does an upper-case paren look like

15:20 bbloom: GUYS-WHAT-IS-GOING-ON?

15:20 justin_smith: CAPS LOCK DAY



15:22 GFREDERICKS: this is a pretty weird website

15:23 bbloom: i love the mobile version

15:23 my capslock key has been ctrl for years, otherwise i'd participate

15:26 ghadishayban: puredanger: fwiw i've often wanted the fold-by-halves functionality to be independent of fork-join

15:27 fold-by-halves from some ticket ... searching

15:27 http://dev.clojure.org/jira/browse/CLJ-1045

15:28 that way i can make an operation that's logically a fold (reduce + combine), but be invoked in a different way

15:29 let's just say an asynchronous combine for the sake of example

15:29 puredanger: that's pretty cool. I don't remember seeing the ticket.

15:29 ghadishayban: i want the subdivision of a collection as the API, building foldvec on top of it specifically for FJ

15:31 this is in response to the hypothetical preduce


15:32 bbloom: amalloy: i used to type D#D(_TEXTURE all the time

15:32 drove me nuts

15:33 evindor: Hi people! IRC seems to be last resort for me. I got a problem with cljs source maps

15:33 puredanger: ghadishayban: I don't really know what shape a preduce would take

15:33 evindor: chrome shows me the source map file itself, not the source

15:34 anyone faced such an issue?

15:41 amalloy: bbloom: what made you need to type d3d9-texture?

15:42 bbloom: amalloy: i worked on lots of directx stuff

15:42 all the damn constants were all upper case

15:42 stuff like this: http://msdn.microsoft.com/en-us/library/windows/desktop/ff471467(v=vs.85).aspx

15:43 llasram: bbloom: how do you know it's a constant if it isn't shouting at you?

15:43 bbloom: even when not typing constant names, it was shit like ID3DXFile

15:43 which i'd surely type as ID#DXFile

15:43 argh.

15:43 or I'd miss a shift

15:43 IDireT#dStateBlock9

15:44 haunted me

15:44 llasram: is it too late to make all the variables upper case? :-)

15:47 EvanR_: obviously variables should have names like IdIRet#DdTAT$z\%634/52345

15:48 justin_smith: EvanR_: no joke, I was talking to a guy who "solved" his clojure design issue by using gensym to create names for all his functions

15:48 bbloom: bwha?

15:48 teslanick: It solves one of those two hard problems.

15:48 So you can focus on cache invalidation.

15:49 justin_smith: bbloom: inorite

15:50 bbloom: http://clojure-log.n01se.net/date/2014-10-21.html it starts up for real on the first page where he asks about AOT compiled scripts

15:52 amalloy: oh, chouser's logger is back up again? i remember it had been down for weeks at some point

15:52 GFREDERICKS: clojurebot: chouser's logger is back up again

15:52 clojurebot: Roger.

15:53 amalloy: gfredericks: you're killing me here. i refuse to acknowledge your all-caps name, which means i can't use tab completion

15:53 drbobbeaty: amalloy: He lives under a rainbow - what can you expect?

15:54 amalloy: huge backpedal from justin_smith in that log: "I have namespaces with hundreds of functions in them. [...] well, at least two"

15:54 justin_smith: heh

15:54 GFREDERICKS: amalloy: I saw puredanger do that earlier to BRONSA and wondered if it was manual

15:55 justin_smith: amalloy: at least two namespaces with hundreds of functions in them

15:56 amalloy: and this is in context of a dude trying to load a file where calling a function would suffice (so treating a namspace as if it were one bit function)

15:56 amalloy: yes, i remember rritoch

15:56 evindor: Does anyone have working source maps for cljs with advanced optimizations?

16:03 justin_smith: evindor: you may get more help on #clojurescript - couldn't hurt to try there if you haven't

16:03 evindor: justin_smith: thx

16:14 amalloy: shame dnolen isn't here - i can't imagine he'd settle for non-working source maps

16:15 evindor: amalloy: they are generated but i guess i have messed up paths inside it

16:16 chrome even laods it but shows the source map file itself instead of source code

16:16 amalloy: yeah, i have no idea. if i did, i'd offer help myself instead of lamenting dnolen's absence

16:17 teslanick: evindor: What's the //#sourceMapingUrl at the end of your compiled JS look like?

16:18 And then open the map file that it points at and check the "sources" array (a sourcemap is just a JSON file)

16:18 evindor: teslanick: //# sourceMappingURL=app.min.js.map

16:19 map file itself looks okay, except it has several empty strings in sources

16:19 teslanick: Interesting. That might be the source of your problems.

16:20 Have you tried nuking all the built cljs and rebuilding?

16:20 evindor: yeah i think so as well. sure i tried rebuilding everything

16:25 puredanger: amalloy: re earlier, dnolen is currently on tour with his band in Europe so won't be around for a while

16:25 afaik

16:25 amalloy: unacceptable. how will cljs patches be applied without him?

16:25 puredanger: he does seem to be online occasionally doing stuff, not sure what his exact schedule is

16:26 amalloy: oh my gosh. i just had a vision of dnolen pausing mid-concert to apply a patch. he's just that committed

16:26 bbloom: heh committed, i get it

16:26 amalloy: (inc unintended-puns)

16:26 lazybot: ⇒ 1

16:26 clojurebot: Titim gan éirí ort.

16:28 amalloy: what does dnolen play? i have this vague notion that it's a brass instrument of some sort but i don't know how i got that idea

16:28 bbloom: amalloy: https://www.youtube.com/watch?v=4E9TGlDxE48 south park?

16:29 amalloy: bbloom: brass, not bass

16:29 but i don't watch south park

16:29 bbloom: amalloy: oh, reading comprehension failure

16:31 andrewhr: oh man, I didn’t know there is a clojurescript channel

16:31 u.u

16:38 puredanger: amalloy: See http://hairysands.bandcamp.com/album/sandy-hairs - I think he plays guitar?

16:39 yeah, some pics here: https://twitter.com/hairysands

16:45 justin_smith: if he played keyboard, the references to patches above would be unintentional puns

16:55 danielcompton: Is there any way to convert a record to a map without altering the keys or values of the record?

16:56 technomancy: into?

16:56 clojurebot: into is like a magical transformer ring. i.e. (into {} something) converts a surprisingly wide variety of things into maps.

16:56 bbloom: ,(defrecord Point [x y])

16:56 clojurebot: sandbox.Point

16:56 bbloom: ,(into {} (Point. 5 10))

16:56 clojurebot: {:x 5, :y 10}

16:57 vIkSiT: hello all

16:58 Im running an experiment : I have a function called myfn that takes about a second to execute. So, I run a (doseq [f files] (myfn f)) and time it.

16:58 (by wrapping doseq with time)

16:58 TIMMC: Are you using criterium?

16:59 SagiCZ1: vIkSiT: yeah<

16:59 danielcompton: bbloom, technomancy: of course

16:59 TIMMC: ~benchmarking

16:59 clojurebot: benchmarking is https://github.com/hugoduncan/criterium

16:59 vIkSiT: Now, I try a (map myfn (partition-all n files))

16:59 I'd like to figure out how to measure times in this case.

16:59 SagiCZ1: vIkSiT: me too

16:59 TIMMC: doall

16:59 justin_smith: vIkSiT: use criterium

16:59 TIMMC: or dorun, I guess

16:59 vIkSiT: (And ideally, Id like to figure out how to use pmap)

17:00 ah

17:04 hmm, thanks for that info - I think dorun really did the trick

17:04 now my follow up question :)

17:05 what's a good guide to using pmap vs parallel programming using reducers?

17:05 justin_smith: ~pmap

17:05 clojurebot: pmap is not what you want

17:06 vIkSiT: justin_smith, hehe - well

17:06 I'm not quite going to start using a 1000 node MR cluster just yet..

17:06 SegFaultAX: Oh pmap. The function we love to hate.

17:06 vIkSiT: so why all the pmap ~love?

17:06 SagiCZ1: wait whats wrong with pmap?

17:06 vIkSiT: ^^ that.

17:07 SegFaultAX: The usual warning that your mapping fn better be more expensive than the coordination overhead of multiple threads.

17:07 vIkSiT: ah that

17:07 SegFaultAX: Either way, try it and test.

17:07 SagiCZ1: SegFaultAX: so? thats something u discover with one test

17:07 vIkSiT: and how does one benchmark the coordination overhead of multiple threads?

17:07 justin_smith: also, it chunks in unintuitive ways

17:07 SagiCZ1: just time pmap and time map

17:07 vIkSiT: for instance in my case, I just saw a reduction in time from 20ms -> 7ms.

17:08 justin_smith: vIkSiT: with criterium

17:08 vIkSiT: precisely - trying that now.

17:08 SegFaultAX: It's not always bad. But usally it isn't worth it for what 99% of people ask about.

17:08 SagiCZ1: i wonder why is that thread overhead so huge

17:09 SegFaultAX: SagiCZ1: It's expensive in both time and space to start up a thread pool

17:09 justin_smith: SegFaultAX: and it's rarely better than an executor with a queue (via core.async abstractions or not to taste)

17:09 vIkSiT: SagiCZ1, coordination is always going to be expensive simply becase you need to maintain a threadpool, start it up. et al

17:09 SegFaultAX: justin_smith: Precismo!

17:09 vIkSiT: justin_smith, speaking of which..

17:09 clojurebot: Pardon?

17:10 vIkSiT: is there a core.async based guide to multi-thread processing? channels, best practices, consuming, map/reduce?

17:10 SegFaultAX: Or reducers

17:10 justin_smith: vIkSiT: SagiCZ1: also, pmap ensures ordering - you can get faster results if you don't care about the ordering

17:10 SegFaultAX: I don't know if transducers have been ported to also leverage ForkJoinPool, but that.

17:10 SagiCZ1: justin_smith: how can it ensure ordering, when its parallel?

17:10 SegFaultAX: Depending on the nature of the work and the processing involved.

17:10 SagiCZ1: That's part of the coordination.

17:11 justin_smith: and part of why said coordination is expensive

17:11 SegFaultAX: SagiCZ1: But a really naive impl is to just create N futures, then map deref over them.

17:12 justin_smith: $source pmap

17:12 lazybot: pmap is http://is.gd/98SQJR

17:12 puredanger: that's all pmap is doing

17:13 justin_smith: puredanger: yeah, that was my intended point with that link :)

17:13 hiredman: well, pmap is doing weird stepping stuff

17:13 SagiCZ1: interesting......... well thats it for thinking pmap is amazing

17:13 hiredman: and pmap does weird things with chunked seqs

17:13 etc

17:13 puredanger: pmap is perfect solution to a very narrow band of problems and pretty bad for everything else

17:14 ghadishayban: What's a favorite resource for explaining the seq/first/rest/next subtleties to a beginner?

17:14 SegFaultAX: Does transducers also already support ForkJoinPool the way reducers did?

17:14 puredanger: no

17:14 see the back chat from the last hour or so :)

17:14 SegFaultAX: puredanger: tl;dr? :D

17:14 ghadishayban: SegFaultAX: transducers are irrespective of collection / eval strategy

17:15 puredanger: SegFaultAX: doesn't exist. but will eventually.

17:15 SegFaultAX: Sure. You might want a fjtransduce fn.

17:15 hiredman: generally for lots of these parallel things, you don't actually care about ordering, lots of the time you have an unordered bag of work you want to happen and want the result of the work as it finishes

17:15 pmap and seqs force ordering

17:16 SegFaultAX: That's the other implicit issue with pmap. You can't represent things where ordering doesn't matter.

17:16 Yup

17:16 puredanger: async/pipeline fits in that group too

17:16 SagiCZ1: so is there some sort of doseq that lets me specify how to exactly get the next element besides loop?

17:17 justin_smith: SagiCZ1: well I guess you could reify an iterator or something...

17:17 hiredman: sure, just make sure you aren't doing io on the go block threadpool

17:17 justin_smith: SagiCZ1: but loop seems more straightforwar

17:17 SagiCZ1: loop it is then..

17:18 SegFaultAX: puredanger: In which group?

17:18 justin_smith: SagiCZ1: depending on what you are doing and how you want to view the result, there is also iterate

17:18 puredanger: the group of things that force ordering :)

17:18 justin_smith: SagiCZ1: though "sort of doseq" I guess implies not using the results

17:19 hiredman: puredanger: is that entirely true?

17:19 SegFaultAX: No.

17:19 Becuase you could use an input channel and an output channel and some number of goblocks or gothreads to read from the input channel and write to the output channel.

17:19 puredanger: hiredman: actually, I guess you're right - it produces results in an order corresponding to the inputs

17:20 but might not actually process them in that order

17:21 SagiCZ1: i might be overthinking this.. i have a queue, and i need to write its consumer.. i get next element by (.take queue).. then i just call (consume element) .. this is how i do it https://www.refheap.com/92176 maybe it can be done better?

17:22 ghadishayban: Is there a resource like clojure.org/lazy but more current? http://clojure.org/sequences doesn't mention next vs rest.

17:22 puredanger: there is actually a dead page that talks about that

17:23 ghadishayban: I'm looking for a well-written link I can handily throw at a beginner to understand the subtleties of seq vs coll, first/rest, rest vs. next

17:23 puredanger: oh, the lazy page is what I was thinking of. I don't think there is a more current version of that but there should be

17:23 hiredman: puredanger: well that is interesting though, I didn't realize the pipelines were that strongly order preserving

17:23 SegFaultAX: So... when are we going to kill clojuredocs?

17:23 ghadishayban: yeah too much real estate devoted to how rest *used* to work

17:23 pre-github

17:24 puredanger: hiredman: they're designed to be used for things like pipeline stages where work passes through them, so the ordering is important

17:24 hiredman: puredanger: does what it says on the tin

17:25 technomancy: SegFaultAX: just when it's sputtered back to life?

17:25 SegFaultAX: Has it?

17:26 technomancy: Wowza, that's awesome. I can't believe I didn't notice it.

17:26 puredanger: SagiCZ1: I'd prob refactor that to just have a single .take inside the loop. and you might need some kind of termination check

17:26 SagiCZ1: puredanger: thank you for having a look, how could i just have one .take call?

17:27 hiredman: I am rethinking through the sort of things I have done, that I thought pipeline was a good fit for, and I think it still is with the ordering on the final results, what matters is the free for all ordering on actual running of the jobs

17:27 puredanger: (loop [] (let [event (.take queue] (consume event) (recur))

17:27 SagiCZ1: isnt that (while true ... ?

17:27 SegFaultAX: That's why he said you need to check for termination.

17:27 puredanger: yeah, but you'll probably want some other stuff there too

17:28 <advert>I have a section on this in my forthcoming book btw</advert>

17:28 SagiCZ1: i see

17:28 i am buying, are you selling?

17:29 SegFaultAX: puredanger: EAP?

17:29 puredanger: will be a Prag beta book soon, hopefully by the conj

17:30 Clojure Applied

17:39 TIMMC: ~books

17:39 clojurebot: books is book

17:39 TIMMC: ~book

17:39 clojurebot: book is http://clojurebook.com/ http://joyofclojure.com/

17:39 TIMMC: You'll have to add to the list.

17:41 SegFaultAX: TIMMC: Why are you yelling your name at us? :D

17:42 TEttinger: SegFaultAX, why are you yelling his name?

17:43 SegFaultAX: TEttinger: Anger issues, probably.

17:45 bridgethillyer: It’s ALL CAPS DAY

17:51 SagiCZ1: any idea what could this mean? "No nREPL ack received"

17:52 justin_smith: SagiCZ1: I think that means cider

17:54 SagiCZ1: though if it helps, an ack is a confirmation in a communication protocol, and it sounds like something is out of sync with a clojure nrepl server (either because of a scrambled message on the line, or the nrepl having some error state)

17:54 SagiCZ1: thank you

17:54 technomancy: I think nrepl acks are sent to indicate the server is up

17:54 so that could mean the server wasn't started successfully?

17:55 justin_smith: technomancy: it can also happen when cider fucks up the message parsing, and thus does not recognize the ack

17:55 technomancy: huh

17:55 justin_smith: when its bencode gets in a bad state or something

17:55 technomancy: that is, you can get an ack, but the client (cider) sometimes does not recognize it as one

17:56 SagiCZ1: its a local lein repl

17:56 technomancy: oh cider http://p.hagelb.org/sisko.gif

17:57 justin_smith: SagiCZ1: any other error output?

17:58 the failure to get an ack basically means the nrepl server did not confirm it was there and ready to accept evaluation requests

18:06 EvanR_: ,()

18:06 clojurebot: ()

18:07 EvanR_: ,'()

18:07 clojurebot: ()

18:07 Bronsa: ,`()

18:07 clojurebot: ()

18:07 Bronsa: yep still a lisp

18:07 EvanR_: ,(= () '())

18:07 clojurebot: true

18:08 stuartsierra: ,(= () nil)

18:08 clojurebot: false

18:10 pmonks: ,(= * =)

18:10 clojurebot: false

18:10 pmonks: (sorry - couldn’t resist some rude ascii art...)

18:12 Or is it a TIE fighter?

18:16 EvanR_: lol <- tie interceptor

18:31 TIMMC: SegFaultAX: I don't know, BRONSA started it! And then GFREDERICKS did it, and I caved to peer pressure.

18:31 SegFaultAX: Apparently HTTP://CAPSLOCKDAY.COM

18:33 TimMc: Maybe it is time to relax though.

18:33 Bronsa: it's no longer CAPSLOCKDAY in Italy.

18:34 justin_smith: $google is it caps lock day

18:34 lazybot: [internetonal caps lock day home page] http://capslockday.com/

18:34 justin_smith: I was hoping for a single serving site

18:39 SagiCZ1: are Italians here?

18:39 why don't we talk about food all day? i am dissapointed

18:39 EvanR_: ,[1 2 3]

18:39 clojurebot: [1 2 3]

18:39 EvanR_: ,'[1 2 3]

18:39 clojurebot: [1 2 3]

18:39 SegFaultAX: TimMc: Hah

18:40 EvanR_: ,'[1 (+ 2 2) 3]

18:40 clojurebot: [1 (+ 2 2) 3]

18:41 justin_smith: '(just about anything goes here, really- go nuts!)

18:41 ,'(just about anything goes here, really- go nuts!)

18:41 clojurebot: (just about anything goes here ...)

18:41 kenrestivo: hmm, this works, but it reeks of old socks and leftover lunch meat: https://www.refheap.com/92177

18:41 SagiCZ1: kenrestivo: here we go.. food

18:42 EvanR_: ,''

18:42 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

18:42 justin_smith: kenrestivo: that's a pretty deep nest of anonymous functions

18:42 kenrestivo: my gawd, capslockday.com is actually a thing? that site... my eyes... myspace 2005...

18:43 noonian: kenrestivo: it might look a bit cleaner if you bound the parsed res in a let before swap, or broke it out into a helper function

18:43 kenrestivo: justin_smith: yeah, it's pretty ridiculous. i think core.async channels might be in order

18:43 justin_smith: kenrestivo: how about maybe flet?

18:43 SagiCZ1: can i create a defmethod which takes anything that couldnt be dispatched? something like default implementation

18:44 kenrestivo: flet?

18:44 justin_smith: kenrestivo: putting together an example

18:44 kenrestivo: “floor of a house; house”), from Old English flet,

18:44 justin_smith: SagiCZ1: a multi can take any function, including one that has a default

18:44 kenrestivo: and i am not going near urban dictionary on that, thankyouverymuch. it sounds filthy.

18:45 SagiCZ1: justin_smith: not sure i follow..

18:45 justin_smith: SagiCZ1: defmulti takes a dispatch function as an argument

18:45 noonian: kenrestivo: maybe something like: (swap! app-state update-in [:foo] #(merge % (parse-res res)))

18:45 SagiCZ1: so if i want default methods i can implement default dispatch in the dispatch function

18:46 SegFaultAX: kenrestivo: If it was myspace, there would have been javascript rain and a clock connected to your mouse.

18:46 justin_smith: SagiCZ1: but I take that back - really you just want to dispatch on type like normal, and then have a version for Object, probably

18:46 and others still work, being more specific and all

18:46 kenrestivo: noonian: good call, that fn [o] is totally superfluous

18:46 SegFaultAX: Just sayin: http://rainbow.arch.scriptmania.com/scripts/mouse_clock3.html

18:47 EvanR_: SegFaultAX: having never used myspace, this sounds rather bizarre without context

18:47 kenrestivo: forgot swap! can pass args, i'm so used to passing it anonymous fns

18:47 noonian: yeah, i forget too but it tends to clean things up when you remember :P

18:47 SagiCZ1: justin_smith: and if the dispatch value is nil, would the Object implementation take it?

18:47 SegFaultAX: EvanR_: It was a simpler time then.

18:48 justin_smith: SagiCZ1: what is your dispatch fn?

18:48 SagiCZ1: just a keyword lookup in map.. ":type"

18:48 justin_smith: SagiCZ1: then define a version for nil instead of Object

18:49 I had wrongly assumed you were using the "type" function

18:49 SagiCZ1: so (defmethod foo nil ?

18:49 justin_smith: SagiCZ1: yup

18:49 SagiCZ1: alright

18:49 EvanR_: and thats all i can about stand for today

18:49 noonian: SagiCZ1: you can also define an implementation for :default

18:49 justin_smith: or, instead of :type use #(get % :type :default) and then (defmethod foo :default ...)

18:49 yeah, what noonian said

18:50 noonian: but you don't need to supply the :default key on nil's multimethods does it for you

18:50 ,(doc defmulti)

18:50 clojurebot: "([name docstring? attr-map? dispatch-fn & ...]); Creates a new multimethod with the associated dispatch function. The docstring and attribute-map are optional. Options are key-value pairs and may be one of: :default The default dispatch value, defaults to :default :hierarchy The value used for hierarchical dispatch (e.g. ::square is-a ::shape) Hierarchies are type-like relationships that do not d...

18:50 justin_smith: noonian: ahh, I had missed that subtlety, nice :)

18:51 (inc noonian)

18:51 lazybot: ⇒ 8

18:52 noonian: :)

18:54 justin_smith: kenrestivo: a slightly silly attempt to use flet as I was suggesting https://www.refheap.com/92178

18:54 kenrestivo: translation likely imperfect

18:55 noonian: justin_smith: is flet new in 1.7 or something?

18:55 kenrestivo: what is this flet?

18:55 noonian: ,flet

18:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: flet in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:55 justin_smith: oh crap

18:55 kenrestivo: yeh

18:55 justin_smith: letfn

18:55 amalloy_: how do i pass options to javac when running lein javac?

18:55 justin_smith: I am so silly

18:55 noonian: ahhh

18:55 justin_smith: brain fart, my bad, fixing the paste

18:56 amalloy_: flet is secret technology of the T Elves, written backwards so we won't suspect a thing

18:56 justin_smith: fixed

18:56 kenrestivo: flet! flet! flet! sounds like a large bird taking off.

18:56 noonian: lol, urban dictionary does have an entry for flet...

18:56 kenrestivo: oh, letfn, sure.

18:56 justin_smith: kenrestivo: flet is basically letfn in common lisp

18:56 kenrestivo: ok.

18:56 justin_smith: clearly I experienced a neural temporal anomoly, and/or a senior moment

18:57 kenrestivo: happens. the more languages you use, the more interference happens

18:57 noonian: ruby hashmap syntax killed me after getting used to clojure keywords

18:58 kenrestivo: i like that device tho, if there are a lot of anon fn's, namign them in a letfn cleans up the nesting

18:59 noonian: i think it also allows for mutual recursion as if you had declared them beforehand

18:59 justin_smith: kenrestivo: and as a bonus, it allows mutual recurion and inlining thanks to the scope

18:59 right

18:59 *recursion

18:59 kenrestivo: clojurebot: recursion is recursion

18:59 clojurebot: Alles klar

19:00 justin_smith: ,(nth (iterate identity 'recursion) 1000000)

19:00 clojurebot: recursion

19:03 SagiCZ1: justin_smith: something very weird happens when you call (method nil "value2") .. the dispatch method skips the nil and tries to dispatch it on the "value2" ..

19:04 justin_smith: SagiCZ1: that's odd

19:04 SagiCZ1: let me try to replicate it here

19:04 ,(defmulti foo :type)

19:04 clojurebot: #'sandbox/foo

19:05 SagiCZ1: ,(foo nil "value")

19:05 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No method in multimethod 'foo' for dispatch value: value>

19:05 SagiCZ1: ,(foo nil "second-value")

19:05 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No method in multimethod 'foo' for dispatch value: second-value>

19:05 SagiCZ1: see?

19:06 justin_smith: ,(defmethod foo :default [a b] :default-value)

19:06 clojurebot: #<MultiFn clojure.lang.MultiFn@a4441a>

19:06 justin_smith: ,(foo nil "value")

19:06 clojurebot: :default-value

19:06 GFREDERICKS: okay I think it's time to write hyper-shrink

19:07 justin_smith: SagiCZ1: the error message is confusing, but the behavior I show above should be fine, right?

19:07 SagiCZ1: is the :default keyword special?

19:07 justin_smith: SagiCZ1: yes, as noonian was pointing out above

19:07 it is the default default

19:08 the meta default

19:08 lol

19:08 SagiCZ1: i missed that

19:08 its in the defmulti doc too.. never mind .. thanks for helping me

19:08 btw that error message is terrible

19:09 justin_smith: yeah, I can't see how that would even make sense in that context at the moment

19:09 perhaps worthy of a bug report?

19:10 SagiCZ1: perhaps

19:10 clojurebot: Cool story bro.

19:17 justin_smith: gfredericks: wtg w/ tla research

19:18 gfredericks: justin_smith: thx

19:21 I'm sure everybody is itching for the raw data: http://upload.gfredericks.com/tmp/missing-tlas.clj

19:21 everybody pick a TLA and work on getting it into wikipedia

19:22 justin_smith: gfredericks: FUX is not taken, must find an acronym for FUX

19:22 technomancy: we can have this done by the weekend; let's get cracking people

19:23 justin_smith: TLA squatting: 1) claim TLA, 2) ??? ...

19:24 noonian: 3) profit!

19:24 er, 4) i guess

19:25 SegFaultAX: gfredericks: Prismatic's pairing question?

19:25 gfredericks: is it?

19:25 SegFaultAX: I think it's one of them.

19:36 mwfogleman: i'm having troubles with the reloaded workflow -- my system.clj file is in my src/.../system.clj directory, and i can't make my users.clj find it.

19:37 noonian: (require [the.path.to.system :as system]) fails?

19:37 mwfogleman: within the ns macro, yeah.

19:37 i tried doing the simplest possible case with stuart's reloaded template and i bump into the same problem

19:37 noonian: you should make sure you can do it manually first. if there is a problem with system.clj then it could block user.clj from loading

19:38 mwfogleman: oh, in the repl?

19:38 noonian: yeah

19:38 mwfogleman: good idea.

19:38 i'll go try that.

19:39 noonian: also, you might want to do that user stuff in a different namespace and have a function in user.clj that calls (in-ns 'dev-ns) so that you can still get a repl up if you have errors in your code

19:41 mwfogleman: noonian: running require in the repl worked.

19:42 i'm not sure i understand your suggestion.

19:42 noonian: don't worry about it for now then

19:42 maybe you don't tell clojure where your custom user.clj is in project.clj?

19:42 either in :init-ns or include the directory in source-paths in the dev profile or something

19:42 mwfogleman: it's in source-paths, that's not the problem.

19:43 it's only when i try to require my own code that the compiler hits an error.

19:43 i'm noticing the problem when i do lein clean; lein deps; lein compile

19:44 one thing is that all the code i've tried to require is in a src/subdirectory/....file.clj

19:44 whereas the user.clj is in dev/user.clj

19:45 noonian: common mistakes include using hyphens instead of underscores in your directory names

19:45 mwfogleman: in the directory name, not the require, right?

19:45 the namespaces have hyphens

19:45 i think the directories are all underscores

19:45 let me double check

19:45 noonian: yeah, what you put in the ns form

19:46 but the ns form (with hyphens) still needs to correspond to the directory structure (with underscores)

19:46 mwfogleman: ohhh

19:46 that's totally the problem. i'm inheriting the project

19:46 and it has a hyphen

19:46 in the directory. strange that hasn't shown up

19:46 until now

19:46 noonian: inheriting?

19:46 mwfogleman: as in I have a new clojure job!

19:46 :D

19:47 noonian: congrats!

19:47 mwfogleman: thanks! :)

19:47 it's strange that this problem hasn't surfaced until now.

19:48 noonian: do you use component and/or the reloaded workflow?

19:48 noonian: yes, although i'm not using clojure at work atm so just for personal stuff

19:49 mwfogleman: ok, ok

19:49 hmm, this might not be the problem. the repo is hyphenated, not the directory.

19:49 i misread the misreading :P

19:49 amalloy: mwfogleman: you shouldn't need to run clean, deps, *or* compile. those are all done pretty automatically. and if you really do need to run them, you can save yourself quite a bit of startup time by combining them into one lein invocation: lein do clean, deps, compile

19:49 mwfogleman: oh, boy!

19:49 i know i don't need to run them regularly

19:49 but that's handy shortcut, thanks

19:49 justin_smith: in particular, pretty much any task will end up invoking deps

19:50 noonian: i don't think bad code in user would mess up your lein deps at all, i just typed some junk into my user.clj and it didn't trip up leiningen

19:50 justin_smith: clean is iffier - it is sometimes needed after you update a library version in your deps for example

19:51 noonian: maybe your project depends on another project that is private to your company and you need to 'lein install' it manually?

19:51 amalloy: justin_smith: updating a library version in your deps? how does that ever need a clean?

19:52 justin_smith: amalloy: just the other day someone was getting really weird errors because they upped a lib version, after a clean the errors went away

19:52 iirc it was schema

19:52 mwfogleman: noonian: that second thing sounds promising

19:52 amalloy: justin_smith: well. i'm not necessarily convinced it was *because* they updated a lib version, so much as that it happened at the same time

19:52 mwfogleman: noonian: we have some git submodules

19:53 justin_smith: amalloy: yeah, it was piranha, they were getting schema exceptions after updating the version, they went away after running lein clean

19:53 amalloy: the main reason to need clean is if you're doing a bunch of AOT compilation and want to make sure old artifacts aren't lying around; i ended up deleting a class once, and then forgot to update the code that was using that class: the old classfile was still around, so it "worked" for days

19:53 justin_smith: amalloy: yeah, aot may have been a contributing factor there

19:54 mwfogleman: noonian: fyi, the problem isn't "bad code" in the user.clj-- there's actually nothing in there yet, really

19:54 noonian: mwfogleman: if your :dependencies vector has anything that looks like an in-house lib you should track it down and lein install it; or maybe just ask someone :P

19:54 amalloy: the main time i end up running lein deps myself is if i want to update a snapshot version: lein -U deps

19:54 noonian: mwfogleman: what error do you get?

19:55 mwfogleman: java.lang.ClassNotFoundException

19:55 hmm. how do i figure out which in-house lib is the problem?

19:56 noonian: and its your system class that isn't found?

19:56 mwfogleman: no-- i don't have to be requiring the system for this error to be thrown. as best i can tell, it's any in-project, in-house code

19:56 things like midje or component don't throw an error.

19:57 noonian: mwfogleman: you can look in your ~/.m2/repository to see which libs are installed are installed. if you have multiple in-house deps you will need to install all of them

19:57 i.e. cd to the project directory and type 'lein install'

19:57 ARRDEM: johnwalker: you should come lurk #clojure-social. 'tis a silly place.

19:58 mwfogleman: ok, good idea.

20:00 i seem to have all the dependencies. and upon reflection they seem to be publically available, albeit developed by our folks

20:01 noonian: they need to be published to clojars or maven for lein to find them

20:01 johnwalker: hehe 7 nicks

20:01 noonian: hmm, do you have any deps or plugins in ~/.lein/profiles.clj that might be causing it?

20:02 mwfogleman: hmm. i do have a plugin: lein-midje (that's also in our project.clj dev dependency); and a dependency on tools.namespace.

20:02 which the reloaded workflow requires in the project.clj.

20:02 as you know

20:03 johnwalker: mwfogleman: has anyone suggested that you run lein deps :tree

20:03 noonian: well, lein deps throws an error for him

20:03 johnwalker: oh.

20:03 mwfogleman: it's actually lein compile that throws the error

20:03 as best i can tell

20:04 justin_smith: mwfogleman: then it should tell your which file is causing the error - can you share the stacktrace?

20:04 mwfogleman: excerpts--- let me get it again. what am i looking for?

20:05 noonian: the file that is not found

20:05 justin_smith: mwfogleman: pastebin the whole trace

20:05 or I should say refheap.com it

20:08 mwfogleman: noonian: justin_smith: https://www.refheap.com/f7e08862a611525c7a24dd8d7

20:08 justin_smith: mwfogleman: there should never be a class called yeti-stack.StackPailStructure

20:08 mwfogleman: a clojure pastebin, nice :D

20:08 justin_smith: that isn't a valid class name

20:09 noonian: yeah, the underscore thing applies to class names also

20:09 mwfogleman: justin_smith: okay, that sounds promising.

20:09 justin_smith: in system_pail.clj, change any reference to yeti-stack.StackPailStructure to yeti_stack.StackPailStructure

20:10 noonian: we could even say that it only applies to class names, and the file name requirement is a side effect of this :)

20:10 mwfogleman: justin_smith: clever ;)

20:10 i think that's coming from the namespaces

20:11 oops

20:11 it's not

20:11 the namespaces are no problem, right?

20:11 it's just hyphens elsewhere in the code

20:11 justin_smith: mwfogleman: the namespace should be called yeti-stack

20:11 classes defined in the namespace should be referenced as yeti_stack.*

20:11 mwfogleman: i have a line like this in the ns macro: (:import [yeti-stack StackPailStructure])

20:12 noonian: if you're importing anything they need underscores

20:12 justin_smith: change that to (yeti_stack StackPailStructure)

20:12 mwfogleman: ok, imports need underscores.

20:12 i'm thinking this is probably going to need changes in more than one place

20:12 thanks for helping me track this down, justin_smith and noonian.

20:13 justin_smith: mwfogleman: yeah, you may just want to grep for :import :) emacs has a wonderful M-x rgrep that lets you jump to each usage with a mouse click

20:13 noonian: np, happy coding!

20:13 mwfogleman: justin_smith: nice, i'll do that :D

20:14 justin_smith: mwfogleman: glad I could help, this stuff is hard the first 100 times or so, but eventually the heuristics are second nature :)

20:14 mwfogleman: justin_smith: glad to hear that.

20:14 justin_smith: we should do an "interpret clojure stacktraces as a service" startup

20:14 mwfogleman: haha, totally.

20:15 i'm getting better at picking out the important parts.

20:15 justin_smith: yeah, it's a kind of literacy basically

20:16 my big hint this time: CamelCase means java level stuff, which means you need _ instead of -

20:16 so - with CamelCase was a red flag

20:16 mwfogleman: okay, good hint.

20:17 andyf: mwfogleman: Eastwood should help you find such namespace/file name mismatches. github.com/jonase/Eastwood

20:17 Among other issues

20:17 mwfogleman: andyf: i've been meaning to check that out for a while. thanks for the reminder.

20:19 andyf: I had the weirdest time testing Eastwood on projects with such mismatches before putting that check in. Adding it was a sanity-preserver

20:25 mwfogleman: justin_smith: does this look problematic to you?: (gen-structure yeti_stack.StackPailStructure

20:25 erm

20:25 (gen-structure yeti-stack.StackPailStructure

20:25 which is better? ;)

20:30 justin_smith: the first is correct - class names can't have -

20:30 though I don't know what gen-structure is

20:33 mwfogleman: justin_smith: it's a macro in clj-pail.

20:34 justin_smith: thanks for the reassurance. i think it's definitely the _'s and the -'s :)

20:36 hashpuppy: reading a clojure book online and they give an example of ((or + -) 1 2 3). what is that doing?

20:36 justin_smith: hashpuppy: the cool thing with clojure is usually each part of a form can be run individually

20:37 ,(or + -)

20:37 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@afe405>

20:37 justin_smith: that looks weird, but it is the value of +

20:37 ,+

20:37 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@afe405>

20:37 mwfogleman: the one cool thing ;)

20:37 justin_smith: mwfogleman: one of many :)

20:37 mwfogleman: :D

20:37 justin_smith: so, we substitute + into your form

20:37 ,(+ 1 2 3)

20:37 clojurebot: 6

20:37 mwfogleman: error messages are one of the few not cool things ;)

20:37 justin_smith: right

20:38 hashpuppy: i see now. thanks

20:38 justin_smith: hashpuppy: since everything is prefix in clojure, we can allow arbitrary numbers of arguments, but I hope it is clear what's happening

20:39 hashpuppy: am i correct that it's just + evaluates to true and so or short-circuits and picks + which it then inserts as you showed above

20:39 justin_smith: right

20:39 ,(or 1 2 3)

20:39 clojurebot: 1

20:39 hashpuppy: i don't know why i didn't see that earlier. thanks. i'm just not used to or'ing two function expressions

20:40 it was just an example, though

20:40 justin_smith: ,((rand-nth [+ -]) 1 2 3)

20:40 clojurebot: 6

20:40 justin_smith: ,((rand-nth [+ -]) 1 2 3)

20:40 clojurebot: -4

20:40 justin_smith: ,((rand-nth [+ -]) 1 2 3)

20:40 clojurebot: -4

20:40 justin_smith: :)

20:40 hashpuppy: :)

20:40 amalloy: hashpuppy: well, not "true" so much as "truthy", which is a slang word for "acts like true in a boolean context"

20:40 because true is after all a different thing from plus

20:40 hashpuppy: amalloy: thanks for that

20:42 Wild_Cat: amalloy: just double-checking, in Clojure only false and nil are falsey, right?

20:42 amalloy: right

20:43 and then there's some stuff in clojure 1.6 that treats even false as truthy, with nil being the only falsey value. stuff like some? and when-some

20:43 justin_smith: and keep

20:44 keep is an underused gem

20:44 hashpuppy: last question, why does (map inc [0 1 2 3]) return (1 2 3 4) instead of [1 2 3 4]?

20:44 dbasch: hashpuppy: because map evaluates to a sequence, if you want a vector use mapv

20:44 justin_smith: hashpuppy: because it isn't fmap :) - map coerces the input via seq

20:45 hashpuppy: i see. thanks again

20:45 justin_smith: and mapv coerces to vector via into :)

20:46 mikefikes: hashpuppy: Another aspect of map evaluating to a sequence is that it supports lazyness

20:46 amalloy: hashpuppy: most sequence functions in clojure convert their input to a sequence, and produce a sequence as a result. sequences are kinda the lowest common denominator, the most light-weight abstraction. you can't expect to get out the same type you put in, except for functions that are specific to that type

20:49 johnwalker: (inc justin_smith)

20:49 lazybot: ⇒ 103

20:57 amalloy: justin_smith: does it really? i thought the point of mapv was that it's more performant than using into

20:58 justin_smith: $source mapv

20:58 lazybot: mapv is http://is.gd/n1z2gs

20:58 amalloy: yeah, indeed, (mapv f xs) uses reduce/transient/persistent!

20:58 justin_smith: aha, the others use into though

20:58 amalloy: it's only the multi-collection arities that use into, because there's no single collection to reduce

20:58 justin_smith: maybe I was just remembering the old version

20:58 mikefikes: Was going through _Clojure High Performance Programming_, and it shows that last for a vector is O(n). Maybe it is too expensive to check type to do something like (defn lastv [v] (get v (dec (count v))))?

20:59 amalloy: mikefikes: ##(doc peek)

20:59 lazybot: ⇒ "([coll]); For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil."

20:59 mikefikes: thanks amalloy

21:00 justin_smith: amalloy: no, even 1.5 had the same definition, my bad

21:00 amalloy: yeah, the point of mapv was to be more efficient than into/map

21:05 mikefikes: There's no such thing as an "unconj", is there? Sounds like that may be ill defined.

21:05 pop?

21:05 gfredericks: sounds like a parallel conference

21:06 mikefikes: Yep, like an unconference

21:06 jeffterrell: for recovering Clojure addicts

21:06 gfredericks: mikefikes: yeah pop works for stacky and queuey things; otherwise it's not clear what unconj would do; like for a map or set

21:07 note disj and dissoc

21:09 mikefikes: gfredericks: Yeah, perhaps it is fair to say pop works for sequential collections

21:10 dbasch: if you use pop on non-sequential collections, it explodes

21:10 gfredericks: even the sorted collections though

21:10 which side would you pop from?

21:11 ,(sorted-set 9 2 83 4 7)

21:11 mikefikes: gfredericks: Right, I was thinking the same wrt sorted

21:11 clojurebot: #{2 4 7 9 83}

21:17 gfredericks: ,(nth nil 42)

21:17 clojurebot: nil

21:17 gfredericks: ,(nth () 42)

21:17 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

21:19 mikefikes: ,(get nil 42)

21:19 clojurebot: nil

21:19 mikefikes: ,(get () 42)

21:19 clojurebot: nil

21:28 justin_smith: ,(get get get)

21:28 clojurebot: nil

21:29 justin_smith: ,(get get get get)

21:29 clojurebot: #<core$get clojure.core$get@1e70c7>

21:29 jeremyheiler: lol

21:30 justin_smith: find . -exec sed -i 's/get /(get get get get) /g' {} ;;

21:31 ,((get get get get) {:a 0} :a)

21:31 clojurebot: 0

21:32 akurilin: quick question: I need to push a change against a clojure lib on github, how do I use a modified local copy of that lib first?

21:32 lein deploy?

21:32 jeremyheiler: akurilin: change the version and do `lein install`

21:32 akurilin: oh right lein install

22:28 TimMc: ,((comp comp) ((get get get get) (get get get get) (get get get get) (get get get get)))

22:28 clojurebot: #<core$get clojure.core$get@1ddfe97>

22:30 mikefikes: ,(get some nil)

22:30 clojurebot: nil

22:30 TimMc: Question: For which f in clojure.core is there some n such that (= (apply f (repeat n f)) f)?

22:32 mikefikes: identity

22:33 bja: mikefikes, I don't think that's true. Pretty sure identity only has arity 1

22:33 TimMc: ,(identity identity)

22:33 clojurebot: #<core$identity clojure.core$identity@46d87b>

22:33 mikefikes: ,(= (apply identity (repeat 1 identity)) identity)

22:33 clojurebot: true

22:34 bja: ,(= (apply identity (repeat 3 identity)) identity)

22:34 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/identity>

22:34 el3ctro: ,(str "hello")

22:34 clojurebot: "hello"

22:34 jeffterrell: TimMc: Are there any others?

22:35 bja: I think he was saying some n (assuming n > 0), not all n.

22:35 bja: oh, fair enough

22:36 justin_smith: ,(= (apply (constantly identity) (repeat 1000 (constantly identity))))

22:36 clojurebot: true

22:36 bja: comp

22:37 justin_smith: ,(= comp (apply comp (repeat 1000 comp)))

22:37 clojurebot: false

22:37 justin_smith: my constantly identity above is broken

22:37 only one arg

22:39 TimMc: ,(comp comp comp)

22:39 clojurebot: #<core$comp$fn__4292 clojure.core$comp$fn__4292@9027f3>

22:39 TimMc: hmm

22:42 justin_smith: ,(((apply comp (repeat 1000 comp)) inc inc) 1)

22:42 clojurebot: 3

22:42 justin_smith: it's efectively equal, just not value equal

22:46 TimMc: => (filter (fn [f] (try (deref (future (= (apply f (repeat 0 f)) f)) 100 false) (catch Throwable t false))) (map deref (vals (ns-publics 'clojure.core))))

22:46 SocketException The transport's socket appears to have lost its connection to the nREPL server

22:46 :-(

22:50 bja: n = 1 yields macroexpand dissoc comp disj eval disj! min identity force macroexpand-1 merge partial max

22:50 justin_smith: n = 2 you get any keyword or symbol

22:50 or hash-map

22:50 bja: n=2 I got merge-with max-key min-key

22:52 nothing on n=3

22:53 TimMc: Nothing? It should turn up get.

22:54 mikefikes: What about n=0?

22:55 justin_smith: ,(= get (apply get (repeat 3 get)))

22:55 clojurebot: true

22:55 justin_smith: which is exactly the silliness I was playing with earlier :)

23:03 jsanda: i want to iterate over a map and for each key/value pair i want to create 2 new key/value pairs that are stored into a new map. any suggestions on how to do this?

23:04 justin_smith: jsanda: reduce

23:05 jsanda: how would that work?

23:05 bja: for some reason (probably me typing wrong), my run of n=3 didn't work before. here is is now: -> get or .> and ->>

23:05 jsanda: i want to create more not less values

23:05 justin_smith: ,(let [input {:a 0 :b 1}] (reduce (fn [m [k v]] (assoc m k v [k k] [v v])) input input))

23:05 clojurebot: {[:a :a] [0 0], [:b :b] [1 1], :b 1, :a 0}

23:05 bja: err

23:06 justin_smith: jsanda: you want to create exactly one value, a map

23:06 oh, new map, my bad

23:07 ,(reduce (fn [m [k v]] (assoc m k v [k k] [v v])) {} {:a 0 :b 1})

23:07 clojurebot: {[:a :a] [0 0], :a 0, [:b :b] [1 1], :b 1}

23:07 bja: ignore some oerr, .> isn't in the real clojure.core

23:07 TimMc: bja: Oh hah, because they're macros.

23:07 bja: hmm

23:07 TimMc: ,(let [m @#'and] (m m m m))

23:07 clojurebot: #<core$and clojure.core$and@e22c0d>

23:07 bja: well, I was checking for fn?

23:08 justin_smith: TimMc: you did explicitly mention apply, didn't you?

23:08 jsanda: justin_smith: thanks. i'll play around with that

23:08 TimMc: Yeah, does it matter?

23:09 justin_smith: ,(apply @#'and (repeat 10 @#'and))

23:09 clojurebot: (clojure.core/let [and__4069__auto__ #<core$and clojure.core$and@e22c0d>] (if and__4069__auto__ (clojure.core/and #<core$and clojure.core$and@e22c0d> #<core$and clojure.core$and@e22c0d> #<core$and clojure.core$and@e22c0d> #<core$and clojure.core$and@e22c0d> ...) and__4069__auto__))

23:09 bja: I was using (defn tc [f n] (= (apply f (repeat n f)) f))

23:09 TimMc: (off to bed, may see reply in morning)

23:09 justin_smith: TimMc: that monstrosity definitly is not equal to @#'and

23:10 bja: ((fn [f n] (= (apply f (repeat n f)) f)) @#'and)

23:10 ,((fn [f n] (= (apply f (repeat n f)) f)) @#'and)

23:10 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval129/fn--130>

23:10 bja: ,((fn [f n] (= (apply f (repeat n f)) f)) @#'and 3)

23:10 clojurebot: true

23:11 justin_smith: (= @#'and (apply @#'and (repeat 4 @#'and)))

23:11 it works with three args, but not with four

23:11 bja: ,((fn [f n] (= (apply f (repeat n f)) f)) @#'and 4)

23:11 clojurebot: false

23:11 bja: ,((fn [f n] (= (apply f (repeat n f)) f)) @#'and 5)

23:11 clojurebot: false

23:21 bbloom: whoa just got a crash in nrepl.bencode

23:46 justin_smith: bbloom: on the clojure side?

23:46 bbloom: yeah, long time in the scroll back

23:46 won't bother reporting it unless it happens again

23:48 justin_smith: with what on the client side?

Logging service provided by n01se.net