#clojure log - Jul 29 2015

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

4:37 Guest52: Hi guys. Small question here. Is there any way to query the repl for the description (required methods with their signatures) of a protocol?

4:45 gilliard: Does (:sigs MyProtocol) do what you need?

5:01 Guest52: @gilliard: there we go, thanks. didn't realise the meta attributes where there

5:03 *were there

5:38 augustl: I'm using this to run tests in a repl - is there a better way? :) (do (prn (refresh)) (clojure.test/run-tests 'my.test.ns))

7:36 expez: augustl: cider can run your tests for you with the press of a button, there's also lein test-refresh which runs your tests after files have changed

9:58 tgoossens: In clojure how can I: Given a string "Integer" or "ClassName" use this to cast an object to this type?

10:02 ,(eval `(cast ~(symbol "Long") 25))

10:02 clojurebot: 25

10:02 tgoossens: ,(eval `(cast ~(symbol "String") 25))

10:02 clojurebot: #error {\n :cause "Cannot cast java.lang.Long to java.lang.String"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast java.lang.Long to java.lang.String"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core$cast invoke "core.clj" 337]\n [sandbox$eval53 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval...

10:02 tgoossens: ,(eval `(cast ~(symbol "Double") 25))

10:02 clojurebot: #error {\n :cause "Cannot cast java.lang.Long to java.lang.Double"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast java.lang.Long to java.lang.Double"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core$cast invoke "core.clj" 337]\n [sandbox$eval79 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval...

10:05 kwladyka: what trace missing could mean? i cant localize a bug

10:07 but mmm maybe i found it

10:38 dabd: I wrote a function using the threading macro ->> that looks like (->> (insta/parse ...) (insta/transform) (map (fn [..] for side effects))). The mapping is done for side effects only. Is there a more idiomatic way to process the parse tree for side effects only?

10:40 snowell: dabd: You could take the collection returned by (insta/transform) and iterate through it with doseq

10:42 Or if you're feeling adventurous, try walking through it with the clojure.walk API

10:43 dabd: but doseq won't play nicely with ->>

10:43 snowell: No, you wouldn't thread it through doseq, but you could (doseq [elem (->> stuff)])

11:05 justin_smith: kwladyka: in 1.7 we have run!, which is like map but only for side effects

11:05 (doc run!)

11:05 clojurebot: "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil"

11:05 justin_smith: ,(run! print (range 10))

11:05 clojurebot: 0123456789

11:06 kwladyka: justin_smith, how it can help me? :)

11:06 justin_smith: kwladyka: use it instead of map in your ->> block

11:06 kwladyka: about trace missing?

11:06 snowell: I think he meant that for dabd

11:06 justin_smith: oh, wait, wrong person, sorry

11:06 dabd: see above, about run!, I think it does what you want

11:06 kwladyka: anyway i found in one moment i hava parameter nil not what it should be

11:06 but i dont have any idea when it is happening

11:07 justin_smith: kwladyka: trace missing can happen because of jvm optimizations - I forget which flag, but I think there is one that turns off some of the vm optimizations that make that happen

11:07 basically thanks to inlining there isn't a stack trace there (since no stack, it's inlined) or something like that

11:08 kwladyka: justin_smith, but there is a bug in my code anyway... but i can't find when.... because all is recusrive and in one moment something is going wrong, but it is magic why :)

11:08 justin_smith: kwladyka: maybe tools.trace would help - if nothing else tracing something makes it much less likely to be inlined

11:09 kwladyka: justin_smith, maybe... i will check

11:11 dabd: justin_smith: thanks for the run! suggestion. Looking at the doc I am not sure I understand what is a procedure.

11:11 justin_smith: dabd: it means function

11:11 kwladyka: o f**** i did :notaion instead of :notation... a few hours... i am going cry

11:11 justin_smith: dabd: run! works just like map

11:12 kwladyka: I hate keyword typos, so crazymaking

11:12 dabd: yes I see, just never read before about the concept of procedure in Clojure

11:13 justin_smith: dabd: I'd almost consider that a documentation bug? ##(clojure.repl/find-doc "procedure")

11:13 lazybot: ⇒ ------------------------- clojure.core/run! ([proc coll]) Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil nil

11:14 justin_smith: dabd: the only doc string in all of clojure with the word "procedure" in it - so for consistency it should maybe be changed to function

11:14 also, find-doc is under-appreciated as a tool for clojure learners

11:17 also, clojure.data.priority-map has an epic level doc string

11:18 dabd: justin_smith: thanks for the find-doc tip

11:26 justin_smith: puredanger: would a jira issue to change the doc of "run!" to mention function instead of procedure, or to elaborate on what a "procedure" is, be worth the trouble?

11:26 (doc run!)

11:26 clojurebot: "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil"

11:26 justin_smith: puredanger: context being that it is the only doc-string in all of clojure mentioning the term procedure - as an ex scheme user I think I know what is meant there, but it is potentially confusing

12:00 dnolen: ClojureScript 1.7.10 pre-release cut, please test to suss out any issues, thanks

12:02 sdegutis: Is there a destructuring way to get all the remaining elements of a seq except for the last one?

12:03 Bronsa: no

12:03 sdegutis: I'm currently doing [a & bs] and assigning [bs (drop-last 1 bs), c (last bs)]

12:03 But it feels so hacky and incorrect.

12:04 Bronsa: sdegutis: droplast-1 is butlast

12:04 sdegutis: Thanks.

12:04 So, this is the hack I have to use?

12:04 justin_smith: sdegutis: you could reverse it and use regular destructuring?

12:04 sdegutis: But.. but.. I thought destructuring was The Future, Man™!

12:04 justin_smith: Oooh clever! I like your style.

12:04 justin_smith: sdegutis: it's actually very limited and weird

12:05 sdegutis: bonus, if you use a vector rseq is cheap

12:05 sdegutis: justin_smith: I have no control over anything.

12:05 justin_smith: :OK

12:06 Bronsa: >insert rant about how reverse doesn't automatically use rseq here<

12:18 pepijndevos: What do people usually do for background work in Clojure web apps (on heroku)?

12:19 Just some clojure.async thread, or a dedicated background worker and message queue?

12:20 sdegutis: justin_smith: because Instaparse gives it to me.

12:21 pepijndevos: In Python it is really common to use a worker with Celery or RQ. But Python doesn't have proper threading. So I thought maybe it's not worth the overhead and complexity in Clojure.

12:22 justin_smith: pepijndevos: there's some decent facilities for scheduled tasks you can use via interop http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html , there is also at-at https://github.com/overtone/at-at

12:23 pepijndevos: note that for those javadocs, a clojure function is a "callable"

12:23 (and also a runnable)

12:24 pepijndevos: justin_smith, I don't need to schedule something, just run it outside the web request. So a normal threadpool might suffice.

12:24 justin_smith: pepijndevos: just use future

12:24 it's easy

12:24 I thought you wanted something scheduled

12:24 (future (your code goes here)) ; and done

12:25 pepijndevos: Nah, just wondering what people usually do. In Python the answer is almost always celery. In clojure... just a thread it seems.

12:25 justin_smith: pepijndevos: right, and the easy way to use a thread is a future

12:25 pepijndevos: right

12:26 Futures are backed by a pool, right?

12:26 justin_smith: yes, they share the agent thread pool

12:27 puredanger: justin_smith: re run!, "via reduce" has a very specific meaning to me, so I don't think it's a big deal as is

12:28 justin_smith: OK. Yeah, I figured it was borderline at best, which is why I asked before going and making a ticket.

12:34 sdegutis: I am going to use split-with.

12:36 timvisher: can anyone think of examples of clojure code that takes advantage of jvm bytecode features that java can't or has difficulty taking advantage of?

12:36 or did i make that up?

12:37 i had gotten it into my head that clojure specifically compiles to bytecode to avoid certain limitations in java

12:38 one example i thought of that i think holds true is the idea of extending a protocol to a new type, which i thought would be somewhat tricky, at least, to do in java

12:39 expez: timvisher: the jvm was written with java in mind. It's only in the last couple of years that Oracle has started thinking about adding bytecode to support other languages at all, so no, there's probably no op that's used by clojure but not by java

12:40 sdegutis: How does the JVM compare in speed to V8 these days?

12:40 I wonder if running ClojureScript on Node.js or Io.js would be a reasonable alternative to running Clojure on the JVM.

12:40 In particular because I don't use any JVM-specific features.

12:44 justin_smith: no threads, futures, agents?

12:47 sdegutis: Maybe in some third party libraries I guess.

12:49 uris77: the jvm has always been faster than V8.

12:52 sdegutis: By orders of magmatude?

12:54 Seylerius: Hrm. I've tried setting org.clojure/tools.nrepl as a plugin in my user profile, in the project, and required a version of "0.2.10" each time, but when I start `lein gorilla` and then connect cider to it, cider bitches about nrepl version being 0.2.6

13:00 timvisher: expez: do you have any idea why clojure doesn't go Clojure → Java → Bytecode then? is there a reasoning doc somewhere?

13:02 Seylerius: timvisher: Probably because Clojure is trying to avoid problems of lossy abstraction in Java's design, and so going directly to bytecode helps.

13:13 expez: timvisher: targetting java as an intermediary language would be a bit roundabout, don't you think? It would certainly make compilation slower. Most likely it wouldn't be much easier either.

13:14 Jaood: expez: but it would have made clojure faster ;)

13:14 expez: Jaood: What makes you say that?

13:14 timvisher: expez: that's true. i also forgot for a second that java is not the execution languange of the jvm, bytecode is

13:15 expez: timvisher: But yeah, targetting java as an intermediary language wouldn't work for e.g. loop/recur

13:15 timvisher: i was thinking of parallels to clojurescript, but that's an innapropriate comparison

13:15 Jaood: expez: what can produce faster bytecode than javac?

13:16 expez: Jaood: bytecode is slow...Most of the speed you get by running on the jvm is from the JIT.

13:16 Jaood: if you add typehints the clojure compiler will emit bytecode of the same quality as javac

13:17 well, mostly ;)

13:24 csd_: I see that creating an uberjar is executing my code. Why is this happening and Is there any way to prevent this?

13:31 expez: csd_: this is happening because you have toplevel forms of the type (launch-missiles!) in your project and `compile' seems to evaluate those forms

13:32 csd_: does a def statement count?

13:32 expez: As to why `compile` does that I'm not sure, I've never really AOT'd anything

13:32 csd_: certainly

13:32 sdegutis: I am writing EBNF.

13:33 csd_: expez: my code uses Guice and the compiler breaks things by running the guice code

13:33 i need to figure out how to make it not instantiate it

13:34 expez: csd_: maybe `delay` fits the bill

13:34 csd_: hrm.. worth a shot

13:37 expez: sdegutis: http://www.quora.com/How-does-Nashorn-compare-to-V8 so clj vs cljs on v8 probably within a factor of 2-3x?

13:37 csd_: expez: still being executed somehow

13:38 expez: csd_: mm, I'm out of my depth here

13:39 sdegutis: expez: that's actually pretty fast

13:41 How do you specify case-insensitive in Instaparse.

13:43 Jaood: expez: yes, the gains of the JIT are much bigger, but the bytecode is still heavily optimized no?

13:44 sdegutis: I found the answer.

13:44 Thanks you.

13:56 expez: Jaood: not really, http://stackoverflow.com/questions/5981460/optimization-by-java-compiler

14:08 akabander: Does anyone here have any experience with clj-http and :basic-auth ?

14:12 justin_smith: akabander: I think I've used it before, what's the issue?

14:13 akabander: I'm trying to send commands to an Ambari server's REST interface. It needs a "X-Requested-By" header, and basic auth.

14:14 (client/get "http://myserver.com:8080/api/v1/clusters/tinderbox/services" {:headers {:X-Requested-By "myapp"}} {:digest-auth ["admin" "PASSWORD"] })

14:15 Sorry, replace :digest-auth with :basic-auth, I copied and pasted from a desperate experiment.

14:15 (client/get "http://myserver.com:8080/api/v1/clusters/tinderbox/services" {:headers {:X-Requested-By "myapp"}} {:basic-auth ["admin" "PASSWORD"] })

14:16 justin_smith: akabander: the basic-auth should be in the same map as the headers

14:16 snowell: akabander: Your headers should be strings instead of keywords {"X-Requested-By" "myapp"}

14:16 justin_smith: I don't even know what that extra arg is meant to do

14:16 akabander: Aha, let me try it

14:17 hiredman: your maps aren't right

14:17 :headers and :basic-auth should be keys in the same map

14:18 akabander: Yes, it worked!

14:18 Thanks guys, I must have mentally "barfed" when I read the examples.

14:18 justin_smith: cheers to the echo caused by hiredman having me on ignore

14:19 akabander: The header key as keyword worked, I'm guessing it may do a string cast.

14:19 justin_smith: probably they call name on the keys

14:19 snowell: Possibly. I remember having problems with it, but that would have been in cljs-http, not clj-http

14:19 akabander: Thanks again, justin (and hiredman :)

14:21 The X-Requested-By header is required by Ambari. I believe it's mostly used for log detail.

14:36 pepijndevos: If I throw an exception in a for, is there a way to stop looping and return the seq so far?

14:36 sdegutis: guys

14:36 hey guys

14:36 im so excited

14:37 it turns out instaparse is very cool

14:37 and fun and exciting

14:37 blkcat: instaparse is terrific

14:43 pandeiro: anyone have experience connecting to a REPL (eg lein repl :headless) running in a docker container?

14:43 i'm getting "SocketException The transport's socket appears to have lost its connection to the nREPL server"

14:44 xemdetia: sdegutis, I am glad you are making progress

14:47 Seylerius: Hrm. I've specified [org.clojure/tools.nrepl "0.2.10"] in my project.clj's plugins (also tried user profile), but Gorilla REPL seems to still be launching with nrepl 0.2.6

14:47 How do I override this?

14:49 hiredman: Seylerius: https://github.com/technomancy/leiningen/issues/1748

14:50 snowell: pepijndevos: Look into (for [x mySeq :while (condition)])

14:50 hiredman: or something like that

14:50 snowell: Once the condition is false it breaks out of the loop and returns the seq up until there

14:51 hiredman: lein can have issues with nrepl dependencies because it has to inject an nrepl dependency in to projects without one

15:01 expez: Seylerius: {:user {:dependencies [[org.clojure/tools.nrepl "0.2.10"]]}} in profiles.clj

15:01 Seylerius: hiredman: That's... unfortunate. There isn't anything we can do about it?

15:09 sdegutis: Oh no wait.

15:09 Instaparse can't handle arbitrary text lazily.

15:10 This is a problem.

15:16 Help?

15:21 vas: sdegutis: you mean you have to have the full text specified/known instead of doing it on-the-fly?

15:21 looking at the docs, it can make lazy trees of parses but that is not what you're asking; I wonder if there is a simple fix for making it play nicely with lazy text.

15:22 sdegutis: vas: I mean I currently have a regex #".+" to match "any character" except it's too greedy, consuming the beginning of the next match that Instaparse should have seen instead

15:28 vas: sdegutis: Hmmm. Well, are there alternatives to using regex in your situation?

15:31 sdegutis: vas: I was hoping Instaparse would give me alternatives.

15:31 It doesn't seem to though.

15:34 Hence my presence.

15:37 I think I will now use regular Clojure utilities to parse this instead of Instaparse. I know how to do it better via ->> honestly.

15:37 The end.

15:51 Instaparse seems useful up until you need to actually deal with almost-arbitrary text.

15:52 At which point it becomes completely useless.

15:54 justin_smith: it seems intuitive that the more freeform the input is, the less useful a parser becomes

Logging service provided by n01se.net