#clojure log - Dec 16 2015

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

0:00 rhg135: I finally got around to writing that irc defibrilator for lazybot

0:01 https://www.refheap.com/112745 too bad the documentation, lack thereof, is bad.

0:08 amalloy: speaking of which, i wrote a lazybot restart script

0:08 which works great when i run it by hand

0:08 but when cron runs it, it just kills lazybot

0:14 rhg135: in theory it should whois 'lazybot' dvdry hour and restart it. additionally it should launch it at start

0:14 I started in bash, but quoting is a mindf***

0:16 princeso: justin_smith: thanks. the problem is at compile time. i just want to know how the repl resolves the dependencies

0:19 then how to make all namespaces available in calls like (schema.core/validate ...) without the need of (require)

4:07 owlbird: ,(update-in {:name "alice"} () #(str "%" % "%"))

4:07 clojurebot: {:name "alice", nil "%%"}

4:08 owlbird: if the second parameter is empty, a new item with nil as key will be append to the result

4:08 why the 'update-in' was designed like this

4:34 ghost_: Hello, beautiful Clojuristas

5:29 justin_smith: princeso is gone, but the repl makes those things available via require :P

5:31 owlbird: the alternative would be to throw an error

5:46 TEttinger: I wonder when justin_smith sleeps... there seems to be a helpful presence in #clojure, like that helpful kami in japanese folklore that cleans houses when you aren't looking

5:47 justin_smith: haha

5:47 MJB47: its a bot

5:47 justin_smith: "when I sleep" is not often enough

5:54 ghost_: justin_smith is a rnn

5:55 TEttinger: radical neural network

5:56 ghost_: anyway, does someone of you guys know how to open my text app on windows?

5:56 in cmd or somethin

5:56 TEttinger: is it made in clojure?

5:56 you can make a runnable jar with lein uberjar

5:57 justin_smith: TEttinger: he wants it to launch inside a console

5:57 TEttinger: oh: java -jar mything.jar

5:57 justin_smith: TEttinger: but that won't launch inside a terminal when double clicked

5:57 ghost_: yes, it will "load" and then do nothing

5:57 TEttinger: javaw is what is used when double-clicking and it suppresses the terminal by default

5:57 Bronsa`: justin_smith: doesn't sleep, he just naps between netsplits

5:58 justin_smith: heh

5:58 powered: weren't runnable jars double-clickable in windows?

5:58 ghost_: TEttinger: so how to open it on windows? on linux, it works just fine

5:58 TEttinger: they are, they just don't have a console, powered

5:58 powered: ah yes

6:00 TEttinger: ghost_: one way that I can think of is to create a cmd window that runs the command 'java -jar whatever.jar'

6:00 and that is usually a bat file

6:00 ghost_: eww, that's awful

6:00 thank you bill_gates

6:01 TEttinger: well yes but the alternative is to create a cmd window and run your app again inside your existing clojure jar, adding on java startup twice

6:01 (which would work when double-clicking the jar)

6:02 there's the different jar to exe things that are more comfortable for many end-users

6:02 ghost_: run my jar within a jar? in cmd?

6:02 TEttinger: and those can have a cmd window specified

6:02 I could explain that I just don't think it's the best approach tbh

6:03 (the -main method would dispatch differently based on when called with no args for the double click vs. some special arg that it gives when it calls its own jar)

6:03 ghost_: pff, I'll check clojueclr then

6:04 TEttinger: not ideal either since none of the libs you use will work

6:04 well, none of the java libs

6:05 my personal recommendation is probably the launch4j or similar jar2exe program

6:05 ghost_: /reads a blogpost about dotnet being awful

6:05 uhm, I'll stay with java

6:05 I'll check 'em, thanks

6:05 and I use none of the libs :^)

6:07 TEttinger: yep, http://launch4j.sourceforge.net/index.html Supports GUI and console apps.

6:08 ghost_: soo, it creates an .exe?

6:09 Glenjamin: there's also that capsule thing?

6:09 schmir: ghost_: yes, .exe

6:09 ghost_: schmir: that rocks

6:10 and it's the best IRC ever

6:10 schmir: ghost_: and shell scripts on unix

6:10 ghost_: schmir: like these written in bash?

6:10 owlbird: write a bat file for windows, and exec java -jar

6:11 ghost_: damn that's good

6:13 TEttinger: Glenjamin: I'll take a look

6:15 Glenjamin: interesting, but doesn't seem to solve this problem. good to know about though

6:22 ghost_: by the way, what is the difference between jars in uberjar and uberjar+uberjar dirs?

7:24 justin_smith: ghost_: what is an uberjar+ubarjar dir?

7:28 ghost_: justin_smith: classes dir, stale dir, snapshot.jar

7:29 justin_smith: so you are asking about all the things in target/ ?

7:31 ghost_: yeah, basically

7:31 justin_smith: the class files are created as part of producing the jar, and the jar is produced as part of creating the uberjar

7:32 ghost_: justin_smith: oh, okay

7:33 and I *have* to have jre on my machine? I can't produce a "standalone" executable?

7:33 justin_smith: ghost_: clojure generates jvm bytecode, it doesn't produce a regular executable

7:34 the closest you can get is a special executable that contains its own jvms

7:34 and then it has to have a jvm inside for every OS that can run it

7:34 it's easier to just expect each user to have a jvm

7:36 ghost_: o-kay, thanks

7:46 jweiss: in core.async/alts! if one of my operations puts nil on channel it seems to not be selected, which is nice, but i don't see that documented anywhere. is that intended behavior?

7:46 justin_smith: jweiss: doesn't putting nil on a channel close it?

7:47 jweiss: justin_smith: the docs for >! says "nil is not allowed", i don't know what that means exactly

7:47 it doesn't say what happens if you do it. undefined behavior?

7:48 if i try to take from that channel with <!! it just blocks, i think if it's closed it returns nil, doesn't it?

7:50 justin_smith: jweiss: so it looks like returning nil from a go block closes that go blocks channel, but you cannot generally close a channel by putting nil on it

7:51 that was the source of my confusion

7:51 jweiss: (let [c (async/chan 1)] (async/go (async/>! c nil)) (async/<!! c))

7:51 that blocks, so it acts as if putting nil is a no-op

7:51 justin_smith: jweiss: I was talking about (<!! (go nil))

7:51 which returns nil

7:52 jweiss: ok, my question is whether it's safe for code to sometimes put nil on a channel

7:52 justin_smith: but nil from a go block does not generalize to putting nil on a channel

7:52 I'm not sure

7:55 ghost_: hey, justin_smith: what do people use clojure for? I've only heard of "web stuff", I haven't seen any killer web app yet though

7:55 jweiss: justin_smith: in this case i don't care about the result of the go block

7:55 justin_smith: jweiss: yeah, I only brought up go block values because that's the one case where putting nil on a channel simply closes it

7:56 powered: how about you put :nil on it and check for that?

7:56 jweiss: well,i guess i'll just proceed as if this is legal and see what happens :)

7:56 justin_smith: but it's not a direct put, it's an incidental put done by go, which I guess behaves differently than an explcit one

7:56 powered: ::done is a good convention for that

7:57 ghost_: I use it to make a SaaS webapp with a distributed computation backend

7:57 powered: :: takes the current namespace?

7:57 justin_smith: ghost_: I don't know about "killer" but it allows a small team to get a lot done quickly and not code ourselves into a corner

7:58 jweiss: powered: yes

7:58 justin_smith: powered: it's a shorthand for :this-ns/foo

7:58 ,::foo

7:58 clojurebot: :sandbox/foo

7:58 justin_smith: powered: in general, for "magic values" it's better to use the namespaced version

7:59 powered: but wouldn't a check in a different namespace fail (= keyword ::foo) ?

7:59 justin_smith: powered: right, but the point of ::done is that it is a magic sentinal value, that only your code in that specific place cares about

8:00 powered: so it should only be used in that namespace, ok

8:00 ghost_: justin_smith: your job or open source?

8:01 justin_smith: powered: I mean this is making a lot of assumptions - I'm just saying this is a common way of doing things - and yeah usually it would be a namespaced keyword since it's a magic value in that specific context

8:01 powered: but you can make namespaced keywords from anywhere, if you know which one is being looked for

8:01 ,:whatever/which

8:01 clojurebot: :whatever/which

8:02 justin_smith: ghost_: if you know of paid work to do clojure on an open source repo let me know! but no, it is not - it's a software as a service so open source would kind of be counterproductive to getting a paycheck

8:03 we release open source libs, but the app is closed

8:03 ghost_: can you link it?

8:05 justin_smith: ghost_: the app? or the open source libs?

8:06 ghost_: justin_smith: both

8:06 justin_smith: our open source stuff is here https://github.com/littlebird our app is here http://www.getlittlebird.com/

8:07 ghost_: sweet name :D

8:07 justin_smith: ghost_: that client list is partial - there's some big companies that won't let us say they use our app :P

8:07 http://www.getlittlebird.com/customers

8:07 ghost_: justin_smith: comcast? TIL you're evil

8:08 justin_smith: haha

8:08 ghost_: if only you could see the rest of our clients, hah

8:09 I mean it's an app for marketers, so it's damned from the start, right?

8:09 ghost_: justin_smith: satan, shkreli and church of scientology?

8:10 justin_smith: close enough

8:10 ghost_: D:

8:11 spacepluk: is there a cleaner way to write this? https://gist.github.com/spacepluk/70a0e9fbd152073828ff

8:11 I've been checking cond-> and friends but I'm not sure they help readability

8:14 justin_smith: spacepluk: (as-> state s (action-events {:action "stop-session"}) s) (assoc s :session (session s (:params action))) (add-events s [(session-start s)]))

8:14 it looks better when it's not all on one line

8:15 spacepluk: justin_smith: thanks! that's perfect

8:15 justin_smith: spacepluk: as-> literally expands to that kind of let block where you have the same symbol on the left hand side every time

8:57 sdegutis: Anyone know an ETA on Clojure 1.8?

8:58 beaky: jrllo

8:58 how does parsing in clijure

8:58 compare to parsing in haskell

8:58 is it just as easy

8:58 or is it a nightmare

8:58 (like parsing in C is)

8:59 puredanger: sdegutis: new rc should be coming soon

8:59 sdegutis: Yay!

8:59 Thanks puredanger :)

8:59 puredanger: I'm most of all looking forward to the built-in socket thing.

8:59 beaky: whats that

8:59 sdegutis: beaky: parsing in Clojure is the same as in any other language

9:00 justin_smith: sdegutis: I'd say it's easier to use instaparse than it is to use a C parsing lib at least

9:01 beaky: ah

9:01 whats instaparse

9:01 is ti like instagram but for parsers

9:01 powered: it's a parsing library

9:01 beaky: oh

9:01 justin_smith: it's based on the popular haskell one iirc

9:02 sdegutis: justin_smith: well along with the language you have to take into account the tools, e.g. lex & yacc &c.

9:02 beaky: exactly. it's like instagram but for parsers.

9:02 justin_smith: sdegutis: have you actually used lex and yacc? I'd say instaparse is easier

9:02 sdegutis: justin_smith: I have not.

9:03 justin_smith: anyway I plan to write my own lua-like language in 2016, entirely in C (no yacc/lex etc) so I'm very excited about taht

9:17 mpenet: I second instaparse, it's a wonderful lib

9:21 oracle: how to pass a vector to a parameter list?


9:21 (j/execute! db ["update tab set a=? ,b=?,c=?", my-vector-for-a-b-d])

9:22 for that code, it actually need three parameters.

9:22 but I have the parameters stored in a vector. Must I unpack the vector? if so that ugly.

9:23 powered: can't you concat it?

9:24 justin_smith: oracle: apply

9:24 powered: concat would be the opposite

9:24 oracle: cancat what? The expected code should be like ["my-sql-string", p1,p2,p3]

9:25 justin_smith: oracle: (apply j/execute! db ...)

9:25 oracle: but I have a value of [p1,p2,p3]

9:25 justin_smith: that way you don't need to unpack

9:25 sdegutis: Hmm, org.clojure/clojurescript 1.7.189 may be broken, it fails to load because it can't find clojure/tools/reader/impl/ExceptionInfo.clj even when I have org.clojure/tools.reader in my deps.

9:25 oracle: let me try

9:25 apply doesn't work here

9:25 justin_smith: oracle: why not?

9:26 ,(apply + 1 2 [3 4 5])

9:26 clojurebot: 15

9:26 oracle: because apply only work for the last parameter as vector

9:26 but there it last paramter is ["sql", p1,p2,p3]

9:27 (j/execute! db ["update tab set a=? ,b=?,c=?", p1,p2,p3])

9:27 powered: then (concat ["sql"] args)

9:27 justin_smith: oracle: oh, the three params need to be inside the vector?

9:27 oracle: that the correct code

9:27 Oh, looks that works, let me try

9:28 justin_smith: (j/execute db (into ["update tab set a=?, b=?, c=?"] coll))

9:28 I guess concat works too

9:28 oracle: yeah... it works

9:28 thanks. clojure is so cool!!!

9:28 powered: seqs vs vectors still scare me because sometimes it appends and sometimes it puts it at the start

9:29 justin_smith: powered: vectors always conj to the end, seqs always conj at the start

9:29 sets conj everywhere

9:29 ,(into #{} :a :b :c :d)

9:29 clojurebot: #error {\n :cause "Wrong number of args (5) passed to: core/into"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (5) passed to: core/into"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 48]\n [sandbox$eval49 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval49 in...

9:29 justin_smith: ergh

9:29 powered: apply!

9:30 justin_smith: ,(into #{} [:a :b :c :d])

9:30 clojurebot: #{:c :b :d :a}

9:30 justin_smith: powered: you should use into instead of apply conj - because into uses transients

9:32 powered: transients are fast?

9:32 justin_smith: typically they are faster, yeah

9:33 oracle: anybody using sql againt postgresql inside clojure?

9:33 It throws the exception of Unhandled java.sql.BatchUpdateException


9:34 powered: oracle you could also ask at #postgresql

9:34 oracle: But If I post sql in the message to run against postgreslq, it work

9:34 justin_smith: oracle: yes, I use it extensively

9:34 powered: why name yourself oracle when you use postgresql

9:35 oracle: hehe, I previously use oracle,

9:35 geirby`: lol, my thoughts exactly :)

9:35 oracle: good guess.

9:35 The issue looks like in postresql command window, it could convert string to int or int to string automatically.

9:36 but if using jdbc clojure, it just failed.

9:36 powered: postgresql doesn't do implicit casting unlike oracle

9:36 oracle: And it doesn't throw the right message.

9:36 luma: what is the error message?

9:37 oracle: I think it did casting in postgresql. I am using pgAdmin III. the sql works in that tool. but doesn't work in jdbc clojure

9:37 powered: does it fail before execution?

9:38 oracle: failed in jdbc.

9:38 luma: what is the error message?

9:40 oracle: I am using (.getNextException e) to get the exception message

9:41 :No operator matches the given name and argument type(s). You might need to add explicit type casts.


9:41 luma: yes, your data types are wrong

9:41 oracle: But it didn't tell me which column name.

9:42 ok, I don't ask future, since it doesn't related to clojure. thanks very much.

9:42 luma: well, check the type of your input values and the types of the database tables and see which one doesn't match

9:42 database columns*

9:43 oracle: yes, I am doing it.

9:43 powered: sounds like a postgresql error though

9:53 oracle: Anybody used clojure webdriver?

9:54 it set a thread level variable. So in each thead we don't need to specify the driver.

9:54 but if use with core.async, looks like it will broken, right? since core.async does'nt bind to a sepcific thread.

9:58 justin_smith: oracle: core.async puts your code into a thread pool, so yes, thread bound things don't work nicely with that

9:59 oracle: though instead of (go ...) you can use (thread (binding [db my-driver] ...))

10:00 because thread is like go, but it doesn't use the thread pool- it uses a new thread

10:05 oracle: but could I set the drive in function fun1, then call (go (fun1 (<! my-chan)))

10:05 will that work?

10:05 will fun1 be run on only one thread?

10:05 justin_smith: yes, of course

10:06 it's only the channel operations that get distributed in the thread pool

10:06 oracle: ok, then that should work If I binding the variable at the start of fun1.

10:06 got it.

12:33 pdpi: Hey, I’m having issues with adding a :local-repository to my project, where I just get “java.io.FileNotFoundException: Could not locate clojure/data/json__init.class or clojure/data/json.clj on classpath.”

12:46 justin_smith: pdpi: adding the repository does not put any artifacts in that repository on your classpath

12:46 pdpi: justin_smith: sorry, clarification: the problem is that _everything else_ stops being available.

12:46 justin_smith: pdpi: you add repositories so it knows where to find jars, you declare dependencies so that it will have those jars on the classpath at runtime

12:46 pdpi: how did you declare the clojure.data.json dependency?

12:48 pdpi: :dependencies [[org.clojure/data.json "0.2.6"]]

12:49 actually, I didn’t.

12:49 but it built fine until I added the local repo

12:49 I was reading that line off another project.clj

12:49 huh.

12:50 now that I added it works fine. Guess it was just grabbing it from the “normal” local repo without it being declared. Thanks!

12:57 ghost__: Have anyone here used launch4j?

14:48 favetelinguis: just fond sente library but im to retarded to get the example project even running, anyone that uses sente and can give me some hints?

14:48 justin_smith: favetelinguis: is this the first time you've used clojurescript?

14:54 favetelinguis: not rly, been playing around with it before, the problem i have is what to do with the example project to get it running so i can view it in a browser and start playing with it, i have used figwheel and lumminus for this before but here there is cljx...

14:56 justin_smith: favetelinguis: cljx is deprecated, but info on how to use it is here https://github.com/lynaghk/cljx

14:56 if you have the repo set up to use it, it should be straightforward

16:13 jamesfordummies: why does (spit FILE (doall (str/join "\n" (list (now) people (rotate chores)))) write clojure.lang.LazySeq@52bb721

16:16 BRODUS: can someone give me a hint a to why this code isn't evaluating correctly: http://pastebin.com/n2jvQ3iJ , i'm stumped

16:19 amalloy: symbols are different from vars

16:19 '/ is not division

16:20 BRODUS: ah

16:27 justin_smith: jamesfordummies: (doall (str/join ...)) doesn't do anything - doall is for forcing lazy seqs to realize, it doesn't do anything to strings (and even if you had doall around the lazy seq inside, it wouldn't change the type to not be lazy-seq or change how it is printed)

16:27 jamesfordummies: justin_smith: i see

16:27 justin_smith: jamesfordummies: the issue is that calling str on a lazy-seq does not show the contents

16:28 jamesfordummies: where is str being called? inside something i’m calling?

16:29 justin_smith: jamesfordummies: string/join calls .toString or str I forget which, and I should have specific .toString above (it's just that in clojure code that's how it's usually used so I get used to that shorthand)

16:29 jamesfordummies: justin_smith: so how can I force force strictness? and where?

16:29 justin_smith: ,(str (rotate "abc"))

16:30 clojurebot: #error {\n :cause "Unable to resolve symbol: rotate in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: rotate in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: rotate in t...

16:30 jamesfordummies: i defined rotate

16:30 justin_smith: jamesfordummies: it's not about the strictness, it's about the type

16:30 jamesfordummies: ah… ok

16:30 justin_smith: even if it's fully realized, the .toString for lazy-seqs kind of sucks

16:31 ,(str (map inc (range 10)))

16:31 clojurebot: "clojure.lang.LazySeq@c5d38b66"

16:31 jamesfordummies: which part of my code is a lazyseq?

16:31 justin_smith: ,(pr-str (map inc (range 10)))

16:31 clojurebot: "(1 2 3 4 5 ...)"

16:32 justin_smith: jamesfordummies: either now, people, or rotate is giving you a lazy-seq - I can't tell you which with the info we have :)

16:32 notice the difference between pr-str and str above

16:34 jamesfordummies: justin_smith: i see… ok one second

16:35 justin_smith: (defn rotate [chores] (concat (rest chores) (list (first chores))))

16:43 justin_smith: ,(class (concat [1] [2]))

16:43 clojurebot: clojure.lang.LazySeq

16:43 justin_smith: jamesfordummies: there's your lazy seq

16:43 jamesfordummies: ;_;

16:44 justin_smith: jamesfordummies: you could change it to (conj (vec (rest chores)) (first chores))

16:44 ,(let [chores [1 2 3]] (conj (vec (rest chores)) (first chores)))

16:44 clojurebot: [2 3 1]

16:45 justin_smith: ,(let [chores [1 2 3]] (conj (subvec chores 1) (first chores)))

16:45 clojurebot: [2 3 1]

16:45 jamesfordummies: hm ok

16:45 justin_smith: (the second one there is faster, but only works if chores is a vector)

16:46 jamesfordummies: alternatively you could replace (rotate chores) with (pr-str (rotate chores)) in the code that does the output

16:47 jamesfordummies: justin_smith: thanks so much dude

16:48 justin_smith: np, glad I could help

17:02 jabb: is there an idiomatic way to do a loop over a range

17:02 the one i wrote took 138 seconds compared to C's 3

17:03 (doseq [i (range 1000000)] (println i)) takes 138 seconds, for (int i = 0; i < 1000000; ++i) printf("%d\n", i); takes 3

17:03 justin_smith: jabb: for side effects or to build a result?

17:03 jabb: both

17:04 justin_smith: yeah, doseq is as good as clojure will offer there, sadly. You might want to use some alternative to println that doesn't call flush after every call? might help

17:04 1/20th the speed of C sounds about right for that kind of operation

17:04 jabb: a simple for loop?

17:04 hmm

17:05 slester: are you timing the actual loop part or the printing too?

17:05 justin_smith: with doseq the printing is the loop

17:05 it won't process the next line until the previous is flushed

17:06 I think C has something slightly more elegant

17:06 slester: I guess just wondering if the hold-up is printing

17:06 justin_smith: I should say with c / println the printing is the loop

17:07 jabb: I believe C flushes on newlines

17:07 so printf("\n") flushes

17:07 python's "for i in xrange(1000000): print i" takes 4.5 seconds

17:07 justin_smith: jabb: is this explicitly done by printf or is it just leaning on console adaptor behavior there?

17:08 jabb: might be console adaptor

17:08 ridcully_: iirc stdout is not flushed?

17:09 justin_smith: jabb: btw that doseq takes 20 seconds on my machine

17:10 jabb: are you running inside emacs or something?

17:10 jabb: lein repl

17:10 justin_smith: jabb: my 20 second time is inside java -jar clojure.jar

17:10 jabb: justin_smith: try a C function

17:11 justin_smith: jabb: 31 seconds inside lein repl

17:12 ridcully_: java -cp clojure.main -e '(doseq [i (range 1000000)] (println i))' 3.68s user 0.76s system 71% cpu 6.239 total

17:12 justin_smith: jabb: a.out takes 3 seconds

17:13 ridcully_: woah, why was yours so much faster?

17:13 ridcully_: 3s is xterm rendering all that nonsesense ;)

17:14 justin_smith: i was using clojure 1.8.beta2 with jdk8

17:14 jabb: justin_smith: echo 'int main(void){for(int i=0;i<1000000;++i)printf("%d\n",i);}' > /tmp/m.c && gcc /tmp/m.c -o /tmp/m && time /tmp/m

17:14 justin_smith: jabb: yes that is what I ran

17:14 3 seconds

17:15 jabb: wonder why mine is taking 138s

17:16 justin_smith: ridcully_: ahh! when I run inside the repl, it's counting the time printing, when running java under the time command it's more forgiving about the time the terminal spends printing so it gives a lower reported number

17:21 ridcully_: jabb: are you printing this all out? with that 138s timing?

17:21 justin_smith: ridcully_: in the shell (time (println (:out (clojure.java.shell/sh "./a.out")))) reports that it takes the same amount of time - about 20 seconds

17:21 jabb: ^

17:21 ridcully_: jabb: can you try with just redir to /dev/null?

17:21 justin_smith: err, s/shell/repl of course

17:21 so it looks like the bottleneck is the jvm and/or clojure's stdout handling

17:21 ridcully_: i use an 100lines xterm with bitmap font. that reduces rendering times _alot_

17:22 justin_smith: ahh, that would yeah

17:22 good old bittymaps

17:22 ridcully_: I use /dev/null - that prints even faster!

17:22 heh

17:23 ridcully_: dev/null is about 3s for clj and 0.06 for c

17:23 justin_smith: still about 20x, funny

17:23 no, that's more like 40x

17:24 ridcully_: but utilizes 150% cpu

17:26 justin_smith: jabb: one thing to note here is that lein repl isn't just a process using a tty - it's a process sending output in a high level format on a TCP socket, another one parsing and consuming that format (with middleware etc. applied) and then finally printing to the tty

17:26 jabb: just switching from my clojure.jar to a lein repl took execution time from 20 secs to 30 secs

17:29 ridcully_: rlwrap vanilla repl: 17s, lein repl 49s

17:29 justin_smith: ridcully_: sounds like you might have some heftier middleware than I

17:29 (in terms of raw io throughput at least)

17:30 ridcully_: pretty could be a culprit?

17:30 justin_smith: ridcully_: ahh - I was running with -server

17:30 or that

17:30 yeah

17:30 by default lein turns off hotspot, which should kick in on a loop like that, but I override that to make sure hotspot is on in my repl

17:31 ridcully_: so that could also be a difference

17:31 ridcully_: that was a rlwrapped clojure.main 1.7 and a no-project.clj lein repl 1.7 - both jdk8

17:32 justin_smith: oyeah, in a no-project lein you will have hotspot turned off

17:32 ridcully_: in my lein config is vinyasa, pretty, eastwood, cljfmt, cider, slamhound, cider

17:33 i guess pretty could be a candidate and maybe cider?

17:35 justin_smith: yup

17:36 but I really think hotspot being turned off would be a big diff too

17:36 ridcully_: well... i dont plan to print millions of lines right now. so i rest my investigations now ;)

17:36 justin_smith: heh

17:40 benjyz1: hi. I'm working with sync sockets and trying to create a thread for each socket

17:40 I mean normal sockets, not NIO

17:41 https://www.refheap.com/112775

17:43 justin_smith: benjyz1: does (handler socket) return a callable function?

17:43 benjyz1: perhaps you want #(handler socket)

17:44 benjyz1: I'm not sure about the constructs I'm using

17:44 justin_smith: benjyz1: what I suspect is happening now, is that (handler socket) is called in the current thread, the return value is passed to the Thread constructor, and it's not callable

17:44 so the new thread crashes, and everything is done in the thread of that while loop

17:45 devtrope: Add an uncaught exception handler to find out? ;)

17:45 justin_smith: benjyz1: normally handler is not a function taking a connection as an arg and returning another function - try changing (handler socket) to #(handler socket)

17:45 because Thread. definitely needs something runnable as its arg

17:45 and #() is runnable

17:45 benjyz1: one issue is I'm trying to store state about the connections as well

17:45 justin_smith: benjyz1: sure, but that's not likely the bug here

17:46 if handler returns anything other than a function of 0 args, that code is broken

17:46 benjyz1: yes, "#" fixed this

17:46 justin_smith: cool, now you can worry about storing state :)

17:47 benjyz1: I've looked at aleph and netty

17:47 justin_smith: aleph is pretty cool

17:47 benjyz1: and zeromq, but I'm doing it the hard way now

17:47 because I'm not worried about performance at the moment

17:48 justin_smith: benjyz1: I've really enjoyed working with kafka

17:49 it's got a nice flexible way of doing many->one one->may or one->one

17:50 benjyz1: wondering whether it would make sense to have a map for all connections

17:52 justin_smith: what would you do with that map?

17:53 benjyz1: the simple issue I have now is, if client sends a disconnect message, then I want to set run flag to false

17:54 so i have a run atom, but I need that for every connection

17:57 justin_smith: or a map in an atom, with a key for each handler that's been started?

17:57 yeah, makes sense

17:58 benjyz1: I'm trying to isolate a few patterns, as you say. request-reply, publish-subscribe

17:58 justin_smith: benjyz1: an elegant option would be to create an agent instead of using Thread, and put the agent in a set or vector in an atom. Then the agent will end up holding the return value of the handler once it returns.

17:59 so first set the agent to ::pending, then send it the job of handler on the new connection, so its value will be ::pending until it returns some value

17:59 (until the handler returns its new value, that is)

18:00 benjyz1: there is several things I want to do with the duplex-stream. not quite sure

18:00 justin_smith: fair enough

18:00 there are definitely options

22:00 kenrestivo: how would i swap columns and rows in a matrix in an idiomatic way?

22:00 ooh wait, i think i remember, apply map or something...

22:01 apply map vector IIRC

22:03 Seylerius: kenrestivo: Yep

22:04 kenrestivo: that's so slick.

22:31 gfredericks: okay this bug is quite a doozie

22:31 I get a ClassNotFoundException when running `lein test`

22:31 sounds vanilla so far

22:31 but I only get it with lein 2.5.3, not 2.5.2

22:32 and I just checked and both versions give identical output to `lein classpath`

22:32 so there is something very spooky here

22:32 I think :eval-in :pprint is the next step

22:36 kenrestivo: that's a weird one

22:36 this is probably the ugliest rube-goldberg device i've ever stacked together, but hey, it works: https://www.refheap.com/112781

22:37 (that's to transform a calendar in one format to a different format for hiccup/html displaying... and there's more on the hiccup side)

23:07 gfredericks: okay apparently my problem is something like :resource-paths ["lib/*"]

23:08 in 2.5.3 leiningen sees that and decides to create a directory called lib/*

23:08 does anybody know if leiningen supports this pile-of-jars-classpath-entry in any other fashion?

23:10 amalloy: downgtade to lein 1.x of course

23:11 gfredericks: :)

23:11 will probably just use 2.5.2 as the workaround for now and figure out how to get away from the pile of jars later

23:45 hiredman: gfredericks: well, you can use unquote to run code to list the jars in lib

23:46 ~(for [jar (.listFiles (io/file "lib/"))] (.getAbsolutePath jar))

23:46 clojurebot: No entiendo

23:46 hiredman: clojurebot: jerk

23:46 clojurebot: you cut me deep, man.

23:54 lambda-11235: clojurebot: No habla español

23:54 clojurebot: Huh?

23:54 lambda-11235: clojurebot: No habla espanol

23:54 clojurebot: Gabh mo leithscéal?

Logging service provided by n01se.net