#clojure log - Jul 29 2015

The Joy of Clojure
Main Clojure site
Google Group
IRC
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

15:57 * wasamasa wonders how fucked linguists are then

15:58 justin_smith: wasamasa: pretty thouroghly - they definitely can't just use a parser

15:59 wasamasa: justin_smith: I find it interesting to read articles about the topic, but they rarely come up in my feed and are stuffed with very specific jargon

15:59 justin_smith: wasamasa: for starters they don't have a spec - all they have are examples of usage

16:00 wasamasa: they can't narrow down some usage as "incorrect" - instead, that just marks a change in usage over time

16:01 TimMc: justin_smith: tbh someting similar applies to Clojure

16:01 except we have the source code so that's nice

16:03 sdegutis: What's an exquisite technique for splitting a collection every time two specific values are found in a row?

16:03 TimMc: wasamasa: NLP is a hodge-podge of dictionaries, statistical models, and a handful of grammatical rules.

16:03 sdegutis: Like, (f [:c :c] [:a :b :c :c :d :e]) => [[:a :b] [:d :e]]

16:03 Thanks.

16:08 Or even to recognize successive things would be nice.

16:08 Ideas?

16:11 wasamasa: I bet recognizing runs is a 4clojure problem

16:12 sdegutis: No I need to use Clojure 1.5.1 so I can't use transducers.

16:14 The only technique I can think of is to either keep state, or to group things into redundant pairs, search those, and split them back out, but that sounds error-prone.

16:18 TimMc: sdegutis: It's basically a state machine.

16:18 sdegutis: Oh good idea I'll write a state machine.

16:18 Thanks TIm.

16:19 TimMc: Use a (loop) that keeps a buffer of last two entries and an output buffer of vectors.

16:19 When you see [:c :c] dump the recent entries buffer skip output.

16:19 *and skip

16:20 You could make this lazy by passing the state in a lazy-seq fn's args.

16:21 sdegutis: Actually I think I've written this before.

16:21 https://github.com/timmc/rand/blob/master/src/rand/core.clj#L26

16:22 sdegutis: Thanks TimMc good idea.

16:23 TimMc: feel free to grab that code under EPL or whatever

16:24 sdegutis: Thanks.

16:26 TimMc: I should review it and add it to org.timmc/handy if I haven't already done so.

16:33 justin_smith: TimMc: that loop could even be a reduce

16:36 sdegutis: That was my first idea, reduce.

16:39 justin_smith: ,apply into (reduce (fn [[results chunk] item] (if (= item (peek chunk) :c) [(conj results (pop chunk)) []] [results (conj chunk item)])) [[] []] [:a :b :c :c :d :e :c :c :f])) ; sdegutis

16:40 clojurebot: #object[clojure.core$apply 0x10bf692c "clojure.core$apply@10bf692c"]

16:40 justin_smith: err

16:40 ,(apply into (reduce (fn [[results chunk] item] (if (= item (peek chunk) :c) [(conj results (pop chunk)) []] [results (conj chunk item)])) [[] []] [:a :b :c :c :d :e :c :c :f])) ; sdegutis

16:40 clojurebot: [[:a :b] [:d :e] :f]

16:40 justin_smith: oh that should be conj not into

16:40 ,(apply conj (reduce (fn [[results chunk] item] (if (= item (peek chunk) :c) [(conj results (pop chunk)) []] [results (conj chunk item)])) [[] []] [:a :b :c :c :d :e :c :c :f]))

16:40 clojurebot: [[:a :b] [:d :e] [:f]]

16:41 sdegutis: Peek! Clever!

16:41 justin_smith: and pop

16:41 sdegutis: Ahh!

16:42 justin_smith: of course generalizing it for a split pattern increases the complexity

16:42 sdegutis: lol "Note - not the same as next/butlast."

16:46 justin_smith: for easter we should implement peep and pock

16:51 Bronsa: uh https://github.com/clojure/clojure/commit/309c03055b06525c275b278542c881019424760e

16:54 hiredman: wild

16:55 Bronsa: https://github.com/clojure/clojure/commit/309c03055b06525c275b278542c881019424760e#diff-d951a5cd799ae841ffcc6b45598180dbR321 ew

16:57 blkcat: unit tests. is clojure.test still the way to go, or are there any other libraries out there that i should consider?

16:57 tcrayford____: blkcat: lots of things both ways. A lotta folk just on Clojure.test these days though

16:57 hiredman: this sort of looks like an attempt to deal with a number of different issues, one of which maybe the fn hoisting that try/catch and loop do when compiled as expressions

16:58 kwladyka: how much faster is Jave then Clojure in clar algorithm counting?

16:58 clojurebot: Pardon?

16:58 hiredman: which is interesting, I hadn't thought about :static in that context

16:59 although, I guess maybe it isn't, because the fns created from try/catch expressions almost always close over stuff

17:00 Bronsa: hiredman: I don't really think it helps that use-case but I'll have to study this commit before being sure

17:01 I can't even understand what parts of the compiler are being changed from the diff :(

17:01 hiredman: it is hard to follow

17:02 and like, all the commented out isStatic calls being replaced by commented out canBeDirect

17:02 Bronsa: yeah

17:05 TimMc: I'd be pretty annoyed to get a PR with a commit like that.

17:05 sdegutis: Okay I just solved this with a bunch of Regex instead of using Instaparse.

17:05 Works like a charm.

17:05 Bronsa: TimMc: luckly we don't have to review that

17:06 TimMc: Solution: No PRs. :-P

17:06 csd_: How can i make lein look to [:profiles :dev :main] to when i call lein run? I can't have a toplevel :main specified in my project.clj

17:06 hiredman: I may just be firing random pattern matches, then, this just shares a lot of the mechanics of emitting clojure code in to a static method

17:07 TimMc: csd_: `lein with-profile +dev run` comes to mind, although I guess I would have expected :dev to be included by default.

17:08 hiredman: well, it's in alpha3

17:08 csd_: TimMc: doesnt work :-/

17:08 vas: sdegutis: glad you got it working =)

17:10 justin_smith: csd_: is it :main or :main-ns ?

17:11 csd_: justin_smith: sorry, dont understand what you're asking

17:11 justin_smith: never mind, it is :main, I had misremembered the key

17:12 Bronsa: hiredman: do you undertand why hasEnclosingMethod is required?

17:12 justin_smith: csd_: I typically use the optional args to lein / java to specify an alternate ns to run

17:12 csd_: justin_smith: do you have a usage example?

17:12 justin_smith: csd_: but I understand the appeal of wanting it to happen per-profile

17:12 hiredman: Bronsa: nope

17:13 TimMc: csd_: oh right, try lein run -m foo.bar.baz

17:13 hiredman: Bronsa: I went the other direction and was wondering why it needed to check that if it could jest check the closed over out

17:13 csd_: the way i lein uberjar cant have my :main inside project.clj, but that also breaks lein run

17:13 hiredman: count

17:13 justin_smith: csd_: lein run -m other.ns

17:13 Bronsa: hiredman: yeah same. but apparently it does matter

17:13 csd_: hence why i want to figure this out

17:13 TimMc: I think you can even specify the var name.

17:13 hiredman: Bronsa: yeah, well I realized of course you can wrap a top level defn in a let

17:13 justin_smith: csd_: see also java -cp your.uber.jar clojure.main your.alternate.ns

17:14 Bronsa: I remember playing with it last summer in the direct branch and removing that check made some code fail to compile even if closed overs is nil

17:15 hiredman: :/ alpha3 is giving me a verify error on our big project at work

17:15 Bronsa: not surprised

17:15 hiredman: actually, it looks like the verify error is coming from migratus

17:15 csd_: lein run -m works.. is there a way to alias lein run -m .... to lein run?

17:15 Bronsa: that stuff is hard to get right

17:17 justin_smith: csd_: what about lein other-ns aliasing to lein run -m other.ns

17:17 that seems a bit more doable

17:18 hiredman: yep

17:18 iwo: hey, can anyone help me understand why this blocks:

17:19 csd_: justin_smith: anything that shortens it really

17:19 iwo: (def foo (chan)) (def bar (chan)) (go-loop [x (<! foo)] (>! x bar)) (>!! foo 1) (<!! bar)

17:20 apologies for that being all on one line: basically I'm creating two channels, creating a go-loop that reads from foo and puts onto bar

17:20 when I put something into foo, i get 'true'

17:21 but when I attempt to take from bar, it just blocks

17:21 shouldn't '1' be available from bar when I try to take it?

17:21 vas: So when I re-deploy my app (scp the .jar over and java -jar ..) the send mail functionality takes ~15-16 minutes to start up. It's bizarre. someone the other day mentioned javamail has an inherent "startup time" and I'm wondering how I can overcome that..

17:21 justin_smith: iwo: putting and taking a channel in the same block doesn't really work

17:21 iwo: and isn't intended to

17:22 iwo: oh okay, so maybe i'm going about this all wrong

17:22 i'm imagining my code as a sequence of processes, where each step should take from one channel and put onto another

17:23 then I just create a bunch of channels to act as the 'plumbing' between the functions

17:23 but i guess this is wrong

17:25 justin_smith: iwo: the steps can do that, but shouldn't be in the same go block

17:26 iwo: when I do something inside a go block, doesn't it make sense to have some channel that causes the go block to do something (a channel it is waiting on) and a channel to put the result on?

17:26 justin_smith: iwo: yes, the problem is reading and writing to the same channel in one block

17:27 iwo: correct me if i'm wrong, but this does not read + write to the same channel: (go-loop [x (<! foo)] (>! x bar))

17:27 ?

17:28 justin_smith: no, it doesn't - it reads a channel from a channel, then writes to it

17:28 oh, wait, I might have misread your paste above... I think I did

17:28 iwo: sorry, that's bad pasting on my part

17:28 easier to read like this:

17:28 (def foo (chan)) (def bar (chan))

17:28 (go-loop [x (<! foo)] (>! x bar))

17:29 (>!! foo 1)

17:29 (<!! bar)

17:29 after those four steps (create two channels, create a go-block that _i think_ reads from foo and writes to bar, put something into foo, try to read something from bar) shouldn't I get 1 out of bar?

17:30 justin_smith: (>! x bar) tries to write the value bar to the number 1

17:30 the number 1 is not a channel

17:30 I think that code will work if you swap those args?

17:31 brb meeting

17:31 iwo: doh!

17:31 thank you

17:31 kwladyka: haha i found good algorithm https://github.com/VlachJosef/scalac-chess-problem but i don't understand it, beucase it is in scala

17:32 but is is super fast

17:38 iwo: I guess the next question is: is this a _good_ way of structuring things?

17:39 When you have a problem you're solving with core async, is it typical to create an in channel and an out channel for each of the steps, then create go blocks where each one takes from its 'in' and puts onto its 'out'? or is this a naive way of doing it?

17:40 Bronsa: uhm the invoke direct stuff doesn't seem to be working

17:42 either that or i'm not understanding how it's supposted to work

18:00 iwo: Is it correct to say that a go-loop is only ever processing one item at a time, and that to get some parallelism you have to create more than one 'instance' of the same go-loop?

18:18 gfredericks: oh man I think test.check just found a bug in goog.math.Integer

18:19 vas: How to prevent a function from writing to the console?

18:19 reiddraper: !!

18:19 Bronsa: gfredericks: what??

18:19 lazybot: Bronsa: What are you, crazy? Of course not!

18:19 gfredericks: so in cljs

18:19 you (:import [goog.math.Integer :as int])

18:19 then youn

18:19 (-> "100000000003000010002203003700000000000000049250000000" (int/fromString 10) (int/toString 36))

18:19 i.e., print the number in base 36

18:20 the result is "17urv5ewb6fhfemuk9dpv4o66lcmq-zh2bgg"

18:20 which it then fails to read back in because of the "-" there

18:20 vas: with-out-str or something similar

18:20 Bronsa: wow

18:20 gfredericks: would love for someone to confirm this

18:21 dnolen: interested if you have any insight ^

18:21 Bronsa: updating to cljs head and will try

18:21 gfredericks: I'm running 0.0-3308

18:23 dnolen: gfredericks: no insight :)

18:23 vas: gfredericks: thx

18:24 base 36 means... numbers 0-9 and then letters a-z, right? why is there a need for a "-" in base 36 if there are 36 characters in A-z0-9 ?

18:24 anyway, awesome find

18:25 gfredericks: vas: there isn't, that's the bug

18:25 dnolen: any guess how responsive the developers are to something like this?

18:26 dnolen: gfredericks: Closure Compiler are very responsive, never interacted with the Closure Library devs

18:26 gfredericks: roger

18:26 dnolen: both projects are very active though, constantly developed

18:26 gfredericks: good to know

18:27 this one will be fun to dig into if nobody else does it first

18:39 justin_smith: iwo: yes, one go block will process one item at a time - the idiom I use is a dotimes in which I launch N blocks (where N is of course a config)

18:42 gfredericks: weird, in my figwheel that returns a function taking bits, sign as parameters

18:42 gfredericks: uhms

18:42 justin_smith: yeah, I know, it's weird

18:43 gfredericks: I've wittled it down to a 15 digit number

18:43 or rather just rerun my tests a bunch

18:43 it's always base 36

18:44 s/15/10/

18:45 justin_smith: now I want to know why my int/toString is returning lambdas

18:45 so weird https://www.refheap.com/107228

18:46 gfredericks: justin_smith: oh you can't pass it a number

18:46 justin_smith: (-> "100" (int/fromString) (int/toString 36))

18:47 justin_smith: gfredericks: updated https://www.refheap.com/107228

18:47 still returns a lambda

18:48 gfredericks: okay that's goofy then

18:49 oh I get that too

18:50 so confused

18:52 * gfredericks lein clean

18:53 Bronsa: gfredericks: yeah i can't repro either. i get the same results justin_smith gets

18:53 gfredericks: what have I done

18:55 hiredman: obviously you shouldn't have mutated that prototype

18:56 gfredericks: okay I see

18:56 gee whiz

18:56 int/toString is a method

18:56 so use .toString instead

18:57 it's way too hot to be debugging things like this

18:57 so my smallest number now is 6501100000

18:58 (-> "6501100000" (int/fromString 10) (.toString 36)) ;; => "2-ziix40"

18:58 justin_smith: Bronsa: ^

18:58 Bronsa: gfredericks: yup

18:58 gfredericks: ,(-> 6501100000 biginteger (.toString 36)) ;; the right answer

18:59 clojurebot: "2zil4v4"

18:59 justin_smith: why does it think - should be part of a base 36 representation I wonder

18:59 gfredericks: justin_smith: it doesn't reading it back in with int/fromString fails

18:59 s/it doesn't/it doesn't,/

19:00 okay good I'm going to call it a bug

19:02 with an example that small I can probably just run a loop to find the smallest one

19:04 hiredman: you should evolve an ffpga to take a bit stream and tell you if it will trigger the bug or not, then try and figure out how the heck the ffpga does it

19:06 gfredericks: :)

19:25 TEttinger: ,6501100000

19:25 clojurebot: 6501100000

19:25 TEttinger: ,(int 6501100000)

19:25 clojurebot: #error {\n :cause "Value out of range for int: 6501100000"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 6501100000"\n :at [clojure.lang.RT intCast "RT.java" 1198]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1198]\n [sandbox$eval47 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6850]\n [clojure.lang.Compiler eval "...

19:25 TEttinger: gfredericks: you realize that using Long/toString would be better here?

19:27 oh this isn't java

19:27 this is js

19:27 * TEttinger needs to read whole backlog

19:31 arrdem: Bronsa and other Compiler.java readers... what exactly is ObjExpr for?

19:32 Bronsa: arrdem: think about tools.emitter's emit-class

19:33 arrdem: Bronsa: ok that's what I was afraid of.

19:34 Bronsa: arrdem: entry point for fn/reify/deftype emission + wrapping class fields emission (e.g protocol callsites, constants, etc)

19:37 arrdem: Bronsa: gotcha that helps thanks

19:39 Bronsa: i guess a better way to put it is it represent a clojure compilation unit

19:39 with all the common analysis and emission code required

19:50 celwell: Hello, is there a smarter pattern for checking values in a map for equality with some vars? I'm using this:

19:50 (and (= (:username config/basic-auth-admin) username)

19:50 (= (:password config/basic-auth-admin) password))

19:52 Bronsa: celwell: you could do something like (= [username password] (mapv config/basic-auth-admin [:username :password]))

19:52 not significantly better

20:40 reutermj: How do you call abiguous java constructors? I'm trying this (Texture. ^FileHandle handle), but I'm still getting the warning.

20:42 nevermind I didn't resync the source with my repl, sorry

20:42 justin_smith: reutermj: is it vararg?

20:43 oh, OK

20:43 reutermj: justin_smith: nah I was just dumb

21:22 guest9000: I'm having trouble with boot. I have an index file here resource/index.html, and js files are here target/js/app.js. How can I reference the js file from the html file?

21:26 justin_smith: guest9000: that's dependent on your http server configuration - where you set up your static root - normal thing would be to server up files in target/js/ at the top level, so you could just reference it as /app.js

21:27 guest9000: if using ring, there's a wrap-static middleware you can use

21:28 slester: dumb dumb question: how do I concat a keyword onto a collection of keywords? (concat my-list :keyword) breaks because it can't make ISeq from Keyword

21:28 wait, I want conj don't I

21:29 justin_smith: slester: concat is for when you have two sequences

21:29 slester: justin_smith: momentary idiocy, thanks haha

21:29 guest9000: justin_smith: thanks, I will look into it

21:30 slester: bbl! thanks again justin_smith

21:53 andyf_: Bronsa: Don't know if this is a Clojure 1.8.0-alpha3 bug, tools.analyzer.jvm bug, or something else, but certainly a change due to the combination of the two, from earlier versions of Clojure: https://gist.github.com/jafingerhut/008a283c6faac8905e9f

21:59 Bronsa: gah, connection failures

21:59 03:54:54 <Bronsa> andyf_: yeah it's a clojure change

21:59 03:55:21 <Bronsa> andyf_: defn now expands to (def foo ^{:rettag ..} (fn ..))

21:59 03:56:37 <Bronsa> still not really sure what that's about or what t.a.j should do about it, I don't plan on working on it until thing things are figured out on the clojure end

21:59 03:57:57 <Bronsa> I don't want to spend time trying to be alphaX-compatible while things are not yet stable/confirmed

21:59 andyf_: Understood. Thanks for checking.

22:00 I may also be seeing weirdness where tools.reader with 1.8.0-alpha3 is getting different line numbers reading the same file, vs. 1.8.0-alpha2. Will let you know if I get a small test case or figure it out.

22:02 Bronsa: andyf_: thanks. looks like the direct invoke changes and the (apparently unrelated?) type hinting changes broke a bunch of things so I wouldn't spend much time investigaing library issues until things are fixxed on the clojure side if I were you

22:02 andyf_: Hmmm.. Actually more likely to be Clojure's reader line numbers that changed.

22:07 facepalm. That part of what I was seeing was simply the change in core.clj from 1.8.0-alpha2 to -alpha3.

22:07 gfredericks: think I figured out the gclosure integer bug

22:09 andyf_: gfredericks: EBCDIC encoding?

22:10 gfredericks: andyf_: nope

22:14 https://github.com/google/closure-library/pull/498

22:17 andyf_: (inc gfredericks)

22:17 lazybot: ⇒ 143

Logging service provided by n01se.net