#clojure log - Dec 07 2015

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

1:20 kenrestivo: is there any way to make networking code less... ugly? i wrote this but i hate it: https://www.refheap.com/112427

1:21 it's for a component. it seems like a tangled unreadable mess. but i can't think of any other way to do it.

1:28 tolstoy: Hm. I wonder if Aleph's client libs would help.

1:28 kenrestivo: it might, though it has its own complexities

1:29 my end goal here is a component that wraps mqtt in core.async

1:29 tolstoy: Are you working with activemq?

1:29 kenrestivo: mosquitto in this case

1:29 tolstoy: Oh, right. Okay

1:30 Hm. When I used to do this using actors, I'd have one actor that represented the connection, and another "linked" actor that was the supervisor.

1:30 When the connection actor threw an exception and died, the "link" mean that the supervisor actor got the message and could restart.

1:30 So, I wonder if you could do something similar?

1:31 kenrestivo: hmm, that might work.

1:31 tolstoy: On "go-loop" that manages the connection. If there's an error (.isConnect conn) or something, it drops a message in the "super" channel, then does.

1:31 The super channel just waits for that message and tries a reconnect.

1:32 kenrestivo: i like that, thanks.

1:33 tolstoy: Decomplects connection stuff from supervisor stuff? Gotta be some Clojury conference-circuit way of phrasing it.

1:34 mqtt seems kinda neat.

2:46 copycat: what does this look like? i'm not sure how to visualize this

2:46 (vec (map vector

2:46 (map + (range length) (repeat xpos))

2:46 (repeat ypos))))

3:03 visof: ,(merge-with conj {:hello {:x 1 :y 3 :other [4 5 6]}} {:hello {:x 3 :y 1 :other [3]}})

3:03 clojurebot: {:hello {:x 3, :y 1, :other [3]}}

3:04 visof: how can i merge values of the same keys to a list

3:04 to be {:hello {:x [1 3] :y [3 1] :other [[4 5 6] [3]]}} ?

3:04 TEttinger: ,(merge-with list {:hello {:x 1 :y 3 :other [4 5 6]}} {:hello {:x 3 :y 1 :other [3]}})

3:04 clojurebot: {:hello ({:x 1, :y 3, :other [4 5 6]} {:x 3, :y 1, :other [3]})}

3:05 TEttinger: wait no that's awful :)

3:05 opqdonut: you need deep-merge-with

3:05 TEttinger: ,(merge-with list {:hello {:x 1 :y 3 :other [4 5 6]}} {:hello {:x 3 :y 1 :other [3]}} {:hello {:x 2 :y 2 :other [1 5]}})

3:05 clojurebot: {:hello (({:x 1, :y 3, :other [4 5 6]} {:x 3, :y 1, :other [3]}) {:x 2, :y 2, :other [1 5]})}

3:06 TEttinger: that's why that's awful

3:06 opqdonut: yeah

3:07 visof: ,(deep-merge-with conj {:hello {:x 1 :y 3 :other [4 5 6]}} {:hello {:x 3 :y 1 :other [3]}})

3:07 clojurebot: #error {\n :cause "Unable to resolve symbol: deep-merge-with in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: deep-merge-with 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 s...

3:07 visof: is it at other lib

3:07 opqdonut: I don't know

3:07 I've defined it myself

3:08 might be in some library with some other name

3:08 but conj is wrong anyway

3:08 or it's ok if you get the empty sequences from somewhere

3:08 e.g. like this:

3:09 ,(merge-with conj {:x [] :y []} {:x 1} {:x 2 :y 3} {:x 3 :y 4})

3:09 clojurebot: {:x [1 2 3], :y [3 4]}

3:09 visof: opqdonut: ah ok

4:04 dxtr_: hi

4:05 is "the joy of clojure" still up to date? or should i be looking at some other book to get started?

4:11 ARM9: it's still mostly up to date, it probably still recommends that "use" be used instead of recommending require

4:16 tolstoy: On a recent podcast, Stuart Holloway mentioned that all the code in his pre-1.0 Clojure book still runs.

4:17 tdammers: as in, he fired up a repl and loaded the code, and that repl is still running?

4:24 Glenjamin: joy of clojure 2nd edition is less than a year old i think

10:35 njorth: gp /st

10:48 ToxicFrog: So, here's a question I haven't needed to ask in ages, such that I've forgotten the answer

10:48 What's the easiest way to just write a one-off .clj script and shebang it?

10:49 lein doesn't seem to have a "lein run-script" command

10:52 tdammers: not usually viable, startup time tends to be prohibitive for this kind of thing

11:02 schmir: ToxicFrog: https://github.com/boot-clj/boot/wiki/Scripts

11:03 ToxicFrog: schmir: that's specific to having the Boot tool installed

11:04 It looks like the answer I actually want is: exec java -cp ~/.m2/repository/org/clojure/clojure/$VER/clojure-$VER.jar clojure.main "$@"

11:04 And then stuff that in a script I can put in the #!

11:05 tdammers: it turns out that when not using lein, startup time is dramatically reduced

11:05 Still not something I'd want to use with, say, find -exec, but Good Enough for some things.

11:10 Sigh.

11:11 "java.lang.Boolean cannot be cast to clojure.lang.Symbol, compiling:(.../2.clj:1:1)"

11:11 The first four lines of this file are comments.

11:15 Hmm.

11:15 (repeatedly read-line) looks like a good way to get a line-seq from *in*, since you can't just (line-seq *in*)

11:15 But it NPEs on EOF.

13:20 visof: hi guys

13:26 i code method which take some time, but i want to make it processed in the background and then run another fast code, i make this (do (future (long-time-method)) (short-time-method))

13:26 and i still get longer time

13:27 i just wnat long-time-method run in background and skip to short-time-method

13:27 rhg135: There is overhead, but how much longer?

13:34 visof: rhg135: what do you mean with how much longer?

13:35 beaky: i have crap shoulders, tspine, and squat mobiltiy

13:35 oops wrong channel

13:37 rhg135: visof: spinning up a thread incurs overhead from scheduling. Usually it should just be a few ms per thread. Also your code seems correct.

13:39 visof: rhg135: is there a method to do this in a more efficient way, what if my long-time-method take 1 min, i and don't want the user wait this time

13:42 justin_smith: visof: the do block takes the amount of time to dispatch the future, plus the time of short-time-method - the run time of long-time-method will not affect it unless long-time-method is heavy enough to lock up basically your whole computer

13:42 rhg135: It depends. In languages without threads you would use callbacks

13:43 But that's not a good fit sometimes

13:44 justin_smith: callbacks are about coordination, not processing - a callback might run on a different thread, it might run on the same thread

13:47 rhg135: justin_smith: I'm assuming callbacks being independent from threads here

13:48 In practice, not usually

13:51 Oh right. Yes, justin_smith is correct. I don't know what I'm thinking

13:52 You can't do parallel execution on the jvm without threads

13:53 justin_smith: callbacks are good if you don't have threads and still have things that need to be done concurrently, or if you need to let some other part of the system have the control of the timing or conditional execution of your code

13:55 rhg135: They're great except for the inversion of control

14:44 fuddu-coder: i have a collection of java objects. what would be the best way to figure out distinct objects in the collection based on certain fields

14:44 the fields would be extracted through interop ofcourse

14:45 ,(+3 4)

14:45 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6943]...

14:45 justin_smith: fuddu-coder: maybe something like (group-by #(.foo %) objects)

14:45 ridcully: ,(+ 3 4)

14:45 clojurebot: 7

14:47 fuddu-coder: justin_smith: true. but i would liek to have a combination of fields determine the distinctness. does that make sense

14:47 *like

14:47 justin_smith: fuddu-coder: hmm so would you want one map where you look up based on the set of fields they have, or one grouped map for each field, or?

14:48 fuddu-coder: one map where you look up based on the set of fields they have

14:48 ridcully: or type

14:49 justin_smith: so make set-of-fields - a function that takes an object and returns a set of relevant fields

14:49 ridcully: could you elaborate on what the differences are there?

14:49 justin_smith: then group-by set-of-fields

14:50 fuddu-coder: yup. that would be one way to go.

14:52 sdegutis: Clojure's first commit: https://github.com/clojure/clojure/commit/894a0c81075b8f4b64b7f890ab0c8522a7a9986a

14:52 justin_smith: fuddu-coder: seems the simplest thing - then you could derive "all objects with field X" by filtering the keys for that field and merging all vals the keys match

14:54 ARM9: sdegutis humble beginnings

15:08 sdegutis: ARM9: aint it ho

15:08 *tho

15:09 TimMc: In the beginning there was a cons cell, a symbol, and scope.

15:13 sdegutis: And a single namespace?

15:14 Can someone ELI5 Rich's hair? https://github.com/richhickey

15:14 is that a NY thing or something?

15:15 ARM9: looks ready to party like it's 1984

15:17 TimMc: There is no need to explain. His hair is amazing and that is all.

15:19 He probably takes the same appoach to fashion I do: Pick a style and let it come around again and again. :-D

15:36 sdegutis: TimMc: haha that's too much work

15:36 clojurebot: Huh?

15:36 sdegutis: TimMc: my approach is to just shave my head every 2 weeks; never have to worry about styling it, and shampooing it is way easy&quick

15:37 plus its not too hot in the summer this way; and in the winter i can just wear a hat. done.

15:39 TimMc: Oh, I meant overall style, not just hair... but I keep my hair in a ponytail for a similar reason. Very little work.

15:39 sdegutis: oh

15:39 haha yeah

15:39 nice

15:40 TimMc: But really I find very little profit to be had in analyzing people's appearance...

15:43 However, I will criticize the heck out of his use of whitespace.

15:45 amalloy: "use" is a strong word. reading compiler.java it sometimes seems like his keyboard is just on the fritz

15:46 Bronsa: it's just postmodern indentation

15:47 TimMc: I wonder if that's what happens when you try to write Java in emacs without good indentiation settings and you're just fighting the mode the whole time.

15:47 Bronsa: TimMc: more likely it's what happens when you switch editors and IDEs

15:52 justin_smith: Whitesmiths style https://en.wikipedia.org/wiki/Indent_style#Whitesmiths_style

15:54 ecmike: no likey

15:55 Allman is ok though

15:55 justin_smith: that wiki page "lisp" style example is wrong in at least two ways - lisp indent applied to algol lang, and hanging open brace

15:55 TEttinger: huh, Allman is what I use. never knew the name

15:56 justin_smith: many GNU projects use K&R

15:56 ecmike: I get annoyed with lines that are purely syntax symbols though, it's unnecessary cognitive noise

16:11 OrbitalKitten: hey guys, is there a reason why \ evaluates to \newline when used 'naked' in the repl and seems to evaluate to a space when used in a function (eg. (str "Hello" \ "World"))?

16:15 amalloy: because the character you typed after the \ in your repl was a newline

16:15 TimMc: OrbitalKitten: You had to hit newline twice in order to enter it in the REPL, yeah?

16:15 It can take either a literal like \™ or a code like \space and what you gave it was a literal newline. :-)

16:15 OrbitalKitten: not sure

16:15 pbx: OrbitalKitten, also at end-of-line in the REPL it's the line contunuation character

16:15 OrbitalKitten: oh

16:16 I get it

16:16 TimMc: (To be clear, \newline is a much better idea.)

16:16 pbx: nevermind what i just said about line continuation, that looks to be false :\

16:16 OrbitalKitten: I will test that in the terminal, maybe it's cider doing weird things.

16:17 Hmm, my bad, cider inserts the newline automatically, I indeed had to tap entre twice

16:50 fuddu-coder: noob here. can i pass multiple functions to a map . is so which one among this can help me

16:50 http://clojuredocs.org/clojure.core/map

16:52 beaky: ,(map (juxt inc dec) [0])

16:52 clojurebot: ([1 -1])

16:53 fuddu-coder: yo.. thx.. juxt can help me. cool

16:53 beaky: ,(map (juxt inc dec) [0 1 2 3])

16:53 clojurebot: ([1 -1] [2 0] [3 1] [4 2])

16:53 beaky: ,(map (juxt inc dec id) [0 1 2 3])

16:53 clojurebot: #error {\n :cause "Unable to resolve symbol: id in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: id 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: id in this context"...

16:53 beaky: ,(map (juxt inc dec identity) [0 1 2 3])

16:53 clojurebot: ([1 -1 0] [2 0 1] [3 1 2] [4 2 3])

16:53 beaky: :D

16:55 WorldsEndless: I can convert .docx to pdf on disk, and I can merge pdf on disk. But I'm trying to take the "on disk" part out of the equation and go straight from my mongodb -> docx -> pdf -> merged pdf -> to client. Anyone have experience with something like this?

16:55 My java stream-fu is a little weak, and it's tripping me up

16:56 justin_smith: WorldsEndless: you can cheat on linux with an in-memory filesystem mounted on tmp

16:56 WorldsEndless: what are the requisite classes for the methods?

16:56 sometimes bad APIs force you to use files, and then you are stuck

16:57 WorldsEndless: I'm using org.docx4j for the doc manipulation, and org.apache.pdfbox for the PDF stuff, and some don't have javadocs to help out...

17:00 amalloy: justin_smith: not necessarily stuck, if they only read/write the files sequentially; you can use a named pipe then

17:01 WorldsEndless: I'm able to write straight from mongo to a client using a clojure.java.io/piped-input-stream (which seems obnoxiously difficult to find docs for)

17:01 But in that case I'm missing both the to-PDF and the merge-PDF steps

17:07 TimMc: justin_smith: I use a ramdisk to speed up clojure compilation. :-D

17:25 sdegutis: Hi

17:31 m1dnight_: How hard would it be to implement a lein plugin that searches for unused imports/uses?

17:31 I need a new pet project and that comes to mind. Ive discussed here a while back.

17:33 beaky: its probably easy

17:34 amalloy: m1dnight_: long ago technomancy did that with slamhound. if you were going to revive the project you'd probably use tools.analyzer

17:36 m1dnight_: Oh, I have the git right here.

17:36 Lets see how hard this will be :>

17:36 TimMc: eastwood, I think

17:37 m1dnight_: Oh, eastwood does that?

17:37 Darnit

17:37 Late to the party :>

17:37 visof: hi guys

17:38 ,(str [+ -])

17:38 clojurebot: "[#object[clojure.core$_PLUS_ 0x2dc40f40 \"clojure.core$_PLUS_@2dc40f40\"] #object[clojure.core$_ 0x468bf604 \"clojure.core$_@468bf604\"]]"

17:38 visof: ,(str '(+ -))

17:38 clojurebot: "(+ -)"

17:38 visof: how can i get the last output from the first input which is [+ -] ?

17:38 how can i get "(+ -)" from input [+ -] ?

17:40 TimMc: m1dnight_: Dunno if it handles both imports and uses...

17:40 MJB47: ,(str (seq '[+ -])) ; visof ?

17:40 clojurebot: "(+ -)"

17:41 visof: MJB47: input should be [+ -] not '[+ -]

17:41 ,(str (seq [+ -]))

17:41 clojurebot: "(#object[clojure.core$_PLUS_ 0x2dc40f40 \"clojure.core$_PLUS_@2dc40f40\"] #object[clojure.core$_ 0x468bf604 \"clojure.core$_@468bf604\"])"

17:41 rhg135: Macro !

17:41 MJB47: yup, use a macro imo

17:42 rhg135: The correct use: endowment of syntax

17:45 MJB47: visof: also you could do

17:45 ,(str (seq (quote [+ -])))

17:45 clojurebot: "(+ -)"

17:46 TEttinger: why quote?

17:46 visof: MJB47: thanks

17:46 MJB47: ' is just syntactic sugar for '

17:46 TEttinger: you don't need quote

17:46 MJB47: quote*

17:47 TEttinger: ,(str (seq [+ -]))

17:47 clojurebot: "(#object[clojure.core$_PLUS_ 0x2dc40f40 \"clojure.core$_PLUS_@2dc40f40\"] #object[clojure.core$_ 0x468bf604 \"clojure.core$_@468bf604\"])"

17:47 TEttinger: oh

17:47 that thing

17:47 ,(pr-str (seq [+ -]))

17:47 clojurebot: "(#object[clojure.core$_PLUS_ 0x2dc40f40 \"clojure.core$_PLUS_@2dc40f40\"] #object[clojure.core$_ 0x468bf604 \"clojure.core$_@468bf604\"])"

17:47 m1dnight_: https://vimeo.com/80650659 # That voice. Such manliness. Such awesome.

17:51 MJB47: visof: incase you cared, the macro would look like: (defmacro m [body] `(str (seq '~body)))

18:15 WorldsEndless: Anyone know where I can find the docs for java.io/piped-input-stream ?

18:19 justin_smith: ,(doc clojure.java.io/piped-input-stream)

18:19 clojurebot: Huh?

18:19 WorldsEndless: yeah...

18:20 justin_smith: ,clojure.java.io/piped-input-stream

18:20 clojurebot: #error {\n :cause "No such var: clojure.java.io/piped-input-stream"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such var: clojure.java.io/piped-input-stream, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "No such var: clojure.java.io/piped-inpu...

18:20 justin_smith: WorldsEndless: what makes you believe this thing exists?

18:20 WorldsEndless: Because it's in my code, and it's working...

18:21 justin_smith: WorldsEndless: the clojure I have doesn't have any such var

18:21 WorldsEndless: oops. I had the wrong ns

18:21 It's in ring...

18:21 Which would be why I've been struggling to fidn the docs

18:21 justin_smith: that would explain not finding the docs

18:22 more evidence that use shouldn't be used

18:22 WorldsEndless: Ha :) I wasn't using "use" but had it as io/piped-input-string and hadn't looked at the ns declaration recently enough to see that io in this file wasn't io as I have it in other files

18:23 And yet, it's still a decent example of possible problems with "use" :)

18:23 justin_smith: heh

18:26 visof: ,(defmacro m [body] `(str (seq '~body)))

18:27 clojurebot: #'sandbox/m

18:27 visof: ,(m [+ -])

18:27 clojurebot: "(+ -)"

18:27 visof: ,(def op [+ -])

18:27 clojurebot: #'sandbox/op

18:27 justin_smith: ,(m (range))

18:27 clojurebot: "(range)"

18:27 visof: (m op)

18:27 justin_smith: haha

18:27 visof: ,(m op)

18:27 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 137]\n [...

18:27 justin_smith: ,(m (mop))

18:27 clojurebot: "(mop)"

18:28 visof: ,(m (op))

18:28 clojurebot: "(op)"

18:28 justin_smith: ,(m (m bop))

18:28 clojurebot: "(m bop)"

18:28 justin_smith: sorry, terrible song

18:28 visof: ,(m (op))

18:28 clojurebot: "(op)"

18:28 justin_smith: visof: macros are tricky

18:28 visof: how can i replace op with actual [+ -]

18:29 justin_smith: yeah it's

18:31 justin_smith: ,(def mm #(map name %))

18:31 clojurebot: #'sandbox/mm

18:31 justin_smith: ,(mm op)

18:31 clojurebot: #error {\n :cause "Unable to resolve symbol: op in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: op 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: op in this context"...

18:32 justin_smith: ,(def op [+ -])

18:32 clojurebot: #'sandbox/op

18:32 justin_smith: ,(mm op)

18:32 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.core$_PLUS_ cannot be cast to clojure.lang.Named>

18:32 justin_smith: ergh

18:32 ,(def op [#'+ #'-])

18:32 clojurebot: #'sandbox/op

18:32 justin_smith: ,(mm op)

18:32 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.Named>

18:32 justin_smith: :P

18:34 ,(defn mm [vars] (map (comp :name meta) vars))

18:34 clojurebot: #'sandbox/mm

18:34 justin_smith: ,(mm op)

18:34 clojurebot: (+ -)

18:34 justin_smith: but that only works with the vars, not the functions - functions don't have names

19:34 didibus: Can I create a null from Clojure?

19:34 justin_smith: ,nil

19:34 clojurebot: nil

19:34 superstructor: nil has the same value as Java null

19:35 didibus: Hum

19:35 I call (str "null:" nullObj)

19:35 And I get aNullPointerException

19:35 but if I do ,(str "null: " nil)

19:35 it works

19:35 ,(str "null: " nil)

19:35 clojurebot: "null: "

19:36 amalloy: mmmmm, that's possible only because nullObj is not in fact nil

19:36 rather it's some sort of lazy thing that realizes itself when you try to print it, and the thing it was lazily putting off doing causes an exception

19:36 justin_smith: didibus: is the object null? what if it has a toString that is getting the NPE?

19:36 didibus: oh, actually, I thought it would print nil, but it prints blank, so it's probably something later on that throws the null pointer

19:37 justin_smith: ,(pr-str nil)

19:37 clojurebot: "nil"

19:37 justin_smith: if you want a less ambiguous printout

19:37 didibus: Oh cool, is that in core?

19:37 justin_smith: yes

19:37 see also prn, pr

19:41 didibus: oh, that does'nt help me because (str) actually does not concatenate the nil

19:41 justin_smith: didibus: you would use pr-str instead of str

19:41 didibus: Ohhhhhhhhhhhhh

19:41 justin_smith: or inside it

19:41 didibus: lol, ok thanks, makes much more sense now

19:42 justin_smith: ,(pr-str "OK: " nil)

19:42 clojurebot: "\"OK: \" nil"

19:42 justin_smith: ,(str "OK: " (pr-str nil))

19:42 clojurebot: "OK: nil"

19:43 didibus: Clojure just really has a function for everything lol

20:23 ecmike: ,(pr-str "null: " nil)

20:23 clojurebot: "\"null: \" nil"

20:24 ecmike: ah, haha

20:24 ,(pr-str 1 2 'a)

20:24 clojurebot: "1 2 a"

20:39 copycat: what kind of error is this?

20:40 No protocol method ReadPort.take! defined for type object: [object Object]

20:41 not much results on google so... =(

21:13 WickedShell: copycat, I'm assuming that thats from trying to use core.async reading from a channel? (If so I suspect its because the object passed isn't a channel).

21:13 copycat: yes, i found the bug. forgot to add in a function to return the channel =)

23:59 dongcarl: clojure newbie here, in this snippet: "loop [stack (:stack state), delims ""]", the comma serves to seperate the two bindings and nothing else right?

23:59 justin_smith: dongcarl: commas are whitespace

Logging service provided by n01se.net