#clojure log - Oct 08 2013

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

0:07 logic_prog: is cursive clojure open source ?

0:08 coventry: logic_prog: No. http://cursiveclojure.com/eap.html

0:08 logic_prog: coventry: nice, thanks!

0:09 * logic_prog crosses "try cursive" off of todo list

0:10 TEttinger: coventry, gfredericks, be careful with getInstanceFields. ##(let [gimme (fn [item] (map #(clojure.lang.Reflector/getInstanceField item %) (map (memfn getName) (.getFields (class item)))))] (gimme {:a 1}))

0:10 lazybot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Reflector is bad!

0:10 TEttinger: well oh well.

0:10 it errors with cannot find a static field

0:10 IllegalArgumentException No matching field found: EMPTY for class clojure.lang.PersistentArrayMap clojure.lang.Reflector.getInstanceField (Reflector.java:271)

0:12 coventry: TEttinger: Thanks for the warning.

0:15 TEttinger: hm, .getFields seems to not return very many fields

0:16 ,(count (.getFields (class (java.util.HashMap.))))

0:16 clojurebot: 0

0:21 TEttinger: oh man...

0:22 it's only finding static public fields, because private fields have setters/getters

0:22 at least for java code

0:26 amalloy: ,(count (.getDeclaredFields java.util.HashMap))

0:26 clojurebot: 10

0:27 amalloy: TEttinger: (class (Foo.)) is silly in like all cases - just write Foo

0:27 TEttinger: item is an argument?

0:27 oh

0:27 I took that later bit from earlier code

0:28 amalloy, but won't declared fields not include inherited ones?

0:29 amalloy: right. you have to walk up the inheritance tree for those, since they're not in .getFields or in .getDeclaredFields

0:31 crocket: How does clojure provide modularity?

0:32 egghead: functions, maps, protocols, namespaces

0:32 crocket: egghead, many languages provide that already.

0:33 I'm talking about OSGi's advanced modularity system.

0:38 egghead: crocket: anything in particular or just want to use the osgi classloader

0:38 crocket: egghead, Do clojure people plan to improve modularity to the level of OSGi?

0:39 clojure has already got out of JVM(ClojureScript).

0:39 I think clojure needs its own modularity

0:39 egghead: you'd have to be a little more clear about what you mean by modularity, I think

0:39 if you mean 'standalone units of abstraction which can be composed with other abstract units' then ya it does that quite well

0:40 crocket: multiple versions of the same library should be easy to handle

0:40 Each module needs to have a clear boundary.

0:40 OSGi provides service layer.

0:40 egghead: you're talking about package management then?

0:40 crocket: It's clear that modules have versions.

0:40 It's modularity.

0:43 egghead, How does clojure deal with multiple versions of the same lib?

1:08 wei_: is there a good thumbnail generation library?

1:08 EchoBot1: Echo: is there a good thumbnail generation library?

1:08 mtp: it's a little gauche to test "bots in a language" in the language's channel

1:08 EchoBot1: Echo: it's a little gauche to test "bots in a language" in the language's channel

1:09 mtp: especially when they're bots like that

1:09 EchoBot1: Echo: especially when they're bots like that

1:16 TEttinger: `msg EchoBot1 die

1:16 EchoBot1: Echo: `msg EchoBot1 die

1:16 logic_prog: is there a way to tell speedbar (maybe etags?) to show clojure functions defined with "defn" but not clojure functions defined with "defn-" ?

1:16 EchoBot1: Echo: is there a way to tell speedbar (maybe etags?) to show clojure functions defined with "defn" but not clojure functions defined with "defn-" ?

1:16 Echo: die

1:17 Echo: die

1:17 TEttinger: technomancy, ops, kban?

1:17 EchoBot1: Echo: technomancy, ops, kban?

1:18 Apage43: what a heinous piece of software

1:18 EchoBot1: Echo: what a heinous piece of software

1:19 indigo: Wow, first time I've seen this kind of crap

1:19 EchoBot1: Echo: Wow, first time I've seen this kind of crap

1:19 TEttinger: everyone, /ignore ?

1:19 EchoBot1: Echo: everyone, /ignore ?

1:23 dcunit3d: wei_: you could try using java.awt.BufferedImage

1:23 EchoBot1: Echo: wei_: you could try using java.awt.BufferedImage

1:24 wei_: looking at it now, thanks dcunit3d

1:24 EchoBot1: Echo: looking at it now, thanks dcunit3d

1:25 jonasen: dnolen: ping

1:25 EchoBot1: Echo: dnolen: ping

1:25 dnolen: jonasen: pong

1:25 EchoBot1: Echo: jonasen: pong

1:25 dcunit3d: wei_: there is also this library https://github.com/mikera/imagez

1:25 EchoBot1: Echo: wei_: there is also this library https://github.com/mikera/imagez

1:26 wei_: wow, fairly recent. looks good.

1:26 EchoBot1: Echo: wow, fairly recent. looks good.

1:27 wei_: I think we need a second Echobot in here ;)

1:27 EchoBot1: Echo: I think we need a second Echobot in here ;)

1:28 seangrov`: wei_: Just a simple /ignore ;)

1:28 EchoBot1: Echo: wei_: Just a simple /ignore ;)

1:29 nightfly: /part

1:29 EchoBot1: Echo: /part

1:29 logic_prog: how is clojure-mode talking to speedbar ?

1:29 EchoBot1: Echo: how is clojure-mode talking to speedbar ?

1:29 logic_prog: is it using etags, or iemnu?

1:29 EchoBot1: Echo: is it using etags, or iemnu?

1:29 logic_prog: how is clojure-mode providing the tags ?

1:29 EchoBot1: Echo: how is clojure-mode providing the tags ?

1:29 logic_prog: just ignored Echobot1.

1:29 EchoBot1: Echo: just ignored Echobot1.

1:30 logic_prog: testing again

1:30 EchoBot1: Echo: testing again

1:30 dnolen: jonasen: applied to master

1:30 EchoBot1: Echo: jonasen: applied to master

1:41 jonasen: dnolen: thanks

1:41 dnolen: jonasen: np

1:42 dcunit3d: does the other bot have echobot ignored lol

1:44 TEttinger: did someone kick echobot1?

1:45 nope, I think he's logic_prog's

1:47 crocket: hey

1:48 TEttinger: crocket: ?

1:48 crocket: How does clojure handle multiple versions of the same lib?

1:49 TEttinger: there's an option in lein to warn or abort on it, I'm not sure if you mean transitive deps or what

1:49 crocket: TEttinger, OSGi allows devs to deploy multiple versions of the same lib.

1:49 module loading

1:50 Multiple versions of a library can be loaded on the runtime.

1:51 TEttinger: http://bit.ly/clojureosgi <-- crocket

1:52 crocket: TEttinger, what about clojure outside JVM?

1:52 Is there a clojure specific way?

1:52 TEttinger: eh?

1:52 you mean clojurescript, or other java VMs?

1:53 crocket: TEttinger, clojurescript and clojure on .NET

1:53 TEttinger: those have osgi?

1:53 crocket: no

1:53 seangrov`: crocket: There isn't a universal way, no. Clojure lets the host details show through a lot more than that.

1:53 TEttinger: https://github.com/aav/clojure.osgi here are some examples

1:53 crocket: So clojure needs its own modularity.

1:55 seangrov`: crocket: Heh, before we get there, we need some way to write cross-runtime libraries ;)

1:55 This has been discussed on the ml before though

1:55 TEttinger: cljx is the main proposal I think

1:55 crocket: seanaway, cross-runtime?

1:55 seangrov`: TEttinger: yeah, more or less feature expressions

1:55 TEttinger: clojure and clojurescript are subtly different

1:56 crocket: Although cross-runtime modularity is good, I had multiple versions of a library in mind.

1:56 TEttinger: and any usage of the host language is incompatible with other host languages

1:56 yeah, I think it's possible.

1:56 crocket: TEttinger, with what?

1:57 TEttinger: maybe not yet, but since lein uses maven, if maven can do it...

1:57 crocket: Does clojure have a tool to load multiple versions of a library on the same JVM?

1:57 maven is just a build tool

1:57 TEttinger: I think the issue is the same stuff on one classpath

1:57 crocket: It doesn't help you with modularity.

2:06 z15tea: I like prismatic's plumbing. Not what you are looking for though

2:22 seangrov`: crocket: I believe this has been discussed on the ml before and isn't really possible in bigger apps

2:22 crocket: seanaway, ???

2:22 lazybot: crocket: How could that be wrong?

2:23 crocket: seangrov`, Can you elaborate about it?

2:23 seangrov`: crocket: https://groups.google.com/forum/#!topic/clojure/WuS31RSiz_A

2:57 TEttinger: crocket, you saw https://github.com/Seajure/metaverse right?

2:57 crocket: Seajure?

2:57 TEttinger: seattle clojure group

2:57 crocket: well

2:57 TEttinger: it was linked in that long ML exchange

2:58 well, metaverse was

2:58 this is the newer version by a bit

2:58 it's not a standard, but you can do it in pure clojure

2:59 once libs start importing java or groovy or jruby or whatever, sane versioning goes out the window :)

3:00 Raynes: TEttinger: Metaverse is wild.

3:16 gravenimage: quit

3:16 quit

3:56 crocket: yo

4:00 andyfingerhut: Awake, but perhaps not fully alert

4:59 logic_prog: is the dumbass echo bot gone yet?

4:59 good :-)

5:00 echo-are`: If a macro expands into a def expression, and I want to add meta data to the defined var, do I have to use an extra expression to add it? 'cause (def ^:meta-data ...) in the defmacro seems not functioning

5:02 borkdude: is there a way in a for to generate two elements instead of one

5:02 like (for [i [1 2 3]] [i (inc i)]) and not have to 'flatten' the end result

5:02 (probably not, but can't hurt to ask)

5:03 amalloy: echo-are`: `(def ^:foo bar) uses the typehint at macroexpansion time, rather than putting it on the code it outputs

5:03 (and of course at macroexpansion time it's totally useless)

5:03 you want `(def ~(vary-meta bar assoc :meta-whatever true))

5:04 borkdude: you can apply concat around the for, or add a second clause to the for iteration list

5:04 echo-are`: amalloy: Got it, thanks

5:04 amalloy: &(for [i [1 2 3], x [i (inc i)]] x)

5:04 lazybot: ⇒ (1 2 2 3 3 4)

5:04 borkdude: amalloy ah

5:06 amalloy in my actual production code I would need apply concat, I was afraid so ;)

5:06 amalloy: borkdude: nonsense. you can write any apply-concat as another step in the for

5:06 borkdude: amalloy ok, I'm generating two datoms in the for

5:07 amalloy: (apply concat (for [x xs] (f x))) => (for [x xs, y (f x)] y)

5:07 borkdude: amalloy what if the second thing isn't related to the first thing

5:07 amalloy: uh...so? what i just wrote is true for all f

5:08 borkdude: as always, you are right and it saved me the apply concat :-) #needmorecoffee

5:19 rurumate_: is there a clojure client for levelDB yet?

5:21 mpenet: rurumate_: yes clj-leveldb I think from factual

5:24 harja: Do you guys have any good decision procedure on when to use a function vs. a macro?

5:25 rurumate_: mpenet: thanks

5:25 llasram: harja: Write a function unless you really can't.

5:27 harja: llasram: Sounds reasonable. But the problem is that I'm seeing application for macros everywhere, like just expanding stuff in place to generate behaviors. But it's not clearly a good thing. It's just that when people get a hammer they seem to be searching for nails everywhere, and this is how I feel now :)

5:27 echo-are`: harja: There is a book On Lisp by Paul Graham for this topic, though that book is not for Clojure

5:28 llasram: harja: I think most people go through that when first exposed to macros :-)

5:29 harja: What do you mean in particular by "expanding stuff in place to generate behaviors"?

5:29 harja: echo-are`: Thanks, I'm familiar with it. Haven't read it all the way through though. Do you happen to have page numbers I should refer to? :)

5:29 llasram: I certainly went through a phase of writing far more macros than necessary...

5:29 echo-are`: harja: Chapter 8, When to Use Macros might help

5:29 llasram: Eh

5:30 harja: llasram: For example, I made an interface for accessing the entities in my system. I decided that the implementation should be Korma, but could be altered if I want to. All of the calls to the interface are macros that get expanded to Korma-queries

5:31 echo-are`: :) Thanks!

5:32 llasram: harja: How is it different than if the interface had been functions?

5:32 harja: llasram: https://www.refheap.com/282c285b56daef57a500ff798

5:33 llasram: Exactly :)

5:33 echo-are`: harja: But Clojure's more focus on simplicity through decomposition subtly differs from CL's philosophy, do keep that in mind

5:34 harja: echo-are`: Good point. Thanks.

5:35 llasram: Ok, yeah. In my opinion those should definitely just be functions. You lose a lot of composability when you make something a macro

5:36 harja: llasram: Yeah. This is what I also discovered. So basically your simple advice should be at least good approximation on the "correct" answer :)

5:36 andyfingerhut: amalloy: Are latest versions of useful lib released as jars anywhere? I didn't see them on Clojars

5:37 amalloy: andyfingerhut: https://clojars.org/org.flatland/useful looks like the latest to me

5:37 harja: Thanks for the input guys!

5:37 llasram: harja: np!

5:38 andyfingerhut: amalloy: doh! I wasn't looking hard enough. Thanks.

5:38 harja: Macros are just such a powerful tool for a newbie like me that just drank the kool-aid :)

5:39 pavelpenev: harja: I've been away from clojure for quite a while(I mostly hack on CL in my spare time now) but from what I can tell, lispers avoid macros if they can help it, and clojurians do so even more(favoring FP).

5:41 I've written 3 or 4 useful macros for 4 years of usage of various dialects, but I've used many libraries that use them to good effect. Maybe examine existing code? Ask why should it this be a macro etc.

5:41 harja: ^

5:57 rurumate_: I write a with-x macro for every Closeable x, at least

6:01 like this: https://www.refheap.com/19523

6:04 opqdonut: why not just use with-open?

6:05 sm0ke: ,(= ::a :user/a); why is this false?

6:05 clojurebot: false

6:05 sm0ke: ,::a

6:05 clojurebot: :sandbox/a

6:05 sm0ke: ,(= ::a :sandbox/a); why is this false?

6:05 clojurebot: true

6:05 sm0ke: oh

6:06 opqdonut: ,::a

6:06 clojurebot: :sandbox/a

6:06 opqdonut: yep

6:06 sm0ke: is :: a special form?

6:06 opqdonut: yeah, kinda, it's part of the keyword syntax

6:06 llasram: It's reader syntax

6:06 sm0ke: what is it used for?

6:06 opqdonut: private symbols, basically

6:06 Jarda: namespaced keywords?

6:07 opqdonut: for example if you have a queue for things and you want to have a marker in there

6:07 you can use ::marker to be extra sure someone doesn't accidentally insert a marker

6:08 sm0ke: ok so i understand it just prefixes the keyword with current namespace

6:08 opqdonut: yep

6:08 sm0ke: thanks

6:09 ordnungswidrig: opqdonut: you can also use (Object.) for marker objects. The instance is guaranteed to be unique :)

6:14 opqdonut: ordnungswidrig: yeah, that's the java way, and it is more reliable

6:18 rurumate_: opqdonut: if it's closeable, yes

6:23 sm0ke: why the following ##(do (identical? (String. "a") (String. "a")) (identical? "aa" "aa"))

6:23 lazybot: ⇒ true

6:23 sm0ke: what the

6:24 ,(identical? (String. "a") (String. "a"))

6:24 clojurebot: false

6:24 sm0ke: oh ok do returns last expression i see

6:24 isnt "aa" and (String. "aa") the same thing?

6:25 llasram: sm0ke: They have *value* identity, but not *object* identity

6:26 ##(let [a1 (String. "aa"), a2 (String. "aa")] [(= a1 a2) (identical? a1 a2)])

6:26 lazybot: ⇒ [true false]

6:26 sm0ke: llasram: yes but why ##(identical? "aa" "aa")

6:26 lazybot: ⇒ true

6:26 llasram: sm0ke: Because string constants are interned and do have object identity

6:29 CommandBot: Greetings! Send me a PM and I'll echo it back to you. If it contains the word 'die', I'll die as a bonus!

6:29 sm0ke: llasram: got it thanks

7:42 Jarda: can I redefine a library method?

7:42 (or a function)

7:43 should (defn foo/bar ...) work?

7:54 llasram: Jarda: For testing?

7:54 Jarda: llasram: no, I'm tryin to use https://github.com/seancorfield/clj-soap and need to infer a bit with the logic

7:55 llasram: Ok. Then I'd use https://github.com/technomancy/robert-hooke

7:55 harja: pavelpenev: Thanks! That sounds like a good and solid approach to follow.

7:56 Jarda: llasram: ok thanks

7:57 harja: Oh hi Jarda, do you guys use Clojure too nowadays?

7:57 Jarda: harja: hi! Nope, not working for Ecom anymore. More like a freelancer nowadays :)

7:58 harja: Jarda: Yeah, heard that you left. Did you go working for a startup?

7:59 Jarda: harja: well I do a lot of javascript coding for Flowplayer atm, but also working on own projects on the side

7:59 harja: Cool

8:12 ThePawnBreak: hello! I'm a clojure newbie; I'm trying to use the Raynes fs library; I added it to project.clj but I don't know how to import it; how do I know what argument to pass to the use function? thanks

8:13 I tried (use 'me.raynes/fs) but it doesn't seem to work

8:13 solussd: you can use the ns macro to load it:

8:13 turbopape: maybe running lein deps ?

8:13 ThePawnBreak: lein downloaded it, I just don't know what its 'correct' name is

8:13 solussd: (use 'me.raynes.fs)

8:14 turbopape: ok, so it is a ns problem, as pointed by solussd

8:14 ThePawnBreak: thanks solussd ; it worked

8:14 still, where could I have found that name? "me.raynes.fs"

8:15 solussd: ThePawnBreak: look at line 1 here: https://github.com/Raynes/fs/blob/master/src/me/raynes/fs.clj#L1

8:16 ThePawnBreak: thank you :)

8:16 solussd: documentation or source code, really. the group and package name for it dont necessarily correspond to the namespaces

8:16 np

8:18 I'm assuming you're playing with it using a repl. When you want to use it in a dource file, use the ns macro. E.g. at the top of the file: (ns (:require [raynes.me.fs :as fs])) and then you can use functions from it like this: (fs/expand-home "somearg")

8:18 *source

8:20 ThePawnBreak: is anything wrong with simply using it using "use"?

8:21 turbopape: use = require + ref, no ?

8:21 ThePawnBreak: I'm not sure I understand what you

8:21 you're asking

8:26 llasram: `use` is `require` + `refer`

8:27 Zerker_: Hello

8:27 llasram: The problem with `use` is that w/o `:only` you have no control over the symbol pulled into your namespace. And with `:only` it's identical to `require` with `:refer`. So if we all just `require`, the world becomes simpler :-)

8:27 solussd: use 'refers' the symbols into your current namespace. It is usually frowned upon, bc it pollutes your current namespace with all the symbols from another

8:27 Zerker_: Would anyone be willing to give me ten minutes of their time for an informal interview? CS student, paper due in 9 hours, you know how it is ^-^

8:29 solussd: its nice to know where your functions are. Using require, like in my example above, you can give a namespace a "nickname", e.g. [raynes.me.fs :as fs]. Then, all of Raynes' fs stuff can be accessed under fs/

8:29 Zerker_: in 2 hours, sure

8:37 ThePawnBreak: solussd: is this how I should import clojure.string? (ns (:require [clojure.string :as st]))

8:37 solussd: yup

8:37 ThePawnBreak: it doesn't seem to work: (ns (:require [clojure.string :as st]))

8:37 ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol clojure.lang.RT$1.invoke (RT.java:237)

8:37 solussd: oh

8:38 you need to specify the namespace

8:38 as the first arg to ns

8:38 e.g., (ns my.stuff (:require [clojure.string :as st]))

8:38 which would go at the top of a file at src/my/stuff.clj

8:41 ThePawnBreak: now I have this at the top

8:41 (ns core (:require [clojure.string :as st]))

8:41 (ns core (:require [me.raynes.fs :as fs]))

8:41 but:

8:41 (ns core (:require [clojure.string :as st]))

8:41 (ns core (:require [me.raynes.fs :as fs]))

8:41 core=> fs.absolute-path

8:41 CompilerException java.lang.ClassNotFoundException: fs.absolute-path, compiling:(/tmp/form-init2759071537655607159.clj:1:882

8:43 solussd: oh, combine those, also the name of your project should be the first component in the namespace: (ns myprojectname.core (:require [clojure.string :as st] [raynes.me.fs :as fs]))

8:43 *me.raynes

8:44 ThePawnBreak: is there any way to "restart" a REPL?

8:44 to a clean state

8:45 besides closing it and opening another

8:45 solussd: well, you could remove all the things aliased into it, but it's easier to just switch to a new namespace

8:46 try: (ns my-new-namespace)

8:46 your prompt will change and you'll have a "clean" repl/namespace

8:48 also, accessing functions in a namespace is always done with a forward slash, e.g. me.raynes.fs/absolute-path

8:49 ThePawnBreak: everything works now; thanks again, you've been very helpful

8:49 solussd: no problem, anytime

9:19 pepijndevos: I'm having math problems :(

9:20 mdrogalis: pepijndevos: What's up?

9:20 pepijndevos: I'm trying to figure out how far I need to drive in a circle to move X cm sideways.

9:21 I'm almost there, but my asin is going the wrong way.

9:21 pasting code...

9:22 https://www.refheap.com/19532

9:22 mdrogalis: Eh, sorry. That's out of my depth. :)

9:22 Maybe try the math Stack Exchange.

9:23 pepijndevos: I think I'll figure it out eventually...

9:24 So the problem is that right now, it's like I'm facing sideways. so maybe I need to add 90 degrees to it. But maybe I just need to use another a?(sin|cos|tan)

9:25 In other wrods, if I say I have a turning radius of 10 cm, and want to move 1 cm sideways, it gives me 1.01.

9:43 noncom: pepijndevos: the code looks too complicated for the task

9:43 better avoid degrees at all, use radians.. only do degrees for input-output

9:43 will save you a lot of confusion and make the code much prettier

9:44 pepijndevos: Math is complicated… haha. Well, I'm open to suggestions.

9:44 noncom: if i were you, i would first get rid of all the degrees stuff and work with radians

9:45 try that, then see what code you get

9:45 pepijndevos: I mean… yes but.. that won;t solve the problem.

9:46 distance-after works fine. Its the (Math/asin (/ sideways radius)) part that is causing trouble.

9:49 noncom: pepijndevos: https://www.refheap.com/19533

9:51 at least, multiplying angle with two pi seens strange

9:51 also, why is it you divide sideways by radius?

9:52 asin is taken from the length of a x-axis segment and gives the angle which corresponds to the projection on the x-axis

9:53 ah, your radius is not normalized, sorry i see

9:53 pepijndevos: well, asin expects somethign between 0 and 1. So if I want to move 1 cm with a turning radius of 10, I plug in 0.1 to that function.

9:53 noncom: right, i missed that

9:53 so ,then to me what is strange seems the line 4 in myrefheap

9:54 (* angle two-pi radius)

9:54 mishok13: probably a stupid question and asked here hundreds of times, however: when I try to access resource from uberjar it fails with java.io.FileNotFoundException while when working from REPL everything works just fine

9:55 pepijndevos: I don't know about that, but what my code did was taking the degrees needed to turn, devide them by a full circle, and then take that much of the circunference of the radius.

9:55 mishok13: basically, the exception says that the path is path/to/uberjar.jar!public/resource.txt which is obviously not openable by io/file or io/reader

9:58 mdrogalis: mishok13: clojure.java.io/resource

9:58 mishok13: yeah, I'm using exactly that

9:58 mdrogalis: Hmph. Not sure then.

9:59 pepijndevos: So since you use radians, that would be (* (/ degrees two-pi) (* two-pi radius)) right?

10:00 noncom, I did not quite parse that bit about the x-axis you said. Can you explain that?

10:01 Oh, i think I got it...

10:01 noncom: ah, yes

10:01 well, maybe then, if your radius is 10 and you get 10.1, then it is because you did not multiply 0.1 by 10 ?

10:02 or what result you expect?

10:02 TimMc: Everything becomes easier if you just use tau (2 pi).

10:02 noncom: uhh, i guess i mess up even more than you did :D

10:02 TimMc: http://tauday.com/tau-manifesto

10:03 noncom: TimMc: ahaha yeah, i remember that one :)

10:03 hyPiRion: isn't like, degrees/2pi * 2pi / radius = degrees/radius? :)

10:05 pepijndevos: So your car is facing north, or 0 deg. and you want to move sideways 1 cm. So you start turning, and at first you are driving almost north, 5deg or so. So it'd take you maybe 3cm to move sideways just 1 cm.

10:06 But the result I'm getting is like if I'm facing west, and turining away from where I want to go. So at first you move almost 1 cm sideways for every 1 cm you drive.

10:06 noncom: so you want the length of the arc

10:07 pepijndevos: ultimately, yes

10:07 distance-after calculates the length of the arc to trun X degrees

10:14 noncom: so, the ultimate formula is (* two-pi r (/ (asin (/ x-dist r)) two-pi))

10:14 ?

10:15 what boils down to (* r (asin (/ x-dist r)))

10:18 pepijndevos: but it's stil facing the wrong way… I think I found something that works… hold on

10:19 https://www.refheap.com/19534

10:20 noncom: hehe

10:21 pepijndevos: It looks wrong, but works correctly.. seemingly

10:23 I'll try on the robot, and if it works, I declare it mathematically, or at least empirically correct.

10:23 noncom: cool!

10:24 pepijndevos: it's fro this one: http://www.youtube.com/watch?v=h9_pNfebQf4

10:26 noncom: wow! that wat you did?

10:26 pepijndevos: yea

10:26 noncom: pretty cool, are you using arduino?

10:27 or is it a different flavor of robot

10:27 pepijndevos: LEGO EV3

10:27 Runs Clojure :)

10:28 Morgawr: nice

10:28 that's pretty cool

10:28 noncom: personally i think this is supa nice thing! probably we're gonna work with something like that in our company sometime

10:29 btw, if you're taking on lisp, probably you could write a self-assembling lego robot sometime!

10:29 pepijndevos: :)

10:30 noncom: you could use opencv to identify lego pieces from cameras

10:30 and try to stack them according to some design, maybe controlled by some fancy ai thing..

10:30 although that'll require very precise servos

10:32 clgv: noncom: evolutionary programming with LEGO :D

10:33 noncom: evolving the code and the physical built that would be cool

10:35 noncom: yeah, but lego may come to be a little harder to handle than, say, plain cubes with magnets and stuff

10:36 they bricks have these.. how you call them, idk, pins, which stack one in another to connect them

10:36 comfortable for hands but i think not for autos

10:42 cmajor7: I am sure there were many discussions previously, but time goes on, software changes.. I am looking for a testing framework. Candidates are clojure.test, midje and speclj. What experiences do you guys have with these?

10:45 tbaldrid_: cmajor7: keep it super simple, go with clojure.test

10:45 tbaldridge: I've tried both of the others and regretted it over time.

10:46 coventry: What are the drawbacks?

10:46 cmajor7: tbaldrid_: that's what I am afraid of. the other two look seductive, but add complexity..

10:46 diogenes: hey. noobie here. how can you transform a integer like 123 to a list '(1 2 3)?

10:47 cmajor7: tbaldrid_: I am also spoiled by using spock (groovy testing framework), hence "seductive"

10:47 tbaldridge: cmajor7: that's my only real complaint. clojure.test just creates defns. The source for all the constructs fits on a few lines. For both of the others, they look pretty perhaps, but they accomplish this via lots of macros.

10:47 borkdude: diogenes (seq (str 123))

10:47 diogenes: borkdude: thanks!

10:47 borkdude: diogenes actually that is a seq of chars, if you want to transform those into ints again, you probably know how

10:48 noncom: ,(map int (str 123))

10:48 clojurebot: (49 50 51)

10:48 noncom: oh

10:48 tbaldridge: cmajor7: I also wonder if we don't really need with-redefs or "providing" if we structure our Clojure code correctly. Have each testable "thing" take its data sources as arguments, and now you don't need to redef any global vars.

10:48 cmajor7: tbaldridge: how would lots of macros behind the scene hurt? (curious)

10:48 diogenes: noncom: that works better. thanks

10:49 noncom: diogenes: but that's worng :)

10:49 borkdude: ,(map #(Integer/parseInt (str %)) (str 123))

10:49 clojurebot: (1 2 3)

10:49 noncom: it gives bytes for the chars

10:49 tbaldridge: cmajor7: it hurts when the blow up. With Midje I'm often wondering what the code means. This is because Midje defines a DSL with different semantics from Clojure. Some parts of the code are run out of order, or even backwards.

10:49 cmajor7: tbaldridge: it does not seem I need to compose them myself, since they are "their" test primitives

10:50 tbaldridge: yea, I get this impression from the docs.. not very simple and .. not very clojure. hence looked at speclj..

10:50 tbaldridge: cmajor7: Midje is based on =>. How is that macro implemented?

10:51 cmajor7: yeah, I like speclj more, but there's little community support. That's often a bad reason not to use something, though.

10:52 cmajor7: so I wouldn't say I love clojure.test. It's just there's no better alternative, IMO.

10:52 cmajor7: tbaldridge: yea, that is my thinking exactly

10:53 tbaldridge: what would some disadvantages (if any) of clojure.test be that you can think of?

10:53 iwillig: does clojure.contrib.mock still exist ? I was looking at this page http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go and it seems like mock was never migrated to a namespace. Is that correct ?

10:53 coventry: What does clojure.test gain by putting the test body in the function metadata?

10:54 maku_: Has anyone used the OrientDB Wrapper: https://github.com/eduardoejp/clj-orient?

10:56 tbaldridge: cmajor7: I have a very minimalistic view of testing. All I need is assert and a way to name tests. Using that, I can built almost any other check that I need. For instance, the core.async CLJS source uses the 30 lines of code I wrote here: https://github.com/clojure/core.async/blob/master/src/test/cljs/cljs/core/async/test_helpers.clj

10:57 cmajor7: that's all I really need from a test suite. And for that, clojure.test fits very well. Power through simplicity :-P

10:58 cmajor7: tbaldridge: that's cool, although is 43 lines :) so you chose not to use clojure.test here at all, or you compliment it with clojure.test?

10:59 tbaldridge: cmajor7: clojure.test doesn't exist in CLJS or it didn't at the time I wrote this

10:59 cmajor7: tbaldridge: oh.. missed the S part in CLJS

11:01 tbaldridge: I see. yea, I am convinced. "clojure.test" it is.

11:05 tbaldridge: on more "test" thing I am contemplating about: since in clojure we use repl pretty heavily, and it's a culture of constantly interacting with the code, do you see a true usefulness from "unit" tests? I do for things like libraries, but I feel that "integration" tests provide a lot more value and a lot less regression headache for "customer problem" solutions (not exactly general purpose libraries)? This is n

11:07 coventry: I generally test something in a repl, then stick it the test battery once it works. Guards against regressions.

11:07 tbaldridge: cmajor7: I agree, and core.async is a good example of this. There are about 700 lines of code behind the go macro, and yet I don't test any of the functions in that namespace. Instead I test the client API to the namespace. With enough tests, you can pin down failures purely on what tests are failing.

11:08 and you end up testing the library's specifications, and not the implementation of the library.

11:08 coventry: agreed, I test because I fear regression.

11:12 mdrogalis: As it turns out, Simulant makes a pretty neat replacement for Curl tests.

11:14 bbloom: bitemyapp: you're impacted by the ArraySeq/RestFn perf issue, right? https://groups.google.com/d/topic/clojure-dev/Gaz17qMfwrk/discussion

11:14 who else was on that list?

11:15 mimieux: 9

11:28 ambrosebs: thoughts on potential Typed Clojure logo? https://raw.github.com/typed-clojure/typed-clojure.com/master/images/letterbox.png

11:30 bbloom: ambrosebs: it's a tau? perfect :-P

11:31 rurumate_: has anyone ever got "goog.string.format is not a function" error?

11:31 ambrosebs: bbloom: yes! :D

11:31 rurumate_: (using latest clojurescript)

11:31 this error happens at runtime

11:32 bbloom: rurumate_: can you produce a minimal reproduction?

11:32 jonasen: rurumate_: are you using cljs.core/format?

11:32 rurumate_: jonasen: not yet

11:33 jonasen: rurumate_: ok, it has been removed from core

11:33 somehow it messed up advanced optimizations

11:34 rurumate_: bbloom: I'm too stressed out right now, maybe on the weekend

11:35 stuartsierra: coventry: Re "What does clojure.test gain by putting the test body in the function metadata?" Originally I thought tests could be attached as metadata to the function they're testing. The `with-test` macro exists to support this. But the style never caught on.

11:35 rurumate_: jonasen, bbloom: try replacing format calls with goog.string.format, it should break at runtime

11:35 coventry: Thanks, stuartsierra.

11:35 stuartsierra: I and others quickly discovered that mixing tests and source in the same file makes the source hard to read.

11:36 bbloom: i feel the same way about type annotations

11:36 * bbloom pokes ambrosebs :-)

11:37 coventry: I'm working on a code-walking/transformation library at the moment, and want it to be able to handle the clojure source code, so having the test bodies in the metadata is complicating my life a little.

11:37 xeqi: tbaldridge: cemerick has built https://github.com/cemerick/clojurescript.test. Not that it helps for core.async since it doesn't fall under the contrib umbrella

11:39 pepijndevos: You know, in math you can do these reorder things, like a + b = c to c - b = a. Would be neat to do that with clojure automagically.

11:39 EchoBot1: Echo: You know, in math you can do these reorder things, like a + b = c to c - b = a. Would be neat to do that with clojure automagically.

11:40 Echo: help

11:40 xeqi: technomancy: ^

11:40 EchoBot1: Echo: technomancy: ^

11:40 * ToxicFrog eyes EchoBot1

11:40 ToxicFrog: Whose fault is that?

11:40 EchoBot1: Echo: Whose fault is that?

11:41 Echo: even sending private messages end up in #clojure

11:41 bbloom: pepijndevos: what you're talking about is called symbolic programming. there are a few small projects to do things like that

11:41 EchoBot1: Echo: pepijndevos: what you're talking about is called symbolic programming. there are a few small projects to do things like that

11:41 Gooder: why I C-x C-e the code, it prompts ""No Lisp subprocess; see variable `inferior-lisp-buffer' ." ?

11:41 EchoBot1: Echo: why I C-x C-e the code, it prompts ""No Lisp subprocess; see variable `inferior-lisp-buffer' ." ?

11:41 ToxicFrog: To the /ignore

11:41 EchoBot1: Echo: To the /ignore

11:41 Echo: Fuck off, EchoBot1. :-)

11:41 pepijndevos: ban dat filth

11:41 EchoBot1: Echo: ban dat filth

11:41 bbloom: i've already ignored it :-P

11:41 EchoBot1: Echo: i've already ignored it :-P

11:42 pepijndevos: me too, but it's still annoying

11:42 EchoBot1: Echo: me too, but it's still annoying

11:42 Jarda: die

11:42 EchoBot1: Echo: die

11:42 Echo: die

11:42 coventry: Gooder: You have to start a repl. Try running M-x nrepl-jack-in before the C-x C-e.

11:42 EchoBot1: Echo: Gooder: You have to start a repl. Try running M-x nrepl-jack-in before the C-x C-e.

11:43 bbloom: technomancy is on the west coast though. he might still be sleeping

11:43 EchoBot1: Echo: technomancy is on the west coast though. he might still be sleeping

11:43 nDuff: ...do we really have any legitimate reason to allow clients from *.compute.amazonaws.com? I'd almost ban the whole subnet.

11:43 pepijndevos: bbloom, cool, thanks. Looking into that.

11:43 EchoBot1: Echo: ...do we really have any legitimate reason to allow clients from *.compute.amazonaws.com? I'd almost ban the whole subnet.

11:43 Echo: bbloom, cool, thanks. Looking into that.

11:43 Gooder: coventry: in the terminal, run the `lein repl` firstly?

11:43 EchoBot1: Echo: coventry: in the terminal, run the `lein repl` firstly?

11:43 hyPiRion: bbloom: no, he was awake 40 mins ago

11:43 EchoBot1: Echo: bbloom: no, he was awake 40 mins ago

11:43 TimMc: nDuff: Sure, some people run bouncers.

11:43 EchoBot1: Echo: nDuff: Sure, some people run bouncers.

11:43 pepijndevos: I don;t know where lazybot runs

11:43 EchoBot1: Echo: I don;t know where lazybot runs

11:44 coventry: Gooder: Wasn't what I was thinking of. Hold down Alt and press "x", then type "nrepl-jack-in", then return. A repl window should appear in a few seconds.

11:44 EchoBot1: Echo: Gooder: Wasn't what I was thinking of. Hold down Alt and press "x", then type "nrepl-jack-in", then return. A repl window should appear in a few seconds.

11:44 TimMc: This is still the same host as CommandBot: ~nodebot@ec2-50-18-210-65.us-west-1.compute.amazonaws.com

11:44 EchoBot1: Echo: This is still the same host as CommandBot: ~nodebot@ec2-50-18-210-65.us-west-1.compute.amazonaws.com

11:44 pepijndevos: bbloom, do you know any good libsa that do this?

11:44 EchoBot1: Echo: bbloom, do you know any good libsa that do this?

11:44 * hyPiRion perhaps it doesn't listen to /me messages.

11:44 * hyPiRion hurray!

11:45 coventry: Gooder: http://clojure-doc.org/articles/tutorials/emacs.html#creating_a_project

11:45 EchoBot1: Echo: Gooder: http://clojure-doc.org/articles/tutorials/emacs.html#creating_a_project

11:45 bbloom: pepijndevos: it's a very hard thing to do well. there is a mathematica/clojure bridge if you need something fancy. other than that, there are a lot of toy libraries to do it. if you only need the basics for polynomials, you can code it up yourself in ~1 hour

11:45 EchoBot1: Echo: pepijndevos: it's a very hard thing to do well. there is a mathematica/clojure bridge if you need something fancy. other than that, there are a lot of toy libraries to do it. if you only need the basics for polynomials, you can code it up yourself in ~1 hour

11:46 pepijndevos: bbloom, basically I just need to do the inverse of the sine/cosine stuff I did earlier. I could just use some brain cells t do it by hand...

11:46 EchoBot1: Echo: bbloom, basically I just need to do the inverse of the sine/cosine stuff I did earlier. I could just use some brain cells t do it by hand...

11:46 Gooder: coventry: okay, reading

11:46 EchoBot1: Echo: coventry: okay, reading

11:47 pepijndevos: it'd require less brain cells than writing a library

11:47 EchoBot1: Echo: it'd require less brain cells than writing a library

11:48 coventry: There's probably a solver which would invert it numerically for you fast enough for your application.

11:48 EchoBot1: Echo: There's probably a solver which would invert it numerically for you fast enough for your application.

11:49 seangrov`: bbloom pepijndevos Wasn't espresso built for that during GSoC?

11:49 EchoBot1: Echo: bbloom pepijndevos Wasn't espresso built for that during GSoC?

11:50 * TimMc hyPiRion: Good call.

11:50 seangrov`: pepijndevos: https://github.com/clojure-numerics/expresso

11:50 EchoBot1: Echo: pepijndevos: https://github.com/clojure-numerics/expresso

11:50 pepijndevos: thanks

11:50 EchoBot1: Echo: thanks

11:52 pepijndevos: hmmm, maybe using the even requires more brain cells than writing my function. Term rewriting is fancier though...

11:52 EchoBot1: Echo: hmmm, maybe using the even requires more brain cells than writing my function. Term rewriting is fancier though...

11:53 indigo: Looks like I found the source code

11:53 EchoBot1: Echo: Looks like I found the source code

11:53 bbloom: seangrov`: i wasn't following that closely, dunno

11:53 EchoBot1: Echo: seangrov`: i wasn't following that closely, dunno

11:54 Gooder: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot2: Echo: Echo: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 EchoBot1: Echo: Echo: Echo: Echo: Echo: Echo: Echo: Echo: coventry: still fails. actually I use the default basic Steve Purcell's configs.

11:54 papachan: ???

11:54 EchoBot1: Echo: ???

11:54 lazybot: papachan: Yes, 100% for sure.

11:54 EchoBot1: Echo: papachan: Yes, 100% for sure.

11:54 lazybot: EchoBot1: How could that be wrong?

11:54 EchoBot1: Echo: EchoBot1: How could that be wrong?

11:54 indigo: Kk, time to report this

11:54 EchoBot1: Echo: Kk, time to report this

11:55 indigo: It's this code here: http://runnable.com/UkmUo7yLFrctAAKe/irc-echo-bot-with-node-irc-for-node-js

11:55 EchoBot1: Echo: It's this code here: http://runnable.com/UkmUo7yLFrctAAKe/irc-echo-bot-with-node-irc-for-node-js

11:55 coventry: Gooder: Fails how?

11:55 EchoBot1: Echo: Gooder: Fails how?

11:56 coventry: indigo: How did you find that? Impressive.

11:56 EchoBot1: Echo: indigo: How did you find that? Impressive.

11:56 indigo: coventry: I can find anything

11:56 EchoBot1: Echo: coventry: I can find anything

11:56 indigo: Also Google

11:56 EchoBot1: Echo: Also Google

11:56 Gooder: coventry: C-x C-e the clojure codes, it prompts : inferior-lisp-proc: No Lisp subprocess; see variable `inferior-lisp-buffer'

11:56 EchoBot1: Echo: coventry: C-x C-e the clojure codes, it prompts : inferior-lisp-proc: No Lisp subprocess; see variable `inferior-lisp-buffer'

11:56 pepijndevos: wth is a Node bot doing in #clojure?

11:56 coventry: indigo: OK, google is impressive. :-)

11:57 Gooder: What about the result of the nrepl-jack-in?

11:58 Gooder: "Connected", a new buffer "*nrepl server*" created.

11:58 hyPiRion: the fact that it's a node bot isn't the problem. The problem is that it echoed everything

11:59 indigo: coventry: I posted a topic on their Get Satisfaction forum

11:59 http://support.runnable.com/runnable/topics/irc_spam_possibility_of_botnet

12:00 I mean, it does run through *their* servers

12:01 Gooder: coventry: I have to leave now, thank you for your helps.

12:01 coventry: Gooder: Good luck.

12:02 dsabanin: hey guys

12:03 is there any particular meaning in using full java class names with namespace in type hints instead of relying on the short names after import?

12:03 gfredericks: I recall some kind of bug with macros that would force you to do that

12:04 clojurebot: No entiendo

12:04 gfredericks: but I don't think there's any intrinsic reason to

12:04 clojurebot: Titim gan éirí ort.

12:04 gfredericks: will the bot respond to this too?

12:04 maybe it was a random chance double hit

12:05 dsabanin: so I guess until I hit that bug (if I do), I'm going to use the short type hints

12:05 thanks

12:08 gfredericks: yeah the bug was pretty loud -- it was a ClassNotFound exception at compile time. so you shouldn't have to worry about it otherwise.

12:09 coventry: indigo: Thanks for doing that. I +1'd.

12:10 indigo: Yeah no problem

12:10 Those guys need to get their shit together or else they're going to cause DoSes ;P

12:15 TimMc: Such a hilariously bad idea.

12:15 coventry: Why does Compiler/load bind RT.UNCHECKED_MATH to RT.UNCHECKED_MATH.deref()? Isn't that a no-op? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7054

12:16 dnolen: coventry: no, it was an atom and then it becomes a boolean

12:17 NotAnEchoBot: Echo: In audio signal processing and acoustics, a reflection of sound, arriving at the listener some time after the direct sound.

12:17 coventry: dnolen: Oh, got it. Thanks.

12:18 wakeup: Hi all

12:20 I have the following situation: I want to build a UNIX-daemon that starts some threads (services) and then idles/does nothing wrapped in a (try ... (finally ...)) form where the started threads should be killed softly in case the process gets kill'ed. How would you guys do this?

12:21 I have tried something like (try (loop [] (Thread/sleep 999999) (recur)) (finally clean-up))

12:21 TimMc: "Killed softly"?

12:22 wakeup: TimMc: E.g. clean up after the started services.

12:24 Simplified, how do I never return and just idle?

12:24 TimMc: wakeup: So if it gets a SIGTERM, it should pass that on to the services.

12:25 wakeup: TimMc: No actually not that invovled, the "services" are plain Thread

12:25 Morgawr: wakeup: if you want to wait undefinitely, just use a promise and deref on it

12:25 wakeup: s

12:26 TimMc: wakeup: Metaphorically. :-)

12:26 Morgawr: then you could have a signal handler (not sure how that works in clojure tbh) delivering the promise once a signal is received

12:26 and when the promise is delivered you clean everything and exit

12:26 bja: anyone know offhand of the clj password hasher library that contains both bcrypt and scrypt hashers?

12:26 I thought I saw one and I apparently forgot to star it

12:27 weavejester/crypto-password

12:27 nvm

12:28 TimMc: wakeup: That Thread/sleep can throw an InterruptedException, and I believe it *will* be thrown if the JVM gets an actual SIGTERM. You can handle it, ask your services to clean themselves up, and then return.

12:28 wakeup: SO you think looping a sleep is fine?

12:28 TimMc: However, there's probably some library out there that will do supervision better.

12:30 tbaldrid_: wakeup: or use core.async. The thread macro returns a channel that is closed when the thread crashes/finishes. Just alts!! over the channels and you can easily handle the termination of the threads. Add a common exception channel for the threads to send to on failure, and you have a fairly simple system.

12:31 cmajor7: tbaldridge: thanks! (for your thoughts on testing core.async). good to know I am not alone :)

12:31 tbaldridge: cmajor7: np

12:39 seangrov`: Is it even possible to figure out a Java api in an exploratory way? I looked through google-oauth-client's oauth1 namespace and javadocs, trying to piece together what had to be instantiated where and given to whom, and lost the thread. They have docs for the oauth2 stuff, read that, and realized I wouldn't have figured it out the oauth1 stuff for a long time if it's analogous to the oauth2 api.

12:45 TimMc: seangrov`: I once considered writing a program that would effectively tab-complete its way to any object you wanted by finding a type-checker-valid path through an API.

12:45 But I wouldn't recommend that approach for anything having to do with security. :-P

12:45 joegallo_: eclipse was very good at that for java apis

12:46 technomancy: "no no, I have *sheep* and I want *wheat*. anybody?"

12:46 * rasmusto throws a brick at technomancy

12:47 technomancy: you mean a BrickFactory?

12:47 rasmusto: :)

12:50 coventry: Is there a cleaner way to add multiple key/value pairs from one map to another than (reduce #(assoc %1 %2 (map1 %2)) map2 [:key :words])?

12:51 rasmusto: coventry merge and select-keys?

12:51 coventry: rasmusto: thanks.

12:52 rasmusto: ,(merge {:a 1} (select-keys {:b 2 :c 3} [:b]))

12:52 clojurebot: {:b 2, :a 1}

12:52 rasmusto: remember that merge favors the rightmost map

12:52 sm0ke: umm guys there is no mailbox concept in core.async? In cse of high message throughput what would be the strategy when working with core.async?

12:53 coventry: rasmusto: Thanks. That would have bitten me.

12:53 * TimMc pounds technomancy's sheep

12:53 sm0ke: i am kind of comparing this to actors in akka (scala) which have mailbox concepts which can be persistent too

12:54 tbaldridge: sm0ke: high message throughput? Explain. We have buffers in core.async.

12:55 sm0ke: tbaldridge: umm oh i see...can a buffer be made to overflow on to disk?

12:55 tbaldridge: sm0ke: there aren't implementations that do that, but the protocol interface for buffers is super super simple and need not be thread safe. So writing your own wouldn't be that hard.

12:56 sm0ke: this is all that is needed to create a buffer: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/buffers.clj

12:56 notice that none of these are thread-safe, core.async does locking so only one thread will call a buffer's methods at a time.

12:57 sm0ke: tbaldridge: cool and awesome..i was just being a tool..i never used a persistent mailbox in akka anyways ;p

12:57 tbaldridge: sm0ke: that being said, unbounded message queues are a design bug, so often its better to explicitly define a size for a buffer.

12:58 sm0ke: tbaldridge: yea specially if we can have sliding window kind of queue..it would be much better

12:59 oh wow i found (chan (sliding-buffer 10))

13:00 i couldnt seem to find any advantage of using actors at all

13:00 they are verbose

13:01 they need callbacks

13:15 bitemyapp: bbloom: yes I've been impacted by that perf issue.

13:15 bbloom: I can't post to clojure-dev though

13:15 bbloom: bitemyapp: if you got a moment, see if you can give alex some help by testing his updated patch

13:16 bitemyapp: bbloom: I could send it through a side-channel, but not directly to that thread.

13:16 bbloom: bitemyapp: no CA?

13:16 bitemyapp: sigh, no.

13:16 I know, I know, I should.

13:16 I'd also have to dig up an old version of the templating stuff Yogthos and I worked on.

13:16 we had a templating library whose main loop runtime was dominated by RestFn, not even kidding.

13:16 tbaldridge: I thought non CA people can comment on JIRA though, perhaps you can do it that way?

13:16 bitemyapp: and it was a quasi-reasonable implementation.

13:17 lazy-seq and recursion.

13:17 bbloom: if I can dig up my copy of YourKit and the offending code, I'll make certain it reaches Mr. Danger.

13:17 bbloom: bitemyapp: k

13:17 bitemyapp: thanks for making me aware he was hustling on this.

13:18 I hope he knows we appreicate what he's been doing to catch everything up.

13:19 mdrogalis: Looking for a new book. Anyone read anything good lately? Open ended.

13:19 bitemyapp: seangrov`: I'll respond to the thread tonight, after I've had a chance to hum a bit.

13:19 mdrogalis: I've got a few options for you that are really good.

13:19 mdrogalis: Fire away.

13:20 bitemyapp: mdrogalis: 1. epic sci-fi, might've already read it, but leaves an impact - well known classic. 2. Very well characterized and enjoyable fantasy with well thought-out magic system, probably the best and most thrilling trilogy I've read in many years. 3. Naval historical fiction, 20 book series but you can drop in and out at will, you won't be compelled to proceed. Two protagonists that are both interesting.

13:21 mdrogalis: which do you want?

13:21 I can recommend CS/programming stuff too, if that's what you want, but I figured I'd just go for pure reading enjoyment.

13:21 mdrogalis: Hm, none of those quite caught me. Bring on the nerd material.

13:22 hyPiRion: I can recommend "Hyperion" by Dan Simmons.

13:22 bitemyapp: mdrogalis: Art of the Metaobject Protocol?

13:22 hyPiRion: are you named after the book?

13:22 mdrogalis: hyPiRion recommends himself. D:

13:22 technomancy: I'm reading that now

13:22 hyPiRion: bitemyapp: no, although it's one of the better books I've read :p

13:22 mdrogalis: Ill check that one out, thanks bitemyapp.

13:23 bitemyapp: mdrogalis: AMOP is the book that brought aspect-oriented programming to Common Lispers. It's a common n+1 recommendation I make to people that already know Lisp.

13:24 coventry: mdrogalis: A Hellhound on His Trail. History of MLK's assassin, related as a thriller.

13:24 bitemyapp: or (inc n) if you like. heh.

13:24 mdrogalis: bitemyapp: That's pretty neat. Still gotta check out LoL too.

13:24 coventry: Sweet, thanks.

13:24 deg: bitemyapp: yes and no... CL had "before" and "after" mixins well before AMOP.... not quite full aspect-oriented, but definitely the seeds of the idea.

13:24 bitemyapp: mdrogalis: LoL is more about macros and macros writing macros. A lot of people think of it as arcane/crazy, but I feel less like that's the case as I get older.

13:25 deg: well sure, people were doing function decoration from afar, but it wasn't nearly as well formulated as what Kiczales was going for.

13:25 turbopape: If noir is deprecated, what is the replacement ?

13:25 mdrogalis: noir-lib is the direct replacement

13:26 deg: bitemyapp: The usual "if I see further it is because I stand on the shoulders of giants" (or however the quote goes)

13:26 But, yes, I agree with you; just nitpicking

13:27 bitemyapp: I love it when somebody rejects my PR to fix a bug, then when I go to use their thing again, the same Null Pointer Exception my PR was supposed to fix pops up, then I take a screenshot and paste the error into a github issue, and they're nowhere to be seen.

13:27 I need Knives over TCP/IP to become a thing.

13:27 SIG_STAB

13:27 deg: Can a project's :main namespace come from one of its dependency libraries, or must it be defined directly in the project itself?


13:28 technomancy: deg: it should work; give it a try

13:28 deg: technomancy: thx, will do.

13:29 turbopape: ok, compojure + lib-noir, I get it ...

13:30 bitemyapp: turbopape: good, because I was questioning my sanity yesterday when I forgot to load the wrap-params middleware.

13:30 I derped when I should've not been an idiot.

13:31 turbopape: bitemyapp, yeah, seems weird to deprecate "noir" and to recommend "lib-noir" (on top of compojure...)

13:31 bitemyapp: turbopape: no, it makes sense.

13:31 technomancy: well, the problem with noir was that it wasn't a library

13:31 bitemyapp: turbopape: it had to made into a library from which people could pick and choose what they wanted.

13:32 turbopape: ok, I just pointed the fact that the message fro the website is confusing ... :)

13:32 excuse my NOOBNESS :)

13:32 bitemyapp: Weavejester is the one true Pope of "everything can be middleware!"

13:32 indigo: Middleware ftw

13:32 technomancy: ah; they finally got a deprecation notice on webnoir.org; good

13:33 bitemyapp: technomancy: I had to bug the shit out of him, but yes.

13:33 I was practically banging on his door with pitchforks and a torch

13:33 technomancy: one of the upsides of living in SF, I suppose

13:33 turbopape: :)

13:33 bitemyapp: luckily it wasn't physical harassment, but that option was under advisement.

13:33 rasmusto: bitemyapp: is libnoir your pitched fork?

13:34 * rasmusto stops the puns

13:34 bitemyapp: rasmusto: lib-noir is yogthos, Raynes, and the long tail of contributors. I just boss them around occasionally.

13:34 rasmusto: ah, gotcha

13:34 bitemyapp: I'm still trying to get them to stop using dynamic vars.

13:34 xeqi: I've been considering templating as middleware

13:34 bitemyapp: so that lib-noir can become completely async-safe.

13:34 xeqi: I can tell you exactly how it could be done.

13:34 xeqi: if you care to know.

13:35 xeqi: bitemyapp: I've done it in a small project

13:35 bitemyapp: xeqi: it's super handy for testing, because then you can request context maps from handlers instead of rendering HTML.

13:35 xeqi: then your "controllers" roughly speaking, become testable.

13:35 technomancy: oh man

13:35 that sounds like fun

13:35 bitemyapp: Doesn't need to be middleware though.

13:35 coventry: Is there a more clojure-ish way to do (. Compiler/LINE_AFTER set 1), given that I've already bound LINE_AFTER in a (binding) form (so I assume (set!) is out)?

13:35 bitemyapp: technomancy: old idea I stole from Pylons/Pyramid. I love it.

13:36 technomancy: I just make a mock request that asks for the JSON in the test cases.

13:36 it's proper "web" style to just use the content accept header to do this anyway.

13:36 technomancy: yeah, I've often wondered what a "proper" generalized content-accept system would look like in ring

13:36 coventry: (I'm porting Compiler/load to clojure. Don't suppose anyone knows of prior work along these lines?)

13:36 technomancy: I should have known the answer would be middleware

13:36 it is always the answer

13:37 bitemyapp: technomancy: I don't do it through middleware, but that's an option.

13:37 technomancy: I capture the request through a dirty macro and condition the behavior against the content of the request.

13:37 xeqi: it also leads to pure view functions that take a map of vars, which I like

13:37 technomancy: huh, a map of vars?

13:37 bitemyapp: xeqi: this only works nicely partly because Selmer is Django-style templating and naturally accepts an associative data structure to create the template rendering context.

13:38 which can just be returned as a map or JSON anyway.

13:38 xeqi: technomancy: eh, associative data structure of names to values

13:38 technomancy: sure

13:39 xeqi: bitemyapp: how are you doing layout wrapping outside of a middleware?

13:39 bitemyapp: xeqi: Selmer dude.

13:39 xeqi: learn it, love it, live it. https://github.com/yogthos/Selmer/

13:40 also, since we're on the topic of middleware, https://github.com/weavejester/clout/ <--- really useful.

13:41 technomancy: isn't cloud part of compojure?

13:41 clout

13:41 xeqi: ah, do it at the template level when they are loaded by the view functions. thats a good idea

13:41 bitemyapp: xeqi: :)

13:41 xeqi: technomancy: if you want your middleware to use compojure

13:41 technomancy: huh

13:42 maybe I should try writing a web app that's more than 500 lines some day

13:42 bitemyapp: technomancy: yeah but then hair sprouts from your knuckles and you turn into me.

13:43 xeqi: is there a good ring content negotation lib?

13:44 bitemyapp: xeqi: https://github.com/rnewman/clj-conneg https://github.com/ngrunwald/ring-middleware-format

13:44 nothing super-holistic.

13:46 TimMc: bitemyapp: Is (2) written by the son of a well-known economist, by any chance?

13:49 coventry: What is the right way to refer to LispReader.ReaderException in clojure catch clause?

13:49 deg: technomancy: fyi, :main from a library class works fine, as expected.

13:50 xeqi: ,clojure.lang.LispReader$ReaderException

13:50 clojurebot: clojure.lang.LispReader$ReaderException

13:50 coventry: xeqi: Thanks.

13:50 bitemyapp: TimMc: don't think so.

13:55 coventry: What's the right way to create a new Compiler/CompilerException for throwing? ##(clojure.lang.Compiler$CompilerException. "foo" 1 2 (Exception. "bar"))

13:55 lazybot: java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.Compiler$CompilerException

13:55 coventry: Huh, that's a different error message than I get in my repl. I get ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

13:56 Oh, do I have to explicitly make the arguments ints?

13:56 xeqi: &*clojure-version*

13:56 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

13:57 rasmusto: ##*clojure-version*

13:57 ,*clojure-version*

13:57 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

13:58 indigo: Lazybot is lazy, it's two versions behind ;P

13:58 coventry: Good to know. I generally choose between the two depending on where it is in my message text. :-)

13:59 TimMc: bitemyapp: Anyway, I'd be curious to hear that recommendation. I like well-founded magic systems.

14:00 coventry: Oh, my repl is horked. Can create a CompilerException instance without problems in a new one.

14:02 bitemyapp: TimMc: Mistborn

14:08 coventry: I'd be grateful if someone with java interop experience could take a look at https://www.refheap.com/19541 vs https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7034 The logic is pretty simple, it's the java interop expressions I'm likely to screw up.

14:22 craigbro: blurp

14:24 dnolen: jonasen: re: cljsfiddle.net so are you thinking about passing compiler warnings to the front end? Also if you have any suggestions about changing how we emit warnings to make them easier to report in cljsfiddle.net I'm all ears - I want to make the warnings usable by tools.

14:24 coventry: updated so at least it compiles. :-) https://www.refheap.com/19541

14:34 Fer__: Hello, what's the reasoning behind making thread pools size = number of processors + 2. Google doesn't tell me much

14:35 jtoy: how does one get ring/jetty to bind to ?

14:37 joegallo_: Fer__: well, i mean, of course you want at least the number of processors. so that's a start. and then two better is like practically twice as good, no doubt. one wouldn't be nearly enough and three would be utter lunacy.

14:37 Q.E.D.

14:37 clojurebot: No entiendo

14:38 Fer__: clojurebot: me neither

14:38 clojurebot: excusez-moi

14:40 jtoy: nm, isee

14:41 technomancy: "Two shall be the number of the counting, and the number of the counting shall be two. Five is right out."

14:43 deg: If my project includes a library twice (once directly, and once via another library); and if the included library has a top-level def of an atom; then what happens?

14:43 Does java have some defined linker-like behavior, or is it just a window to disaster?

14:43 coventry: deg: Depends on how you include. If you use require/use, and don't use :reload, it only gets executed once.

14:44 Fer__: =[

14:45 technomancy: deg: only an issue during development

14:45 deg: Hmm, that's good but makes it less clear what lossage I'm hitting. Probably I'll shout back in a few minutes when I've debugged further.

14:45 technomancy: what do you mean?

14:46 technomancy: deg: the atom will get reset back to the initial value whenever you reload, but reloading only happens in development

14:46 coventry: deg: You can verify the number of times it's executing by putting a println in the included file.

14:46 deg: I see; good idea.

14:46 aaelony: first foray into clojurescript... I have clojurescript code that uses a data structure to create a visualization. Should my existing clj code (1) talk to the database and write the data out to file such that the cljs code can pick it up, or (2) should I attempt to make cljs talk directly to the database? What do people recommend?

14:47 TimMc: Fer__: http://stackoverflow.com/questions/13834692/threads-configuration-based-on-no-of-cpu-cores

14:47 That doesn't tell you why a thread pool is cores + 2, but it does have some good discussion of how one might pick such a number.

14:57 Fer__: TimMc: thanks

15:00 deg: I'm starting my project with lein ring-server headless. I have code in one .clj file, including a top-level println, that doesn't run when the project starts. (And, a println in another file, the one tagged :ring in the project.clj, does print, so it's not a stdout problem).

15:03 coventry: Yay, my Compiler/load clone works with only minor modifications.

15:04 deg: Hmm, if I require the second file from the main file, then I see its println. Does lein ring only include files that are transitively required by the entry point?

15:06 gfredericks: deg: yeah that sounds plausible

15:06 deg: (yeah, I know that sounds dumb. ... how could code be needed if its not called from the entry point. Full story, effectively, is that the other code is loading plug-ins that get registered in an atom owned by the main file)

15:07 Am I just barking up a path that can't work?

15:07 gfredericks: and you don't want to require it from the entry point because that seems like the wrong responsibility?

15:07 deg: Exactly.

15:08 gfredericks: so who cares about this? the entity starting the server?

15:08 if you could do this from your project.clj somehow would that feel better?

15:08 deg: In the fuller picture, the problem may go away, because there will be a diamond dependency that will fix the problem (I think). Full story is:

15:09 One small project, "muxx" is a bit of compojure code that dispatches to multiple small websites.

15:09 Each website will be its own project and will register itself with muxx.

15:10 A deployment will be another tiny project that will just list all the websites that are deployed together on one site.

15:11 So, if I made the main entry point be the deployment site, then all should work. But, since there will be multiple deployments, I'd rather not duplicate code and instead have the entry point always be in muxx.

15:11 (end of typing)

15:11 llasram: deg: `require` is a function -- you can provide config which lists the namespaces to `require`

15:14 deg: llasram: I see, but not quite sure how to apply that. ...

15:14 I guess the deploy site could ask muxx to require each of the needed website namespaces. Yeah, a bit more plumbing than I'd like, but I can see that working, I think.

15:17 piranha: dnolen: are you by any chance here? I discovered one thing and I'm not sure if that's intended or not...

15:17 dnolen: piranha: what's up?

15:18 piranha: dnolen: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L211 - this take-while here basically says 'this file can provide only single module'

15:18 I just have a big file with lots of modules in there...

15:18 and if I comment this take-while out, it gets in

15:19 (I'm still trying to join a gcc-modularized stuff with :libs option)

15:19 so the question is if you think it would be harmful to remove this line

15:20 dnolen: piranha: why do you have file with multiple modules?

15:21 deg: llasram: gfredericks: (can IRC flag two folks?) Actually that doesn't, because the websites need to require the muxx ns to call its api. So, I can't require them back since cycles are not allowed.

15:21 piranha: dnolen: closure compiler has a mode to convert a lot of file using CommonJS modules into a single file using goog.provide/require

15:21 deg: So, looks like my only choice not to have my entry point in muxx, but rather in the deployment. Right? sigh.

15:22 dnolen: piranha: and it can't convert them into separate files?

15:22 piranha: dnolen: at least I can't find how... it just spits them in the stdout

15:23 llasram: deg: They're only not allowed when they're actually recursive. You can have `muxx` expose a function which when called causes it load other namespaces, even namespaces which themselves require `muux`.

15:23 dnolen: piranha: I would investigate some more, or figure how to make Closure do the right thing. Dependency resolution in closure.clj assumes module -> file, I don't want to complicate that logic at all.

15:24 piranha: dnolen: oh... I see, maybe I can separate this stuff to small files

15:24 dnolen: piranha: yes

15:25 deg: llasram: Really? Wow. Why is that not considered to be a cycle?

15:25 piranha: dnolen: also, unrelated things - maybe you can suggest something... if a library gets compiled in advanced mode and something small is failing, what do you usually do to discover what it is?

15:25 llasram: deg: Because it isn't a load-time cycle

15:25 The `muxx` namespace is already loaded. Once fully loaded, it's free to cause other nses to be loaded which depend on it

15:26 deg: llasram: cool. And, the run-time load will still cause one-time evaluation of all forms in the loaded namespace?

15:27 llasram: Yep. `require` has the same effect at "run time".

15:28 deg: Thanks. This is going to be a fun API to define; loads of trampolining.

15:29 Might even become generally useful. My motivation is that I have some VERY lightly-used personal sites, and I want to deploy multiple sites onto one cloud-hosted site to reduce deployment costs.

15:30 llasram: Oh -- in a way that using e.g. jetty as a multi-application container doesn't already support?

15:30 jcromart_: why the heck is clojure.xml even still there?

15:30 deg: ???? OH. I didn't know jetty already had this support.

15:31 My guess, then, is that I was just reinventing the wheel. Guess I should take a long pause and look at the jetty docs.

15:31 jcromart_: is there any reason hiccup would be inappropriate for generating XML?

15:31 deg: Big thanks! You probably just saved me a few hours.

15:32 llasram: Hah. I've never done it myself, but I know some people here do (e.g. amalloy IIRC)

15:32 Anyway, good luck :-)

15:33 amalloy: we've actually stopped doing it, llasram. too much arcane jetty weirdness for little benefit, given the server resources we have available

15:33 deg: Serves me right for trying to program web sites in Clojure without knowing the first thing about J2EE.

15:33 amalloy: Do you recommend that I wrestle jetty, or roll my own in Clojure?

15:33 amalloy: meh

15:34 rolling your own version of jetty sounds kinda pointless

15:34 deg: agreed, until you said "too much arcane jetty weirdness". Definitely 'meh' either way.

15:35 amalloy: i can't imagine why you would write it to have cycles, though, if you were going to do it. have the server namespace expose hooks, or functions that take a handler, or something. there's no reason at all it should know about the various handler namespaces

15:36 deg: Ideally, yes. The only reason for the cycle is if I want the ring entry point to be in the server, then I needed (per above) some way to tell the loader to bring in the namespaces that will register with it.

15:36 amalloy: or have a -main function that calls (muxx/serve [{:sitename "foo" :handler f} {:sitename "bar" :handler g}])

15:36 and -main requires the namespaces containing f and g itself

15:37 Morgawr: question.. how can I run a .clj file/script from the command line with lein? Like in clojure normally I can just do "clojure myscript.clj" and it will compile + execute the single file

15:37 deg: Yup. The only downside of that is that I then need to write a -main for each deployment. But, I'm being silly. I can reduce that down to one line of code.

15:37 Morgawr: I want to do the same with lein

15:37 without having to create a whole project

15:38 deg: So, yeah. Looks like choice 1 is to see if Jetty just does what I want. Choice 2 is to let the -main be the deployment. The hairy namespace cycles are a distant choice 3.

15:39 jonasen: dnolen: re:warnings. I'm planning to start with the new error messages and see if I can highlight the offending code in CodeMirror. And yes, if I can easily pass warnings I'll do that too.

15:39 deg: Thanks all. Hitting the witching hour in my timezone. I think I've got my marching orders for tomorrow. g'nite all.

15:39 jonasen: dnolen: I'm not a big fan of warnings in general.. I like that in golang there are no warnings, either the code compiles or it doesn't.

15:43 noonian: Morgawr: https://github.com/kumarshantanu/lein-exec

15:43 Morgawr: noonian: thanks!

15:44 melipone: hello! I have a (print ".") in a loop statement before the recur but it does not print. Changing that to println works but I don't want that. What to do?

15:45 joegallo_: print doesn't flush

15:45 you need to flush

15:46 melipone: ha! thanks

15:47 TimMc: There

15:47 There's also *flush-on-newline*, incidentally.

15:47 It's not quite what you're asking about, but it's worth knowing that it exists.

15:47 melipone: TimMc: thanks

15:48 TimMc: (I don't think you can test it in the REPL, since the REPL seems to call flush...)

15:48 dnolen: piranha: used to be quite hard, now you can use source maps

15:49 jonasen: yes, but CLJS compilation model is a bit trickier because of things like browser REPL where you don't currently consistently know what has been defined

15:52 jonasen: dnolen: yeah, I'm sure there are good reasons. That's why I said "in general" :)

15:54 Morgawr: best way to remove all odd positions in an array?

15:54 like I have [1 2 3 4 5] and I want to have [2 4] (content doesn't matter, it's the index that matters)

15:55 jonasen: dnolen: When are you planning a new cljs release?

15:56 any blocking issues?

15:56 Morgawr: oh, looks like I want take-nth

15:56 TimMc: melipone: Cancel that, you can test it in the REPL... I just made the mistake of using Thread directly, which doesn't convey *out*.

15:56 sroy: hi, new to clojure and I have a "import" question if anyone would like to help me

15:56 TimMc: (def nf (future (binding [*flush-on-newline* false] (loop [] (Thread/sleep 500) (println "foo") (recur)))))

15:56 dnolen: jonasen: not really, probably later in the week, did you land a change that cljsfiddle really needs or something? the alias thing?

15:57 TimMc: And then run (flush) after a few seconds.

15:57 melipone: TimMc: ok

15:57 jonasen: nah, no hurry.

15:58 I did notice the alias issue there but it's not a big thing

15:58 jcromart_: Could I dispatch a multimethod based on set membership?

15:59 it's a little messy, I'll admit

15:59 scriptor: looking at gensym, is the heart of its implementation based on AtomicInteger and incrementing it every time it's called?

16:01 Fer__: jcromart_: you can dispatch on anything! :P

16:01 jcromart_: I've kind of got it going now

16:01 but I mean can I specify a dispatch value and test if that value is a member of a set?

16:01 It's potentially ambiguous

16:01 which is a bit troubling

16:02 namccarty: scriptor: http://clojuredocs.org/clojure_core/clojure.core/gensym

16:02 coventry: scriptor: That's how I read it. Interesting that there's no checking for collision with existing symbols.

16:02 namccarty: expand the source fold

16:02 scriptor: namccarty: yeah, I know how to use clojuredocs

16:02 Fer__: jcromart_: Sorry. I'm not following.

16:02 scriptor: I was looking at RT.java

16:02 Fer__: dispatch values are functions

16:03 namccarty: It does indeed look like it has an atomic integer it is incrementing

16:03 jcromart_: Fer__: functions that return values, which must "isa?" the dispatch value in a defmethod

16:04 scriptor: coventry: that surprised me too, maybe they get around it with the prefixing

16:06 Creap: I have a seq of functions that I want to apply to each item in a seq (the seq is a line-seq from a BufferedReader). I currently have (doseq [line (map parse-line lines)] (doseq [cb cbs] (cb line))))

16:06 coventry: jcromart_: You could probably get the effect you're looking for by representing the sets in (derive) relationships. Then you would get errors when the relationship was ambiguous.

16:06 Creap: I just have a feeling there is a more Clojure:ish way, this is my second day with Clojure..

16:07 coventry: Creap: (apply juxt cbs)?

16:07 That will generate an unused vector of the results, though.

16:07 Creap: and the seq is lazy so it would be a no-op?

16:09 I noticed my first attempts were basically imperative programming within let macros, so now I'm making another attempt trying to dig into the list processing

16:09 coventry: No, ((apply juxt cbs) line) should be eager.

16:11 ToxicFrog: (->> lines (map parse-lines) (map (apply juxt cbs)) ?

16:11 TimMc: &[(gensym) (gensym)]

16:11 lazybot: ⇒ [G__85825 G__85826]

16:11 TimMc: &[(gensym) (gensym)]

16:11 lazybot: ⇒ [G__85836 G__85837]

16:11 ToxicFrog: (doc apply)

16:11 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

16:11 TimMc: &(let [g (gensym)] [g (= g 'G__85847)])

16:11 lazybot: ⇒ [G__85847 true]

16:11 ToxicFrog: Oh wait, juxt is not comp

16:12 TimMc: coventry: ^ Clojure's genysm just isn't very good.

16:12 Creap: what do you mean with "not comp"

16:13 ToxicFrog: Creap: given a line line and a set of callbacks f g h, do you want [(f line) (g line) (h line)], or (h (g (f line)))?

16:13 Creap: the former

16:14 ToxicFrog: Oh, then you do want juxt. Ignore my confusion!

16:14 TimMc: Extra credit: Come up with f, g, h such that (= ((comp f g h) 5) ((juxt f g h) 5))

16:15 ToxicFrog: I think (->> lines (map parse-lines) (map (apply juxt cbs)) will actually do what you want, then.

16:15 hyPiRion: TimMc: is that actually doable?

16:15 TimMc: I dunno.

16:16 Creap: I'm writing an IRC program, I just call this function with a seq of callbacks that will be invoked for each line, from a line-seq

16:16 TimMc: hyPiRion: I think it is.

16:16 hyPiRion: yeah, I can see a way now I think

16:17 coventry: ,(let [g (gensym) d (Integer/parseInt (re-find #"\d+" (str g))) g2 (symbol (str "G__" (inc d)))] ((juxt identity eval) `(let [~g2 (gensym)] ~g2)))

16:17 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:17 coventry: Bah. My output was [(clojure.core/let [G__25216 (clojure.core/gensym)] G__25216) G__25218]

16:18 TimMc: &(let [f #(if (= % 7) [:hi 6 6] :hi) g inc h inc] (= ((comp f g h) 5) ((juxt f g h) 5)))

16:18 lazybot: ⇒ true

16:18 TimMc: BAM

16:18 ^ Spoiler, sorry.

16:19 As for the general case... I *think* I have an answer for that as well.

16:19 Creap: ToxicFrog: It just returns nil, I probably need doseq?

16:20 coventry: "Gensym collisions can be engineered." https://groups.google.com/forum/#!topic/clojure/-054P1u5M7o

16:20 mtp: "doseq uis"

16:20 scriptor: hah

16:21 coventry: Creap: Wrap it in (doall)

16:21 scriptor: yeah, I guess the only concern is that eventually someone might write a convoluted enough of a mess and runs into this problem

16:21 llasram: Creap: OR `dorun` if you don't care about the return values

16:22 Creap: yeah, that worked. cool

16:22 scriptor: I guess using a combination of microtime and a random integer would be a bit safer

16:22 hyPiRion: TimMc: Find f, g, h such that (= ((comp f g h) x) ((juxt f g h) x) [x x x])

16:22 scriptor: anyway, good to know I can implement gensym in my lisp in a minute

16:23 hyPiRion: not sure if that's possible

16:23 TimMc: hyPiRion: Oh, that's actually easy. I think.

16:23 hyPiRion: TimMc: not sure what h may be there.

16:26 TimMc: Oh, nope. So much for that.

16:27 `cbp: you can if it's [[x] [x] [x]] instead :P

16:28 hyPiRion: well, there's one way I think

16:29 coventry: Oops, there are a few more gensyms in the construction of that form, I guess. Have to inc it a couple more times: ##(let [g (->> (gensym) str (re-find #"\d+") (#(Integer/parseInt %)) inc inc inc (str "G__") symbol)] ((juxt identity eval) `(let [~g (gensym)] ~g)))

16:29 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

16:32 TimMc: hyPiRion: You're gonna like this...

16:32 &(let [gross (reify Object (equals [_ x] true)), f #(if (identical? % gross) [gross gross gross] gross), g (constantly gross), h (constantly gross), x 5/19] (= ((comp f g h) x) ((juxt f g h) x) [x x x]))

16:32 lazybot: ⇒ true

16:32 `cbp: LOL

16:32 hyPiRion: (inc TimMc)

16:32 lazybot: ⇒ 49

16:33 llasram: (inc TimMc)

16:33 lazybot: ⇒ 50

16:33 scriptor: &(gensym)

16:33 lazybot: ⇒ G__86045

16:34 scriptor: &(gensym)

16:34 lazybot: ⇒ G__86055

16:34 scriptor: hmm

16:34 hyPiRion: &(let [sym (gensym) h #(with-meta % {sym true}) g #(if (-> % meta sym) (constantly %) %) f #(if (fn? %) [(%) (%) (%)] %) x 'foo] (= ((comp f g h) x) ((juxt f g h) x) [x x x]))

16:34 TimMc: (inc amalloy) ; who I learned that trick from, I think

16:34 lazybot: ⇒ true

16:34 ⇒ 72

16:34 hyPiRion: doesn't work for non iobjs though

16:39 TimMc: hyPiRion: g can be identity, and f can take g's dispatch and avoid wrapping stuff in fns

16:40 That allows you to use a pipeline of n >= 2 fns.

16:40 hyPiRion: wehey, generalized.

16:46 technomancy: Morgawr: not sure if you found this, but a better solution than lein-exec is to use clojure.main

16:46 lein run -m clojure.main/main -i somefile.clj

16:46 Morgawr: technomancy: ah, that's nice too

16:46 thanks

16:58 JanxSpirit: what is the current recommended toolset for building REST services in Clojure? I'm thinking something lightweight like Scalatra, without MVC or presentation at all - Json, auth, content negotiation etc would all be great

17:01 TimMc: hyPiRion: I had been thinking of using state and blocking, but juxt and comp evaluate the fns in opposing orders.

17:01 It would also be hard to achieve state separation.

17:02 noonian: JanxSpirit: on top of ring you could use compojure for routing, friend for auth, and there are ring middlewares for serializing different formats based on the content-type

17:03 JanxSpirit: noonian - cool…so it's sort of mix and match the pieces you want. Are there any projects similar to Dropwizard for Java that group together the commonly used bits so they all play nicely?

17:04 maybe it's not as much of a consideration for Clojure?

17:04 katratxo: JanxSpirit: http://clojure-liberator.github.io/liberator/ ?

17:04 noonian: JanxSpirit: I've never heard of Dropwizard, but I think luminus does something like that http://www.luminusweb.net/

17:06 JanxSpirit: luminus is basically a minimal project that has already put the pieces together, for what you want you would probably want to take out the code and dependencies for templating and what not

17:06 JanxSpirit: but for getting started, it might be wiser to start from something simpler like the compojure_app template

17:06 and just add in libraries as you need them

17:06 JanxSpirit: looks like a similar idea - thanks noonian and katratxo

17:07 sounds like a plan

17:07 is there a standard json serializer? or a wrapper for Jackson or something? Not asking anyone to Google for me - I've looked around - just wondering if there's one that's preferred

17:09 xeqi: JanxSpirit: I perfer chesire

17:09 https://github.com/dakrone/cheshire

17:10 JanxSpirit: thanks xeqi

17:12 technomancy: "Discerning Clojure programmers prefer the freshness and exciting taste of Cheshire-brand JSON products."

17:13 danlarkin: ...it's toasted

17:16 noonian: yeah, cheshire's got a sweet name and its api is a superset of the other json library thats in use think

17:18 joegallo_: cheshire's a pretty good library, but that dakrone is a bit of a pill -- not the nicest guy you'll ever meet

17:19 jk, he's totally the nicest guy you'll ever meet

17:19 dakrone: :)

17:20 ThePawnBreak: how can I check whether a string is a digit/number?

17:23 joegallo_: ,(every? #(Character/digit % 10) "123")

17:23 clojurebot: true

17:23 joegallo_: ,(every? #(Character/digit % 10) "12a")

17:23 clojurebot: true

17:23 joegallo_: that's surprising...

17:24 coventry: ,(binding [*read-eval* false] (number? (read-string "1e10")))

17:24 clojurebot: true

17:24 coventry: ,(binding [*read-eval* false] (number? (read-string "foo")))

17:24 clojurebot: false

17:24 ThePawnBreak: (remove number? "12gigi23")

17:24 (\1 \2 \g \i \g \i \2 \3) -- could someone explain what's happening here?

17:24 joegallo_: ah, it returns the digits, not a boolean

17:24 noonian: ,(#(try (Double. %) (catch Exception e nil)) "17")

17:24 clojurebot: noonian: excusez-moi

17:24 joegallo_: ,(every? #(Character/isDigit %) "123")

17:24 clojurebot: true

17:24 joegallo_: ,(every? #(Character/isDigit %) "12a")

17:24 clojurebot: false

17:24 noonian: ,(#(try (Double. %) (catch Exception e nil)) "17")

17:24 clojurebot: noonian: Titim gan éirí ort.

17:24 noonian: hmm

17:24 ThePawnBreak: ,(remove number? "12gigi23")

17:24 clojurebot: (\1 \2 \g \i \g ...)

17:25 ThePawnBreak: this is so awesome :)

17:25 joegallo_: ThePawnBreak: none of them are numbers, all of them are characters ;)

17:25 noonian: ,((fn [n] (try (Double. n) (catch Exception e nil))) "17")

17:25 clojurebot: noonian: excusez-moi

17:25 noonian: lol, why doesn't clojurebot like me?

17:25 ,(+ 2 2)

17:25 clojurebot: 4

17:25 noonian: ,(Double "7")

17:25 clojurebot: #<RuntimeException java.lang.RuntimeException: Expecting var, but Double is mapped to class java.lang.Double>

17:25 noonian: ,(Double. "7")

17:25 clojurebot: 7.0

17:25 noonian: ,(try (Double. "7"))

17:25 clojurebot: 7.0

17:26 noonian: ,(try (Double. "7") (catch Exception e nil))

17:26 clojurebot: noonian: Huh?

17:26 noonian: ,(try (Double. "7") (catch Exception e true))

17:26 clojurebot: noonian: Gabh mo leithscéal?

17:26 noonian: doesn't like catch

17:27 seangrov`: Is there still no built-in deep-merge for maps??

17:27 lazybot: seangrov`: Uh, no. Why would you even ask?

17:27 ThePawnBreak: how can I get a string's length?

17:27 noonian: (count "1 2 3")

17:27 ,(count "1 2 3")

17:27 clojurebot: 5

17:27 seangrov`: Jesus, lazybot is uppity today

17:27 awalker: ,(remove (set (map char (range 48 58))) "12gigi23")

17:27 clojurebot: (\g \i \g \i)

17:28 TEttinger: ,(apply str (remove #(Character/isDigit %) "alpha123beta"))

17:28 clojurebot: "alphabeta"

17:28 ThePawnBreak: here's what I came up with:

17:28 (defn digit? [s]

17:28 (if (> (count s) 1)

17:28 false

17:28 (number? (read-string s))))

17:28 jared314: can anyone point me to the source of clojure.core/import* ?

17:29 TEttinger: ThePawnBreak, that will return true for 42

17:29 ThePawnBreak: I only care about strings

17:29 coventry: ThePawnBreak: You'll need some exception handling for the reader complaining about unreadable forms.

17:30 ,(read-string "(aonthun"))

17:30 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

17:30 ThePawnBreak: TEttinger: nope, it doesn't work at all for 42; count doesn't work on long

17:30 how the heck isn't this function in a library?

17:31 nathanic: ,(re-matches #"\d" "4")

17:31 clojurebot: "4"

17:31 TEttinger: sorry, "42"

17:31 joegallo_: maybe it's a less useful function than you think it is ;)

17:31 coventry: Also, there was something about the reader being insecure earlier in the year, even with *read-eval* turned off.

17:31 hiredman: http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isDigit%28char%29

17:31 joegallo_: or your definition of library is too narrow, as hiredman is pointing out

17:32 technomancy: hiredman: I... wow.

17:32 watch out for those Devanagari digits

17:32 they get you every time

17:32 amalloy: TimMc: what the hell is this thing you're giving me credit for?

17:33 hiredman: technomancy: watch this

17:33 dnolen: jared314: you need to look in Compiler.java at ImportExpr

17:33 hiredman: ,(Long/parseLong "३")

17:33 clojurebot: 3

17:33 * technomancy stares in stunned surprise

17:34 jared314: dnolen: thank you

17:34 TimMc: &(.getPort (java.net.URL. "http://google.com:६"))

17:34 lazybot: ⇒ 6

17:34 TimMc: technomancy: ^

17:34 technomancy: oh dear

17:34 TimMc: Problem?

17:35 amalloy: The reify-equals-constantly-true thing. You mentioned it in the context of cheat-y 4clojure answers.

17:35 amalloy: ah

17:36 TimMc: You inspired me to use it in production code!

17:36 (Kidding.)

17:37 TEttinger: ,(re-matches #"\p{Nd}" "\u0966")

17:37 clojurebot: "?"

17:37 bitemyapp: hiredman: so...it's unicode aware?

17:37 TEttinger: ##(re-matches #"\p{Nd}" "3")

17:37 lazybot: ⇒ "3"

17:40 tm3da: Hello, can anyone explain me why the following code throws StackOverflowError?


17:40 (defn my-fn [a b]

17:40 (swap! a #(assoc % :out [b]))

17:40 (swap! b #(assoc % :in [a])))


17:40 (my-fn (atom {}) (atom {}))

17:40 mtp: because it overflows the stack

17:41 can you examine the backtrace and come up with an explanation as to why that might happen?

17:41 TEttinger: ThePawnBreak, you would probably want to use (fn [s] (re-matches #"\p{Nd}" s)) for strings, or (fn [c] (Character/isDigit c)) for chars.

17:42 both are unicode-aware.

17:42 tm3da: I will try.

17:42 TEttinger: tm3da, use a pastebin for the stack trace?

17:42 coventry: For safely reading numbers, this looks pretty cool: http://stackoverflow.com/a/2651056/1941213

17:42 gfredericks: tm3da: I'll give you a hint; that code executes without overflowing the stack

17:45 ThePawnBreak: TEttinger: thanks

17:45 TEttinger: I just should say, I have never used \p{Nd} before, but damn the whole \p set looks useful

17:46 they're listed here http://www.regular-expressions.info/unicode.html

17:46 oh never mind, recommending \p{N} instead.

17:47 Raynes: technomancy: Just got an email from a Sonian recruiter. Nostalgia.

17:47 coventry: There's also clojure.tools.reader.impl.commons/match-number.

17:47 technomancy: Raynes: you're a hot commodity

17:47 Raynes: technomancy: Well, I'm pretty sure it's random based on this guy seeing how many Clojure projects I have. :P

17:48 technomancy: Raynes: (sort-by (comp count :repos) (map tentacles/get-repos users)) ; clearly

17:48 Raynes: technomancy: Clearly.

17:49 technomancy: tentacles is some good stuff

17:49 Raynes: technomancy: I doubt I'd be a first choice, given that one of their engineers really doesn't like me very much. :P

17:49 TEttinger: ##[(re-matches #"\p{N}" "⁶") (re-matches #"\p{Nd}" "⁶")]

17:49 lazybot: ⇒ ["⁶" nil]

17:50 Raynes: Possibly two.

17:50 TEttinger: Raynes, I don't dislike you in the slightest!

17:50 Raynes: <3

17:51 technomancy: Raynes: but have they considered http://p.hagelb.org/riker.gif?

17:51 Raynes: Once or twice.

17:52 TEttinger: What's your github username?

17:52 TEttinger: tommyettinger , it's a mess

17:52 lots of old projects

17:52 lots of languages though

17:53 it doesn't have all my little scripts I write for utility, which are all clojure these days

17:54 technomancy: Raynes: weird; you mention recruiters and I cehck my mail fie minutes later and there are two recruiter emails in it

17:54 are they in cahoots?

17:54 bitemyapp: technomancy: the fire rises

17:55 technomancy: oh haha; one of them actually is Sonian

17:55 welp.gif

17:56 yedi: has anyone played around with websockets in clojure

17:56 s4muel: i can't stop laughing at that riker pic.

18:00 tm3da: TEttinger: I've posted it here http://pastebin.com/Ep0Tqciw but still have no idea why is it happening.

18:01 je: yedi: only a little but that was using Immutant: http://immutant.org/ (se two latest news entries)

18:03 `cbp`: tm3da: you are creating a circular reference

18:04 cemerick: technomancy: it seems to be making the rounds

18:08 tm3da: `cbp`: I know I'm trying to have some graph structure in which each node knows its parent and its children and it has some cycles in it. Is there a better way to represent it?

18:08 dcunit3d: i have a ui namespace where i want certain elements to redraw based on the value of atoms in another namespace. whats the best way to do that?

18:09 dottedmag: How do the objects which are not Clojure functions nor Java functions work as functions? (such as :keyword in function position during evaluation).

18:09 noonian: .(fn? :foo)

18:09 ,(fn? :foo)

18:09 clojurebot: false

18:09 ucb: dottedmag: IIRC they implement IFn

18:09 noonian: ,(callable? :foo)

18:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: callable? in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:10 dottedmag: ,(ifn? :foo)

18:10 clojurebot: true

18:10 dottedmag: I see.

18:10 ucb: thanks

18:10 noonian: ah, thanks

18:13 klokbask_: core.async question: how do I cancel the process created by a go expression? the return value is the channel and not the process, as I understand it.

18:13 gfredericks: ,((reify clojure.lang.IFn (invoke [me a b c d] (+ c d))) 1 2 3 4)

18:13 clojurebot: 7

18:13 gfredericks: dottedmag: ^

18:14 `cbp: tm3da: what you did is okish just don't try to print it :)

18:15 tm3da: try using a deftype for the same results but more idiomatic

18:15 tm3da: `cbp: thank you! It didn't occur to me that it can be caused by printing :)

18:18 dottedmag: gfredericks: and reify creates new object confirming to protocol(s)/interface(s) specified, right?

18:22 tm3da: Just out of my curiosity is in clojure a way how to print cyclic structures like it is in Common Lisp (*print-circle*)?

18:24 `cbp: tm3da: *print-level* maybe

18:24 nDuff: tm3da: If the CL printer emits something its reader can process back to the same structure, then no.

18:24 tm3da: ...but your question assumes CL knowledge not everyone here has.

18:24 indigo: coventry: Those guys replied and changed the channel name

18:25 tbaldridge: klokbask_: you can't cancel processes. You could provide a channel and then have the process alt! on the channel, and exit early if it closes.

18:28 tm3da: `cbp: thanks

18:28 dcunit3d: la

18:28 woops

18:31 tm3da: nDuff: yes, I should have formulated the question this way: Is in clojure way to print a cyclic structure? The CL part was only to better explain myself.

18:31 nDuff: tm3da: again, are you printing it for human consumption, or consumption by the reader?

18:32 tm3da: which is to say, does it need to round-trip?

18:32 ...if you need round-tripping, I believe the answer is "no".

18:32 tm3da: nDuff: just for human consumption

18:33 nDuff: tm3da: ...so, first, it's actually tricky to get a cyclic structure in Clojure; we don't have cons cells here.

18:34 TimMc: At least not mutable cons cells.

18:34 nDuff: tm3da: ...beyond that, the answer `cbp gave you was on-point (in terms of limiting recursion depth).

18:35 It's not a great answer, but, well, it's not a common situation.

18:37 tm3da: nDuff: thank you. I've just made it work with *print-level* :)

18:48 technomancy: cyclic structures are technically possible with laziness, but you basically have to go out of your way to make them

19:05 no7hing: when i have multiple implemented protocols in a namespace, want one of them instantiated and def'ed in said namespace - what is the smartest way to call the functions on that instance from other namespaces?

19:07 noonian: no7hing: you should just be able to call them and the protocol's dispatch should call the correct implmentation

19:08 you have to require the namespace with the protocol definition

19:08 hyPiRion: You don't need mutable cons cells to get cyclic structures though, but you need unbound variables at least.

19:16 scriptor: https://github.com/clojure/tools.emitter.jvm

19:16 hmmmmmmm

19:16 am I late in everyone talking about this?

19:16 no7hing: @noonian this is the gist to my question https://gist.github.com/mhaemmerle/6893036

19:19 i want to encapsulate the service behind namespace 'a' in the gist without a client needing to care about a concrete instance

19:19 noonian: no7hing: I commented on the gist, you need to explicitly implement the P protocol in your deftype

19:19 no7hing: obviously line 21 is the exact opposite

19:19 sry, forgot that

19:19 noonian: I think the dynamic var part just makes it more confusing

19:21 no7hing: maybe it's (my) the wrong take on it and i should just ditch protocols here

19:21 noonian: no7hing: I think the deftype is also missing a vector of fields

19:22 no7hing: sorry for supplying such a bad gist, i just wanted to illustrate the point behind the setup

19:23 noonian: no worries, I think what you are doing is fine, but from namespace b's perspective, it should just care about the functions described with the defprotocol

19:24 instead of the dynamic var I'd just write functions that operate on some instance, and then whichever instance (an instance of Foo or Bar in this case) is passed in will be the one whos implementaion is used

19:25 you can also use extend-protocol to give implementations of your protocol for already existing type, like clojure maps

19:26 no7hing: but if i want to work with that same instance from multiple namespaces, to stay with the example e.g. from (ns c), then i'd have to store it somewhere

19:26 noonian: no7hing: you very rarely have store things like that

19:27 normally, in (ns c) you would declare other functions, and whichever namespace you do stuff from you would require those functions from a, b, and c and then call them passing in a specific instance

19:28 (def foo (Foo.)) (fn-from-ns-b foo) (fb-from-ns-c foo)

19:29 no7hing: in this case it's a service-wrapper that's used from multiple places

19:32 noonian: do you have to create your instance at runtime because or credentials or something? I usually use an atom or dynamic var for the credentials in those cases and still make the object instances manually using those credentials

19:33 it would probably work the way you are doing it, but I still try to stay away from alter-var-root and using (binding [*blah* ...] ...) instead where I can

19:34 no7hing: based on the configuration it would use either of the implementations - so at runtime

19:35 i would write small wrapper functions that pass in the def'ed instance, but i thought there might be a better way

19:36 the way i got it in clojure land is that it's personal preference if an instance of e.g. a db driver is passed out to the user or wrapped inside the driver

19:36 as in https://github.com/michaelklishin/welle/blob/master/src/clojure/clojurewerkz/welle/core.clj#L22 for example

19:39 noonian: yeah, although like in that example you usually set it to something concrete from a function or using a binding form (or macro that expands to one), instead of calling alter-var-root inline in your library code

19:39 the alter-var-root won't affect other threads though, so make sure to call it before you spawn them

19:40 no7hing: are you sure about the last part?

19:40 i thought binding would convert to a thread-local

19:42 thanks for your extensive help!

19:43 noonian: no7hing: yep, Vars are thread local except for the initial root binding I believe

19:44 no7hing: if you want it to work across pools then you could use an atom instead

19:44 er, across threads

19:53 no7hing: thx

20:51 Frozenlock: Any advice on dealing with multiple domains with compojure?

20:53 xeqi: Frozenlock: what do you want to do with them?

20:55 Frozenlock: Well I'm hosting a website with compojure. Not really hard... run the server and forward traffic to the given port. But with multiple domains... it must be on a single compojure instance?

20:58 xeqi: are you wanting to serve the same site on multiple domains, or have multiple domains point to the same compojure app but be served different things?

20:59 Frozenlock: Different things.

21:00 ie I can't just run another server, because the port 80 and 443 are already taken by the first one.

21:01 xeqi: If I was going to build an architecture this way, I'd use nginx, let it check the server name, and then forward to the right compojure app

21:02 but you could check :server-name in the request and dispatch that way inside the compojure app

21:03 Frozenlock: Ah, I'll look nginx, thanks!

21:03 clojurebot: Cool story bro.

21:06 ddellacosta: Frozenlock: I've done it the latter way xeqi describes, with middleware, but I suspect getting the web server to handle it is a better solution.

21:06 Frozenlock: ddellacosta: Yeah, it would even give me the opportunity to try the emacs webserver :p

21:19 akurilin: Am I correct to believe that you cannot do a comparison between a ratio and a double without explicitly coercing the former?

21:19 Or I guess there's the == operator

21:20 Although the docs say that = should also compare in a type-independent manner

21:25 Am I interpreting the docs wrong?

21:27 lunk: ,(= 5/2 2.5)

21:27 clojurebot: false

21:28 gfredericks: akurilin: slightly

21:28 = is type independent, but it won't compare exact numeric types to inexact numeric types

21:28 the type independence refers to e.g., comparing longs and bigints, or lists and vectors

21:29 akurilin: gfredericks, I'm just reading "compares numbers and collections in a type-independent manner" and == says "if nums all have the equivalent value (type-independent)"

21:29 gfredericks: the distinction there does not sound obvious

21:29 akurilin: gfredericks, I get what you're saying though.

21:29 lunk: ,(== 5/2 2.5)

21:29 clojurebot: true

21:30 akurilin: gfredericks, so I'll just use == whenever I know I'm comparing non-integers from now on

21:30 or at least one of the sides is a non-integer

21:30 gfredericks: another difference is == can crash

21:31 ,(== 3 nil)

21:31 clojurebot: #<NullPointerException java.lang.NullPointerException>

21:31 gfredericks: if you don't use numbers

21:31 akurilin: That's fair. I like crashes.

21:31 gfredericks: :)

21:47 logic_prog: how big is clojure-mode + paredit + nrepl?

21:47 I'm trying to understand why all efforts to rewrite an emacs-like editor in clojure has failed

21:48 indigo: logic_prog: Emacs is too big to fail

21:49 epichero: Because nobody wants such a specific editor, efforts to write a new editor are huge efforts and it takes a community to flourish

21:49 logic_prog: why does things liek eclipse, netbeans, intellij, and the such all have builtin editors then?

21:50 epichero: Because they have huge communities and millions in budget

21:50 logic_prog: yeah; but everyhing I've read

21:50 said clojure progs are 100x more producitive than java progs

21:50 epichero: Cool story

21:51 There are relatively few clojure programmers

21:51 Take everything with a grain of salt

21:53 uvtc: logic_prog, I think there's a perception that Emacs is difficult. In reality, it's may be difficult to *program*, but it's pretty usable right OOTB. You just need to learn some key combos. I wrote up a little 10-minute tutorial article, if you're interested: <http://www.unexpected-vortices.com/clojure/10-minute-emacs-for-clojure.html>.

21:53 s/it's may be/it may be/

21:54 epichero: i don't like emacs myself, but i have tuned evil mode and written hooks so i do it my own way

21:57 If you had a good team you might be able to crowdfund an emacs rewrite.

22:02 uvtc: Many have tried to rewrite Emacs in their language of choice ... so many, but none has succeeded.

22:02 arrdem: uvtc: yet. none have succeeded yet.

22:03 uvtc: arrdem, You're supposed to say, "tried and failed?" And then I make with the Dune quote. :)

22:03 arrdem: uvtc: sorry... it's been a few years since I last read Dune and that slipped my mind

22:04 uvtc: Hehe. Sorry. Back to our regularly scheduled programming... :)

22:04 arrdem: uvtc: I see what you did there...

22:07 uvtc: I'd like to find an element of a sequence that matches some criteria. For instance, in a list of words, find the word that begins with "flu" ... is there a better way to do it than this: <https://gist.github.com/uvtc/6894751>?

22:08 arrdem: uvtc: there's clojure.string/prefix?

22:08 john2x: uvtc: nice write up. why do I want to run it as "emacs &"?

22:08 xeqi: &(some (partial (re-find #"^flu")) ["florian" "fluid" "flack" "flask" "flan"])

22:08 lazybot: java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to java.util.regex.Matcher

22:08 uvtc: john2x, To send it to the background, so that you get your terminal window back. :)

22:09 xeqi: bah

22:09 uvtc: ack ... AFK for a moment ... thanks for the help. brb

22:10 xeqi: &(some #(re-find #"^flu" %) ["florian" "fluid" "flack" "flask" "flan"])

22:10 lazybot: ⇒ "flu"

22:10 xeqi: still bah

22:10 john2x: but why send it to the background where it can't be used?

22:10 arrdem: john2x: because he's implicitly using the X version of emacs I assume

22:12 john2x: oh ok. makes sense. I thought there was some cool trick I was missing. thanks :)

22:13 mtp: Text Editor Users Hate him

22:14 learn how to write clojure using this one weird trick

22:16 uvtc: xeqi, Oh, nice. Thanks!

22:17 john2x, Right. I'm running `emacs` from by terminal window running bash. Maybe I'll have to clarify that --- I just figure that's what everyone uses. :)

22:17 mtp, hehehe :)

22:20 TEttinger: xeqi: ##(some #(re-find #"^flu\w+" %) ["florian" "fluid" "flack" "flask" "flan"]) ?

22:20 lazybot: ⇒ "fluid"

22:21 john2x: :D so I guess using the GUI/X version of emacs is much more common? (as opposed to vim where terminal/gvim users are pretty-much 50-50) uvtc's writeup makes me want to give emacs a 2nd try this weekend.

22:22 uvtc: TEttinger, Ah, right. I wanted the whole word. Thanks. :)

22:23 TEttinger: np

22:53 bergmark: I'm a bit of a clojure beginner and trying to debug a program. Is it expected that I get back nothing when I try to print the value of a lazy-sequence (such as the eturn from reduce)?

22:54 Sorry I mean filter not reduce

22:54 amehta: bergmark: you might want to wrap the filter in a dosync

22:55 arrdem: ,(doc dosync)

22:55 clojurebot: "([& exprs]); Runs the exprs (in an implicit do) in a transaction that encompasses exprs and any nested calls. Starts a transaction if none is already running on this thread. Any uncaught exception will abort the transaction and flow out of dosync. The exprs may be run more than once, but any effects on Refs will be atomic."

22:56 uvtc: amehta, You mean `doall`?

22:56 arrdem: uvtc: presumably...

22:56 amehta: uvtc: yeah thanks

22:57 arrdem: wow... pmap over map give me a 300x speedup 0.o

22:58 bergmark: Thanks to both of you. Its still printing nothing but presumably that means I've screwed up my filter pred.

22:59 amalloy: amehta: whoa, (dosync (filter ...) ...) is like never right, if that's what you're suggesting

22:59 uvtc: bergmark, one thing to keep in mind (which may or may not be relevant here), in the repl, expressions are evaluated eagerly --- since you presumably want to see what they evaluate to as you go. In your code, they are often lazy.

22:59 amalloy: oh, you said doall

22:59 Raynes: How to tell your friend has gotten into category theory: [18:51:53] relrod: Raynes: so a profunctor is a bifunctor that is contravariant in the first argument and covariant in the second. *nod*

22:59 amalloy: (doall x) prints the same as just x, for all x

23:00 usually you just want to be sure to use a print function from the pr family, such as prn, rather than one from the print family, such as println

23:01 epichero: I like category theory in a way, i just don't like people who are really into it. It's like when mormons come to my door

23:01 They are good neighbors but i dont want to talk religion

23:01 bergmark: amalloy: Thanks, I'll give prn a shot as well.

23:02 TEttinger: what's the predicate, bergmark?

23:02 heck, the line would be nice

23:05 bergmark: prn seems to have done the trick. The filter was (filter #(= (get % "player_id") myId) state)

23:05 TEttinger: prn is just... pr with a newline?

23:05 bergmark: state is a seq of maps that were parsed from json, and I am trying to filter it to just the ones that applt to my id

23:06 bbloom: TEttinger: yup

23:06 Raynes: &(clojure.repl/source prn)

23:06 lazybot: ⇒ Source not found nil

23:06 Raynes: $kill

23:06 lazybot: KILL IT WITH FIRE!

23:06 uvtc: Ah, because `prn` flushes on newline?

23:06 bbloom: $source prn

23:06 lazybot: prn is http://is.gd/Xx0wYU

23:06 bergmark: I was using println before, which apparently was not evaluating the lazy sequence?

23:06 Raynes: bbloom: lol

23:06 bbloom: I forgot that even existed. Congratulations, you officially know more about my own bot than I do.

23:07 bbloom: Raynes: honestly, i wasn't sure WHICH bot was going to respond to that

23:07 TEttinger: ,(prn [1 2 3])

23:07 clojurebot: [1 2 3]\n

23:07 TEttinger: ,(println [1 2 3])

23:07 clojurebot: [1 2 3]\n

23:07 TEttinger: hm

23:07 Raynes: bbloom: best bot

23:07 bbloom: $lastseen bestbot

23:07 $seen bestbot

23:07 lazybot: I have never seen bestbot.

23:07 Raynes: $seen bbloom

23:07 lazybot: bbloom was last seen talking on #clojure 1 second and 525 milliseconds ago.

23:07 bbloom: 1.525 seconds ago?

23:07 feels like only yesterday

23:07 TEttinger: it's not hard to have that say what the last thng said was

23:08 Raynes: wat

23:08 $logout

23:08 lazybot: You've been logged out.

23:08 Raynes: $reload

23:08 lazybot: Raynes: It is not the case that you don't not unhave insufficient privileges to do this.

23:08 Raynes: <3 that text.

23:08 bbloom: i do not not don't can't read that not won't

23:09 TEttinger: with some small changes, my bot does: TEttinger3 was last seen talking on #rgrd 3 hours and 9 minutes ago: after it timed out it responded again

23:09 bbloom: please note: i have made no effort to have the correct number of negations in that sentence

23:09 TEttinger: if you want the source I have it lying around

23:11 ucb: is it possible to intern a var with meta-data?

23:12 bbloom: (doc alter-meta)

23:12 clojurebot: Cool story bro.

23:12 ucb: I've tried something like (intern *ns* 'name (with-meta Thing {...})) but it doesn't seem to work

23:12 bbloom: (doc alter-meta!)

23:12 clojurebot: "([iref f & args]); Atomically sets the metadata for a namespace/var/ref/agent/atom to be: (apply f its-current-meta args) f must be free of side-effects"

23:12 bbloom: (doc reset-meta!)

23:12 clojurebot: "([iref metadata-map]); Atomically resets the metadata for a namespace/var/ref/agent/atom"

23:12 bbloom: ucb: you can use those on #'some/var

23:13 TEttinger: Raynes: https://dl.dropboxusercontent.com/u/11914692/seen.clj

23:13 ucb: bbloom: cool, will try with that. I was hoping I could directly intern a var with meta-data.

23:15 bbloom: ucb: i think you can… you just need to with-meta on the symbol

23:15 (doc intern)

23:15 clojurebot: "([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var."

23:15 bbloom: ucb: note the last sentence

23:15 ucb: ooh

23:15 I've been doing it wrong then

23:17 bbloom: awesome. It worked. Thanks for making me notice the last sentence :)

23:17 indigo: (fire intern)

23:17 ;P

23:22 bitemyapp: indigo: harsh

23:23 indigo: Hehe

23:23 I'm scared to put our intern's code into production

23:23 Even though he has an MS in CS

23:23 arrdem: indigo: just you try it...

23:28 Raynes: indigo: I'm younger than he is and have no degree. Want some code?

23:28 arrdem: Raynes: sometimes I'm really really jelly of that...

23:29 Raynes: Jelly of my degrelessness?

23:29 degreelessness*

23:29 indigo: Raynes: I'm also younger than him and have an unrelated degree

23:29 Raynes: indigo: <3

23:29 indigo: But I guess that's why he gets to be the intern ;)

23:29 :D

23:29 Raynes: arrdem: It was really easy to no get a degree.

23:29 logic_prog: for clojure libraries, we have hiccup for HTML, and garden for CSS -- is there any standard library for outputting SVG ?

23:30 TEttinger: gah who keeps dropping these nodebots in here

23:30 Raynes: logic_prog: SVG is XML.

23:30 logic_prog: what does this mean?

23:31 Raynes: It means you probably want an XML library and not an SVG library. For example, data.xml

23:31 TEttinger: https://github.com/pallix/tikkba ?

23:31 Raynes: Sure, that works too.

23:32 TEttinger: also for Raynes' approach, http://www.learningclojure.com/2010/10/generating-xml-to-make-svg-vector.html

23:32 amalloy: bbloom: "atomically resets" is a strange phrase to use, in the docs for reset-meta!

23:33 Raynes: With the caveat that that article uses old contrib and thus isn't particularly useful.

23:34 TEttinger: http://liebke.github.io/analemma/ then :-)

23:34 bbloom: amalloy: why?

23:34 (doc reset!)

23:34 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

23:34 amalloy: bbloom: what does "atomic" mean, in the context of "set this thing to x, ignoring what it was before"

23:35 bbloom: amalloy: i'd assume it implies that the metadata is a volatile or something like that

23:35 amalloy: like...you won't somehow end up with a corrupted pointer?

23:35 bbloom: isn't that a possibility in C? :-P

23:36 heh: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AReference.java#L16 i guess it's just a normal field :-P

23:36 *shrug*

23:36 amalloy: well, i don't think any of the C standards address multithreading at all. so anything at all is possible

23:36 c++11 does, but nothing before that

23:36 bbloom: my guess is alter-meta! was written first and reset-meta! was involved a copy paste of the doc string :-P

23:37 copy paste: the original prototypical inheritance

23:44 uvtc: Ok. I see that, in the source for lein-exec, the leiningen.exec/deps function does indeed use pomegranate: <https://github.com/kumarshantanu/lein-exec/blob/master/src/leiningen/exec.clj>.

23:44 Oooof. Sorry, wrong channel.

Logging service provided by n01se.net