#clojure log - Jul 01 2014

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

0:29 fowlslegs: Does anyone know how to find out for what range of values the minimal binary representation of a java.math.BigInteger is less than 512 bits?

0:44 cespare: How could I return a clojure vector from a function implemented in Java? Or alternatively, what type could I return that would be most efficient to call vec on in a clojure wrapper function?

0:45 dat_eye_socket: hiredman, I came to apologize.

0:45 About 6 years back or something, I was sceptical about having an actual list datatype instead of just working with cons cells.

0:46 I realized about 3 years back I think how wrong that idea of mine was and that an actual list datatype is one of the few things CLojure has one up on on Scheme.

0:46 Well, not apologize, that's stupid

0:46 but admit I was wrong

0:46 kristof: dat_eye_socket: What do you mean an "actual list datatype" instead of cons cells?

0:47 dat_eye_socket: kristof, in common lisp and scheme, there is no list datatype, interestingly enough.

0:47 There is a datatype called pair, which is basically a vector of length 2, both slots can contain anythinhg

0:47 which is used to make ad-hoc lists.

0:47 kristof: dat_eye_socket: That's not an ad-hoc list, that's a list. :)

0:47 dat_eye_socket: And list? as a praedicate actually has to test the structure, walking from left to right.

0:47 An ad-hoc list is a list.

0:48 It would also be a list if you used [1 [2 [3 [4 []]]]] in Clojure with vectors

0:48 But it would still be ad hoc.

0:48 the point is, that in clojure, list? runs in constant time and is an actual tag and there is a guarantee that the cdr of te cell is also a list

0:48 kristof: A vector isn't the concatenation of smaller fixed sized arrays, so that isn't quite accurate.

0:48 dat_eye_socket: The above isn't a vector.

0:49 Well, it's that too.

0:49 kristof: Oh, I see what you mean.

0:49 dat_eye_socket: But it's mostly a datastructure with two cells, what I used it atl.

0:49 kristof: So clojure boxes its data structures?

0:49 dat_eye_socket: You need a minimum of two cells in a datastructure to make your list.

0:49 kristof, all datastructures in clojure are Java objects, so yes.

0:50 The thing is, in clojure to guarantee something is structurally a list, one only needs constant time.

0:50 In Scheme and Common lisp one needs linear time, which is why often it is not checked before application and you just have faith.

0:51 This is explicitly allowed by the standard.

0:51 kristof: dat_eye_socket: I see what you're saying and I don't question that you probably find this useful, but I can't think of a case where I'd be passed a tree instead of a linked list and would need to explicitly check for something like that.

0:52 dat_eye_socket: kristof, well, people make errors is what I mean.

0:52 In any case, you do need to somerimes ask list? in CL or Scheme

0:52 And that is linear, in Clojure it is constant

0:53 kristof: dat_eye_socket: I'm pretty sure that listp in common lisp is constant time. It just checks to make sure that the first element is a cons type.

0:54 dat_eye_socket: kristof, isn't that pairp?

0:54 kristof: It's actually consp, I was mistaken

0:54 dat_eye_socket: (listp (cons 1 2)) => true

0:54 kristof: Even so, when I use listp, I'm checking to see if something's NOT a list, not if it is one.

0:54 dat_eye_socket: Oh wow

0:55 That is pretty bad.

0:55 Something can be not a list, such as (cons 1 2)

0:55 kristof: cons 1 2 is a list

0:55 :)

0:55 dat_eye_socket: Ah, oh well, in Scheme it is not.

0:55 kristof: Only familiar with common lisp, sorry.

0:55 dat_eye_socket: IT's only a list in scheme if it's an empty list or a cons cell whose cdr is a cons.

0:55 whose cdr is a list*

0:56 kristof: A dotted pair is kind of a list! Sort of. :P

0:56 dat_eye_socket: (1 . (2 . (3 . 4))) doesn't count

0:56 Well, many functions which assume nil termination don't work on it I guess.

0:56 kristof: Well that's why people use pairs only when they know ahead of time that they're expecting a pair. :)

0:57 dat_eye_socket: What if you make some kind of other data structure from a pair that is not a list.

0:57 kristof: That sounds complicated, which falls under "know ahead of time"

0:57 dat_eye_socket: But I certainly like that in clojure every time you cons it verifies that the last element is a list as well.

0:57 Hmm.

0:58 Common lisp was never one for type safety as much as Clojure and Scheme are though.

0:58 I like my functions to barf as early as possible when I made an error some-where and the type is wrong.

0:59 kristof: I'm not sure what you're talking about.

0:59 pdk: cl typedefs are pretty much for optimization

1:00 kristof: What I meant was that if you cons anything to anything, you construct cells. You don't need to "guarantee" that the last element is a list.

1:01 dat_eye_socket: kristof you do need a proper list, how do you wish to otherwise disambiguate the case that the last element of a list is simply a cons cell

1:02 kristof: Oh, that's what you mean.

1:02 dat_eye_socket: lists can contain cons cells. Say you have an improper list and you want its last element to be a cons cell.

1:02 That's am ambiguity then

1:07 kristof: I suppose

1:20 cj3kim: Hi. How do I drop any value in a vector? On a side note, how come my loop function doesn't work? https://gist.github.com/cj3kim/79e8f67ee0d0f1f613ac

1:25 gfixler: cj3kim: dissoc?

1:26 or subvec? http://stackoverflow.com/questions/1394991/clojure-remove-item-from-vector-at-a-specified-location

1:26 cj3kim: i tried subvec gfixler

1:26 gfixler: no luck?

1:27 cj3kim: it simply returns the dropped values

1:28 gfixler: there aren't enough parentheses in your gist example

1:36 TEttinger: cj3kim: ##(let [v [10 11 12 13 14]] (concat (subvec v 0 5)(subvec v 5)))

1:36 lazybot: ⇒ (10 11 12 13 14)

1:36 cj3kim: thanks

1:36 TEttinger: cj3kim: ##(let [v [10 11 12 13 14]] (concat (subvec v 0 2)(subvec v 2)))

1:36 lazybot: ⇒ (10 11 12 13 14)

1:36 cj3kim: solved :)

1:36 TEttinger: wait crap

1:36 cj3kim: ##(let [v [10 11 12 13 14]] (concat (subvec v 0 2)(subvec v 3)))

1:36 lazybot: ⇒ (10 11 13 14)

1:36 TEttinger: there we go

1:36 needs to have the second subvec incremented

1:47 cespare: How could I return a clojure vector from a function implemented in Java? Or alternatively, what type could I return that would be most efficient to call vec on in a clojure wrapper function?

1:52 for instance, right now my java function returns an ArrayList but doing (into [] array-list) is slower than I'd like and also increases with the size of the ArrayList.

1:53 So I'd like to do better than that.

2:00 TEttinger: ,(class [])

2:00 clojurebot: clojure.lang.PersistentVector

2:03 TEttinger: cespare: there's a bit of an example in the src https://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/PersistentVector.java#339

2:04 cespare: TEttinger: ah, ok. Right now my java code makes an ArrayList, adds some items, and returns it -- I guess I can just use a PersistentVector from the beginning.

2:04 or a transient and return v.persistent()

2:04 TEttinger: er, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java#L736 is newer

2:15 cespare: Why does (= s "") take ~50ns? I can't seem to find a faster way to check if a string is empty.

2:19 ddellacosta: cespare: not positive but I believe (.isEmpty "") is going to be the fastest

2:20 TEttinger: (.isEmpty s) you mean?

2:20 Frozenlo`: ,(time (clojure.string/blank? ""))

2:20 clojurebot: "Elapsed time: 0.044849 msecs"\ntrue

2:20 cespare: ddellacosta: ah yeah perfect. about 6ns

2:20 I had been trying (= s "") and (= 0 (count s))

2:21 ddellacosta: cespare: yeah, in general you're probably going to want Java for that kind of stuff, if you're trying to squeeze out the last bit of performance possible

2:21 TEttinger: count would have to do a lot more steps, right? since strings aren't exactly seqs, they just convert to them

2:21 ddellacosta: TEttinger: yeah, I think everything else is handling a lot of edge cases. If you know you have a string, then best to just go low-level

2:22 cespare: TEttinger: I guess? Speed seemed almost identical to (= s "") for some variously sized strings.

2:22 TEttinger: huh

2:22 cespare: i didn't do an exhaustive test though.

2:22 TEttinger: maybe it does an element-wise compare

2:23 cespare: ddellacosta: yup, I'm writing gross java-clojure (lots of java calls and transients) and i'll probably try writing the function in java as well after I benchmark.

2:23 it's pretty small and self-contained.

2:23 clojurebot: Cool story bro.

2:23 cespare: haha

2:24 ddellacosta: count has to perform dynamic dispatch, that's going to make it slower right off the bat.

2:25 er, sorry, that's not the right way to put it

2:27 blur3d: I’m trying to convert a 4 byte array into a float in clojure. I’m guessing Java interop would be the best way. How do I convert the following java into clojure

2:27 byte[] bytes = { }

2:27 float f = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();

2:34 I think I got most of it worked out

2:34 mange: blur3d: Something like (let [bytes (byte-array [0 0 0 0])] (.. (java.nio.ByteBuffer/wrap bytes) (order java.nio.ByteOrder/LITTLE_ENDIAN) getFloat)) ?

2:34 blur3d: (import [java.nio ByteBuffer])

2:35 (.getFloat (. ByteBuffer wrap (byte-array [0 0 0 89])))

2:35 mange: thanks, I’ll give it a go… I’m not too familiar with java or interop

4:49 sveri: Hi, I am trying to setup a websocket connection with http-kit and it fails because it gets server error 500 as a response: http://pastebin.com/qZX3ceBT Any Ideas what might be wrong here?

5:02 never mind, seems like I missed some ring middlewares, just dont know which one yet

5:18 asmala: I’m looking for resources on Clojure web app deployment. After a couple of hours of googling, I found the “DevOps Done Right” video by Vince from Room Key, but not much else. Any tips?

5:20 The app in question would be a fairly simple all-Clojure stack, running a single-page ClojureScript app on the front-end and using Datomic for storage

5:57 augustl: asmala: the story is pretty similar to all JVM web apps

5:57 asmala: you can choose between embedding jetty or creating a war for a container :)

6:00 asmala: augustl: thanks, good point. I could just start looking resources for Java deployments. Ideally though I’d like to see something along the lines of “Use Pallet for config management, with a local VirtualBox testing environment and a CloudFormation-driven production/staging environment. And here’s how:”

6:07 ddellacosta: asmala: unfortunately I don't think there's many great resources for this yet out there. I've had trouble myself getting pallet going from scratch. In my day job we simply have some scripts that get things up and running.

6:08 asmala: of course, Heroku makes it pretty nice to deploy clojure web apps if that's a solution you can consider.

6:11 asmala: ddellacosta: yes, that could work. I’m familiar with it from my previous life doing (primarily) Rails apps. I feel drawn to AWS, though, given the more flexible scalability scenarios and DynamoDB for Datomic.

6:12 ddellacosta: asmala: I mean, it's been about six months since I tried using Pallet seriously. And my issues at that point mostly had to do with the fact that I'm trying to deploy from Asia...I think. Not that that's a ringing endorsement or anything, but probably still work trying to get Pallet going if you want to use AWS.

6:12 asmala: ddellacosta: haha, gotcha. Thanks for the heads up though.

6:13 ddellacosta: asmala: np. Have you tried the pallet tutorial, btw? Seems like it could be pretty nice (it's nicer than last time I tried it): http://palletops.com/pallet/doc/first-steps/

6:14 asmala: yeah, I checked it out earlier today. looks like a good starting point

6:15 ddellacosta: asmala: well, I wish you luck--and I would add, if you *do* get through deploying with AWS via Pallet, documenting what you've done for the community would be super appreciated, I'm sure!

6:15 asmala: ddellacosta: aye, definitely planning on a post or three if/when I figure out a good way to do it

7:12 * clgv imagines that a Clojure DSL for TeX/LaTeX would be awesome

8:15 ssideris: clgv: shouldn't be too hard

8:16 clgv: ssideris: well in my vision it should be directed toward replacing LaTeX and compiling to plain TeX

8:16 ssideris: erm, that *does* sound a bit harder

8:16 clgv: ssideris: so that it has a backwards compatible layer for the transition phase

8:17 ssideris: but why would you do it like that, what's wrong with latex?

8:17 clgv: ssideris: you didnt use it that much right?

8:18 ssideris: it has no proper modularity concept. latex packages can be incompatible with each other and in fact are incompatible often

8:18 ssideris: clgv: I wrote my whole PhD in latex, so yes, I've used it a bit :-)

8:18 clgv: visualizations, pseudocode or other stuff may work in articles but suddenly dont in beamer

8:22 ssideris: well than you should have experienced the pain ;)

8:23 ssideris: and for visualizations or animations you actually program in LaTeX but that's painful as well

8:23 +can

8:28 ssideris: hm, maybe I was a bit conservative with my packages etc, but I don't remember a painful experience

8:31 clgv: ssideris: than you were lucky ;)

8:31 *then

8:33 ssideris: it looks like I was

8:33 so are you starting with the DSL?

8:33 clgv: I am using TikZ a lot for visualizations. anything that goes beyond a for loop is just painfull

8:34 probabaly not since I got no time. that PhD document isnt writing itself meanwhile ;)

8:40 ssideris: PhDs are the main target demographic for latex :-)

9:00 n|k: Hi there! The VimClojure plugin should automatically add closing brackets by default, shouldn't it?

9:02 ambrosebs: n|k: no, there's a separate paredit plugin I think

9:02 n|k: ambrosebs: I see, thanks!

9:04 ambrosebs: yeah, the paredit plugin did the trick

9:11 dave-7: Hi, I'm new to clojure and running through the basic om tutorial at the moment. I'm at the part where you add an event listener to the input field, and I'm not sure what the 'e' argument is to handle-new-contact-change (the event listener). Is it some kind of a ref to the input field's dom node?

9:12 mnngfltg: Hello. I'm trying "lein repl" but my core.clj is located in `subdir/src/myproject/core.clj` rather than `src/myproject/core.clj`. But leiningen doesn't find my source file.

9:13 I've tried :source-paths ["turbod/src"] in project.clj, but it didn't make a difference

9:16 nikolap: dave-7: I believe that's an event object every handler receives as an argument (i.e. https://facebook.github.io/react/docs/events.html)

9:16 mnngfltg: Does anyone have an idea? It gives me: Could not locate myproject/core__init.class or myproject/core.clj

9:19 Oh! Now I made it work with ["myproject/src"]. Strange.

9:21 dave-7: That makes sense, thanks nikolap!

9:22 jonathanj: hrm, where can i put resources for tests (like files) and how do i reference that path from my tests?

9:26 nikolap: dave-7: sure thing! it may be worth noting that you can always do a (.log js/console some-var) to dump the thing to the browser console. if it's a Clojure data structure, dumping (pr-str some-var) might be more useful. :)

9:27 dave-7: mnngfltg: I think lein only checks the folders you supply to :source-paths and one layer deeper. (ie. if :source-paths is "some/dir/", putting core.clj in "some/dir/" or "some/dir/here" will work, but putting it in "some/dir/here/again" won't.)

9:28 mnngfltg: dave-7: got it

9:29 It's a bit surprising that `lein` doesn't have real documentation, just a sample project.clj file.

9:30 bhauman: mnngfltg: there is documentation

9:31 mnngfltg: look in the doc directory on github

9:32 hyPiRion: dave-7: lein checks the source paths and all the subdirectories recursively

9:32 bhauman: mnngfltg: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md

9:32 mnngfltg: bhauman, thanks, I'll have a look

9:41 blur3d: How would you extend a multi-method that is private and part of a dependancy using defmethod? Is it possible, or would it have to be public?

9:42 silasdavis: looks like reverse on a vector does not call rseq

9:42 is there any reason why that is?

9:42 blur3d: here is some example code http://pastebin.com/2hFtfDT1

9:42 silasdavis: (reduce1 conj () coll)

9:42 is implementation

9:45 fowlslegs: ,'((biginteger 8))

9:45 clojurebot: ((biginteger 8))

9:45 alandipert: blur3d, i'd be very surprised if it wasn't possible

9:45 fowlslegs: How could I rewrite this such that it returns '(8)?

9:46 Nevermind

9:46 dave-7: hyPiRion: thanks

9:46 blur3d: yeah, I’m just not sure how multimethods work across namespaces, nor how private effects them

9:53 alandipert: blur3d, https://gist.github.com/alandipert/a383318cff6f21d309a3 - the trick is the @#' to locate and deref the private Var

9:54 blur3d: alandipert: nice :) thanks

9:56 I always find it insane how function programming can solve everything

9:56 make you wonder where we went so wrong, and why OO is what it is

10:47 Frozenlock: Is there a way to prevent cljs stuff to be included in a uberjar? Getting an extra 13mo from google is really annoying.

10:49 perplexa: hai. when i have a function x and i want to override that function in a different function, how would i do that? cos just saying (let [x (newx "arg")]) would make x not callable.

10:49 and i end up getting null pointer exceptions ofc ;x

10:50 Frozenlock: perplexa: I'm not sure of what you are trying to do, but [x #(newx "arg")] should be callable.

10:51 perplexa: Frozenlock: yeah, thanks

10:52 fowlslegs: Can someone tell me what the funk is going on here?

10:52 ,((fn [funk] (funk (biginteger 1) (biginteger 2))) '.xor)

10:52 clojurebot: 2

10:52 fowlslegs: ,(.xor (biginteger 1) (biginteger 2))

10:52 clojurebot: 3

10:53 cbp: the first one is equivalent to ##(:a {} :default)

10:53 lazybot: ⇒ :default

10:53 cbp: but with a symbol instead of keyword

10:54 ,('.xor {} :default)

10:54 clojurebot: :default

10:54 cbp: you cant pass methods around as functions

10:54 you need to wrap them in a function

10:55 fowlslegs: ,((fn [funk] (funk (biginteger 1) (biginteger 2))) #(.xor % %2))

10:55 clojurebot: 3

10:56 fowlslegs: Now that's fuuuunnnnnnkkkkkyyy!

10:56 You're welcome for being the cheeziest human being on Earth. And thank you cbp.

10:57 silasdavis: I didn't know symbols were ifn...

11:01 Glenjawork: ,(doc memfn)

11:01 clojurebot: "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn. name may be type-hinted with the method receiver's type in order to avoid reflective calls."

11:33 pjstadig: are there API docs for ClojureScript anywhere?

11:46 Frozenlock: pjstadig: sure, it's #clojure :-p

11:52 quangquach: ia /msg NickServ identify 05051989

11:54 verma: I wonder if there's a better way of doing this: https://gist.github.com/verma/304538e144216453809a

11:54 basically I am iterating over a list of strings (and then over each character) and mapping it into a tile-set and blitting it out

11:54 looks ugly as hell

11:55 I need to keep track of rows and columns because I need them to figure where the destination for blit is, wonder if there's a cleaner way for doing this

11:58 pjstadig: Frozenlock: if only it was

12:02 cbp: verma: change (iterate inc 0) for (range), combine both doseqs and change (get symbols c) for (symbols c)

12:11 arrdem: puredanger: I agree that the "namespace" and "name" of a Var is chasing a pointer the wrong way, however there are cases in which it's valuable to do so especially when Bronsa and I are playing with resolving and manipulating bindings.

12:12 puredanger: I mean thanks to Bronsa I've got snippets for doing this that work (obviously) but since the printing format of a Var shows name and namespace I would have expected that those values would be trivially exposed via name and namespace.

12:12 * arrdem goes back to real work

12:20 puredanger: arrdem: I understand what you're saying and think it's a reasonable question

12:21 mnngfltg: When running a webserver with compojure in the REPL, I cannot seem to re-run (defoutes); the changes don't take effect unless I restart the REPL. Is there a workaround for this?

12:21 koreth_: Is there a good way to make Leiningen execute code before the REPL starts accepting user input but after the NREPL service is started? :init seems to be run before NREPL and anything long-running in there causes Leiningen to time out and exit.

12:22 cbp: mnngfltg: make sure the ring handler gets the var, as in (serve #'my-routes ..)

12:23 Frozenlock: mnngfltg: Like cbp said (jetty/run-jetty #'app ...

12:27 johnwalker: has clojure seen performance improvements with java 8?

12:29 mnngfltg: cbp, Frozenlock, hmm, I don't get it

12:29 https://www.refheap.com/87732 -- it doesn't work that way

12:29 puredanger: johnwalker: yes. I usually see about 5-10% improvement on Java 8.

12:30 mnngfltg: Ahh.. I need to reload (def app ...) as well as (defroutes ...)

12:30 I guess I'm not clear on how the vars/macros/functions interact :)

12:32 johnwalker: puredanger: thanks. what parts of clojure do you think got faster?

12:33 puredanger: johnwalker: I don't think any specific thing got faster, just that java 8 is generally faster on things most programs do (constructing and allocating objects, optimizing locks and locals, etc)

12:33 mnngfltg: Or I can simple re-evaluate the current buffer, which also works.

12:33 Thanks! :)

12:34 puredanger: johnwalker: you might find these graphs interesting http://jafingerhut.github.io/clojure-benchmarks-results/Clojure-expression-benchmark-graphs.html

12:34 johnwalker: take them with the usual grain of micro benchmarking salt

12:34 johnwalker: right

12:35 thanks again :)

12:35 (inc puredanger)

12:35 lazybot: ⇒ 2

12:35 johnwalker: wow that should be a lot higher. does it reset nightly?

12:35 puredanger: ha, no I don't hang out here much

12:35 I usually just read the logs :)

12:35 johnwalker: lol

12:39 Frozenlock: puredanger: Wow... so much data pron

12:42 puredanger: yeah. I consider the 32-bit stuff to be noise - we really don't care for Clojure. Most of the intermediate releases are uninteresting but admittedly, they do tell a story that is sometimes important.

12:46 and as always props to Andy Fingerhut for maintaining those tests

12:46 mdrogali`: He's a champ.

12:47 hyPiRion: puredanger: I think both you and Andy do an amazing job.

12:47 puredanger: well thank you but the difference is that I'm paid for it and he's not so props to him

12:51 hyPiRion: heh, I just wanted to say thank you for the work you're doing. I feel many people don't know how important the work you two do is.

12:52 bbloom: hyPiRion: dammit, you can thank puredanger by letting him be modest

12:52 :-)

12:53 verma: cbp, nice, thanks, how do I combine doseqs?

12:53 hyPiRion: Okay okay, sorry :p

12:53 * hyPiRion walks slowly out

12:53 mdrogalis: hyPiRion: When do I get a copy of your thesis? ;)

12:54 Come back I want to read your freakin' paper! :P

12:54 arrdem: mdrogalis: I thought it was done already..

12:54 cbp: verma: ##(doseq [x [[1 2] [3 4]] y x] (print x))

12:54 lazybot: ⇒ [1 2][1 2][3 4][3 4]nil

12:54 cbp: er print y

12:54 you get the point :-P

12:54 mdrogalis: arrdem: *Shrug*

12:54 verma: cbp, trying :P

12:55 cbp, hmmm, that form is new to me :P

12:56 cbp, checking docs

12:57 cbp, oh that's badass

12:58 ##(doseq [x [[1 2] [3 4]] y x] (print y))

12:58 lazybot: ⇒ 1234nil

12:58 verma: cbp, naice .. trying

12:59 dave-7: I'm having some trouble getting secretary going. I've included the dependency in project.clj and restarted the server, so it's got the files, but when I run it through lighttable it tells me "Could not locate secretary/core__init.class or secretary/core.clj on classpath:"

12:59 symfrog: Has anyone attempted to use closure IframeIo for file uploads? I am using it and everything is working fine except timeouts and connection refused scenarios are not triggering registered events (goog.net.EventType.TIMEOUT) even after setting a timeout interval with setTimeoutInterval.

13:00 hyPiRion: mdrogalis: It is done, I just want to finish moving, and make some parts of the thesis independent of other papers behind paywalls

13:01 I don't like paywalls.

13:01 mdrogalis: hyPiRion: Got it :)

13:01 Where're you moving?

13:02 hyPiRion: mdrogalis: moving from Trondheim to Oslo (cities in Norway)

13:03 mdrogalis: hyPiRion: Cool :D

13:04 alexhbg2: hi

13:05 {blake}: I have a structure of {:parent ({:child ...stuff1...}{:child ...stuff2...}{:child ...stuff3...})} and I want to turn that to {:parent :child (...stuff1... ...:stuff2... ...:stuff3...)}.

13:05 (Is that "slurping"?)

13:06 alexhbg2: Could someone explain this code to me: (defmacro defscreen [n & {:keys [] :as options}]

13:06 dont understand whats going on insde the [ ] brackets

13:07 aperiodic: {blake}: no, slurping is reading bytes in from a resource such as a file or InputStream

13:07 {blake}: aperiodic, thanks!

13:07 aperiodic: sorry, not bytes, a string

13:07 {blake}: also the thing you want to turn your map into is not a valid map, so that might be difficult

13:09 {blake}: aperiodic, Well, I have a map of sequences where child sequences have common keys, and I want to draw that key up, but keep the sequences beneath it. This is so I can use "get-in".

13:09 hyPiRion: {blake}: is ##(let [m {:parent '({:child :foo} {:child :bar} {:child :baz})}] (update-in m [:parent] (partial map :child))) sufficient?

13:09 lazybot: ⇒ {:parent (:foo :bar :baz)}

13:10 {blake}: hyPiRion, heh...I don't know. Let me grok it. (What's the ## for?)

13:10 silasdavis: I'm using ordered-map from https://github.com/amalloy/ordered, wondering if it will work with clojurescript

13:10 hyPiRion: {blake}: ## is to make lazybot evaluate it

13:10 silasdavis: does anyone have an idea?

13:10 aperiodic: alexhbg2: it's a destructuring statement, that assumes all arguments besides the first are key-value pairs that make up a map named `options`. the empty keys binding is pointless and should be omitted

13:10 hyPiRion: so ##(+ 1 2) makes lazybot print 3

13:10 lazybot: ⇒ 3

13:10 silasdavis: I've not really used clojurescript before

13:11 {blake}: hyPiRion, Duh. Thanks. =P

13:11 hyPiRion: np

13:11 aperiodic: alexhbg2: also, in my experience the "rest args as implicit map" pattern is more trouble than it's worth and you should just pass around options maps explicitly

13:13 alexhbg2: aperiodic: cheers. this is from the play-clj source code. but being new to clojure im just trying to understand it

13:13 {blake}: hyPiRion, My starting point is a vector of maps, where any given value of a key may itself be a vector of maps.

13:13 aperiodic: alexhbg2: you can read more about destructuring here: http://clojure.org/special_forms#binding-forms

13:14 {blake}: hyPiRion, So I can't enumerate the children explicitly, and I'm applying this recursively.

13:14 alexhbg2: thanks!

13:14 {blake}: "In any case where there are multiple maps containing the same key, draw that key up and turn the values for that key into a single sequence."

13:16 So I can say "get-in :grandparent :parent :child" and get back a sequence of all values for that branch.

13:16 I'm positive this is easy; I'm either looking at it wrong or just ignorant of the right...thing.

13:17 aperiodic: you can use a very slightly modified version of what hyPiRion used above

13:17 {blake}: Update-in, maybe where I take the existing value and add to it?

13:17 aperiodic: although it may be more appropriate to use group-by here

13:17 {blake}: aperiodic, Oh, yeah, group-by...that might do it.

13:25 OK, I think I need to take a step back. I have some XML I'm simplifying with this: https://www.refheap.com/87735

13:26 Wait...okay, I could group-by the results of this by pulling off the keys of the resultant sequences. I think that'll work.

14:15 jjcomer: If you make a blocking call in a go-block do the underlying mechanics of async kick in or does it actually tie up the thread?

14:15 tim: jjcomer: there are no "underlying mechanics of async"

14:15 tbaldridge: jjcomer: you will block the thread.

14:16 The only "async" ops are alt!, >! <! and put!

14:16 jjcomer: perfect, that answers my question

14:35 _99hats_: 09:21 <koreth_> Is there a good way to make Leiningen execute code before the REPL starts accepting user input but after the NREPL service is started? :init seems to be run before NREPL and anything long-running in there causes Leiningen to time out and exit.

14:35 koreth_: _99hats_: I am writing a Leiningen plugin to do this, having found no better approach. Luckily it's a really simple plugin.

14:36 _99hats_: Hi folks! Abt how long does it take to go through Clojure Koans? (n00b)

14:45 puredanger: the koans live on within you forever

14:46 _99hats_: puredanger: good answer ;)

14:46 puredanger: seriously though, an experienced Clojurist could probably do them in 20 minutes or so? (anyone?)

14:46 and depending on your noobiness and how much time you spend seeking your answer, maybe an hour or two

14:47 certainly I see many people asking here, google group, and stack overflow about the questions

14:48 _99hats_: that's helpful, I was afraid it was 10-20 hours of material

14:48 puredanger: I have no idea if any of those times is actually reasonable. surely someone here has done them recently?

14:48 no, I don't think so

14:48 amalloy: just looking over them for the first time ever i'd say puredanger has underestimated the time for newcomers and for experienced users

14:49 koreth_: Definitely not 10-20 hours unless you get stuck on a concept at some point. I did them after learning the basics of the language elsewhere and it took me a couple hours.

14:49 puredanger: amalloy: it's been a while and I would not be surprised at that :)

14:49 Raynes: is cider-show-error-buffer an illusion or something?

14:49 It appears to do exactly nothing when I change its value.

14:50 cbp: Raynes: when it's t and you get an exception a buffer appears

14:50 puredanger: koreth_: thanks, that's a helpful benchmark

14:50 Raynes: cbp: When it's nil and I get an exception a buffer appears.

14:50 So

14:50 :(

14:50 puredanger: Does http://clojurescriptkoans.com/ have everything from Clojure Koans?

14:51 Raynes: I posit that it doesn't give a shit what I think.

14:51 _99hats_: Yes, thanks puredanger koreth amalloy

14:52 Raynes: Oh there we go.

14:52 cbp: I had an older version of cider hanging around in a sekrit directory deep within the bowels of hell.

14:53 Now it isn't even producing a repl after cider-jack-in.

14:53 So that's cool.

14:53 amalloy: I'm suddenly missing SLIME, man. It's crazy.

14:54 technomancy: the cider from marmalade is pretty stable

14:54 Raynes: I think that's what I have.

14:54 so (setq cider-show-error-buffer nil) = works

14:54 (setq cider-show-error-buffer 'except-in-repl) does not.

14:55 technomancy: Raynes: I have that version but that var doesn't exist here

14:55 so I'd guess you're on something newer

14:58 Raynes: technomancy: Well, using your version sure wouldn't help then.

14:58 Since it doesn't even have the var I need to tweak.

14:59 technomancy: How do I figure out which repo I got cider from, out of curiosity?

14:59 Once installed package-list-packages no longer shows me where it came from.

14:59 I'm sure that's a feature.

15:00 technomancy: Raynes: the best way to know for sure is to never put melpa on your list of sources

15:00 Raynes: technomancy: What's wrong with melpa?

15:00 technomancy: for real?

15:01 Raynes: technomancy: I literally know nothing about it other than it gives me packages that I need.

15:01 technomancy: Raynes: it's basically just all snapshots, all the time

15:01 Raynes: Well, that's cool, since I needed a snapshot in this case.

15:02 technomancy: except now everything you install will use the bleeding edge version

15:02 iirc there's no way to say you want melpa but just for a single package

15:02 Raynes: technomancy: Except not really because I also have marmalade and for new packages it shows me where I'm getting it from.

15:02 wat

15:02 DerGuteMoritz: technomancy: there is actually

15:03 technomancy: DerGuteMoritz: oh, is that new?

15:03 Raynes: technomancy: Yeah, I can get packages from either source.

15:03 technomancy: without that ability it's completely nuts to use melpa

15:03 Raynes: technomancy: https://dl.dropboxusercontent.com/s/y738qlow36vjwgz/2014-07-01%20at%2012.02%20PM.png

15:03 technomancy: http://blog.jorgenschaefer.de/2014/06/the-sorry-state-of-emacs-lisp-package.html

15:03 Raynes: oh fancy; they must have added that ~recently

15:04 that's a relief

15:04 DerGuteMoritz: technomancy: you need the "melpa" package which provides package-archive-exclude-alist and package-archive-enable-alist

15:04 Raynes: I'm using a nightly Emacs build technomancy

15:04 Because I live on the edge

15:04 Frozenlock: bold

15:04 technomancy: http://p.hagelb.org/candle.gif

15:07 johnwalker: i'm also on nightly cider, but i'm not experiencing the problems you described Raynes

15:08 you can always try el-get

15:08 :)

15:09 Raynes: Yeah, no.

15:09 johnwalker: I have 20140624.1355

15:10 johnwalker: Can you confirm you have the same snapshot, because this definitely is broken.

15:10 jcromartie: Any opinions on whether core.async is "production ready"?

15:10 or just used in production at all?

15:10 Raynes: (setq cider-show-error-buffer 'except-in-repl) is what I'm talking about, to be clear.

15:10 It does not function as intended. Setting it to nil works fin.

15:10 fine*

15:10 tbaldridge: jcromartie: many people are currently using it in production

15:11 jcromartie: tbaldridge: well it's your baby so of course you'd say that :)

15:11 tbaldridge: jcromartie: probably the fastest adoption of any Clojure contrib project I'm aware of

15:11 jcromartie: that's awesome

15:11 amalloy: jcromartie: when something breaks in production it's more likely to be your fault than that of core.async

15:11 johnwalker: ahh, you said the repl did not appear on jack-in

15:11 jcromartie: yeah

15:12 Raynes: johnwalker: That went away second try.

15:12 amalloy: much more likely, i might even say

15:12 tbaldridge: jcromartie: when core.async doesn't work it doesn't work all the time. I'd have problems suggesting putting a library into production that suffers from lots of heisenbugs

15:12 Fare: hi

15:12 jcromartie: that's good

15:12 tbaldridge: jcromartie: and if you wait for stuff to be "production ready" you really shouldn't be using reify/defprotocol either ;-)

15:12 jcromartie: :)

15:12 tbaldridge: those were alpha until 1.6

15:12 Fare: can someone help me understand source code directory structure for java and/or clojure ?

15:13 johnwalker: el-get does not give me 20140624/etc but i can confirm that i am on the latest from github

15:13 Fare: do I really need to create one directory per package name component?

15:13 Raynes: Oh, if you're using el-get then we can't really compare.

15:13 Fare: most code seems to, but some code seems to do just fine without

15:13 Raynes: D'oh well

15:13 johnwalker: no, we can compare

15:13 Raynes: This is good enough

15:13 jcromartie: I'm trying to grok the use cases, because my code is OBVIOUSLY heavy in async stuff, but I am not sure where channels and go blocks would apply..

15:13 It seems to be a big paradigm shift.

15:13 amalloy: Fare: yes

15:13 johnwalker: i will check if that setting is broken

15:14 Fare: amalloy: yes I need to? Why?

15:14 amalloy: because that's the way the compiler knows where to find a file when you type (require 'foo.bar.baz)

15:14 Fare: and how does the code that doesn't do it?

15:14 amalloy: it looks for foo/bar/baz.clj

15:14 johnwalker: ok, that setting works for me

15:15 Fare: so I need those directories for clojure code? Do I need them for java code?

15:15 TimMc: Fare: Example of code that doesn't do that?

15:15 Fare: and what if my git repo has several projects? do I need to repeat this hierarchy for each project?

15:15 johnwalker: when 'except-in-repl evaluation outside the repl creates a popup buffer with the stacktrace

15:15 sritchie: Fare: yup :)

15:16 johnwalker: when it's nil, an error line shows up in the repl

15:17 amalloy: Fare: yes, you need directories for everything. the jvm loves directories

15:17 as for code that doesn't do that, who knows? if you have a specific example that confuses you, feel free to link to it

15:18 johnwalker: the last commit for my cider build is

15:18 Tue Jun 24 23:55:08

15:18 so it's confirmed that we're on the same build

15:21 Raynes: so i have no idea what the problem migh tbe

15:22 Raynes: johnwalker: with 'except-in-repl, if I'm inside the repl I get a line in there + a buffer popup.

15:22 Fare: maybe the code that didn't "just" had very short package names, and/or got by by explicitly invoking the compiler with proper invocation.

15:23 Can I share the same directory structure between multiple "projects" or is there a reason not to?

15:23 where "projects" are separate for dependency purposes.

15:24 sorbus_: I'm reading through Joy of Clojure. can someone tell me what #( does as I can't find an explanation in the book, and net searching isn't helping

15:24 amalloy: it's not clear what you're suggesting, Fare

15:24 ,'#(+ % :test)

15:24 clojurebot: (fn* [p1__25#] (+ p1__25# :test))

15:24 amalloy: oops. well, that function doesn't succeed for any input, but it shows what #(...) expands to

15:25 mocker: sorbus_: http://aphyr.com/posts/303-clojure-from-the-ground-up-functions

15:26 johnwalker: Raynes: i get only the line, but no popup

15:26 Fare: com/example/ contains projecta/ projectb/ projectc/ that are distinct for the sake of dependencies.

15:26 Raynes: johnwalker: Then I guess my computer is broken.

15:26 I can consistently reproduce this issue over restarts, etc.

15:26 mocker: sorbus_: #(+ % 1) is equivalent to (fn [x] (+ x 1))

15:26 sorbus_: ah right, many thanks

15:27 amalloy: Fare: but where would you put project.clj? if you put it above com/ then there's only one project, and if you put it under project[abc]/, then the com/example/ structure doesn't exist in any interesting way

15:27 Fare: mocker: is p1__25# always equal to p1__25# ? When or when not? What is the scope of gensyms?

15:28 johnwalker: lol

15:28 Fare: amalloy: could I put it in projecta/ and have it specify :source-paths ["../../"] :test-paths ["../../"] or something like that?

15:29 amalloy: that sounds weird as shit

15:29 johnwalker: one thing you might try is re byte-compiling your cider

15:29 amalloy: i would advise against trying to play tricks - just use the same directory structure across your N projects

15:29 Fare: would it be a problem because some jar file generator would end up putting all the files in all the jars?

15:30 TimMc: Fare: What benefit are you trying to achieve?

15:34 Fare: TimMc: sanity in not having to reproduce three-level deeps directories all the time for a single file?

15:37 amalloy: if creating two directories every time you start a project is the biggest challenge to your sanity that programming offers you, i'd say you're probably not going to be put into an asylum anytime soon

15:38 cespare: I have a helper function in java. What package name should I give it? The associated clojure code is in mylib.core

15:38 Just wondering about conventions.

15:39 johnwalker: you can always automate that shit with bash

15:40 TimMc: Fare: lein new and mkdir -p have worked fine for me.

15:40 johnwalker: but i don't think it will be better than mkdir -p

15:40 ^^

15:40 TimMc: Fare: The only thing I've had trouble with is changing package names.

15:41 Fare: amalloy: the problem is not creating the directories but constantly switching between them, duplicating or merging them back when grouping or not grouping files together.

15:41 amalloy: huh, this is a funny quirk i didn't know about:

15:41 ,(let [x 1] do x)

15:41 clojurebot: 1

15:41 johnwalker: ,do

15:41 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:42 johnwalker: ,(let [x 1] for x)

15:42 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/for, compiling:(NO_SOURCE_PATH:0:0)>

15:42 mattmoss: ,(let [x 1] x)

15:42 clojurebot: 1

15:43 johnwalker: why does that work?

15:43 is it because do is a special form?

15:43 mattmoss: The [x 1] in the let binds 1 to x for the duration of the x.

15:44 tbaldridge: johnwalker: probably a bug, do is not a macro, it's a special form

15:44 ,(let [x 1] fn* 1)

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

15:44 johnwalker: ,(let [x 1] try 1)

15:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: try in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:44 tbaldridge: ,(let [x 1] do 1)

15:44 clojurebot: 1

15:44 tbaldridge: ,do

15:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:44 johnwalker: ._.

15:44 mattmoss: ,(let [x 1 y 2] (+ x y))

15:44 clojurebot: 3

15:44 johnwalker: wat

15:44 tbaldridge: waaaaaaat

15:45 johnwalker: https://www.destroyallsoftware.com/talks/wat

15:46 bbloom: i seem to remember do being MORE broken in the past, but got fixed to some extent at some point

15:46 mattmoss: ,(let [x 1] (do x))

15:46 clojurebot: 1

15:46 * Fare notes that clojure.lang.LineNumberingPushbackReader does not handle tab width :-/

15:47 Fare: is that on purpose, or would a contrib be accepted that did?

15:47 s/contrib/patch/

15:47 dbasch: ,(let [do 1] do)

15:47 clojurebot: nil

15:47 johnwalker: hahahahahahhaha

15:47 tbaldridge: Fare: what do you mean? does not handle tab width

15:48 johnwalker: (inc dbasch)

15:48 lazybot: ⇒ 7

15:48 bbloom: tbaldridge: i assume he means tab = 1 char

15:48 TimMc: Fare: Are you asking for tabs to be reconciled with spaces? Won't happen.

15:48 dbasch: (inc wat)

15:48 lazybot: ⇒ 1

15:48 johnwalker: (inc wat)

15:48 lazybot: ⇒ 2

15:48 mattmoss: ,(+(+)(+))

15:48 clojurebot: 0

15:48 bbloom: tbaldridge: rather than N columns

15:48 Bronsa: uhm I believe I might have sent a patch for the do issue

15:48 tbaldridge: bbloom: Fare: yeah, that sounds like a bad idea

15:49 Bronsa: yeah http://dev.clojure.org/jira/browse/CLJ-1216

15:49 verma: cbp, your suggestions worked great

15:49 bbloom: tbaldridge: tabs are kinda a bad idea in general

15:49 TimMc: Fare: No matter what behavior you're seeing or desiring, I'm sure the answer would be "don't use tabs".

15:49 verma: cbp, thanks

15:49 johnwalker: lol that's just crazy Bronsa

15:49 dbasch: ,(let [do 1] (println do) do)

15:49 clojurebot: 1\n1

15:50 mattmoss: ,(let [your-mother "nice"] (do your-mothing))

15:50 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: your-mothing in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:50 dbasch: ,(= (let [do 1] (println do) do) (let [do 1] do))

15:50 clojurebot: 1\nfalse

15:50 mattmoss: I can't even type.

15:50 dbasch: ^ that's a wat

15:50 mattmoss: ,(let [your-mother "nice"] (do your-mother))

15:50 clojurebot: "nice"

15:50 Bronsa: dbasch: the compiler reads (let [do 1] do) as (let [do 1] (do))

15:50 Fare: TimMc: not if I'm reading Python code where tab is explicitly declared to be of width 8.

15:51 dbasch: Bronsa: but why?

15:51 johnwalker: oh god

15:51 tbaldridge: Fare: but...why does that matter this is Clojure, not Python

15:51 johnwalker: this is an eich language isn't it

15:51 *hides*

15:51 bbloom: Fare: the push back reader is not a public API

15:51 Fare: it exists for reading clojure code

15:52 tbaldridge: oh he's using the PushbackReader? yeah don't do that.

15:52 go find/write your own

15:52 Fare: tbaldridge, in what language to write a python parser, better than clojure?

15:52 ok, wrote my own.

15:52 bbloom: Fare: are you doing that for fun? or do you need it for something? may be much easier to shell out to python 3's ast library & slurp in the result as json or similar

15:53 tbaldridge: Fare: and if I were going to parse something like that I'ld be highly tempted to either use Jython to parse, or a parser generator (like Instaparse)

15:54 Fare: tbaldrige: instaparse won't easily handle either the indentation or the layering on top of a lexer that does.

15:55 Those I suppose the lexer could use magic escape characters for the purpose of encoding indentation.

15:55 bbloom: Fare: instaparse can parse things other than strings. you can use it to create a "lexer"

15:55 Bronsa: dbasch: tldr the current implementation in the compiler can't distinguish "synthetic" do's from actual do's

15:55 dbasch: interesting

15:55 TimMc: Fare: In this case I would suggest pre-processing tabs into 8 spaces.

15:56 Fare: TimMc: except you should only pre-process those that appear outside strings.

15:56 * tbaldridge grumbles about the state of the compiler in general. Fast, but flawed in design

15:56 TimMc: Fare: How about just those in leading whitespace?

15:56 Fare: how do you know it's not part of a multi-line string?

15:56 bbloom: Fare: do you care?

15:57 Fare: bbloom: some

15:57 bbloom: multiline strings w/ leading whitespace probably ALSO want tabs to be spaces

15:57 doesn't python chop leading whitespace inside strings?

15:57 Fare: bbloom: I don't know. Does it?

15:57 TimMc: Find out.

15:57 Fare: I will.

15:57 bbloom: Fare: not in my repl, but i thought it did in code files

15:58 TimMc: Fare: I'd be curious, actually.

15:59 bbloom: seems it doesn't

15:59 *shrug*

15:59 people using multi-line strings who care about tabs vs spaces are just asking for trouble

15:59 use a data file dammit people

15:59 tbaldridge: "use data for everything", there, fixed it for ya

16:01 TimMc: ew

16:03 scottj: tbaldridge: do you happen to know if this approach to speeding up clojure startup time got much discussion offline by cognitect people? it got almost no replies online from what I could see https://github.com/galdolber/clojurefast

16:03 tbaldridge: scottj: https://github.com/clojure/clojure/tree/fastload

16:04 scottj: tbaldridge: thanks

16:04 tbaldridge: scottj: also, https://github.com/clojure/clojure/tree/direct

16:04 scottj: there's some talking happening now about how much it matters (good or bad) and how this all relates to maven.

16:06 hiredman: it really only matters for aot'ed code, which is often broken anyway, because aot

16:10 tbaldridge: hiredman: true, but it's a design goal Rich has aimed for from the beginning with this feature

16:10 scottj: it seems pretty important for android apps, but I haven't seen the numbers for rich's implementation

16:10 hiredman: tbaldridge: it seems like it would be better to file the rough edges off of aot before adding more features

16:11 scottj: adroid apps require aot compilation, clojure's current aot implementation is something of a slow motion train wreck

16:11 dgleeson: hello all, I'm writing an api. I'd like to use different middleware depending on the resource. Example /resource1 might get wrap-middleware1 and /resource2 might get /wrap-middleware2. I can't seem to find any clear information on the internet on how to do this. Does anyone have any suggestions? maybe point me in a direction?

16:12 hiredman: all kinds of gotchas and things that work differently from in the repl or if you load a file

16:13 I mean, cool, new features, piled on top of a feature that #clojure general advises people not to use, great!

16:15 whodidthis: dgleeson: http://weavejester.github.io/compojure/compojure.core.html#var-routes

16:16 tbaldridge: hiredman: I think the idea goes a bit further than that though. For example, shipping versions of Clojure that boot to the repl faster. By doing things like disabling redeffing clojure.core

16:16 redeffing stuff in clojure.core

16:18 sure that breaks some test frameworks, but those people can either use the "normal" version of clojure, or use a different way of testing that doesn't involve redef'ing ^:static defns

16:19 hiredman: tbaldridge: *shrug* it still seems like optimizing things while there is plenty of broken cruft, but I am sure it is more interesting to work on than trying to fix stuff

16:25 tbaldridge: hiredman: I hear that. If I had my way we'd work on switching over to tools.analyzer before tweaking much else on the compiler, but that's just me.

16:25 seangrov`: tbaldridge: Is that likely to happen? It'd be fantastic

16:26 tbaldridge: seangrov`: I know of no such plans. The first step is to prove that tools.analyzer stuff isn't too slow to be used for normal compilation.

16:27 tolitius: is there a maven plugin/way to build clojurescript? build team needs everything based on maven, (can't use lein)

16:27 tbaldridge: Making a case to switch is easier if you can say "it produces faster code" or "it compiles only 2x slower than the existing compiler". Extensibility/maintainability is hard to argue for if the better designed code is 10x slower.

16:28 (or whatever the performance diff is, Bronsa would know the answer there).

16:29 seangrov`: tbaldridge: Good point. So it's not beyond belief, but unlikely to happen any time soon, and with no hurry to do so

16:29 dgleeson: whodidthis: I looked at that, and I'm having a hard time deciphering how I might apply that stuff. I think that is why I am asking.

16:30 tbaldridge: seangrov`: exactly

16:32 whodidthis: dgleeson: write a separate handler for /resource1 and /resource2 and combine them with that, im not sure if there are any more concise way

16:32 johnwalker: if an agent has ten actions enqueued and shutdown-agents is called

16:33 will those ten actions be processed ?

16:34 if they aren't processed, is there an agent-shutdown-handler?

16:34 brunov: johnwalker: from the docs "Running actions will complete, but no new actions will be

16:35 accepted". My interpretation is that enqueued actions will be processed. This would be like calling shutDown() on the executor.

16:35 As opposed to shutDownNow(), which is more drastic and will even interrupt running Runnables

16:36 johnwalker: i also think thats what is meant there

16:37 still, a shutdown handler would be extremely useful for cleanup

16:38 brunov: johnwalker: confirmation! Under the hood it's calling ExecutorService#shutdown(), which says "Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down."

16:38 johnwalker: nice!

16:43 (inc brunov)

16:43 lazybot: ⇒ 1

16:44 brunov: gracias!

16:45 amalloy: (dotimes [_ 1e5] (shutdown-agents)) ;; just in case

16:47 johnwalker: lol why

16:47 just to make sure they're all dead?

16:47 brunov: "Invocation has no additional effect if already shut down." I think amalloy is joking

16:48 puredanger: scottj: (and others), if there are questions re the fastload or direct branches, I have been working with Rich on testing some of it and could tell you what I know

16:50 fastload is primarily designed to defer var loading and cache classes with the goal of reducing load times. I have tested a large set of public projects (and some private ones) and generally find it's about 10% faster but on a couple it's significantly better. this really affects any code, whether AOT'ed or not.

16:51 In some very narrow benchmarks, I have found that fastload actually makes var invocation slower in very hot loops as you have put a lazy check in the middle of the code path

16:54 the direct branch at turning var invocation into static method calls (like the old ^:static), but for everything. If you have those method calls in a hot code path, this is faster than current invocation through var. One of the limiting factors in the branch as it stands is that it does not handle direct linking of self calls (eg. a fib that calls itself) and from what I've seen that's limiting a variety of hotspot inlin

16:54 possibilities. probably the next thing to come.

16:57 tbaldridge: (inc puredanger)

16:57 lazybot: ⇒ 3

16:57 tbaldridge: only 3, too low!

16:57 only 3, too low!

16:57 (inc puredanger)

16:57 lazybot: ⇒ 4

16:57 puredanger: the direct linking can happen during AOT or can happen outside AOT. Linking decisions can potentially be made at several points. There's a lot of research to be done on how and when it's useful to choose that linking.

16:59 a namespace for example could choose to direct link into Clojure, direct link calls within its own namespace, or even direct link all but a few vars that are left open for dynamic extension

17:00 even if you use a Clojure that is direct linked at build time (we would need to produce multiple variants of the clojure jar), you could still use for example with-redefs to monkey patch core in your scope (but only in calls into Clojrue fns; calls from core to core could not be affected).

17:01 tbaldridge: puredanger: which is kindof asking for trouble, IMO

17:01 puredanger: in some cases, it could be a feature :)

17:01 tbaldridge: "redefing may or may not work...."

17:01 but yes, I agree, make all of that switches and then allow people to tune them. More knobs are always better

17:02 arrdem: tbaldridge: yeah that's one of the things I've kinda been stressed by... one you say "oh redefining has all these caviats" it starts making sense to just say "one def one binding".

17:02 tbaldridge: except perhaps when it comes to the JVM GC

17:02 Fare: better have a clear semantics for what is bound early or late, like Erlang.

17:02 puredanger: there is potentially dizzying variations but in reality most are not used or useful in practice

17:02 Fare: then implementations can optimize or not optimize, at their leisure

17:03 tbaldridge: arrdem: I agree, and I think the community at large is slowly starting to agree that with-redefs is of-the-devil.

17:03 puredanger: I have run direct on about 25 oss projects and only found a handful of cases where code would need adjustment (or just wouldn't work with the direct linked version of Clojure)

17:03 technomancy: with-redefs outside tests anyway

17:04 arrdem: tbaldridge: I mean.. either it's a language feature (and I have enjoyed being able to crowbar into the core some days) or it isn't and we can play more tricks.

17:04 amalloy: puredanger: that seems like a weird position to be in, as a library developer. i can't make my library depend on dynamic calls to clojure.core, because i may be included in an app that has a static core; but i shouldn't link statically either, because the app that uses me may depend on rebinding core stuff

17:04 so i'm almost stuck calling core dynamically (ie, slowly), but not able to take advantage of the flexibility that could afford me

17:04 puredanger: yes, one of the many thorny things to think about

17:05 if we produced multiple clojure jars (clojure and clojure-prod) and gave library developers the tools to build their own, would that be a positive direction?

17:05 or a nightmare

17:05 and what happens when you mix and match

17:06 even in the direct linked case, the paths for dynamic invocation WILL still exist in the compiled code

17:06 that was an early design question

17:07 so the choice is really at compile time

17:12 bbloom: puredanger: have you looked at racket's units?

17:12 puredanger: nope

17:12 bbloom: puredanger: http://docs.racket-lang.org/guide/units.html

17:13 amalloy: puredanger: i don't understand what you mean by "even in the direct linked case, the paths for dynamic invocation WILL still exist in the compiled code". if i choose to include static-core, what code for dynamically calling "vars" in core will still exist, if it doesn't even really have vars?

17:13 bbloom: puredanger: they are similar to ML's modules

17:14 i mention them here b/c they are essentially a mechanism of static typing that would enable consumers of code to declare what bits are static/dynamic

17:14 scottj: puredanger: thanks for the info! have you done any testing on android to see how much it improves startup time there? the clojurefast blog post had really impressive numbers for ios http://gal.dolber.com/post/78110050703/reduce-startup

17:15 bbloom: puredanger: in short, signatures : modules :: protocols : types

17:15 puredanger: but there is / can-be an explicit linking phase

17:15 puredanger: amalloy: in the compiled class representing say, "range" there will be both an "invoke" (current method) and an "invokeStatic" (additional static method). your library code can decide (through knobs TBD) whether to make a static or dynamic call to range. If you are using a direct linked version of core, it might have internal static calls from some other function to range - you could not change that (b/c it's already

17:15 compiled)

17:16 scottj: have done no work re android

17:16 bbloom: puredanger: the overview paragraph on that page contains this statement:

17:16 "a unit’s imported variables can be partially linked with the exported variables of another unit prior to invocation"

17:16 puredanger: scottj: there's no reason someone couldn't try the fastload branch for it

17:16 amalloy: got it, thanks

17:17 puredanger: bbloom: (not ignoring you btw, just many threads here)

17:17 bbloom: puredanger: no worries. i understand that i've basically given you homework ;-)

17:17 puredanger: yeah, totally

17:17 there may be some other person directing my efforts as well. ...

17:19 bbloom: puredanger: it's an avenue worth exploring, considering namespaces are already reified, it wouldn't be too much of a stretch to capture some or all of the bindings in a namespace statically as a value, and merge them

17:19 then compile against that

17:19 arrdem: this being exactly what Mike Anderson and I are doing in our respective projects..

17:20 puredanger: is reading

17:21 bbloom: puredanger: worth noting that racket's units are much more featureful than you really need here... they also address dynamic contracts

17:33 puredanger: as usual, the people of #clojure are kind and wise. 5 stars, will visit again.

17:34 (inc bbloom)

17:34 lazybot: ⇒ 34

17:34 puredanger: and go <insert name of soccer team country>

17:35 johnwalker: come back soon puredanger :)

17:35 bbloom: puredanger: awesome. i've wanted a proper modularity construct for some time. getting you to read about units is a significant small win

17:35 puredanger: I inserted it at the end of my infinite list of things to learn more about

17:35 (see what I did there)

17:36 bbloom: created a type error?

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

17:36 bbloom: there's no append operation for infinite seqs :-P

17:36 johnwalker: i'm pretty sure oracle did that with tco

17:36 puredanger: bbloom: it'll be in clojure 1.8

17:37 bbloom: puredanger: you can't promise that

17:37 puredanger: don't even thunk it

17:37 * bbloom invites more puns

17:38 puredanger: I added it to the end of the infinite list of 1.8 features

17:38 this is kind of like the reverse time travel paradox

17:51 Shayanjm: So I'm still trying to work my way around clojure - and I was wondering if anyone could take a second to review some of my code? https://github.com/shayanjm/Sentimental/tree/develop/src/sentimental

17:52 Essentially, I want to know if I'm writing things in an idiomatic "clojure-ish" way

18:00 amalloy: Shayanjm: https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/core.clj#L41 should be a function, not a macro. i don't like the repetition in https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/core.clj#L29-L32, and would write instead https://www.refheap.com/18bffe0e1342c905555eccbfb

18:01 the (new foo) syntax is rather unusual, so https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/nlp.clj#L10 should be (StanfordCoreNLP. props)

18:02 and you should import the classes, even if you only use them once: seeing edu.stanford.nlp.pipeline scattered throughout the "real" code is distracting

18:02 https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/nlp.clj#L18 is a bad way of writing (seq glob)

18:04 Shayanjm: Thanks for the feedback amalloy. Looking through the code and fixing :)

18:04 amalloy: it's a little worrying that https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/utils.clj#L3 will run forever if n is negative, or not an integer

18:05 Shayanjm: amalloy: so the reason why I needed that is because for whatever reason, I ocassionally get null pointer exceptions with the update-sentiments method (I think it has something to do with the data coming in from NYT)

18:05 if I re-run the function, it usually executes fine

18:05 I couldn't come up with a more elegant solution than having a maximum cap on recurs

18:06 amalloy: i'm not arguing that you shouldn't have that function; that's not my problem

18:06 i'm pointing out that if your n is negative or not an integer, it runs forever

18:06 because (zero? n) is never true

18:06 Shayanjm: How do you suggest I handle that best?

18:07 amalloy: simplest would be to check (pos? n) instead, or to complain if someone gives you anything but a positive integer

18:08 Shayanjm: gotcha

18:11 amalloy: I'm trying to plug in the imports, but I think I'm getting the syntax wrong. specifically: https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/nlp.clj#L20-L21

18:11 when I try importing the CoreAnnotations class and accessing the nested SentencesAnnotation class - I get a Runtime exception

18:12 amalloy: you need to import edu.stanford.nlp.ling.CoreAnnotations$SentencesAnnotation

18:12 Shayanjm: ahhh the whole thing?

18:12 amalloy: "nested" classes in java are just ordinary, distinct classes to the jvm

18:13 Shayanjm: I see. And then how do I access it in the code?

18:13 amalloy: CoreAnnotations$SentencesAnnotation

18:13 Shayanjm: Just AnnotatedTree?

18:13 err, SentencesAnnotation**

18:13 kk

18:13 amalloy: it's "just" a class named CoreAnnotations$SentencesAnnotation in the package edu.stanford.nlp.ling

18:14 Shayanjm: the definition of find-sentiment is a little worrying: you say it returns a seq of ints, but https://github.com/shayanjm/Sentimental/blob/develop/src/sentimental/nlp.clj#L24 suggests there can be nils in the seq as well

18:14 Shayanjm: Yeah. So I'm still trying to figure out if I want to keep that functionality or not

18:15 I did think about that. The reason why I'd like to persist it is in the case of an article not actually containing text

18:15 (NYT occasionally has 'video-only' article bodies)

18:15 In the presentation-layer, I was planning on just defaulting nil values to '2' (a 'neutral' sentiment)

18:16 amalloy: why not just remove them? is (nil nil nil nil) more informative than ()?

18:17 Shayanjm: Mm, yes, because then position is retained

18:17 i'll be mapping the resultant values to titles, abstracts, etc. of the respective articles

18:18 so without explicitly building a map of the result values, having a bunch of seqs that correspond with each other is useful

18:18 dbasch: Shayanjm: then your docstring is wrong. IMHO you should keep the docstring, and default to neutral

18:19 amalloy: ew. a bunch of seqs corresponding to each other by index is not very nice, if you can instead have a seq of tuples. ie, instead of [(1 2 3) (a b c)], prefer building [(a 1) (2 b) 3 c)]

18:19 skipping my silly typo, of course

18:20 Shayanjm: That makes sense

18:20 Okay but I'm just failing on importing it seems

18:21 * Frozenlock realizes his fallback gif is loaded even if the <video> is working

18:21 Shayanjm: https://www.refheap.com/87748

18:21 Frozenlock: Damnit...

18:21 I hate the web

18:23 amalloy: Shayanjm: i think you don't want those []s in your import list

18:24 Shayanjm: Aha! Thanks amalloy :)

18:31 dbasch: Shayanjm: this line (if (and (not (nil? glob)) (> (count glob) 0))

18:32 could be (if (and glob (pos? glob))

18:32 sorry, pos count glob

18:33 Shayanjm: dbasch: just fixed thanks :)

18:34 dbasch: Shayanjm: you probably don't need the and because (count nil) is 0

18:34 {blake}: I am close (thanks to all for help) but stuck. My code to simplify my XML works but I want common tags to be expressed as single keys with a sequence of values. Given a sequence of maps, I find I can "apply merge-with into" to unite siblings at the top level, but can't figure out how to apply it to all the children.

18:34 This https://www.refheap.com/87749 details with code and example output.

18:35 Seems like I should be able to put that "apply merge-with into" into my "simplify-xml" routine somewhere but no dice.

18:36 amalloy: dbasch: i already told him that line could just be (if (seq glob)

18:37 dbasch: amalloy: didn't see that, I had one eye on the world cup :P

18:40 amalloy: dbasch: yeah, i got up at the end of the game to go join the crowd in my office

18:41 seangrov`: amalloy dbasch: well, at least we can breath again

18:42 dbasch: seangrov`: I'm not getting very excited by the world cup. International soccer has reached the point of quasi-randomness

18:42 nullptr: quasi-randomness ~= competitiveness

18:43 dbasch: nullptr: no, it's more about the fact that it's much easier to lose a game because of a single mistake than to win it on merit

18:45 sorry to derail the topic, let's go back to clojuring :P

18:45 amalloy: there are a lot of fields where merit is mainly the absence of isolated mistakes

18:50 {blake}: Knife-throwing, e.g.

18:54 hiredman: seems like that might an artifact of an asymmetry between offense and defense

18:56 if scoring were easier, then it would be easier to make up for a mistake (missing a chance to score, or letting an opponent score)

19:07 dbasch: amalloy: what makes soccer different is that some mistakes have a probabilistic chance of costing you, depending on the referee's subjectivity

19:08 e.g. stepping on an opponent's foot in the penalty box because you were a few milliseconds late can be a penalty or not, at the ref's discretion

19:09 professional coding is mostly about the absence of mistakes, despite what most tech interviews test for

19:12 {blake}: I've been known to piss more than a few people by suggesting that if they don't like debugging, they shouldn't put so many bugs in their code.

19:14 dbasch: {blake}: even though your comment is tongue-in-cheek, we all know that a substantial portion of bugs are simply missing checks

19:15 {blake}: dbasch, It is TIC, but also true. Yeah, missing checks, misunderstood scope, and sloppiness, etc. It makes a lot of sense for a programmer to take responsibility for these things.

19:16 (It is a little bit like saying "First, solve AI..." of course.)

19:26 AndIrc: hello

19:43 ttasterisco: hey dbasch, a blog post of yours is #1 in HN

19:44 dbasch: ttasterisco: thanks, I wasn't expecting that one to make it to HN

19:44 ttasterisco: it's not even very good

19:46 Lanny: "Netscape has been effectively dead so long that younger generations may think it was a brand of milk chocolate"

19:46 ttasterisco: btw, typo: "the original people where leaving"

19:47 Lanny: is that a pun on nestle?

19:47 ttasterisco: or hershey's :p

19:47 dbasch: thanks ttasterisco

19:48 Frozenlock: dbasch: I once asked the interviewers why they had chosen me over other candidates for the interview.

19:48 dbasch: Lanny: I vaguely remember but I think that was the intent :)

19:48 Frozenlock: that should be an easy question to answer

19:48 Frozenlock: Right?

19:48 By the answer they gave, I quickly realized they didn't put much thought at all into it...

19:48 ttasterisco: Frozenlock: what was their answer?

19:49 Frozenlock: As generic as you can get. Paraphrasing "well, we still haven't read your resume... but HR selected you..."

19:50 amalloy: Lanny: it made me think of nescafe

19:51 dbasch: I hope I never need funding from Marc Andresseen

19:51 ttasterisco: lol

19:51 you mean from A16Z, cause Ben's there too

19:53 dbasch: what were you doing in Pittsburgh at the time? CMU?

19:53 dbasch: ttasterisco: yes

20:05 bbloom: amalloy: on my TODO list of random projects to do at some point for my own edification is a propAgator library... i'm considering bumping it to the top of the queue, since i screwed up the spelling again recently.... maybe i can beat this error out of myself by typing it a bunch

20:07 amalloy: it sounds like you're going into business selling stuffed alligators for use in movies or something

20:08 get it? gator props. who doesn't love puns, right?

20:08 Lanny: I chuckled

20:08 bbloom: :-P

20:25 johnwalker: whats the difference between #^ and ^ in typehinting?

20:28 amalloy: johnwalker: #^ is very old and should no longer be used, but is equivalent

20:28 clojurebot: #^ is very old and should no longer be used, but is equivalent to ^

20:28 clojurebot: You don't have to tell me twice.

20:28 amalloy: ~#^

20:28 clojurebot: #^ is very old and should no longer be used, but is equivalent to ^

20:28 amalloy: hurrah

20:29 johnwalker: thanks amalloy

20:31 ttasterisco: why should #^ no longer be used?

20:32 cbp: because ^ is now a thing and its like one less character

20:35 Lanny: you can still use #^ if you don't caret about the one additional caretacter

20:36 wow, tough audience

20:41 amalloy: Lanny: your joke was just too meta

20:41 Lanny: heh

21:08 Shayanjm: out of curiousity: how many of you guys write clj/cljs at your day job?

21:09 ttasterisco: why are you assuming everyone has a job :(

21:11 Shayanjm: *out of curiousity: how many of you (employed) people write clj/cljs at your day job?

21:13 Lanny: I managed to sneak clojure into my day job, but it probably only makes up like 20% of the code I write

21:14 zanes: If you have an iterator the traversal of which may trigger an exception, is it idiomatic to interact with it as a seq?

21:14 Hope that made sense.

22:09 technomancy: zanes: (map (partial / 4) [1 3 2 0])

22:09 that is to say, exceptions can strike anywhere

22:09 zanes: Fair enough.

22:10 Frozenlock: Get checked, not just old people get exceptions.

22:10 zanes: What I’m trying to do is implement exponential back off in response to rate-limiting exceptions from an API while preserving the seq abstraction.

22:10 It’s getting a little ugly, so I was wondering whether what I was doing was still idiomatic.

22:11 Lanny: not everyone has access to good exception catching facilities Frozenlock, check your privilage

22:12 Frozenlock: :-p

22:13 technomancy: if you have pattern matching available you could use an option type =)

22:13 it's not terribly idiomatic, (and super annoying without pattern matching) but it's a lot nicer than exceptions

22:13 zanes: I considered that. It felt cleaner somehow to just slow down the realization of the seq.

22:14 This keeps downstream consumers from knowing about rate-limiting exceptions at all.

22:14 But the implementation was a little hairy for me.

22:22 akurilin: quick question: what's your guys' take on mocking db calls when testing Ring apps that mostly do CRUD? Do you generally tend to err on the side of writing integration tests?

22:26 mange: zanes: Were you meaning something like this? https://www.refheap.com/87751

22:28 zanes: mange: Yep. I wound up with something like this: https://gist.github.com/zane/58e3c77951eaa5159f26

22:29 akurilin: If you have the leeway to use Datomic you can even unit test hitting the database!

22:30 I prefer to avoid integration tests as much as possible.

22:31 mange: Ah, okay. That's a bit more special-purpose. I was wondering if you could use something like ribol (https://github.com/zcaudate/ribol) to make it so the consumer can choose the strategy on failure, but I don't really have the time/energy/inclination to look into that now.

22:31 dbasch: zanes: you don't need the nil https://gist.github.com/zane/58e3c77951eaa5159f26#file-gistfile1-clj-L8

22:32 akurilin: zanes: any particular reason why?

22:32 zanes: dbasch: Just change that to a when-let?

22:32 dbasch: zanes: sure

22:32 zanes: akurilin: Because they’re slow, brittle, and tend to make the rest of my test suite less useful.

22:32 dbasch: zanes: the only advantage of a when-let being the implicit do

22:33 zanes: Oh, that’s interesting. I thought single-armed ifs were kind of distasteful.

22:33 akurilin: zanes: do you mock db calls or how do you avoid that?

22:34 zanes: mange: I hadn’t heard of ribol. Thanks!

22:34 akurilin: Pretty much.

22:34 akurilin: zanes: don't you find mocks also very brittle though?

22:35 zanes: It sounds like you have a good handle on the tradeoffs here. :)

22:35 akurilin: I don't, what's why I'm curious what others have chosen for their projects

22:36 I've been seesawing back and forth between the two approaches for years

22:43 rufoa: I've noticed that in the context of destructuring, ":as" and ":keys" are referred to as "directives" rather than "keywords". Is there a semantic difference between the two?

22:44 dnolen_: ClojureScript 0.0-2261 out, murmur3 hashing landed (hard dep on 1.6.0)

22:44 rufoa: it seems directive is also used to describe :use, :gen-class etc inside an (ns) macro

22:46 Frozenlock: dnolen_: thanks!

22:48 At which point does a .edn file 'database' can't do the job anymore? I always use a database backend, but for small project I think I might as well keep everything dead simple...

22:50 technomancy: Frozenlock: depends on so many factors

22:51 atoms or refs? read/write ratio, cost of update function, variability of cost of update function, concurrency of updates, etc

22:58 Frozenlock: Ok, I'll rephrase my question. I would like to store users info (maps of ~10 fields per user). Would the Universe hate me for using a simple file for say 0-100 users?

22:59 I used to store an elisp 'database' this way up to hundreds/low-thousands of element without much trouble. /cowboy

23:01 technomancy: that seems reasonable. clojars uses in-memory maps for users with a very low level of writes.

23:02 Frozenlock: nice, thanks!

23:04 pandeiro: anyone use archiva? i'm trying it out for the first time but can't get the URL right (?)

23:36 bbloom: amalloy_: ERROR: Propegator not defined

23:36 amalloy_: i made it ~2 hours without seeing that error....

Logging service provided by n01se.net