#clojure log - Aug 03 2014

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

0:05 awwaiid: Do I really have to put the full version of core.async as a dependency, as in [org.clojure/core.async "0.1.303.0-886421-alpha"] ? I'd love to do [org.clojure/core.async "0.1"] and have it just get the latest 0.1.*

0:10 rhg135_: idk about emacs but i :r!cat ~/.casync in vim

0:11 keep the coordinatine in the file

0:11 to save typing

0:27 awwaiid: wha? like you keep that version string in that file and read it in at your leisure when you want to update it?

0:30 rhg331: Yes

0:39 awwaiid: ah. Not quite what I was looking for :)

0:43 acagle1: (quit)

0:43 quit

0:43 exit

0:43 TEttinger: acagle: /quit

0:44 acagle1: /quit

1:26 jeremyheiler: cb

1:35 ChouLin: hi everyone, I wonder if there's a non-recursively 'flatten' ? I want (nr-flatten ['([1 2] [3 4]) '([5 6] [7 8])]) return ([1 2] [3 4] [5 6] [7 8]) and still be 'Lazy'.

1:35 I've tried 'concat' , not working.

1:36 rhg331: Apply it maybe?

1:37 ChouLin: yes! apply it is!

1:37 how stupid I am.

1:52 swgillespie: Hi all, I'm getting a really strange compile error here: https://gist.github.com/swgillespie/7325058250c7190d5881

1:53 it works when I use the repl to define it, but when I try to compile it from my buffer I get this ClassCastException on line 6

1:53 is there something weird going on here?

1:55 also, when I comment out the uuid function, the last line in the namespace macro gets the same error...

2:04 ddellacosta: swgillespie: I think the line number is out of sync--it seems rather that it's complaining about not being given a protocol/interface for the deftype call

2:04 swgillespie: hmm

2:04 that's strange

2:05 ddellacosta: &(defprotocol Foo (test [this]))

2:05 swgillespie: but that makes sense, thanks ddellacosta

2:05 ddellacosta: &(deftype Foo [] (test [this] "blah"))

2:05 (deftype Foo IFoo [] (test [this] "blah"))

2:05 d'oh

2:05 &(deftype Foo IFoo [] (test [this] "blah"))

2:05 hmm, can I not make protocols/types with lazybot?

2:06 swgillespie: sure thing, hope that helps

2:06 ,(defprotocol Foo (test [this]))

2:06 clojurebot: eval service is offline

2:06 ddellacosta: right

2:06 ddellacosta_: ,(defprotocol Foo (test [this]))

2:06 clojurebot: Warning: protocol #'sandbox/Foo is overwriting function test\n#<SecurityException java.lang.SecurityException: denied>

2:06 swgillespie: ddellacosta: it does :)

2:06 ddellacosta_: swgillespie: great. :-)

2:07 ,(deftype Foo [] (test [this] "blah"))

2:07 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol>

2:07 ddellacosta_: swgillespie: yeah, *that* was what I was trying to dump out ^

2:07 swgillespie: that's kind of a strange error message for this

2:07 ddellacosta_: swgillespie: well, it makes sense if you think about it

2:07 ,(deftype Foo [] IFoo (test [this] "blah"))

2:07 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: IFoo in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:07 swgillespie: it's interpreting the [] as a symbol for a protocol?

2:07 ddellacosta_: whoopos

2:08 ,(defprotocol IFoo (test [this]))

2:08 clojurebot: Warning: protocol #'sandbox/IFoo is overwriting function test\n#<SecurityException java.lang.SecurityException: denied>

2:08 ddellacosta_: ,(deftype Foo [] IFoo (test [this] "blah"))

2:08 clojurebot: #<CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:0:0)>

2:08 ddellacosta_: d'oh

2:08 anyways

2:08 swgillespie: haha

2:08 ddellacosta_: swgillespie: yeah, it's attempting to interpret the function as the name of the protocol --so it wants a symbol but is getting a list

2:09 swgillespie: ddellacosta_: gotcha, makes sense

2:09 ddellacosta_: I guess that denied means...I can't do that.

2:10 gws: ,(defprotocol IFoo (test-1 [this]))

2:10 clojurebot: IFoo

2:10 gws: ,(deftype Foo [] IFoo (test-1 [this] "blah"))

2:10 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class>

2:10 ddellacosta_: gws: oh, duh, 'cause I'm using the fn "test" huh

2:11 gws: yeah that's how i interpreted the error at least

2:11 ddellacosta_: but, what is that last exception?

2:11 works in my repl, don't get that

2:12 oooh, no it doesn't, not like that

2:12 okay, wait a sec

2:12 (deftype Foo [] IFoo (test_1 [this] "blah"))

2:12 talios: technomancy - http://central.sonatype.org/articles/2014/Aug/03/https-support-launching-now/ - with details for maven, leiningen, etc. etc.

2:12 ddellacosta_: ,(deftype Foo [] IFoo (test_1 [this] "blah"))

2:12 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class>

2:12 ddellacosta_: ,(defprotocol IFoo (test1 [this]))

2:12 clojurebot: IFoo

2:12 ddellacosta_: ,(deftype Foo [] IFoo (test1 [this] "blah"))

2:12 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class>

2:12 ddellacosta_: okay, I'm spacing something obvious here

2:14 swgillespie: is there a naming convention for protocols?

2:14 sort of like the "-able" interfaces in java?

2:14 ddellacosta_: swgillespie: often times you'll see an "I" prefix

2:14 for interface, I believe

2:15 ,(defprotocol IOnceMoreWithFeeling (testa [this]))

2:15 clojurebot: IOnceMoreWithFeeling

2:15 swgillespie: cool, thanks

2:15 ddellacosta_: ,(deftype OnceMoreWithFeeling [] IOnceMoreWithFeeling (testa [this] "okay now"))

2:15 clojurebot: sandbox.OnceMoreWithFeeling

2:16 ddellacosta_: yeah, right, there's something going on with using the same names, maybe I'm not understanding how compilation is working. Hmm

2:16 (testa (OnceMoreWithFeeling.))

2:16 ,(testa (OnceMoreWithFeeling.))

2:16 clojurebot: "okay now"

2:24 gws: how often does the sandbox get cleaned out?

2:26 ddellacosta: gws: yeah, I dunno, I wonder if there's a way to flush it? Maybe create a new ns? Not sure if that's allowed

2:27 (ns SandboxPart2)

2:27 er

2:27 ddellacosta_: ,(ns SandboxPart2)

2:27 clojurebot: nil

2:27 ddellacosta_: (def foo "foo")

2:27 ,(def foo "foo")

2:27 clojurebot: #'sandbox/foo

2:27 ddellacosta_: ,*ns*

2:27 clojurebot: #<Namespace sandbox>

2:28 ddellacosta_: huh, guess not, unless I forgot something, which is equally possible

2:30 gws: ,(ns myns) (println *ns*)

2:30 clojurebot: nil

2:30 ddellacosta: gws: I'm guessing you have to add , to each form

2:30 gws: ,(do (ns myns) (println *ns*))

2:30 clojurebot: #<Namespace myns>\n

2:30 ddellacosta_: ,(println *ns*)

2:30 clojurebot: #<Namespace sandbox>\n

2:31 ddellacosta_: right, so I guess you can change ns local to a form then

2:31 ,(do (ns local-ns) (println *ns*)) ,(println *ns*)

2:31 clojurebot: #<Namespace local-ns>\n

2:31 ddellacosta_: well then, that didn't work

2:31 ,(prinltn *ns*)

2:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: prinltn in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:31 ddellacosta_: ,(println*ns*)

2:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: println*ns* in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:32 gws: lol

2:32 ddellacosta_: ,(println *ns*)

2:32 clojurebot: #<Namespace sandbox>\n

2:32 ddellacosta_: some day, I will learn to type

2:40 rhg331: ,(do (do (ns hi) (println *ns*)) (print *ns*))

2:40 clojurebot: #<Namespace hi>\n#<Namespace hi>

3:19 ChouLin: I wonder if it's safe to read & loop a file like this: (map #(...) (line-seq (clojure.java.io/reader *in*))]) , should I always use 'with-open' ?

3:19 or even worse, explicitly open and close ?

3:21 expez: use (with-open [rdr (io/reader "some/file")] (map #(...) line-seq))

3:21 kovrik: Guys, if I use (clojure.walk/postwalk #(println %) coll) - it prints each form it walks. What should I do if I want it not to print each form, but add each form to a collection and return this collection?

3:21 expez: that last line-seq should be rdr, obv ><

3:24 kovrik: (let [forms (atom []) (postwalk #(swap! forms conj coll)) then finally you can return the contents of the atom with @forms

3:25 kovrik: conj will add to the end of a [], if you want the reverse order you can conj onto a regular list instead of a vector

3:26 kovrik: Thanks! But is it possible to solve this problem without atoms? Atoms are overkill here, IMO, no?

3:26 expez: You need something that is mutable, most stuff in clojure is not :)

3:26 gws: ,(clojure.walk/postwalk (partial conj []) [1 2 3 4])

3:26 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>

3:27 gws: kovrik: try that approach, see if it suits what you're trying to do

3:28 kovrik: It works! Thanks!

3:28 gws: cool! np

3:30 expez: what is the difference between binding and with-redefs when redefining a function? Is it that binding only works on vars that are marked as ^:dynamic?

3:30 kovrik: But I don't get it. How it works? postwalk walks each form and calls a function on each form. Shouldn't it return the last call of a function to the last form of the collection?

3:31 gws: clojure.walk/postwalk:

3:31 Performs a depth-first, post-order traversal of form. Calls f on

3:31 each sub-form, uses f's return value in place of the original.

3:31 Recognizes all Clojure data structures. Consumes seqs as with doall.

3:32 kovrik: Oh, I see. Thank you!

3:33 gws: if you check the return value when you do the original postwalk with #(println %) as you had done - you'll see that the return value has a collection of nils, one for each time you called println

3:35 kovrik: Can I control the way it walks the form? If I have a binary tree (represented as vector of vectors), can I have 2 postwalks - each uses depth-first, but one goes left subtree first and another goes right subtree first?

3:36 rhg331: ,(do (require 'clojure.walk) (clojure.walk/postwalk (partial conj []) [1 2 3 4]))

3:36 clojurebot: [[[1] [2] [3] [4]]]

3:38 kovrik: To be clear: I'm trying to solve this problem: https://www.4clojure.com/problem/96 It is very easy to solve it, for example, in Java. But I'm stuck with Clojure

3:39 And label "Difficulty: Easy" makes me feel stupid :)

3:40 TEttinger: it is number 96

3:40 so I guess it's easy for almost 100 programs in

3:40 rhg331: Wouldn't that be an equality among branches?

3:41 kovrik: No. Branches are not equal - they are 'mirrored'

3:44 As far as I understand, the solution in Java is to walk each branch with DFS, but in left branch we go left subtree first, and in the right branch we go right subtree first. We record our path while walking and then compare two paths. If they are equal, then binary tree is symmetric

3:45 rhg331: I see now

3:46 kovrik: But I can't get it work in Clojure...

3:47 ChouLin: thank you expez , its works, but personlly I'm trying to avoid a outside 'with-open' . I'm using (... (map #(..) (clojure.java.io/reader "myfile"))) all the time, just want to ensure if I'm just lucky or it's a right way.

3:48 rhg331: I think recursion might help but it's only a hunch

3:49 expez: ChouLin: you will be leaking file handles if you don't close open files, this may or may not become a real problem

3:55 ChouLin: guess I've been lucky for a while. I also found a simple loop & print, apart from jvm start time, clojure is much slower than Python. Am I missing something or Python is too good at this ?

3:56 (with-open [F (clojure.java.io/reader *in*)]

3:56 (let [line (line-seq F)]

3:56 (println line)))


3:57 I collect 1000 copy of 'wget' man page, then `cat 1000.manpage | clj print_std.clj 1>/dev/null` , it takes 10 times longer than Python code.

3:58 import sys

3:58 for line in sys.stdin:

3:58 print line


3:59 gws: ChouLin: how are you discounting JVM start time?

4:00 ChouLin: I give a 10 line file as input, count the whole process time as jvm start time.

4:01 the manpage I give later has 170million, I guess the start time is independent with file size.

4:02 gws: i'm not sure - you can try something like (doseq [line (line-seq F)] (println line))

4:02 that's inside the with-open form

4:15 ChouLin: thank you gws, still slow. But fast enough for me either way :)

4:21 ddellacosta: ChouLin: in general, Clojure is really not well suited to doing that kind of scripting. You could check out Grenchman though, it may scratch some itches: https://github.com/technomancy/grenchman

4:23 ChouLin: another approach for your specific task is to use conch inside the repl, and process the output of a shell command that way: https://github.com/Raynes/conch

4:49 ChouLin: thank you ddellacosta , I'll try conch later. My current goal is use Clojure as text processor, most job are easy, so far so good. at this stage I want use less dependency as possible.

4:53 ddellacosta: ChouLin: sure thing--you can also just try using a Java ProcessBuilder (which conch is just wrapping) to exec stuff, if you still want to try the "all in repl" approach (which is how most folks do stuff like this because of the horrendous Clojure startup time).

4:54 ChouLin: in any case, good luck. :-)

5:12 kovrik: Yay! I've solved 4clojure's problem 96 :) https://gist.github.com/kovrik/8e47bccfbe68586060bf

5:13 TEttinger: woo kovrik

5:13 kovrik: Is there a way to simplify the code? or make it more idiomatic?

5:14 TEttinger: looks pretty clear to me

5:14 kovrik: Thanks :)

5:14 TEttinger: probably making it shorter would make it harder to understand, here

5:14 gws: yeah i'm with TEttinger that looks clear to me too

5:18 kovrik: I wish there was something like conditional 'let'-form. Not if-let (which binds result of the evaluation). But something like (let [(if (condition) [a b] [b a]) v] ...)

5:30 ddellacosta: kovrik: I often find myself doing something like (let [x (if (some-pred? x) (do-something-to-x x) x)] ...)

5:31 kovrik: not exactly what you were asking about, but similar

5:32 pyrtsa: ddellacosta: cond-> could work for that, although I think it's a bit hard to read at times. (let [x (cond-> x some-pred? do-something-to)] ...)

5:32 kovrik: Yes, looks similar. But in my case it will make solution more complicated

5:32 ddellacosta: pyrtsa: yeah, that may be superior, not sure

5:33 kovrik: yeah, I think what you have in your specific example is not bad

5:34 pyrtsa: I've found myself wanting something similar to Haskell's do notation at times with Clojure. Ended up making my own variant of the let macro which does all the short-circuiting of nil values and that, but it certainly could be better.

5:34 ddellacosta: I'm struggling to see how to refactor in such a way that it would be cleaner, I think it's pretty good as is

5:34 pyrtsa: would be interested to see it

5:36 pyrtsa: ddellacosta: Actually, wrapping the `for` macro inside an (apply concat (for [...] ...)) gets you quite close to it. The only thing to remember (and where the Clojure compiler doesn't really help) is that you must return a seqable thing in the body.

5:37 ddellacosta: pyrtsa: interesting, I'll have to play with that some more

5:38 gws: i've used the Maybe monad in clojure for that kind of thing too

5:38 pyrtsa: ,(defmacro forcat [exprs body] `(apply concat (for ~exprs ~body)))

5:38 clojurebot: #'sandbox/forcat

5:38 pyrtsa: ,(forcat [x [1] y (if (odd? x) [:bar])] [(str x y)])

5:38 clojurebot: ("1:bar")

5:38 pyrtsa: ,(forcat [x [2] y (if (odd? x) [:bar])] [(str x y)])

5:38 clojurebot: ()

5:38 pyrtsa: Et cetera.

5:39 (Btw, forcat is very useful for recursively defining Datomic transactions from nested data.)

5:41 I haven't checked what it's like to play with monads in Clojure + core.typed, but without type checking, monads just get on the way in plain Clojure.

5:43 kovrik: Here's my solution to 4clj #94 with some more destructuring: https://gist.github.com/pyrtsa/c66630466396064cee24

5:43 I mean, #96.

5:44 gws: what is a better way to clean up the nested-if antipattern here? https://gist.github.com/gws/3d091805d6ba1b359c5d

5:45 kovrik: pyrtsa: very concise!

5:46 pyrtsa: gws: That's exactly the kind of use case I was talking about above. My above forcat macro _could_ (but should not) be used for that.

5:47 Other options I've used with varying success are 1) a custom let macro (call it e.g. `ret`) that short circuits when it sees a special value being bound (similar to reduce & reduced), 2) throwing exceptions.

5:48 thheller: gws: not sure why you'd call nested if an anti-pattern

5:48 but a monad seems pretty overkill to me

5:48 gws: the anti-pattern is repeating the else clause n times

5:48 thheller: try https://gist.github.com/thheller/cda2a325c5e36b5f479c

5:48 there are other ways to get rid of it ;)

5:48 gws: obviously

5:49 i never said a monad was the only way, and i even suggested it wasn't the best way

5:49 pyrtsa: thheller: That works there. What keeps troubling me is that it's always a slightly different trick you'd play when the nesting is different. A uniform way to get around it would be nicer.

5:50 thheller: well you can't solve it in a uniform way

5:50 cause every case is different

5:50 sometimes you need to carry state

5:51 but imho its always better to try an simplify before going the macro route

5:51 pyrtsa: The do notation of Haskell is a uniform way to solve it, state or not. I'm just saying Clojure doesn't seem to have it's own way here.

5:52 *its

5:52 thheller: https://gist.github.com/thheller/cda2a325c5e36b5f479c

5:52 dont know haskell very well

5:52 pyrtsa: No worries.

5:57 thheller, gws: The latest Gist further simplified with if-let: https://gist.github.com/pyrtsa/878491ba0f6d97fe91f1

5:57 gws: i'm missing how these scale to multiple short-circuitable tests

5:57 thheller: hehe I did that too after the last paste :)

5:58 pyrtsa: gws: Yeah, that's what I'm missing too.

5:58 thheller: gws: Its not a uniform solution, its just a simple solution to your example

5:58 gws: if i want to add a second test in the monadic version, it's just a second binding form below the 'ident' line

5:58 thheller: gws: YAGNI :)

5:59 gws: in most cases yes, in this case i will but i haven't written the code for it yet

6:21 pyrtsa: gws, thheller: Here's what it would look like with my silly `ret` macro. https://gist.github.com/pyrtsa/1af9fdd56267a3631b0c

6:41 gws: pyrtsa: thanks for that example

8:30 kovrik: Why do we need to write recur (or loop-recur) explicitly? If we write a recursive call to a function not in a tail-position, then compiler will throw an exception: 'Can only recur from tail position'. So, the compiler determines that our recursive call is not in a tail position. If the complier can determine such things, then why can't we just make a recursive call without loop-recur? Can't compiler add loop-recur forms automatically?

8:32 LauJensen: Ive just switched to cider-mode in Emacs and most shortcuts and so on work, but when I type "(reduce" emacs would normally show me the argumentlist for reduce below the modeline, but this does not happen. It works in the nrepl window, but thats it. Any idea why?

8:34 expez: LauJensen: (add-hook 'cider-mode-hook 'cider-turn-on-eldoc-mode)

8:34 there's a long readme for cider on github

9:06 LauJensen: expez: I already had that, an ElDoc mode is active

9:12 visof: hi

9:13 i'm using java interop but i got strange error which is http://sprunge.us/gSGO ?, what maybe cause this error and how can i fix it?

9:14 i just tried to execute (.getVertices graph "name" "foobar"))

9:26 hyPiRion: visof: can you try to do (import 'com.tinkerpop.blueprints.util.DefaultGraphQuery)?

9:27 visof: hyPiRion: (:import (com.tinkerpop.blueprints.util DefaultGraphQuery) is right too?

9:28 hyPiRion: visof: yeah, sure. Just something which attempts to import it

9:30 I'm guessing you don't have that class on your classpath – you may have to add blueprints to your dependencies

9:34 visof: hyPiRion: that's the full error http://sprunge.us/JfDH , what i try to do is transform this java List<Vertex> r = graph.getRawGraph().command(new OCommandGremlin("g.V[1].out.out.in")).execute(); to clojure println (. (.command (.getRawGraph g) (OCommandGremlin. "g.V[1].out.out.in")) (execute (object-array []))))

9:38 hyPiRion: visof: Yeah, I remember from yesterday. You're using leiningen as a project manager, right?

9:38 visof: hyPiRion: yeah

9:40 hyPiRion: visof: try to add [com.tinkerpop.blueprints/blueprints-core "2.5.0"] to your :dependencies vector, and check if that helps

9:40 inside project.clj

9:42 visof: hyPiRion: there is no 2.5.0 i'm already added 2.4.0

9:43 hyPiRion: huh, I see it on maven central

9:43 http://mvnrepository.com/artifact/com.tinkerpop.blueprints/blueprints-core/2.5.0

9:44 but if that doesn't help, then I don't know :x

9:49 visof: hyPiRion: Thanks man

9:49 hyPiRion: visof: did it work? Or is it still not working?

9:50 visof: Oh, I found someone with the same problem: https://groups.google.com/forum/#!msg/orient-database/Dv3EY4MdJo8/57n7Ld1-qO4J – so apparently, adding using version 2.5.0 should fix the problem

9:51 visof: hyPiRion: works man

9:51 hyPiRion: nice

9:52 sveri: Hi, I have a list of maps, when I do a two step operation on them, first, I update-in a key for each map in that list, then I take the new list, and do an update-in in the map again on a different key and return the result, I am pretty sure there is a way to do this in a more idiomatic way, anyone feels like looking at it? Here is the function: http://pastebin.com/Li1gsNv7

9:55 hyPiRion: sveri: is `es` `events`?

9:56 at the end of line 4

9:57 sveri: hyPiRion: ah yea, copy and paste error, repl state makes it possible :D

9:57 hyPiRion: hehe

10:00 sveri: something like this? http://pastebin.com/CUGDeEPE

10:01 sveri: hyPiRion: that looks nice

10:02 hyPiRion: I guess you could probably factor even more out, but there's always this question on readability vs. cleverness

10:04 sveri: hyPiRion: yea, I find myself struggling much more in doing refactoring in clojure than any other language

10:04 and sometimes I think , jeez, I could have done 3 features in that time :D

10:05 hyPiRion: sveri: It comes with experience as well :) After some time, you can easily read and reason around "normal" Clojure code quite easily

10:06 sveri: hyPiRion: yea, I hope so, and it has the effect to learn more, so I guess it's worth to spend this time doing a lot of refactorings and looking for more idiomatic ways

10:06 hyPiRion: right

10:08 sveri: hyPiRion: I like the fact you defined the functions first and than the function sequence, I always do it the other way around

10:11 hyPiRion: sveri: It sort of depends from time to time. I did it this way because the function calls were essentially equivalent (minus the val to update) and because they are so long that it's useful to name them something (for readability)

10:11 Now whether the names are sensible or not is another matter.. :p

10:14 sveri: hyPiRion: my names almost never are sensible

10:16 hyPiRion: haha

10:29 jgt: How can I create a delay before calling a function?

10:30 tadni: Are there any general "introduction to programming" texts for Clojure?

10:31 jgt: something with Thread/Sleep ?

10:36 kovrik: jgt: yes. (do (Thread/sleep 10000) (println "Done"))

10:36 jgt: cheers

10:37 kovrik: or (future ((Thread/sleep 10000) (println "Done"))) if you need to do it asynchronously

10:37 jgt: yeah, I probably need it async

10:38 I’m just tinkering with Clojure; trying out the sleeping barber problem

10:42 hyPiRion: Isn't that's a problem which fits nicely with core.async?

10:45 jgt: no idea; I’m very much a Clojure beginner :)

10:45 I’m also very much a FP beginner

10:51 hyPiRion: ah

11:29 ruzu: tadni: http://www.braveclojure.com/ perhaps?

11:31 pandeiro: anyone have a workflow suggestion for building/signing/deploying clojure artifacts from jenkins to a repository? i am caught up on how to integrate gpg w/ jenkins

12:22 jjwatt: /quit

12:33 schmee: hey all, I have this piece of code: (binding [*out* (io/writer socket)]

12:33 ), but I actually want to write to multiple sockets, something like (binding [*out* (io/writer socket1 socket2)]

12:33 )

12:33 I just need some pointers in the right direction. Proxy, reify, something else?

12:52 gfredericks: reify should suffice

12:53 maybe there's a builtin class for that already though?

12:53 I don't know jvm socket stuff

12:54 bbloom_: java.io.Writer is an abstract class

12:54 it doesn't have any useful interfaces really

12:55 there's Appendable, but that doesn't cover the more common "write" operations

12:58 schmee: java.io isn't great for these sorts of things, there's java.nio which has lots more support for multiplexing

12:58 and there's interop at the top level for java.io, so you can still use *out* (if you insist)

12:59 * gfredericks must have been wrong

13:00 schmee: alright, I'll take a look at nio, thanks

13:15 OldTree: has anybody used Stuart Sierra's Component framework with something like Korma?

13:38 pandeiro: so i ended up creating a gpg key w/o passphrase for my jenkins user and using that to encrypt credentials.clj and sign artifacts (w/o having to enter a passphrase during automated builds/deploys) -- is this a terrible idea?

14:09 H4ns: pandeiro: it depends on what threat you're addressing.

14:10 ro_st: is it possible to temporarily expand the classpath for a clojure app with a leiningen project's dependency map, and then dispose it again?

14:11 jeremyheiler: ro_st: what are you trying to do?

14:12 ro_st: i'm using shadow-build to compile cljs for multiple cljs projects. i want fast compilation so i'm doing it all from a single jvm, to avoid startup time etc. i'd like to give shadow access to the deps for the cljs lein project in question so that it can resolve deps etc

14:13 right now i have all the deps from all the projects in the host of shadow-build. that's proving painful

14:18 danxensen: are there any preferable places to blog about clojure and programming?

14:20 xeqi: ro_st: nothing built in to lein, but you might be able to build something w/ alembi+classlojure

14:20 * alembic

14:22 ro_st: xeqi: interesting, thank you. i'll have a dig around those

14:23 pandeiro: H4ns: i am just trying to do the sensible thing in integrating a private maven repo into a continuous integration... not really addressing anything in particular. the two options i saw were do passphraseless or just don't sign

14:45 AeroNotix: pandeiro: uhm, no

14:45 that

14:45 That's not a bad idea (having Jenkins sign stuff)

14:46 Providing that there's proper ACLs on the Jenkins box

14:46 this is what $DAYJOB does

14:49 ToBeReplaced: how do i tell eastwood "use all linters"? all i can see is that i manually add the linters that are disabled by default; is that the best way?

14:56 Balveda: yogthos, are you on?

15:00 mi6x3m: hey, how do I get the name of a namespace?

15:01 xeqi: ,(.name *ns*)

15:01 clojurebot: sandbox

15:01 dnolen_: ,(doc ns-name)

15:01 clojurebot: "([ns]); Returns the name of the namespace, a symbol."

15:02 mi6x3m: xeqi: implementation spefic

15:02 inc dnolen_

15:02 dnolen_: mi6x3m: some implementations don't have reified namespaces

15:02 mi6x3m: i.e. ClojureScript

15:02 mi6x3m: thanks dnolen_ :)

15:04 dnolen_: what do you mean reified?

15:07 justin_smith: mi6x3m: I think that means in clojurescript namespaces aren't actual objects you can access

15:08 mi6x3m: justin_smith: ehm, isn't this a language requirement?

15:08 i mean, of the stdlib

15:12 dnolen_: mi6x3m: no

15:12 mi6x3m: reified namespaces nor many concurrency constructs or host IO specific things do not exist in ClojureScript

15:17 mi6x3m: dnolen_: is there something like ns? then

15:18 dnolen_: mi6x3m: first classes namespaces do not exist in ClojureScript, thus no supporting APIs either

15:19 in ClojureScript namespaces are a static construct only

15:19 you only manipulate / inspect them via macros

17:53 so_halt: Hi, I'm having trouble with a compojure webapp. I'm trying to get basic-authentication for a part of my routes, but not all of them.

17:53 I defined my routes as (defroutes r public-routes (wrap-basic-authentication admin-routes authenticate)) (def app (-> r wrap-params wrap-json-params))

17:54 but everything under admin-routes gets me a 404 not found

17:55 If I reorder the admin-routes and public-routes the admin-routes start working again, but now all routes (public-routes included) require basic-auth.

17:55 Does anybody know, what I'm doing wrong?

17:59 I found this https://stackoverflow.com/questions/10822033/compojure-routes-with-different-middleware stackoverflow post, but the solution proposed there unfortunately doesn't seem to work.

18:00 gfredericks: so_halt: I'd suggest pasting your code a bit more formally (e.g. refheap.com); I can't read your code in IRC very well

18:00 so_halt: Ok, sorry. You're right. It's quite painful to read it that way.

18:03 https://www.refheap.com/14db7cc5a74f8336346e10458

18:04 admin-routes and public-routes are both defined with defroutes

18:10 rksm_: re namespaces: are there plans to make them first class?

18:15 so_halt: I guess I found the source of my "bug". had the not-found handler at the end of the public-routes. That was holding me up for the last hour or so. Well, sometimes just staring long enough at the code helps…

18:16 And I thought all the time it had to do with me composing my routes wrong in the final step.

18:50 technomancy: rksm_: I don't think so

18:54 gfredericks: ,#"(?<=SHA256-s\d+--)\w{64}"

18:54 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:54 gfredericks: ,#""

18:54 clojurebot: #""

18:54 gfredericks: &#"(?<=SHA256-s\d+--)\w{64}"

18:57 justin_smith: http://www.regular-expressions.info/lookaround.html "

18:57 Java takes things a step further by allowing finite repetition. You still cannot use the star or plus, but you can use the question mark and the curly braces with the max parameter specified. Java determines the minimum and maximum possible lengths of the lookbehind. "

18:57 gfredericks: it didn't even like it when I replaced + with {,20}

18:58 justin_smith: try {1,20} or {20,20} if that is absolutely the number to be found

18:59 TimMc: "PatternSyntaxException Look-behind group does not have an obvious maximum length near index 16"

19:05 gfredericks: Java needs an explicit lower bound in repetition ranges, I think.

19:08 gfredericks: ,#"x{,20}"

19:08 clojurebot: #<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.util.regex.PatternSyntaxException>

19:08 gfredericks: &#"x{,20}"

19:08 I give up

19:09 there was an easy enough workaround

19:09 ticking: clojure seems to handle more than one namespace declaration per file pretty well, is that behaviour accidental or hacky yet acceptable

19:10 rksm_: technomancy: ok. is there currently ongoing work towards a self-hosted clojurescript? https://github.com/lazerwalker/clojurescript-in-clojurescript seems not to be active anymore

19:11 technomancy: ticking: I don't know if it was accidental, but it's definitely not acceptable in codebases I maintain.

19:11 rksm_: I don't really know anything about clojurescript

19:13 ticking: technomancy: yeah it seems rather nasty, but it's the simplest way to inject a helper namespace into clojurescript compiled from within clojure

19:20 justin_smith: ,ping

19:20 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ping in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:49 blaenk: how can I turn a map into a list of key followed by value? that is, not a list of pairs but a list of :key value :key2 value

20:49 I tried running it through something like (comp concat seq) but it doesn't seem to flatten it?

20:52 bbloom_: ,(apply concat {:x 1 :y 2 :z 3})

20:52 clojurebot: (:y 2 :z 3 :x ...)

20:53 bbloom_: blaenk: your error is that concat operates on multiple arguments

20:53 comp will only thread a single argument through the composition

20:53 and (concat anything) is anything

20:53 blaenk: what about (concat (seq themap))

20:53 I guess that's unnecessary but wondering why it wouldn't work

20:53 bbloom_: (doc concat)

20:53 clojurebot: "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."

20:53 bbloom_: notice the overloads ^^

20:54 check (source concat) in your repl too, you'll see that the single arity overload is a no-op

20:54 ,(concat [1 2 3])

20:54 clojurebot: (1 2 3)

20:54 bbloom_: ,(concat [1 [2 3] 4])

20:54 clojurebot: (1 [2 3] 4)

20:54 blaenk: ohhh that's right

20:54 thanks bbloom_

21:36 rksm_: Macro question: I want to splice in a conditional function call and combine it with a gensym arg like here: https://gist.github.com/rksm/562cd712cf843080cf4c

21:37 DomKM: How does one implement clojure.lang.IMapEntry? Inlining it is producing an AbstractMethodError.

21:38 bbloom_: rksm_: you can splice a vector

21:38 ,`[1 2 ~@(when true [3]) 4 ~@(when false [5]) 6 7]

21:38 clojurebot: [1 2 3 4 6 ...]

21:38 rksm_: The problem is the gensym

21:38 bbloom_: DomKM: what do you mean by "inlining it"

21:39 rksm_: oh, just use gensym explicitly in a let

21:39 rksm_: The problem is that the gensym inserted in the spliced form is not the same as defined in the let before. The ` in `(~fn arg#) seems to forget the arg name

21:39 bound in the outer let

21:39 bbloom_: ,(let [env (gensym "env")] `(let [~env 123] ....

21:39 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

21:39 DomKM: bbloom_: ,(deftype Foo [] clojure.lang.IMapEntry (key [_] 1) (val [_] 2))

21:40 TEttinger: (doc deftype)

21:40 clojurebot: "([name [& fields] & opts+specs]); (deftype name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Dynamically generates compiled bytecode for class with the given name, in a package with the same name as the current namespace, the given fields, and, optionally,

21:40 bbloom_: DomKM: that's just a normal interface implementation... nothing "inlined" about it. when do you get the abstract method error?

21:40 DomKM: ,(deftype Foo [] clojure.lang.IMapEntry (key [_] 1) (val [_] 2)) (key (Foo.))

21:40 clojurebot: sandbox.Foo

21:40 bbloom_: rksm_: you just can't use the auto gensym feature, just manual gensym

21:41 DomKM: well that didn't work

21:41 TEttinger: ,(deftype Foo [] clojure.lang.IMapEntry (key [_] 1) (val [_] 2))

21:41 clojurebot: sandbox.Foo

21:41 bbloom_: DomKM: clojurebot only evaluates one form, you can use (do ...)

21:41 or two lines

21:41 TEttinger: ,(key Foo.)

21:41 clojurebot: #<CompilerException java.lang.ClassNotFoundException: Foo., compiling:(NO_SOURCE_PATH:0:0)>

21:41 TEttinger: ,(key (Foo.))

21:41 clojurebot: #<AbstractMethodError java.lang.AbstractMethodError: sandbox.Foo.getKey()Ljava/lang/Object;>

21:41 DomKM: ,( do(deftype Foo [] clojure.lang.IMapEntry (key [_] 1) (val [_] 2)) (key (Foo.)))

21:41 clojurebot: #<AbstractMethodError java.lang.AbstractMethodError: sandbox.Foo.getKey()Ljava/lang/Object;>

21:41 bbloom_: DomKM: look at (source key) it uses java.util.Map$Entry

21:42 it's looking for getKey():Object, not key():Object

21:42 DomKM: bbloom_: How is IMapEntry used?

21:42 bbloom_: also IMapEntry extends Map.Entry: https://github.com/clojure/clojure/blob/c9e70649d2652baf13b498c4c3ebb070118c4573/src/jvm/clojure/lang/IMapEntry.java#L15

21:42 i have no idea if IMapEntry is used at all, quite honestly

21:43 DomKM: seems like you just have no choice but to implement both key/val and getKey,getValue

21:44 rksm_: bbloom_: okay, thanks.

21:44 bbloom_: rksm_: seems like a historical accident: https://github.com/clojure/clojure/commits/master/src/jvm/clojure/lang/IMapEntry.java

21:45 seems like rich just made his own interface and only later discovered that Map$Entry existed, probably b/c it is sorta stealth, being an inner class and all

21:45 also, MapEntry has setValue too, which seems *insane*

21:45 you can just omit those

21:46 it never ever makes sense to mutate values in a map, lest you break the hashing

21:46 DomKM: Thanks bbloom_

21:46 bbloom_: well, i guess that's key, can maybe change value but not key

21:46 either way

21:46 silly idea

22:03 AWizzArd: What is Incanter’s equivalent to Python’s (numpy’s) “linspace” function?

22:15 shanemhansen: AWizzArd : maybe http://clojuredocs.org/clojure_core/clojure.core/range ?

22:17 blaenk: is there a way to have lein repl autoload all namespaces in my project?

22:17 or am I missing something?

22:17 AWizzArd: shanemhansen: range can be used, however, linspace is nice and is doing some math in the background.

22:18 for example, say you want the range -5 to 5 and you want 10 numbers. Then what is the right stepping? (solution: 1.11111…)

22:19 ,(range -5 5 (float 10/9))

22:19 clojurebot: (-5 -3.8888888359069824 -2.777777671813965 -1.6666665077209473 -0.5555553436279297 ...)

22:19 AWizzArd: However, I need to calculate the stepping myself. Thought there could be something in Incanter already.

22:20 shanemhansen: AWizzArd, oh I see. So like you kind of need to map a linear space to something like a logspace?

22:21 (using logspace as an example of non-uniform point distribution, not implying you're actually using logarithms)

22:21 blaenk: anyone?

22:21 clojurebot: anyone is anybody

22:21 AWizzArd: Yes, could well be.

22:43 TEttinger: blaenk, uh maybe. how many namespace are we talking?

22:44 blaenk: just the namespaces in my project, under 10 I think. the weird thing is it seems it loaded them this time and I don't know why

22:44 but I can access them by fully qualifying them now

22:45 TEttinger: blaenk: here http://dequeue.blogspot.com/2014/01/reloading-lein-repl.html

22:46 it has a dev-dependency, but you can just call (refresh) in their lib and itreloads all of them

22:46 blaenk: thanks, knew about that, I meant when I first start it, being able to access the namespaces from the beginning

22:46 TEttinger: ohhhh

22:46 blaenk: I don't know why but it seemed like it wasn't working before, maybe I was doing something wrong

22:46 TEttinger: so you want to import/require multiple at once?

22:46 blaenk: but now it works. I can fully qualify them as project.something.whatever/function

22:47 TEttinger: how are you requiring them?

22:47 blaenk: I'm not, actually

22:47 I just start lein repl and I can refer to them that way

22:47 which is what I wanted I think

22:47 but I thought it wasn't working before so I was wondering if there was something I had to do

22:49 TEttinger: ah, here blaenk http://dev.solita.fi/2014/03/18/pimp-my-repl.html

22:49 the nice thing about clojure is that people seem to blog every possible tweak you can do...

22:50 blaenk: thanks TEttinger

22:50 TEttinger: well, and how short code is, how well all the seqs work, and lisp in general :P

22:50 no prob blaenk, I never got into full-fledged repl dev and this would probably help me

Logging service provided by n01se.net