#clojure log - Dec 22 2011

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

0:01 hiredman: the best answer to that is java is not c++

0:01 accel: so if an object has been GCed

0:02 how can it still manage runnign threads?

0:02 hiredman: you do have finalizers, which are called when objects are gc'ed, but you don't have control of when or where or on what thread, so the use of finalizers is generally frowned

0:02 accel: how would it be managing them?

0:03 accel: perhaps I am wrong but it seems that to schedule a bunch of threads; you need to keep state around; and if that sate has been GC-ed, you can't manage those threaes anymore

0:04 hiredman: you should try implmenting the executor interface, it requires very little state, all of which can go away leaving the threads running fine

0:04 but the running threads will all have a reference to at least the task queue of the executor

0:05 threads are gc roots

0:05 http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html

0:05 accel: so the scheduler won't be GCed as long as some thraed is running

0:05 hiredman: http://www.yourkit.com/docs/75/help/performance_problems/memory_leaks/gc_roots.jsp

0:06 accel: got it; thanks

0:06 hiredman: accel: that is not what I said

0:07 if the threads reference the queue, and the executor references the queue, there is no reference from the queue to the executor

0:07 accel: is it no implied by what you said?

0:29 dnolen: hmm is there a fn that returns both the filtered and the removed items of a predicate?

0:30 Raynes: (juxt filter remove)

0:35 dnolen: Raynes: yeah, that's was I was going to do, but wondering if I was missing something.

0:35 Raynes: dnolen: There used to be something in contrib, but that was back before birds could fly and fish could swim,

0:35 alandipert: group-by?

0:37 jodaro: &((juxt filter remove) even? [1 2 3 4 5])

0:37 lazybot: ⇒ [(2 4) (1 3 5)]

0:37 jodaro: nice

0:47 amalloy: ~juxt

0:47 clojurebot: juxt is a little hard to grok but it's the best thing ever

0:53 Raynes: amalloy: I'm surprised that it doesn't say something about being nuts.

0:58 dnolen: alandipert: group-by puts things into a map, which is not really what I want, I want to preserve the order some.

0:59 amalloy: dnolen: it preserves as much order as (juxt filter remove) would

1:00 &(let [{truthy true, falsey false} (group-by even? (range 20))] [truthy falsey])

1:00 lazybot: ⇒ [[0 2 4 6 8 10 12 14 16 18] [1 3 5 7 9 11 13 15 17 19]]

1:00 dnolen: amalloy: I'm adding a bit of my own logic to preserve order.

1:02 espringe: (-> 25 #(+ % 1) int)

1:02 java.lang.ClassCastException (NO_SOURCE_FILE:19)

1:03 What's wrong with that?

1:03 hiredman: ,(macroexpand '(-> 25 #(+ % 1) int))

1:03 clojurebot: (int (clojure.core/-> 25 (fn* [p1__27#] (+ p1__27# 1))))

1:03 hiredman: ,(macroexpand '(clojure.core/-> 25 (fn* [p1__27#] (+ p1__27# 1))))

1:03 clojurebot: (fn* 25 [p1__27#] (+ p1__27# 1))

1:04 espringe: Still not quite seeing what's going on

1:05 hiredman: ,(macroexpand '(-> 1 (2 3 4)))

1:05 clojurebot: (2 1 3 4)

1:05 hiredman: ,(macroexpand '(-> 1 (fn [])))

1:05 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long>

1:05 hiredman: weird

1:05 ,(macroexpand '(-> 1 (fn* [])))

1:05 clojurebot: (fn* 1 [])

1:06 Raynes: It is trying to insert 25 as the first element in the form that #() expands to. It isn't inserting it as the first argument to your function.

1:07 espringe: Ah, I see. Thanks

1:07 Is there a quick fix for that? Or i have to give a name to my function?

1:08 hiredman: well, what is -> doing?

1:08 espringe: I want the result of that to be 26

1:09 It should get 25, feed it into the function that increments it. Then make it an int

1:09 hiredman: ok, but what is -> doing "Ah, I see."

1:09 espringe: Yeah, just for learning

1:09 nothing practical

1:09 hiredman: sure, so what is -> doing?

1:09 you said you saw, so what did you see?

1:09 Raynes: &(-> 3 (#(+ 3 %)))

1:09 lazybot: ⇒ 6

1:10 espringe: hiredman: I assume that #() is expanding into a list of some sort. And -> is throwing 25 into that list

1:10 Is that wrong?

1:10 hiredman: ,(macroexpand '(-> 1 2))

1:10 clojurebot: (2 1)

1:10 hiredman: ,(macroexpand '(-> 1 (2)))

1:10 clojurebot: (2 1)

1:10 hiredman: espringe: sure, where in the list?

1:10 espringe: At the end?

1:11 ,(macroexpand '(-> 1 (2 3 4)))

1:11 clojurebot: (2 1 3 4)

1:11 espringe: apparently not

1:11 Raynes: &(doc ->)

1:11 lazybot: ⇒ "Macro ([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

1:12 espringe: Ahh! I see why it's doing what it's doing

1:12 So I need something like -> except it inserts at the very end of the list -- instead of the 2nd element

1:12 accel: can I read from an agent using @?

1:13 hiredman: accel: have you tried it?

1:13 accel: yeah

1:14 and I get an error saying: "Nu such var: foo.bar/blah"

1:14 hiredman: did it work?

1:14 * Raynes chuckles

1:14 accel: No, it failed.

1:14 espringe: (->> 25 #(+ % 1) int)

1:14 So shouldn't that work?

1:14 hiredman: espringe: did you run macroexpand on it to see what it does?

1:14 espringe: ,(macroexpand '(->> 1 (2 3 4 5)))

1:14 clojurebot: (2 3 4 5 1)

1:14 hiredman: accel: with an error unrelated to agents

1:15 Raynes: espringe: No. It inserts 25 as the last element of the form created by the #().

1:15 hiredman: espringe: on your actual expression, feel free to use your own repl to play with it

1:16 espringe: Thanks. I think I got it:

1:16 ,(->> 25 (#(+ % 1)) int)

1:16 clojurebot: 26

1:16 espringe: Thanks for your help everyone

1:17 Raynes: espringe: If that is your actual code, you can actually just do ##(-> 25 (+ 1) inc)

1:17 lazybot: ⇒ 27

1:17 hiredman: ,(macroexpand '(-> 1 (2)))

1:17 clojurebot: (2 1)

1:17 hiredman: ,(macroexpand '(->> 1 (2)))

1:17 clojurebot: (2 1)

1:19 espringe: Raynes: Now you've just confused me again :(. What's (+ 1) and why does it evaluate to 1

1:19 Isn't + a binary function?

1:20 ((+ 1) 1) doesn't work either

1:20 brehaut: espringe: its sum

1:20 espringe: So it's not a partially applied function

1:20 Raynes: I'm not sure you understand what -> does at all.

1:20 brehaut: ,(+)

1:20 clojurebot: 0

1:20 espringe: ,(+ 1)

1:20 brehaut: ,(+ 1 2 3)

1:20 clojurebot: 1

1:20 6

1:20 espringe: Why does that give 1

1:20 Raynes: I'm trying to think of the best way to explain this.

1:20 brehaut: espringe: what is the sum of the list containing the number 1 and nothing else?

1:20 Raynes: (-> 1 (+ 2) inc) = (inc (+ 1 2))

1:20 espringe: Oh, never mind. I see.

1:21 It works on any amount of arguments

1:21 Raynes: But that still isn't what is happening in my example.

1:21 brehaut: espringe: now to really bake your noodle ##(< 1 2 3)

1:21 Raynes: It is working on two numbers.

1:21 lazybot: ⇒ true

1:21 espringe: Yeah, I know that

1:21 When i first read the code, I thought (+ 1) was going to be shorthand for #(+ 1 %) as I assumed + was a partially applied binary function

1:22 but i was just being dumb :D

1:22 accel: foo/cat.clj requires foo/dog.clj; foo/dog.clj depends on foo.cat/some_agent ; how can I make this work w/o creating circular dependencies?

1:22 Raynes: Even if + didn't work at all on one argument, it still would work in my example. The arguments aren't evaluated until the form is complete. Thus is the wonder of macros.

1:23 Not doing it is an excellent way.

1:23 hiredman: that is the definition of a circular dependency, don't do it

1:24 accel: i can't forward declare the var or something?

1:25 hiredman: accel: http://www.essortment.com/5-stages-grief-16816.html please skip to acceptance and structure your code in a way that doesn't require this

1:25 Raynes: Hahaha

1:26 That was the greatest hiredmanism to date.

2:11 accel: how can I run clojure/java in real time mode? I have a cursor that I want to blink 5 times a second; and looking at it visually; I can see the gc hiccups

3:29 is there a way to define a multimethod as memoizable?

4:42 does clojure have an idiomatic way of saying: write this acyclic list out to file?

4:53 clgv: accel: you mean something like pr/prn?

4:53 that writes the list to *out* which ist stdout by default: ##(prn (range 10))

4:53 lazybot: ⇒ (0 1 2 3 4 5 6 7 8 9) nil

4:54 clgv: via (binding [*out* (writer "myfile.data")] (prn mydata)) you can use that to write to a file

4:55 accel: clgv: Cool. What is the inverse of prn?

4:55 clgv: accel: e.g. load-string if you already read that string

4:56 or load-file for a whole file. but then you only get the last value returned

4:57 accel: hmm, is there a way to do a read w/o eval?

4:57 i guess I can attach an extra "quote" aroudn the prn

4:57 clgv: oh right load does eval, but read/read-string does not

4:58 accel: is there no read-file ?

4:58 clgv: thats 'read

4:58 Chousuke: read happens one form at a time

4:59 accel: one more dumb question; how do I go from a filename to a stream for reading?

5:00 clgv: accel: use clojure.java.io/reader and put that into a LinePushBackReader

5:04 accel: clgv: got it; thanks for all your patience

5:04 clgv: np

5:06 kral: namaste

5:35 Blkt: good morning everyone

5:39 tscheibl: Hachdj Dorsmno

5:40 ... gesundheit

5:44 G0SUB: namaste, kral

5:47 voldemordor: the language is pleasure, but does any company actually develop any application with clojure?

5:47 see i'd like to go to development, but dont want to deal with java...

5:47 ejackson: voldemordor: many, check out the clojure success stories on the home page.

5:47 nachtalp: voldemordor: a couple of examples can be found here: http://dev.clojure.org/display/community/Clojure+Success+Stories

5:48 voldemordor: thx i will look into it

6:08 erujolc: #couchdb

6:12 alekx: hi! what's the recommended setup for a newbie? what's the best way to set repl?

6:16 tsdh: alekx: Probably, the easiest is installing Leiningen http://github.com/technomancy/leiningen, lein new first-steps && cd first-steps && lein repl

8:37 ambrosebs: is there a reason why the #myns.MyRecord{...} syntax only works for fully qualified classes? Just the implementation?

8:41 pyr: hi guys, when running a ring app in an existing servlet container

8:41 (say, jetty7)

8:41 is there a standard way of telling the ring war servlet

8:41 to not care about the uri prefix

8:42 i.e: if i handle routes such as /foo, /bar/:id and deploy the uberwar to /myapp, i get failures since i get hits to /myapp/foo

8:43 i can't seem to find a reference for web.xml which is where this sort of config seems happen

8:59 krey: Hi there, I do not really understand https://github.com/clojure/tools.logging

9:00 tsdh: ambrosebs: Just a blind guess, but maybe you need to `import' myns.MyRecord as if it was a Java class to refer to it without qualification...

9:01 krey: Where to call log-capture! ?

9:02 ambrosebs: tsdh: the reason it doesn't work it the implementation. it uses (RT/classForName ...) which doesn't take into consideration the current scope

9:02 I wasn't sure if this was a design choice

9:02 i see no mention in the design docs

9:06 tsdh: Hm, that's consistent with Class/forName, which also relies on qualified names.

9:12 TimMc: What's the syntax in question?

9:23 broquaint: I'm failing to understand the output (possibly because I'm failing at debugging too) of this test - https://gist.github.com/1510460

9:23 My confusion lies in why the second COND isn't [:a :b] [[:a :b]].

9:25 That relates to this 4clojure problem BTW - http://www.4clojure.com/problem/93

9:37 samaaron: broquaint: it might help if you made your question more specific

9:37 pandeiro: is there another way to get the path of a clj file besides *file*? in one of my noir handlers, *file* returns NO_SOURCE_PATH

9:39 broquaint: Sure, samaaron, my expectation is that after recursing on the first nested structured [[[:a :b]]] the next condition that would be evaluated would be [[:a :b]] but the output indicates that it skips straight to [[:c :d]].

9:46 I should really reduce that to a minimal test case and come back with something more coherent ;)

9:56 krey: Getting Message: n.spy.memcached.MemcachedConnection - Could not redistribute to another node, retrying primary node for set-item-test. << why?

9:58 Raynes: samaaron: What are you getting me for Christmas?

9:58 samaaron: Raynes: you can have a cup stacking set and a Skrillex EP

9:58 Oh My Gosh!

9:58 Raynes: Fantastic.

10:01 samaaron: do you want it gift wrapped?

10:01 Raynes: samaaron: I wouldn't take it any other way.

10:02 samaaron: have you heard much Skrillex?

10:02 Raynes: Closer to none at all, ever.

10:02 samaaron: what kind of "youth of today" are you?

10:03 Raynes: The bad kind.

10:03 sritchie: Ohai.

10:03 samaaron: surely the bad kind listens to skrillex??

10:03 lazybot: samaaron: What are you, crazy? Of course not!

10:03 sritchie: what up, good sir

10:04 Raynes: sritchie: You can either send me a pull request or I can just give you write access to my lein-noir fork. The latter would probably be better if you have more work to do on your stuff, since you wont have to constantly bother with pull requests.

10:04 Your choice.

10:04 Red pill or blue pill.

10:05 Also, someone buy me the hat on this list: http://www.amazon.com/gp/registry/wishlist/ref=ya_52

10:05 sritchie: any decision in pill form is a decision I feel very comfortable making

10:06 I'll take write access, but I'll work in a branch

10:06 Raynes: Heh. Why, so you don't make me angry for screwing up your own template?

10:06 :P

10:06 TimMc: Raynes: The URL you have dialed is not available. Please hang up and try again.

10:06 Raynes: TimMc: I still haven't quite figured out Amazon wishlists.

10:07 TimMc: That wasn't the public URL.

10:07 Raynes: TimMc: http://amzn.com/w/3AB1JVMTPUFSQ

10:07 That might be it.

10:08 sritchie: I might freak your watchers out with my character-by-character commits, each documented obsessively with tortured rationale

10:08 Raynes: I have watchers?

10:09 Yeah, didn't think so.

10:09 sritchie: in that case, let's tear it up

10:10 thanks for the access, I'll move that stuff over now

10:11 TimMc: Raynes: Who is Connie?

10:11 Raynes: TimMc: Eh?

10:11 TimMc: "This list is for:" on the left.

10:11 Raynes: Says Anthony for me.

10:12 TimMc: "This list is for: Anthony"?

10:12 Raynes: Connie would be my mother, whose name was originally on this account. Hasn't been for at least a year or so. It still shows her name in the title for me, but nowhere else. I assume amazon doesn't understand name changes.

10:12 TimMc: haha

10:15 pandeiro: why does *file* have NO_SOURCE_PATH in my noir module? anyone? how can i work around this?

10:19 TimMc: Cup stacking!

10:19 Oh man, I remember that.

10:20 cemerick: samaaron: skrillex is what made me aware of cup stacking to begin with

10:20 what an absurd corollation

10:20 samaaron: it's insane

10:21 OH MY GOSH!

10:21 wub wub wub wub

10:21 cemerick: hah

10:21 Raynes: cemerick: Get out of my internets.

10:21 samaaron: i've been listening to skrillex quite a bit of late

10:21 some good sounds

10:22 cemerick: Raynes: Hey, I could be talking about nyan…things. Whatever that is.

10:22 samaaron: Raynes: what's your cup-stacking pb?

10:22 Raynes: FYI, I've got no idea what you're talking about.

10:22 samaaron: again, what kind of "youth of today" are you??

10:22 lazybot: samaaron: Uh, no. Why would you even ask?

10:22 cemerick: Don't google it.

10:22 samaaron: you're not conforming to stereo-types

10:23 cemerick: samaaron: I lost a bit of my sanity when I discovered that such a thing existed. Give Raynes a chance to live a well-adjusted life.

10:23 samaaron: hahahaha

10:25 TimMc: One of my cousins had a stacking mat and everything.

10:25 cemerick: gaaaah

10:25 TimMc: I was kind of horrified.

10:25 * cemerick plugs his ears

10:26 samaaron: I used to have a yo-yo as a kid

10:26 although, I still have one now

10:26 TimMc: That's perfectly respectable.

10:26 cemerick: I don't see how that's at all comparable.

10:27 TimMc: pandeiro: Cup-stacking is why you're getting NO_SOURCE_PATH, I am sure of it.

10:27 cemerick: TimMc: Thanks for making me blow juice out my nose.

10:28 TimMc: Welp, back to the bracket mines.

10:29 Raynes: Mother of God, is this for real?

10:29 cemerick: He googled it.

10:29 TimMc: ahaha, he *warned* you about googling it

10:29 samaaron: hahaha

10:29 Oh My Gosh!

10:30 http://www.youtube.com/watch?v=8pbFR3jXWi8

10:30 TimMc: http://www.mspaintadventures.com/sweetbroandhellajeff/archive/001.jpg

10:31 samaaron: then listen to: http://www.youtube.com/watch?v=WSeNSzJ2-Jw&feature=related

10:31 jodaro: heh

10:31 samaaron: make sure you make it through to 40s

10:32 jodaro: still watching the tp commercial

10:32 about pieces

10:34 Raynes: samaaron: Oh my Gosh.

10:34 clojurebot: Cool story bro.

10:34 samaaron: haha

10:34 wub wub wub

10:34 did you make it to 40s?

10:34 Raynes: Yes.

10:34 TimMc: clever bot

10:35 Raynes: I see the correlation.

10:35 I've never been that happy about anything in my life.

10:35 samaaron: wub wub

10:35 cemerick: Raynes: No one else has either, EVER.

10:35 samaaron: :-)


10:37 Raynes: cemerick: I don't know. samaaron seemed pretty happy up there during his talk.

10:37 Maybe not quite this happy.

10:37 I don't know, I slept through most of it.

10:38 cemerick: OK, so samaaron and the cup-stacking-girl can be that happy. :-P

10:38 samaaron: :-)

10:38 wub wub

10:38 Raynes: Staying awake was a bigger challenge than talking at the conj. Every time I dozed off I felt a little more guilty. People probably thought I wasn't interested in *anything*.

10:39 samaaron: Raynes: and you didn't even have any jet-lag to deal with

10:39 Raynes: Yeah. Just late nights and my untrained body.

10:39 cemerick: I fell asleep for at least the last 5 minutes or so of your talk.

10:39 I nearly fell out of my chair when the applause started.

10:40 I was like "YAY!WHATHAPPENED!"

10:40 samaaron: Oh My Gosh!

10:40 wub wub wub

10:40 cemerick: I *knew* it. Damn you, Raynes, DAMN YOU.

10:41 ;-)

10:41 Raynes: :)

10:43 TimMc: wub

10:43 I think that's actually the first time I've heard dubstep.

10:45 gfredericks: Clojurescript is more sensitive about namespaces and files, isn't it? E.g., I couldn't write a macro that defs a function in two different namespaces?

10:45 TimMc: gfredericks: I think you could, as long as that namespace had beenr equired already.

10:46 gfredericks: would I use the (ns) macro, or some set!s?

10:46 TimMc: Wouldn't you just fully-qualify the names?

10:46 gfredericks: you can def a fully-qualified name?

10:46 TimMc: Hmm, maybe not...

10:47 You definitely can't do ns twice for the same namespace.

10:47 GClosure will error on that to "teach you a lesson". No kidding.

10:47 gfredericks: that's in its error message?

10:49 TimMc: Not exactly.

10:49 samaaron: TimMc: I've never seen Closure referenced as GClosure - I like that a lot

10:50 TimMc: gfredericks: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl.clj#L73

10:50 pandeiro: so, uh, why doesn't *file* return the relevant info for my noir handler again?

10:51 gfredericks: TimMc: hmph

10:51 well I think I'll just be generating a separate cljs file then

10:51 poor man's macro

11:02 pandeiro: TimMc: i saw that you were talking about clojure again so i thought i'd give it another shot... :-/

11:03 TimMc: Yeah, sorry for the topic excursion.

11:04 pandeiro: when you (:require) a certain module, does clojure not read that file and set the *file* var?

11:04 TimMc: I'm not familiar with the *file* var, or noir. :-(

11:04 pandeiro: i realize i am way out of my league here amongst people who live sleep eat breath language implementation for years... but can anyone help a noob?

11:05 gfredericks: pandeiro: does it have something to do with :require only doing anything the first time?

11:05 samaaron: Oh nice, so now I've got two university talks lined up next year where I can inject Overtone and Clojure into everyone's minds


11:05 krey: What's overtone?

11:05 pandeiro: gfredericks: i have no idea, i can't even find where :require is implemented in the clojure source, and probably wouldnt understand the code if i could

11:05 ejackson: that which is about to injected into your mind !

11:05 gfredericks: clojurebot: YOU |WILL| LIKE OVERTONE & CLOJURE

11:05 clojurebot: Ik begrijp

11:06 samaaron: krey: it's like cup-stacking and skrillex rolled into one package

11:06 pandeiro: i just figured it was probably a common use case, ie for writing a config file, i want to know where i am in absolute path terms

11:06 gfredericks: pandeiro: it results in a call to the clojure.core/require function I think

11:06 ejackson: samaaron: well, it's usually the case that a roll of cups has been stacked

11:06 samaaron: yeah, but with awesome wub wub as part of the process

11:07 krey: I don't know cup-stacking and skillrex

11:07 samaaron: krey: oh damn that's unfortunate

11:07 cemerick: pandeiro: Are you loading any code via a REPL?

11:07 TimMc: krey: Good, keep it that way.

11:07 pandeiro: If you need to load a config file, use clojure.java.io/resource

11:07 samaaron: krey: http://vimeo.com/22798433

11:08 cemerick: pandeiro: sorry, I misread your question

11:08 TimMc: pandeiro: I just tried using *file* in a minimal project and it didn't work.

11:09 pandeiro: cemerick: actually i am trying to do up a quick and dirty noir + clutch thing, and i want to allow the user to set the couch instance, and write that to a file

11:10 instead of hard-coding where that config file is, i wanted to be able to dynamically resolve the path from inside my couch-noir.db.init module, since init.clj and config.clj will live in the same subdir

11:10 krey: How to compare strings during tests with clojure?

11:10 TimMc: pandeiro: Yeah, definitely use io/resource or something -- it'll be on the classpath.

11:11 krey: (info (test/get-item "set-item-test")) => xyz

11:11 pandeiro: TimMc: yeah i was going straight to (java.io.File. "")

11:11 TimMc: &(= "hello" "hello")

11:11 lazybot: ⇒ true

11:11 pandeiro: but that gives me the project's root dir

11:11 krey: (is (= (test/get-item "set-item-test") "xyz")) << actual: (not (= xyz "xyz"))

11:12 TimMc: krey: looks like a symbol, not a string

11:12 &'[xyz "xyz"]

11:12 lazybot: ⇒ [xyz "xyz"]

11:12 krey: ahh worked with str

11:14 Awwwww... replace method did not use escaping for the data structures :)

11:14 How good tests are

11:15 jsabeaudry: Is it possible to return an http response that is too big to fit in memory with ring?

11:15 krey: How to encapsulate: (binding [*print-dup* true] (prn-str value))

11:15 Need it multiple times,... seems to be not DRY

11:17 nachtalp: jsabeaudry: as a stream? https://github.com/mmcgrana/ring/blob/master/SPEC#L85

11:18 jsabeaudry: sorry, i meant https://github.com/mmcgrana/ring/blob/master/SPEC#L104

11:18 pandeiro: TimMc: clojure.java.io/resource doesn't seem to help... i guess i am stuck hard-coding the location if there is no way for a module to know what file it is in... damn

11:18 jsabeaudry: nachtalp: Yes precisely! Many thanks! :D

11:19 krey: https://github.com/heroku/devcenter-memcache-java/blob/master/README.md << awww the warnings are even in the example with java

11:19 "Could not redistribute to another node, retrying primary node for"

11:19 Everything works as excepted... Why a warning here?

11:20 nachtalp: jsabeaudry: sure :)

11:22 Raynes: samaaron: Teach me to play the Overtone.

11:22 bweaver: Hello, I'm new to Clojure and want to parse an XML document, transform it, then print the new document out. I found xml/parse and zip/xml-zip, but I'm stuck on printing the modified document. There's an xml/emit method, but it's not documented. What's the best practice in this case?

11:22 samaaron: Raynes: do you have it installed yet?

11:22 Raynes: No.

11:22 samaaron: ok, that's your first task

11:23 Raynes: Heh

11:23 samaaron: https://github.com/overtone/overtone/wiki/Installing-overtone

11:23 TimMc: bweaver: Try emit, see what happens.

11:23 Raynes: samaaron: This cake stuff can go.

11:24 It's evil.

11:24 samaaron: Raynes: only when lein 2 is out :-)

11:24 i still use cake happily

11:24 Raynes: $guards

11:24 lazybot: SEIZE HIM!

11:24 bweaver: TimMc: It seems to work, I'm just curious if there's something I should be using since it's not part of the documented API?

11:25 TimMc: bweaver: It's part of the API -- just not documented. :-(

11:25 bweaver: TimMc: Ah, good then. Thanks!

11:25 TimMc: Huh, I wonder if it prints the preamble.

11:25 pandeiro: wow, so it is because I was referencing *file* inside a function... if I bind a var to it outside, then i get it... but it's just a path snippet that parallels the namespace, not an absolute path... what good is that?

11:26 TimMc: pandeiro: I don't think it's intended for use like that.

11:26 It's a compiler-level thing.

11:26 Raynes: samaaron: You've got music on my Clojure!

11:26 samaaron: you made a noise?

11:26 pandeiro: TimMc: i guess clojure just doesn't have something like __FILE__ in PHP or (I think) ruby

11:27 Raynes: samaaron: No, maven hasn't finished downloading the internet yet.

11:27 samaaron: hahaha

11:27 Raynes: But I'm going to make a noise. I'm going to make so much noise.

11:27 samaaron: i like to keep a cache of the internet to help with that situation

11:27 TimMc: pandeiro: Use the classpath to your advantage.

11:30 Raynes: samaaron: Overtone just crashed my JVM.

11:30 samaaron: are you using linux?

11:30 pandeiro: TimMc: please expound

11:30 samaaron: awk

11:30 Raynes: samaaron: OS X.

11:30 I tried to start an internal server.

11:30 "*** ERROR: open directory failed '/Users/anthony/Library/Application Support/SuperCollider/synthdefs'"

11:31 I was under the impression that there weren't any external dependencies for that.

11:31 cemerick: pandeiro: so you're trying to load a file at "foo/bar/config.clj"?

11:31 pandeiro: cemerick: yeah write to it

11:32 Raynes: samaaron: Looks like the actual problem was 'input and output sample rates do not match. 48000 != 44100'.

11:33 I'm glad that it told me this though, because I would have otherwise assumed those numbers to be equal. They look so darn similar.

11:33 cemerick: pandeiro: Well, (spit "foo/bar/config.clj" content) will do that, but I suspect that's not what you're aiming for. maybe gist what you're working on so we can have some context.

11:34 samaaron: sorry, awk should have been afk

11:34 but i'm back now

11:34 the error you saw wasn't anythign major

11:34 Raynes: I'm good for some asynchronous conversation.

11:34 samaaron: and yep, it's the sample rate issue

11:35 if you can figure out a way of usign AppleScript or some nonsense to automatically set the sample rate to 44100 then that would be awesome

11:35 otherwise you need to head into "Audio MIDI Setup" and do it manually

11:35 pandeiro: cemerick: sure, http://sprunge.us/PAXL

11:38 TimMc: pandeiro: Surely slurp is called for, not spit.

11:38 Wait, writing to it?

11:38 cemerick: pandeiro: I'm still not sure about the use case. You want the user to be able to set the database config once somewhere, and then reuse it everywhere else?

11:39 pandeiro: cemerick: yeah and i figured why not do it right in the noir db module?

11:39 as opposed to a flat config file somewhere i would slurp, i load it as clojure

11:40 i am a total noob so tell me if that is a terrible idea

11:40 or impossible, as the case may be

11:40 cemerick: pandeiro: I've never used noir, so I can't say one way or the other if that's typical.

11:40 Raynes: samaaron: What is a sample rate?

11:40 cemerick: The thing is, you're trying to generate a clojure source file at runtime, which would presumably be read the *next* time the app runs?

11:41 pandeiro: basically: user loads webapp, webapp checks db connection, if none exists reroutes to /setup/, and post to /setup/ tries to establish connection and write config file for future use (in case server is restarted)

11:41 samaaron: ok, so you need to meet nyquist and chums

11:41 pandeiro: does that make sense?

11:41 TimMc: Raynes: How many samples per second make up the digital capture of the analog signal.

11:41 Raynes: I'd google it, but if you say it I'll get to hear it in my head in your lovely accent.

11:41 TimMc: Damn you.

11:41 samaaron: basically, sound can be stored as reading the current voltage generated by a microphone

11:41 cemerick: pandeiro: OK, so this is being used as a one-time setup procedure?

11:41 pandeiro: cemerick: yeah

11:41 cemerick: OK; you're doing it the hard way :-)

11:42 samaaron: the thing is, you need to store that voltage in discrete parts

11:42 pandeiro: cemerick: i should just put a flat config file somewhere in the project root or something?

11:42 TimMc: Raynes: http://www.mathworks.com/help/toolbox/daq/daqsample.gif

11:42 samaaron: each of those parts is typically called a sample

11:42 pandeiro: i had just read this steve yegge blogpost about how lisp makes for great data storage format...

11:42 clojurebot: http://www.assembla.com/wiki/show/clojure/Datatypes

11:42 lazybot: Assembla is deprecated. Use http://dev.clojure.org

11:42 samaaron: so the sample rate is the number of values of the microphone you store per second

11:42 pandeiro: lol over my head apparently

11:42 cemerick: pandeiro: well, first, if you're just saving and loading data, just save and load data, don't mess around with namespaces.

11:42 TimMc: Raynes: I'm just jealous and vindictive because I didn't get to see his talk/

11:42 cemerick: ,(pr-str {:some "data"})

11:42 clojurebot: "{:some \"data\"}"

11:43 cemerick: ,(read-string "{:some \"data\"}")

11:43 clojurebot: {:some "data"}

11:43 Raynes: samaaron: I made sound!

11:43 samaaron: Raynes: yey!

11:43 pandeiro: gotcha

11:43 really no plus in trying to keep it in the namespace hierarchy

11:43 cemerick: Second, if this is going to be used in a deployed app, then likely is no project directory.

11:43 TimMc: Raynes: http://4.bp.blogspot.com/_D_Z-D2tzi14/TOM8bCK7rRI/AAAAAAAAEFo/rjD1XRjQKns/s400/dogs38alt.png

11:44 pandeiro: cemerick: yeah i'm a beginner, i don't know how the big boys do it

11:44 TimMc: ^ not a sample rate thing

11:44 cemerick: pandeiro: namespaces are for code; this is just some data. :-)

11:44 pandeiro: ok few hours down the drain but i've learned my lesson

11:44 cemerick: 'course, you *can* put non-code data in namespaces, but they're unnecessary, and probably won't fit into how the classpath ends up being configured at runtime.

11:45 IMO, I'd just dump a "saved" database config to ~/.your-config-directory-name/config.clj.

11:46 (spit (io/file (System/getProperty "user.home") ".your-config-directory-name" "config.clj") (pr-str database-config))

11:46 Then (read-string (slurp config-clj-path)) to read.

11:47 pandeiro: and make sure you're starting off with clutch 0.3.0 :-)

11:47 pandeiro: cemerick: ok thanks... but i dont totally understand why it wouldnt be cleaner to put it in the project root dir if i am using lein or something?

11:47 (yep, clutch 0.3.0 :)

11:48 cemerick: pandeiro: You can certainly save it to the current directory — but when a user's app is deployed, there _is no_ project directory anymore.

11:48 Or, you can't assume that there's one, e.g. might be a .war file.

11:49 pandeiro: i see

11:49 cemerick: thanks a lot

11:49 TimMc: you too

11:49 cemerick: pandeiro: If there's a better location than what I suggested, then use that. Maybe noir has a convention for storing settings somewhere?

11:49 Ask ibdknox when he's around. :-)

11:49 pandeiro: cemerick: i will ask, for sure...

11:50 cemerick: on a scale of 1 to 10, how hard is it to get the clojure view server up and running with clutch 0.3.0?

11:51 cemerick: pandeiro: Dead-balls simple IMO. See configure-view-server and view-server-exec-string docs @ https://github.com/ashafa/clutch

11:51 pandeiro: awesome, i will give it a shot

11:51 cemerick: I can imagine scenarios where it might not work, but it's done well in every environment I've tried.

11:52 I think if I were using the view server for serious stuff in production, I'd probably use curl to automate the configuration so that it's stable and out of the app's hands (rather than re-setting it on every startup or something), but maybe that's just me being enterprisey.

11:53 On balance, I'm far more interested in the clojurescript view server. Hopefully that can be merged in soon.

11:54 krey: hmpf, damn spymemcached

12:07 pandeiro: cemerick: got it set up and working, easy... though i notice the classpath (due to noir, mostly) is about 40 lines long... should that be a concern, performance wise?

12:08 cemerick: pandeiro: nah, no worries

12:08 pandeiro: i'm curious too what the advantage of a clojurescript view server would be exactly? still requires jvm right?

12:09 cemerick: Capturing the whole thing is the only way to ensure that people's view function dependencies (if any) are available.

12:09 pandeiro: Nope, no JVM needed with cljs views.

12:09 Thus the interest. :-)

12:09 pandeiro: wow, i dont see how that can be

12:09 but that would be very cool indeed

12:09 cemerick: clojurescript compiles to javascript

12:10 pandeiro: but the program that compiles it runs on the jvm, no?

12:10 cemerick: Try it for yourself if you like: https://github.com/cemerick/clutch-clojurescript

12:10 Right, yes, but you don't need a JVM/Clojure runtime for the view server.

12:10 i.e. you can run cljs-generated views on Cloudant, etc.

12:11 pandeiro: ah i see

12:12 that is terrific

12:12 cemerick: Yup.

12:12 Note that clutch-clojurescript necessarily uses a bundled (now old) version of clojurescript. Feel free to tinker, but I wouldn't use it for anything serious until it's integrated into clutch.

12:14 samaaron: cemerick: do you know what's happening with clojurescript bundling?

12:14 pandeiro: when you say necessarily, you mean it couldn't just seek out $CLOJURESCRIPT_HOME and try to use the compiler there?

12:14 cemerick: samaaron: Nope.

12:14 pandeiro: i ask naively, not having looked at the impl at all

12:14 samaaron: last time I checked you had to run a shell script to download stuff to specific directories to get it to work

12:15 cemerick: dnolen might have a clue there.

12:15 cmeier: samaaron: We have a Overtone band booked for our March meeting of the Cincinnati Functional Programmer's meetup :)

12:15 samaaron: which seems to be a temporary measure

12:15 pandeiro: samaaron: yeah the bootstrap script is still there

12:15 samaaron: cmeier: what??

12:15 lazybot: samaaron: Uh, no. Why would you even ask?

12:15 cemerick: pandeiro: it could, but I think that'd be stupid, and a huge PITA upon deployment.

12:15 pandeiro: lol ok

12:16 cemerick: pandeiro: I mean, you could easily throw an updated version of all the jars on the classpath, and stuff should work, but…

12:16 samaaron: cmeier: does this band have a name and a leader?

12:17 cmeier: Guys from EdgeCase Columbus office - inspired by Clojure Conj. (they are still working on a name)

12:17 I will be happy to pass on suggestions :)

12:17 samaaron: cmeier: can you get them to email me some details?

12:17 i'd love to know more about what they're doing

12:17 cmeier: sure

12:17 samaaron: thanks :-)

12:18 as long as they don't use the name (λ-tones) I'm happy ;-)

12:19 right, i'm going to cycle home

12:19 chat later

12:20 pandeiro: cemerick: last thing, i promise: did you guys ever consider some kind of helper function to facilitate authentication with the couchdb instance? it's a small PITA having to splice credentials into the URL... am i missing something?

12:20 (i've read through the clutch source but i couldn't find anything)

12:21 cemerick: pandeiro: just haven't gotten around to documentation yet :-)

12:21 (-> "http://some-couch-url" com.ashafa.clutch.utils/url (assoc :username "foo" :password "bar"))

12:22 pandeiro: nice

12:22 cemerick: There are other fields of interest on the utils.URL record type.

12:23 pandeiro: yeah i saw that but i still dont grok what defrecord is and exactly how it's used... it's the connect function that returns an instance of it, yeah?

12:23 cemerick: pandeiro: connect?

12:24 pandeiro: the private fn used by couchdb-request

12:24 jsabeaudry: I have a ring handler that has a body "(repeat 0)" which I would like to use to test throughput but I get abysmally low speeds, is one tcp packet sent for each element of the ISeq?

12:24 cemerick: pandeiro: no, that URL is java.net.URL. :-P

12:25 com.ashafa.clutch.utils.URL is the only record type that clutch users should care about

12:25 (which really only exists because java.net.URL sucks pretty hard)

12:26 pandeiro: i see, i need to try to understand what a record is first, but i did notice that piece of code when i was trying to figure out how to easily insert auth credentials

12:27 cemerick: fundamentally, you shouldn't need to know anything about http-client

12:27 most of it is going to be eliminated, FWIW :-P

12:28 pandeiro: i found the impl interesting since i just wrote a browser-side version of the same

12:28 (much simplified)

12:28 when you say eliminated, you mean separated out into a different package?

12:28 different repo i mean

12:29 cemerick: Well, significantly refactored. Clutch currently uses the JDK's HTTP client, which has a number of failings. I'm hoping to use something more sane soon-ish.

12:42 Raynes: dakrone: Ping.

12:42 dakrone: Raynes: pong

12:43 Raynes: dakrone: I'm getting a strange error with the wunderground JSON API that I never got before. "ZipException unknown compression method java.util.zip.InflaterInputStream.read (InflaterInputStream.java:147)"

12:43 I assume something changed on the server side, but I'm not sure what could cause something like this.

12:44 dakrone: do you have a url I can try to reproduce?

12:44 Raynes: Can you grab ororo? I'll let you use my API key.

12:44 http://github.com/Raynes/ororo

12:45 dakrone: sure

12:51 dbleyl_: hi. simple question. how do you overload a function that can take either a string, or a sequence of strings?

12:52 do you test for sequential? or is there a cleaner way?

12:53 destructure?

12:53 nachtalp: dbleyl_: (defn myfun [& args] ) ?

12:53 cgray: dbleyl_: you could do (defn foo [& strs] ...)

12:56 TimMc: dbleyl_: You mean, a single arg that is either a string or a sequence?

12:57 dbleyl_: yes

12:57 TimMc: I'd say (fn [x] (if (string? x) ... ...))

12:57 and in the else clause, call seq on x

13:09 dbleyl_: TimMc: thanks. I'm going with defn x [[s & more]]

13:11 TimMc: I don't think that's what you want...

13:11 dbleyl_: the repl just proved that you are correct.

13:11 treats string as a seq of chars.

13:11 TimMc: You only ever have one argument, and destructuring won't help you dispatch on anything.

13:15 jodaro: dbleyl_: i'm doing almost exactly that right now with multimethods

13:15 so you might look there

13:22 Vinzent: don't you think it'd nice to be able to write something like (defn foo ([^String s] ...) ([^IPersistentCollection coll] ...))?

13:23 TimMc: dbleyl_: multimethods would be useful if you want consumers of your code to be able to extend its functionality. Otherwise, just use an if.

13:26 Vinzent: or even [^pos? x] and [^neg? x] - much more declarative than spagetti of ifs! but it looks like I'm thinking about pattern matching

13:34 cgray: does the jvm impose its own limit on the number of open files that's allowed?

13:36 hiredman: why do you ask?

13:37 cgray: because i'm having a problem where files aren't getting properly written... i have about 500 open, so i'm thinking that might be it

13:37 hiredman: cgray: are you properly closing the files?

13:37 cgray: hiredman: i'm trying to keep them open so that there's no cost associated with seeking to append to them

13:38 hiredman: are you flushing?

13:38 cgray: yep

13:39 hiredman: and have you tried it with closing the file?

13:39 cgray: yeah, and that worked

13:39 but it slowed down once the files got big

13:40 hiredman: are you sure you are flushing?

13:40 cgray: i'll put it in a gist

13:40 hiredman: because closing automatically flushes

13:41 cgray: https://gist.github.com/1511359

13:42 hiredman: cgray: most likely the gzip outputstream is the issue

13:43 cgray: that seems strange to me because it worked when i was closing the file

13:44 i'll try without it though

13:44 hiredman: I imagine gzipos uses a certain blocksize, and waits for that blocksize number of bytes for writing to the underlying stream

13:44 and closing makes it stop waiting

13:45 cgray: that makes sense, but what's happening is that files are getting big and then going back to 10 bytes...

13:45 let me try without gzip though

13:45 hiredman: you have a race in your open-category-writer

13:46 cgray: really? i thought swap! was atomic

13:46 hiredman: it is, but you don't check to see if a writer for that category exists

13:46 the only thing atomic is the function you hand to swap

13:46 cgray: i only use it if the category doesn't exist though

13:47 TimMc: cgray: Your gist is deleted?

13:48 cgray: TimMc: yeah, sorry... i kind of f-ed it up...

13:48 hiredman: I am assuming this is a multithreaded program, you check for the existence outside of the function passed to swap, that means between the check and the call to swap some other thread could have swapped a writer in

13:48 cgray: hiredman: it's not intended to be multithreaded, but it's a good point

13:49 hiredman: if it's not multithread then why are you using an atom?

13:49 cgray: good practice for global variables? what should i use instead?

13:49 (i don't have a great reason for that tbh)

13:50 hiredman: why is it global?

13:50 cgray: because i'm mapping over the last function in the gist and it needs to change

13:50 hiredman: why not reduce?

13:51 cgray: good question...

13:51 hiredman: (reduce f writer-map ...)

13:52 cgray: i think you were right about the problem being gzipwriter though

13:55 kenth: Hi, is there a function that pulls up the code for a function loaded in REPL? or the return type?

13:56 jodaro: source

13:56 kenth: cool, thanks

14:04 mcrittenden: what's the best way to insert a | (bar) inbetween every character in a string, returning a new string. e.g. a function takes "test" as a param and returns "t|e|s|t" ...can interpose be used for this?

14:04 in between*

14:04 cemerick: ,(apply str (interpose \| "test"))

14:04 clojurebot: "t|e|s|t"

14:05 mcrittenden: cemerick: ok so interpose returns a seq which is then converted back to a string via apply str?

14:05 cemerick: yup

14:05 mcrittenden: awesome, thanks a bunch

14:06 amalloy: &(clojure.string/join "|" "test")

14:06 lazybot: ⇒ "t|e|s|t"

14:07 amalloy: (apply str (interpose foo bar)) makes me so sad. use join

14:07 mcrittenden: amalloy: cool, sounds good. thanks.

14:07 btw what's the diff between lazybot and clojurebot?

14:08 cemerick: amalloy: what can I say, I'm old school :-P

14:08 amalloy: lazybot is lazier

14:09 Raynes: mcrittenden: They're entirely different bots. lazybot is written by amalloy and I and clojurebot by hiredman.

14:09 amalloy: seriously, the difference is: they're completely different source trees written by different people to do different things. clojure evaluation is the most important thing either does, but they both have a bunch of add-ons

14:10 mcrittenden: are either or both open source?

14:10 i'd be curious to take a look

14:10 amalloy: ~source

14:10 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

14:10 amalloy: $whatis source

14:10 lazybot: source is http://github.com/flatland/lazybot

14:11 Raynes: amalloy: Did you see the latest?

14:11 $guards

14:11 lazybot: SEIZE HIM!

14:11 Raynes: I can't believe nobody added this crucial feature.

14:12 jodaro: heh

14:12 amalloy: interesting. is that a generic feature like clojurebot's ~foo, or a specific guards command?

14:12 mcrittenden: thanks amalloy!

14:12 Raynes: amalloy: Specific guards command.

14:12 amalloy: $help guards

14:12 lazybot: amalloy: SEIZE HIM!

14:13 jodaro: lazybot has cool stuff like

14:13 $wotd

14:13 lazybot: jodaro: pfeffernusse: (noun) A gingerbread biscuit served traditionally around Christmas time.

14:13 Raynes: Still waiting on jodaro to write the factoids plugin. Unfortunately, I'm not sure he knows he is supposed to do it.

14:13 jodaro: factoids?

14:13 Raynes: $know Who was the 7th president of the united states of america?

14:13 lazybot: Raynes: Andrew Jackson (1767-1845), the 7th President of the United States

14:14 jodaro: thats pretty factoidish

14:14 Raynes: jodaro: It's magic and I was kidding.

14:14 I'll do it eventually.

14:14 jodaro: $know what color is an orange?

14:14 lazybot: jodaro: orange (of the colour between red and yellow)

14:14 Raynes: It's just the syntax that I'm having trouble coming up with.

14:15 jodaro: pfeffernusse

14:29 jsabeaudry: Is there an easy way to coerce an ISeq to an InputStream?

14:35 foodoo: Do functions declared by protocols always dispatch by their first argument?

14:36 TimMc: jsabeaudry: Your question doesn't make sense.

14:36 amalloy: yes

14:36 TimMc: jsabeaudry: Seqs produce objects, inputstreams produce bytes.

14:37 foodoo: and should java.lang.object be used as a call-all variant of a protocol implementation?

14:38 call-all -> catch all (sorry)

14:39 jsabeaudry: TimMc: these sound very similar to me. Basically I'm looking for way to make an input stream as easily as I can make an ISeq ( (repeat 10 0) for example)

14:40 mcrittenden: I'm trying to use clojure to read from stdin and having trouble. Here's a simplified example which I want to take input and just re-print it. Can someone take a quick look? https://gist.github.com/1511559

14:40 actually, just figured it out. never mind!

14:42 brehaut: foodoo: yes, but its not a catch all; it just catches all objects

14:43 foodoo: nil isnt an object

14:43 TimMc: jsabeaudry: If you're trying to convert sequence data into bytes, you have to serialize it somehow.

14:45 jsabeaudry: I don't know offhand of any lazy inputstream producers, but it shouldn't be hard to write.

14:45 jsabeaudry: TimMc: What if it is already a byte (repeat 10 (byte 0))?

14:46 mcrittenden: new question, how can I tell clojure to stop listening to stdin when the user hits enter? https://gist.github.com/1511559

14:47 jsabeaudry: TimMc: alrighty, I'll look into writing these myself, thank you for your help :)

14:48 gfredericks: just got a patch into underscore that fixes the cljs incompatibility

14:49 TimMc: jsabeaudry: You may want to look at gloss. It's a byte-oriented library.

14:49 foodoo: mcrittenden: It's probably rather a Java issue as Clojure uses the java.io classes

14:49 sritchie: mcrittenden: usee (defn prompt-name [] (println "What's your name?") (read-line))

14:49 amalloy: fwiw, there's https://github.com/flatland/io/tree/develop/src/java/io/core which lets you reify an interface to create a new kind of InputStream instead of having to extend a class

14:51 foodoo: mcrittenden: I forgot about (read-line) I only looked at clojure.java.io

14:51 mcrittenden: sritchie wow, I wish I found read-line earlier. thanks

14:51 sritchie: no problem

14:52 brehaut: amalloy: thats great

14:52 amalloy: and https://github.com/flatland/io/blob/develop/src/clj/io/core.clj#L8 is a sample implementation of turning a ByteBuffer into an InputStream

14:53 jsabeaudry: TimMc: Oh wow, thanks that gloss library is going to be handy!

14:54 amalloy: but yeah, gloss is pretty excellent for byte stuff. we wound up using gloss instead of this io lib we wrote

14:54 TimMc: I haven't had an excuse to use it yet. :-(

14:58 foodoo: hypothetical question: Would it make sense to implement (seq coll) as a protocol so that anyone could create their own sequence types for Clojure?

15:00 brehaut: foodoo anyone _can_ implement their own seq types in clojure

15:00 foodoo: Because if I look at (reduce) it requires the collection to implement InternalReduce. But most types will already fail at the (let [s (seq coll)]) statement

15:00 brehaut: How is the idiomatic way to do that?

15:01 brehaut: ,(map inc (reify clojure.lang.Seqable (seq [this] (list 1 2 3))))

15:01 clojurebot: (2 3 4)

15:01 brehaut: foodoo: implement clojure.lang.Seqable for your type

15:02 foodoo: okay. That's a Java interface

15:02 brehaut: yes.

15:03 foodoo: whats the problem with that?

15:03 foodoo: It's okay.

15:04 Maybe it's just that this doesn't seem to be covered in the official docs

15:04 brehaut: foodoo: theres three[1] ways to make a type in clojure: defrecord, deftype, gen-classes. records already implement seqable, and you can trivially implement seqable for the other two. [1] ok so there is really more

15:06 foodoo: ah, thanks :) Still I wish this would have been better documented

15:06 accel: good mrning ladies and gentlemen; it's 12:07pm here as we start coding clojure again

15:06 amalloy: goodness, when did #clojure get a sportscaster?

15:07 brehaut: amalloy: 12:07pm dec 22, 2011

15:07 amalloy: so let it be written

15:07 brehaut: is it the 22nd?

15:07 mcrittenden: yes

15:07 accel: should I live cast my clojure coding session? I think I could improve quite a lot afer you guys see all the idiotic things I do.

15:11 Bronsa: here it's 21:11

15:24 gfredericks: if clojure is a sport, who is winning?

15:25 hiredman: me

15:26 pbuckley: gfredericks: anyone writing code with it is winning? But like a football game their head hurts after playing.

15:28 brehaut: gfredericks: im pretty sure it was a game of two halves, but clojure was the winner on the day

15:29 in hindsight that joke might not translate to non-rugby playing countries

15:29 gfredericks: I was just wondering if that was why I didn't understand it.

15:29 pbuckley: I thought I just wasn't smart enough to get the joke

15:30 accel: is there a canonical way to reprenset infinity in clojure?

15:30 brehaut: pbuckley: if im telling the joke, that should never be a problem

15:30 gfredericks: accel: if there is I'd like to know about it. a couple times I wrote a bunch of arithmetic code that used :infinity

15:31 hiredman: I write clojure code while wearing a bathrobe with "mr. bigshot" embroidered on it, I think I win

15:31 amalloy: &Double/POSITIVE_INFINITY

15:31 lazybot: ⇒ Infinity

15:31 accel: gfredericks: what amalloy said :-)

15:31 gfredericks: hiredman: now that you mention that I think I remember it being the exact conditions for winning.

15:32 amalloy: &'∞

15:32 lazybot: ⇒ ∞

15:32 brehaut: accel: alternatively (last (cycle :a))

15:32 gfredericks: ,(+ 5 Double/POSITIVE_INFINITY)

15:32 clojurebot: Infinity

15:33 kurtharriger: How do I create a byte data type for 0xFE in clojure?

15:34 (byte 0xFE) reports value out of range

15:34 brehaut: ,(short 0xFE)

15:34 clojurebot: 254

15:34 brehaut: theres no unsigned primative data in java

15:35 kurtharriger: but that returns a java.lang.Short I need java.lang.Byte

15:35 brehaut: kurtharriger: time to start crying

15:35 TimMc: kurtharriger: I can never remember how to do this.

15:35 pbuckley: &(- Double/POSITIVE_INFINITY Double/POSITIVE_INFINITY)

15:35 lazybot: ⇒ NaN

15:35 hiredman: http://www.javamex.com/java_equivalents/unsigned_arithmetic.shtml

15:36 brehaut: ,Byte/MAX_VALUE ;; kurtharriger

15:36 clojurebot: 127

15:36 TimMc: unchecked-byte?

15:36 &(unchecked-byte 0xFE)

15:36 lazybot: ⇒ -2

15:36 TimMc: Had to grep the chatlogs.

15:37 kurtharriger: ah ha

15:37 thanks

15:37 TimMc: &(doc unchecked-byte)

15:37 lazybot: ⇒ "([x]); Coerce to byte. Subject to rounding or truncation."

15:37 pbuckley: TimMc: how do you save the chatlogs? just C-x C-w?

15:38 TimMc: pbuckley: autolog_path = "~/chatlog/$tag/$0.log";

15:38 in .irssi/config :-P

15:42 pbuckley: TimMc: thanks, I just setup logging for erc :-)

15:45 amalloy: TimMc: i even remembered reading about unchecked-int, when i was looking into how to use the 4-byte constant 0xFFFF0000, but i was like..."naw, that can't be it. i must be misremembering and there's a way to enter it as a literal"

15:57 brehaut: i finally remembered to use (map f x (rest x)) instead of (for [[a b] (partition 2 x)] (f a b)). you're a hero!

15:57 brehaut: hah am i?

15:57 amalloy: well, cause it's better code and you usually write it that way

15:58 ibdknox: all the cool kids do ;)

15:58 brehaut: lol

15:58 haskell has taught me some things apparently :)

16:01 TimMc: amalloy: Is that a correct transformation?

16:01 amalloy: TimMc: yes, i believe it's correct for all f and x

16:01 TimMc: I think you need a 1 in that partition to make it overlap.

16:01 amalloy: oh sorry

16:01 yes, clearly need a 1

16:02 TimMc: partition 2 1 x

16:02 amalloy: right

16:04 TimMc: &(take 10 (partition 0 (range)))

16:04 lazybot: ⇒ (() () () () () () () () () ())

16:05 TimMc: &(take 5 (partition 0 1 (range)))

16:05 lazybot: ⇒ (() () () () ())

16:06 TimMc: &(take 5 (partition 1 1 (range)))

16:06 lazybot: ⇒ ((0) (1) (2) (3) (4))

16:06 TimMc: &(take 5 (map seq (range)))

16:06 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

16:06 TimMc: &(take 5 (map list (range)))

16:06 lazybot: ⇒ ((0) (1) (2) (3) (4))

16:06 TimMc: Oops, sorry -- I thought I was in /msg lazybot

16:07 It's a good thing I didn't decide to discuss intimate topics with the bot.

16:09 Vinzent: lol

16:10 can you help me setup cljs+emacs?

16:11 I've opened index.html from the repl sample which comes with clojurescript, started inferiour-lisp. I see the repl, but it hangs when I'm hitting enter

16:12 (I've followed instructions on cljs wiki)

16:13 zakwilson: Is there currently a good reason to use Java 7 with Clojure?

16:13 hiredman: there are a lot of new features in 7

16:14 http://openjdk.java.net/projects/jdk7/features/

16:14 huh, sctp support, I had forgotten that protocol even existed

16:20 brehaut: ibdknox: re:state-m in korma; did you come to any decision?

16:20 ibdknox: I don't think it's the right thing to do

16:21 brehaut: it's very cool, but the trade-off in conceptual complexity doesn't seem worth it to me

16:21 especially given it's not common in Clojure

16:22 TimMc: Monads? In my Clojure?

16:23 mcrittenden: assuming a nested 3x3 vector, anyone have a smart way to convert a number 1-9 to the appropriate position in the vector? for example, 9 would become [2, 2] and 1 would become [0, 0] and 4 would become [1, 0]

16:23 TimMc: mod and div

16:23 mcrittenden: TimMc: cool, just didn't know if there was a shortcut. thanks!

16:24 TimMc: I don't think there's a divmod operator in Clojure.

16:25 $findfn 20 6 [3 2]

16:25 lazybot: []

16:26 sritchie: (juxt quot mod)

16:26 TimMc: Ouch.

16:26 sritchie: ,((juxt quot mod) 20 6)

16:26 clojurebot: [3 2]

16:26 TimMc: ((juxt quot mod) (dec 9) 3)

16:26 &((juxt quot mod) (dec 9) 3)

16:26 lazybot: ⇒ [2 2]

16:26 brehaut: (comp (partial (juxt mod quot) 9) dec)

16:26 ibdknox: ~juxt

16:26 clojurebot: juxt is usually the right answer

16:27 brehaut: rats. sniped twice.

16:28 and i got the order wrong. sigh

16:28 amalloy: i usually use (juxt quot rem). i think for positive integers it doesn't matter, and i can never remember the difference between rem and mod, but for negative ones it should matter

16:28 ibdknox: ,(doc rem)

16:28 clojurebot: "([num div]); remainder of dividing numerator by denominator."

16:28 ibdknox: ,(doc mod)

16:28 clojurebot: "([num div]); Modulus of num and div. Truncates toward negative infinity."

16:30 foodoo: ~clojure

16:30 clojurebot: clojure is a language to use if you want to up your game

16:30 brehaut: ~math

16:30 clojurebot: math is hard.

16:30 sritchie: ~science

16:30 clojurebot: science is http://sunpig.com/martin/images/2008/10/iwilldosciencetoit.jpg

16:30 foodoo: ~xkcd

16:30 clojurebot: Gabh mo leithscéal?

16:30 TimMc: &(let [num 20, div -6, [a b] ((juxt quot rem) num div)] (= (+ (* a div) b) num))

16:30 lazybot: ⇒ true

16:30 TimMc: &(let [num 20, div -6, [a b] ((juxt quot mod) num div)] (= (+ (* a div) b) num))

16:30 lazybot: ⇒ false

16:32 mcrittenden: ((juxt quot mod) (dec 9) 3) <- i love that so much. thanks all

16:32 TimMc: mcrittenden: Use rem

16:33 mcrittenden: in this case it will never be negative but I hear you, I'll use rem

16:33 TimMc: The semantics are clearer.

16:34 brehaut: mcrittenden: ordinals vs cardinals for your index might help too

16:35 mcrittenden: brehaut: that just went over my head. care to explain?

16:35 brehaut: start counting at 0 rather than 1

16:35 mcrittenden: ah so I can avoid the (dec x)?

16:35 gotcha

16:36 TimMc: brehaut: I've never heard those words used that way.

16:36 brehaut: TimMc: i thnk its a computerscience bastardisation of math

16:36 TimMc: Haha, OK.

16:36 brehaut: TimMc: some languages have arrays that have 1 as the first index

16:36 (BASIC for instance)

16:36 TimMc: Yep.

16:37 brehaut: so weird :P

16:38 TimMc: brehaut: Are you sure that "ordinal" doesn't refer to 1-based in this context?

16:38 brehaut: TimMc: nope ;)

16:38 TimMc: cardinals definitely start at 0 in math

16:39 Wikipedia: "The finite ordinals (and the finite cardinals) are the natural numbers: 0, 1, 2, â...,"

16:39 brehaut: timmc: http://c2.com/cgi/wiki?OrdinalsAndCardinals

16:40 TimMc: note the 'minor nitpick' ;)

16:40 zakwilson: ibdknox: what do you think about the idea of replacing lazy-with in Korma with some sort of smart join?

16:40 TimMc: brehaut: Yeah, that's a nice touch.

16:48 ibdknox: zakwilson: what would be the between what join is now?

16:48 and what you're proposing

16:48 zakwilson: also, korma.incubator would be a great place to try such a thing :D

16:48 zakwilson: ibdknox: I just read about incubator *as you were typing that*.

16:49 ibdknox: zakwilson: I'm not opposed to what I think you're going to suggest :) It's just slow and pretty annoying to implement (unless you drastically limit the cases you're willing to deal with)

16:50 zakwilson: I assume you're saying a has-many that comes back in one query and then you dissect the results and put them into objects

16:50 zakwilson: ibdknox: yes, something like that.

16:51 ibdknox: zakwilson: if it's limited to one level deep, then it's fairly easy to do :)

16:51 zakwilson: Essentially, I want the apparent behavior of with, but one query instead of the potential for zillions.

16:51 ibdknox: and would be a good addition I think

16:52 mcrittenden: sritchie: your idea worked really well. thanks again. made good progress, learned a lot

16:53 zakwilson: I've been thinking about this for a while - since before I even know about Korma. I had it in mind for ClojureQL - something that knows about relationships and generates a query to traverse them as requested.

16:53 sritchie: awesome

16:53 semperos: using clojure.java.jdbc with h2, trying to select a column which returns a clob value

16:53 ibdknox: zakwilson: indeed, I've done such things before

16:53 semperos: using the function to "declobify" the text into a string shown here: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#SELECT

16:53 ibdknox: zakwilson: it's a tough thing to build while maintaining flexibility and speed

16:54 zakwilson: I'm all for trying to do it though

16:54 semperos: if I just try to go through the result set and println the declobbed string, it works fine; if I try the same operation, but use a for comprehension to return a seq of such strings, I get an error

16:54 here's a gist showing what I'm doing: https://gist.github.com/1512012

16:54 zakwilson: I had in mind something that looks like with and requires you to manually specify what you want to traverse - e.g. (with [:foo :bar :baz]) would join to foo, which joins to bar which joins to baz.

16:54 semperos: seems like I'm missing something basic; any thoughts?

16:55 zakwilson: I also had in mind something that would traverse all known relationships to a certain depth: (traverse 3)

16:55 hiredman: semperos: did you read the exception?

16:55 ibdknox: semperos: results need to be realized immegiately

16:55 immediately

16:55 hiredman: semperos: those things don't just messages for fun

16:55 semperos: I did read the exception

16:55 I don't understand how my two fn's differ in terms of when I'm realizing the results

16:55 hiredman: ~for

16:55 clojurebot: for is not a loop

16:55 semperos: right

16:56 ibdknox: for creates a lazy seq

16:56 semperos: ah, that's right

16:56 * semperos forgot the lazy bit

16:56 semperos: thanks guys

16:56 zakwilson: I haven't done anything like that before and honestly, I'm bad at databases, as my not-in group post illustrates. (I finally figured that one out, BTW and will post about it as soon as I fix the code)

16:56 ibdknox: np

16:56 semperos: thought it was something simple I was overlooking

16:57 amalloy: TimMc: btw, i had forgotten earlier, but the one that goes with mod is div. so div/mod or quot/rem are probably both reasonable; i was just objecting to quot/mod

17:00 TimMc: amalloy: Ah, there is a div? Good. I was speaking in general terms.

17:01 brehaut: ,(apropos 'div)

17:01 clojurebot: (unchecked-divide-int)

17:01 TimMc: &((juxt div mod quot rem /) 20 6)

17:01 lazybot: java.lang.RuntimeException: Unable to resolve symbol: div in this context

17:01 amalloy: apparently not

17:01 TimMc: harmph

17:02 brehaut: def mod (comp int /)

17:02 s/mod/div/

17:02 amalloy: i think unchecked-divide-int is basically div though

17:02 TimMc: &((juxt unchecked-divide-int mod quot rem /) 20 6)

17:02 lazybot: ⇒ [3 2 3 2 10/3]

17:02 TimMc: &((juxt unchecked-divide-int mod quot rem /) 20 -6)

17:02 lazybot: ⇒ [-3 -4 -3 2 -10/3]

17:03 TimMc: &(doc unchecked-divide-int)

17:03 lazybot: ⇒ "([x y]); Returns the division of x by y, both int. Note - uses a primitive operator subject to truncation."

17:04 TimMc: OK, so that's the same as Java's / with integer types.

17:15 antares_: technomancy_: hi. I see that lein deps with 1.6.2 does not exit when one of the dependencies is not found. This causes stall builds on travis-ci.org and I can reproduce it locally. Is it a known leiningen issue?

17:17 schleyfox: hi, is there any way to force identity equality (java ==) in clojure on the built in persistent data types?

17:17 hiredman: ,(doc identical?)

17:17 clojurebot: "([x y]); Tests if 2 arguments are the same object"

17:17 schleyfox: fantastic, thanks

18:33 srid: the highest rated answer on a stackoverflow question reads: "You use hashmaps to represent members of the population. I'd rather recommend you create a little class to represent them" http://codereview.stackexchange.com/a/372/6446

18:33 goes against clojure's philosophy of using built-in datastructures to represent objects

18:38 amalloy: srid: that's a...ruby question? ruby dudes like classes; you should probably use classes in ruby

18:41 srid: yea, that's what I thought. it is non-straightforward to write functions / simple-datastructure code in ruby.

18:45 alexbaranosky: no first class functions in ruby! (don't let them try to fool you : ) )

18:49 amalloy: alexbaranosky: i don't know a ton of ruby, but isn't Proc basically as first-class as clojure's functions? at a lower level both of them are actually instances of a class, but you treat them as functions

18:50 alexbaranosky: amalloy: you have to go out of your way to make a proc though; meaning you can't just take a function and pass it around, like you could in JS or Python

18:51 amalloy: alexbaranosky: your argument is that functions are first-class, but most "functions" are actually methods, which aren't?

18:51 alexbaranosky: amalloy, but maybe you could just write your code in terms or Procs, and leave methods out of the picture entirely, and then get away with it :)

18:52 amalloy: alexbaranosky: http://experthuman.com/programming-with-nothing was a fun blog post on that topic

18:52 alexbaranosky: amalloy, well I guess I see JS and Python's approach as nicer - basically that their methods are functions with a this associated

18:52 amalloy, I'll take a look in a minute

18:56 amalloy, I've read enough of that article to realize it is awesome

18:57 amalloy: grep "lambda calculus" # pretty good indicator of awesome

19:01 alexbaranosky: amalloy, I've been using `for` a lot more since ClojureConj thanks to your prodding

19:02 amalloy: excellent. finding it suitable/useful?

19:02 alexbaranosky: definitely

19:03 amalloy: not coincidentally, i added 2 problems to 4clojure last night to introduce 'for

19:05 alexbaranosky: have I mentioned lately that Clojure is awesome ? :)

19:06 for a little fun I got the idea to write some "Java" in Clojure... Write a little project with all of the class-oriented features of Clojure just to flex more of those Clojure-muscles

19:16 accel: does {} always create hashmap?

19:17 seancorfield: ,(type {})

19:17 where's the bot?

19:17 &(type ())

19:17 lazybot: ⇒ clojure.lang.PersistentList$EmptyList

19:17 seancorfield: &(type {})

19:17 lazybot: ⇒ clojure.lang.PersistentArrayMap

19:18 seancorfield: the array map becomes a hash map once it has more than 10 entries i believe

19:18 &(type (into {} (range 30)))

19:18 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

19:18 seancorfield: darn!

19:18 &(type (apply into {} (range 30)))

19:18 lazybot: clojure.lang.ArityException: Wrong number of args (21) passed to: core$into

19:18 seancorfield: groan...

19:19 accel: &(type {:a a, :b b, :c c, :d d, ... crap I'm tired

19:19 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

19:19 seancorfield: heh

19:19 accel: 30 is a big number.

19:19 ibdknox: &(into {} (partition 2 (range 30))

19:19 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

19:19 ibdknox: &(into {} (partition 2 (range 30)))

19:19 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry

19:19 ibdknox: lol

19:19 amalloy: omg guys

19:19 alexbaranosky: y'alls syntax is hurting my eyes ;)

19:19 :P

19:19 amalloy: &(into {} (map vec (partition 2 (range 30))))

19:19 lazybot: ⇒ {0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29}

19:19 seancorfield: sorry, i'm on vacation and my brain is away...

19:20 amalloy: &(type (into {} (map vec (partition 2 (range 30))))) ; if you like

19:20 lazybot: ⇒ clojure.lang.PersistentHashMap

19:20 seancorfield: thank you

19:20 accel: woot

19:21 how many clojure-ists does it take to figure out the type of {} :-D

19:21 amalloy: actually, sorta simpler to do ##((juxt type identity) (apply hash-map (range 30)))

19:21 lazybot: ⇒ [clojure.lang.PersistentHashMap {0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29}]

19:21 seancorfield: is it 10 items or 15 that is the tipping point for array map becoming a hash map?

19:21 amalloy: 10, for now

19:21 seancorfield: yeah, i remember having to look in the source for a change i made in java.jdbc (removing structs)

19:22 amalloy: also my hash-map example is ridiculous. of course it's a hash-map, i asked for a hash-map

19:22 ibdknox: :p

19:22 seancorfield: hahaha

19:22 &(type (into {} []))

19:22 lazybot: ⇒ clojure.lang.PersistentArrayMap

19:23 seancorfield: gotta love juxt tho'... i'm using that a lot these days

19:23 amalloy: ~juxt

19:23 seancorfield: when i have a sequence of maps and only want a subset of the keys, juxt is perfect! :)

19:23 amalloy: clojurebot: :(

19:24 seancorfield: juxt isn't really ideal for that. what if your keys aren't all keywords?

19:24 ibdknox: &(doc select-keys)

19:24 lazybot: ⇒ "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

19:25 amalloy: right, select-keys or (map the-map [k1 k2 ...])

19:25 depending on if he wants out a map or a tuple

19:25 ibdknox: yeah

20:05 brehaut: im pretty sure you oculd write an accurate siesmic activity monitor by drinking the twitter firehose

20:06 TimMc: brehaut: Or scraping usgs.gov. :-P

20:06 brehaut: TimMc: in new zealand its geonet.org.nz :P

20:06 but its at least 15 minutes behind twitter

20:07 accel: #<questino redacted, reading "Proggramming Clojure" instead>

20:10 TimMc: < amalloy> seancorfield: juxt isn't really ideal

20:10 :-O

20:10 $guards

20:10 lazybot: SEIZE HIM!

20:12 accel: how do I allow a function to be able to call itself?

20:14 hiredman: recur is the best way

20:14 accel: recur looks like it[s paired with loop

20:14 skeeterbug: http://java.ociweb.com/mark/clojure/article.html#Recursion

20:14 accel: I'm not sure how to use recur/loop to write a recursive (non-iterative) version of fibonacci

20:15 skeeterbug: nice; thanks

20:15 amalloy: TimMc: any good relationship, like mine with juxt, is predicated on honesty. someone has to be there to tell him when he's going out in an ugly shirt

20:15 accel: in a very weird way; multimethods also get me out of this bind

20:17 jli: bah.

20:18 TimMc: amalloy: haha

20:18 jli: amalloy: what's ugly?

20:18 brehaut: accel: you need to refactor fib into a tail recursive form before recur is useful

20:19 TimMc: accel: Functions can call themselves without doing anything special. What's the trouble.

20:25 jli: TimMc: "without anything special"? not quite - if you want it to be tail recursive, you need to use recur

20:25 TimMc: jli: accel is asking for general recursion, not iteration

20:26 jli: oh

20:26 TimMc: ...which is odd, but whatever.

20:26 accel: I shudder to think how you are using multimethods for this.

20:27 brehaut: TimMc: i wonder if he means he actualy wants mutual recursion

20:27 accel: nono; just a function calling itslf

20:27 im an idiot

20:27 brehaut: ,((fn fib ([n] (if (< 2 n) (fib (- n 2) 1 1) 1)) ([n a b] (if (<= n 0) b (recur (dec n) b (+ a b))))) 10)

20:27 accel: when I ask a question, it it can either be internted as (1) sheer stupidity or (2) a brilliant way to tackle a known difficult problem; asusme (1)

20:28 brehaut: clojurebot hates my fib

20:29 amalloy: brehaut: clojurebot is dead atm

20:29 brehaut: that would be why then

20:29 in that case http://spl.smugmug.com/Humor/Lambdacats/13227630_j2MHcg#965006899_x8v3L

20:30 TimMc: re earthquakes; twitter told me it was a mag 5.8 in chch nearly 20 minutes before gns had the official reading

20:32 qbg: brehaut: I like this one: http://spl.smugmug.com/Humor/Lambdacats/13227630_j2MHcg#1288212148_5KLHJ3V

20:32 brehaut: haha

20:33 LoganLK: What clojure book or guide would you recommend for someone who knows Java but has never done any functional programming/lisp before?

20:33 amalloy: personally i recommend Joy of Clojure to all comers. some people claim it's not a good first book but i dunno what is wrong with them

20:34 4clojure.com is free and fun, but a bit narrowly-focused - it teaches mechanics more than the big picture

20:34 ekoontz: I like Clojure in Action by Amit Rathore a lot

20:35 has a lot of practical stuff like integration with SQL and HBase

20:35 qbg: You can also complement those books with SICP or the SICP videos

20:35 brehaut: theres very little waffle in Joy of Clojure; if you are new to FP or lisp you probably dont want to belt through it in only a few sittings. if you space it out a bit it should be fine

20:36 LoganLK: many thanks

20:36 hiredman: I recommending reading the documentation on clojure.org

20:37 you can start from the top of the left side bar and work your way down

20:37 qbg: Take this with you: http://clojuredocs.org/

20:38 amalloy: oh yeah, SICP is excellent too

20:38 TimMc: brehaut: You will of course recall the XKCD re: speed of Twitter vs. speed of seismic waves.

20:38 brehaut: hiredman: occasionally going back to the top and going down again is helpful too

20:38 TimMc: yes.

20:38 TimMc: brehaut: I periodically re-read clojure.org/lisps in particular

20:41 &((fn fib [n] (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) 6) ; accel: see, fib calls itself directly

20:41 lazybot: ⇒ 13

20:41 qbg: LoganLK: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

20:44 brehaut: TimMc: the slow version is so much cleaner than a linearized version

20:44 TimMc: Not if you have recur.

20:45 The explicit accumulator version is slightly ugly.

20:45 brehaut: TimMc: yeah, that version is linearized

20:46 &((fn fib ([n] (if (<= 2 n) (fib (- n 2) 1 1) 1)) ([n a b] (if (<= n 0) (+ a b) (recur (dec n) b (+ a b))))) 6)

20:46 lazybot: ⇒ 13

20:49 amalloy: they're all uglier than the iterate version, though

20:54 qbg: &((fn [n] (let [f (fn [n f] (if (<= 2 n) 1 (+ (f (- n 1)) (f (- n 2))))) f (memoize f)] (f n f)) 6)

20:54 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

20:54 qbg: &((fn [n] (let [f (fn [n f] (if (<= 2 n) 1 (+ (f (- n 1)) (f (- n 2))))) f (memoize f)] (f n f))) 6)

20:54 lazybot: ⇒ 1

20:55 qbg: &((fn [n] (let [f (fn [n f] (if (<= n 2) 1 (+ (f (- n 1)) (f (- n 2))))) f (memoize f)] (f n f))) 6)

20:55 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox19315$eval21954$fn--21955$f

20:55 qbg: &((fn [n] (let [f (fn [n f] (if (<= n 2) 1 (+ (f (- n 1) f) (f (- n 2) f)))) f (memoize f)] (f n f))) 6)

20:55 lazybot: ⇒ 8

20:56 qbg: &((fn [n] (let [f (fn [n f] (if (< n 2) 1 (+ (f (- n 1) f) (f (- n 2) f)))) f (memoize f)] (f n f))) 6)

20:56 lazybot: ⇒ 13

20:57 brehaut: amalloy: hah yes definately

20:59 qbg: &((fn [n] (first (nth (iterate (fn [[x y]] [y (+ x y)]) [0 1]) n))) 6)

20:59 lazybot: ⇒ 8

20:59 qbg: &((fn [n] (first (nth (iterate (fn [[x y]] [y (+ x y)]) [1 1]) n))) 6)

20:59 lazybot: ⇒ 13

20:59 qbg: Yep, iterate is good

21:00 brehaut: &((fn [n] (first (nth (iterate (juxt second (partial apply +)) [1 1]) n))) 6)

21:00 lazybot: ⇒ 13

21:00 brehaut: much better ;)

21:01 TimMc: brehaut: Are you a wizard? o.o

21:01 amalloy: haha brehaut, i hadn't seen it written out with juxt

21:02 brehaut: TimMc: oh. my bad ##((comp first (partial nth (iterate (juxt second (partial apply +)) [1 1]))) 6)

21:02 lazybot: ⇒ 13

21:02 amalloy: in fairness though, you should be starting with [0 1]

21:02 hiredman: ,(tkae 10 (let [p (promise)] (deliver p (lazy-seq (concat [1 1] (map + @p (rest @p))))) @p))

21:02 damn

21:02 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: tkae in this context, compiling:(NO_SOURCE_PATH:0)>

21:02 hiredman: ,(take 10 (let [p (promise)] (deliver p (lazy-seq (concat [1 1] (map + @p (rest @p))))) @p))

21:02 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NullPointerException>

21:02 brehaut: i took qbg's code and mangled it; i take no responsibility for the logic

21:02 qbg: hiredman just took my idea

21:02 :)

21:03 amalloy: nice. i was getting set to mock you for actually naming a variable, brehaut

21:03 brehaut: amalloy: lol

21:03 hiredman: thats great

21:03 hiredman: if the damn thing worked

21:03 brehaut: a mere detail

21:04 amalloy: hiredman: chunked seqs causing the problem?

21:04 brehaut: TimMc: i had an point-free epiphany when i learnt haskell. its been hard to shake it ever since

21:04 qbg: &(take 10 (let [p (promise) s (lazy-cat [0 1] @p)] (deliver p (map + s (rest s))) @p))

21:04 lazybot: ⇒ (1 2 3 5 8 13 21 34 55 89)

21:05 qbg: &(take 10 (let [p (promise) s (lazy-cat [1 0] @p)] (deliver p (map + s (rest s))) @p))

21:05 lazybot: ⇒ (1 1 2 3 5 8 13 21 34 55)

21:05 hiredman: ,(take 10 (let [p (promise)] @(deliver p (lazy-cat [1 1] (map + @p (rest @p))))))

21:05 clojurebot: (1 1 2 3 5 ...)

21:05 sandy1986: Hi, wrap-reload doesn't work. I'm using net.cgrand.moustache and lein ring server-headless 8080 to run the app

21:06 TimMc: &(doc lazy-cat)

21:06 lazybot: ⇒ "Macro ([& colls]); Expands to code which yields a lazy sequence of the concatenation of the supplied colls. Each coll expr is not evaluated until it is needed. (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))"

21:07 qbg: &(take 10 (let [p (promise) s (lazy-cat [0 1] @p)] (deliver p (map + s (rest s))) s))

21:07 lazybot: ⇒ (0 1 1 2 3 5 8 13 21 34)

21:08 qbg: Hehe... Only one deref

21:08 brehaut: hiredman: does that imply that you can use promises to implement any 'tie the knot' type stuff for mutually recursive data?

21:08 amalloy: brehaut: that only works because of the delayed execution provided by lazy sequences

21:09 qbg: Well, a promise basically is mutation under the covers

21:09 hiredman: well, you can use any kind of mutable state to do it, promises are just nice cause it is one shot

21:09 * amalloy apprently didn't think it through

21:09 hiredman: I have a letfn as a macro that uses promises are delays or something under the covers

21:09 or

21:09 qbg: If clojure was fully lazy and had letrec, we wouldn't need it in this case

21:10 hiredman: https://gist.github.com/1179073

21:11 amalloy: hiredman: probably promises. doing it with delays doesn't seem easy

21:11 brehaut: ibdknox: are you paying attention?

21:11 amalloy: damn it i hate you. delays, huh?

21:11 hiredman: I guess, I don't really recall how it works

21:12 I would have thought promises

21:13 accel: how do I convert a string to a throwable?

21:13 brehaut: (Exception. "string")

21:13 ,(Exception. "string")

21:13 clojurebot: #<Exception java.lang.Exception: string>

21:13 brehaut: on the other hand. dont, and go look at slingshot

21:13 amalloy: interesting. it looks like you're having the body of each function start with (let [f (force f-delay), g (force g-delay)] ...). makes sense, i suppose

21:13 accel: brehaut: noted; thanks

21:13 brehaut: why?

21:14 qbg: &(Throwable. "string")

21:14 lazybot: ⇒ #<Throwable java.lang.Throwable: string>

21:14 brehaut: accel: because why tunnel data through strings when you can use a arbitrary structured data

21:14 qbg: lolz

21:14 brehaut: throwable is a class?

21:14 not an interface?

21:14 qbg: yes

21:14 brehaut: goddamn java

21:14 hiredman: right, I sort of remember this, because clojure isn't lazy you just can Y combinator up the functions, you need delays

21:14 accel: brehaut: gah; how am I supposed to remain a crappy clojure programmer if you keep on telling me the right way to do things?

21:14 amalloy: slingshot is great, but it's hardly the only choice. using underlying host exceptions makes interop easier

21:15 hiredman: you can't just Y combinator up

21:15 qbg: brehaut: You also can't have generic subclasses of throwable

21:15 Luckily it doesn't matter to Clojure users...

21:15 brehaut: qbg: i seem recall all this. but everytime it comes up i am annoyed

21:16 hiredman: 1.4 is gonna have ExceptionInfo

21:16 qbg: That made the ACM programming competition hard

21:16 amalloy: oh really

21:16 hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ExceptionInfo.java

21:17 brehaut: excellent!

21:17 hiredman: and slingshot already sort of supports using it instead of using slingshot's own exception class

21:17 amalloy: welp, that's good. now slingshot doesn't need a Stone anymore; it can just be a layer of nice macros on top of this ExceptionInfo thing, right?

21:18 hiredman: https://github.com/scgilardi/slingshot/blob/master/src/slingshot/support.clj#L19

21:18 right

21:19 accel: woot; it owrks again

21:19 yay for learning how to use exceptions

21:19 brehaut: thats some crafty code

21:19 accel: I feel like I should pay you guys tuition.

21:19 What do you prefer, chicken or beef flavored ramen?

21:20 Okay; no tuition then.

21:20 hiredman: brehaut: it went through a number of iterations to get to that

21:20 brehaut: geez christchurch; calm the fuck down

21:22 hiredman: it re-emphasises my need to go looking at other peoples code in detail.

21:22 accel: because it's incomprehensible or beacuse it's brilliant?

21:22 qbg: So Throwable is Serializable... Not sure why you would want to do that

21:22 brehaut: accel: if i wanted incomprehensible i'd be a c++ developer

21:23 hiredman: qbg: rpc exceptions

21:23 accel: brehaut: Im pretty sure you can get most of the way there with defmacro

21:23 qbg: hiredman: makes sense

21:23 brehaut: accel: defmacro is simple

21:24 accel: the syntax quote reader stuff makes macros seem a bit more magical than they really are

21:24 amalloy: brehaut: fwiw, i prefer (every? #(ns-resolve 'clojure.core %) '[ex-info ex-data])

21:25 accel: brehaut: I have no problem with defmacro; it's the things that defmacro can create that scares me.

21:25 brehaut: accel: i dont really have anything to say to that

21:26 amalloy: nice

21:26 hiredman: the real tricky bit is using resolve again down below

21:26 qbg: accel: Like compiler-in-a-macro macros?

21:27 hiredman: (which is required to avoid statically linking to a particular implementation at compile time)

21:30 brehaut: accel: more seriously, even though i can use the basics in clojure well, there is a heap of real smart stuff out there that is worth learning from, so why waste the opertunity

21:31 accel: brehaut: for you absolutely; for me, I still need to master basis

21:31 brehaut: accel: reading comprehension comes before writing comprehension

21:32 if you only read what yuo are writing, its going to take a lot longer to learn

21:33 accel: start with 'source' in your repl; whenever you use a new function, see how its implemented.

21:34 TimMc: Of course, sometimes you'll just see calls to RT, or nasty tricks, or implementation-specific stuff.

21:34 The stuff near the top of core.clj is more likely to have those.

21:36 accel: why is clojure's map so much uglier than sicp's map?

21:37 brehaut: does sicp have a variadic map?

21:37 hiredman: clojure's map also handles chunked seqs

21:37 brehaut: and is it lazy?

21:37 hiredman: (except when it isn't)

21:38 really chunking is what makes it ugly

21:38 ibdknox: brehaut: hm?

21:38 accel: is there a good book of clojure pearls?

21:38 I wouldn't mind reading such a text.

21:39 brehaut: ibdknox: did you see the discussion about using promises and delays to write macros that allow mutually recursive data?

21:39 ibdknox: I didn't, but that's what I did...

21:39 lol

21:39 brehaut: thats what i thought :)

21:40 hiredman: ,(for [m (repeat 5 {:a {:b {:c 1} :d 2} :e 3}) [k v] m :when (= k :a) [k v] v :when (= k :b)] v)

21:40 clojurebot: ({:c 1} {:c 1} {:c 1} {:c 1} {:c 1})

21:41 hiredman: ,(for [m (repeat 5 {:a {:b {:c 1} :d 2} :e 3}) [k v] m :when (= k :a) [k v] v :when (#{:b :d} k)] v)

21:41 clojurebot: ({:c 1} 2 {:c 1} 2 {:c 1} ...)

21:42 brehaut: 4clojure?

21:43 hiredman: me? no, for is just cool

21:43 brehaut: ah :)

21:50 hiredman: actually letfn- has 5 calls to for

21:53 brehaut: hiredman: is letfn- just a reimplementation of letfn? or does it do some other stuff?

21:53 hiredman: I believe it is just letfn

21:57 accel: (def a 20) `(,a) <-- why does this not say (20) ?

21:57 inquiring minds want to KNOW


21:57 hiredman: because this is not scheme

21:57 brehaut: because a: a is an int, not a function

21:57 b: , is white space

21:57 clojurebot: Alles klar

21:57 ibdknox: lol

21:57 accel: crap

21:57 how do I unquote in clojure?

21:57 brehaut: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:a

21:57 clojurebot: :a

21:57 accel: brehaut: point taken

21:57 hiredman: accel: read the docs, you'll find out

21:58 accel: REMOVE ALL THE ,'s

21:58 hiredman: this question actuallyc ame from watching the clojure data structures part 1 screencast

21:58 brehaut: (thats incidentally why clojurebots eval character is superior to lazybots. sorry ranyes)

21:58 accel: ha

21:58 ~

21:58 clojurebot: Gabh mo leithscéal?

21:58 hiredman: brehaut: well, I got to pick first

21:59 brehaut: true

21:59 its still objectively better :P

21:59 TimMc: amalloy: Why did sexpbot get changed to lazybot?

22:00 amalloy: TimMc: sexpbot looks too much like sexbot

22:00 ibdknox: I always read it as sex-puh-bot

22:00 amalloy: and is hard to pronounce, too. lazybot is a more awesomer name all around, really

22:01 brehaut: amalloy: now to get core to introduce a new visible whitespace character into clojure

22:01 amalloy: meh

22:01 i agree , is nice, but & is fine too, and sticks out a bit more

22:07 TimMc: amalloy: Hard to pronounce, which is a major problem in an IRC channel. :-P

22:08 hiredman: ,(* 12345678 12345678)

22:08 accel: 19 minutes into Clojure Data Structures part 1; and I realize I have learned more from it than an entire season of terra nova

22:08 clojurebot: 152415765279684

22:08 TimMc: ,Long/MAX_VALUE

22:08 clojurebot: 9223372036854775807

22:33 sandy1986: ;) bye bye.

22:37 accel: whoa

22:37 clojure's built in numeric types are quite nice

22:37 why has no one written mathematica within clojure yet?

22:37 clojureritica is just a matheamtica binding

22:37 but not actual mathematica

22:46 moogatronic_: If I have a function that uses destructuring: (defn test [& {:keys [a b c] :or [a 1 b 2 c 3]}] (+ a b c)) is there a way to call the function and pass a map as the params?

22:47 like: (test :b 0 {:a 1 :c 7}) ... ie, can i pre-destructure the params somehow?

22:48 brehaut: i recall this coming up before, and ithink the solutions are fairly hideous

22:48 (flatten the map into a seq of keys and vals)

22:49 ,(apply (fn [& {:keys [a b]}] [:a a :b b]) (mapcat identity {:a 1 :b 2 :c 3}))

22:49 clojurebot: [:a 1 :b 2]

22:50 brehaut: moogatronic_: i think the problem is that java has no varargs; they are a myth built ontop of an array of objects.

22:52 moogatronic_: brehaut: ah, I will investigate this. THat looks usable. The destructuring is nice for the function def, but sometimes I build up a map of the params that I want to pass along.

22:52 brehaut: ,(destructure ['[& {:keys [a b]}] [:a 1 :b 2]])

22:52 clojurebot: [vec__61 [:a 1 :b 2] map__62 (clojure.core/nthnext vec__61 0) map__62 ...]

22:53 brehaut: moogatronic_: if you can, make the function take a map; you could provide a utility that takes varargs and calls that

Logging service provided by n01se.net