#clojure log - Nov 10 2010

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

0:14 Derander: when I'm working in slime and hit c-d d I get a documentation buffer in the other window in my frame

0:15 is there a simple way to close that?

0:15 amalloy: Derander: C-x 4 0

0:15 or do you want the old window back?

0:16 if so, C-x 4 C-o <RET> should work

0:35 Derander: amalloy: thank you

0:35 I ended up just writing a macro to flip over and hit "q'

0:35 "q"*

0:35 amalloy: lol

1:17 uberjar: just for the record I predicted this Oracle JVM monetization strategy in this channel 3 months ago and at least 5 of you laughted at me, taunted me, and told me it could never happen :)

1:17 * uberjar does his proud victory dance

1:19 uberjar: thats all, just had to rub it in :P l8rz

1:20 Raynes: Cool story, broy.

1:23 coldhead: ahahah

1:25 Adamant: he got his victory dance and didn't get to hear the rebuttal

1:25 I think this means he wins

1:26 one internet.

1:40 coldhead: i'll PM him the rebuttal

2:01 hiredman: ping?

2:01 clojurebot: PONG!

2:03 LauJensen: The boat is rocking: https://blogs.apache.org/foundation/entry/statement_by_the_asf_board1

2:06 defn: anyone have stuart halloway's slides from clojure-conj? day 2?

2:21 ppppaul: boat is going to sink

2:22 rdsr: defn: are these what u are looking for? https://github.com/stuarthalloway/clojure-presentations

2:24 ppppaul: is the lambda shorthand only for non-nested shorthand functions?

2:25 rdsr: oh they don't contain the clojure-java interop slides

2:25 if u want I can mail u that one

2:25 amalloy: ppppaul: yes, #() doesn't nest

2:25 because how would the compiler know which % is associated with which closure?

2:26 ppppaul: name them?

2:26 %1

2:26 %2

2:26 i dono

2:26 Raynes: Those aren't names.

2:26 amalloy: ppppaul: that syntax already means something

2:26 ppppaul: hehe

2:26 oh

2:26 i want to do something like the below

2:26 (every? #((map #(= % ) (integer? '* '/ '+ '-))) (flatten (read-string string)))

2:27 checking that everything in a list is an int or a math symbol

2:27 wait, that's wrong

2:27 lol

2:27 amalloy: ppppaul: that code kinda makes no sense

2:27 ppppaul: i don't need map, i need any?

2:27 amalloy: you need some

2:28 ppppaul: but i need to use fn [] format

2:28 i guess

2:29 amalloy: &(every? #(some '#{+ - * /} %) '[+ -])

2:29 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

2:29 amalloy: &(every? #(some #{'+ '- '* '/} %) '[+ -])

2:29 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

2:29 amalloy: bah, what

2:29 anyway ppppaul it's pretty common to use sets as predicates for things like this

2:30 ppppaul: yeah, i'm looking at the some docs

2:31 makes sense, but is it for performance?

2:31 LauJensen: &(every? #{'+ '- '* '/} ['+ '-])

2:31 sexpbot: ⟹ true

2:31 LauJensen: &(every? #{'+ '- '* '/} ['+ '- 'b])

2:31 sexpbot: ⟹ false

2:32 LauJensen: amalloy: I think I use sets in a few posts on bestinclass.dk :)

2:33 amalloy: LauJensen: maybe i'll read your blog so i understand how this language feature works :)

2:34 LauJensen: Wee, I finally got my last subscriber, I can retire as a blogger now

2:35 ppppaul: lol

2:35 jartur: Hi.

2:36 amalloy: LauJensen: time to move on to twitter

2:36 LauJensen: Oh, you're not following me on Twitter either?

2:36 You missed the ClojureQL aggregate syntax poll :(

2:36 (technically its not over yet)

2:36 jartur: Does anybody have an idea how to keep a persisten SQL connection?

2:36 LauJensen: http://twitter.com/laujensen

2:36 jartur: I need to poll some db value every second

2:36 LauJensen: jartur: Yea, the trick is to not close it

2:36 :]

2:37 jartur: LauJensen: with standard contrib.sql it's not that simple, aye?

2:37 LauJensen: jartur: No its not. Wait a little while and ClojureQL will be out in 1.0 - I have seriously considered making a connection pool

2:37 jartur: I can of course put an endless loop within (with-connection ...)

2:38 LauJensen: jartur: But I guess if you need something now, you could simple override with-connection in contrib.sql.internal

2:40 I always write 'simple' when I meant 'simply' - I should make an emacs hook to catch that :(

2:40 amalloy: LauJensen: that should be pretty simply

2:41 LauJensen: haha, punk

2:41 jartur: Hmm, I don't really see how overriding with-connection could help. Do you mean make it not to close a connection after its scope ends?

2:42 Chousuke: find the var that clojure.sql binds the connection to and then just use that manually?

2:42 LauJensen: Yep. Or just to check if it gets a map or a java.sql.Connection. If its the latter dont close. Something like that

2:42 It binds *db* IIRC

2:43 jartur: I really do not like how contrib.sql works now, btw =)

2:43 hiredman: if only there was something that looked like a loop but really yielded a succession of async tasks with depend on the result of the previous task...

2:44 LauJensen: jartur: Like I said, CQL is just around the corner now

2:44 jartur: Or maybe just use pure java interop for my pretty simple task for now

2:44 LauJensen: Check out the github page to see how much is already working

2:44 jartur: I only need to write to one db and immediately check value from its slave. And do this every second.

2:45 Actually, multiple slaves. And serve delays as a graph on web

2:48 ppppaul: gah, i feel like i just want to convert my list to a string and then use regex on it

2:50 &(str '(+ 2 3 4))

2:50 sexpbot: ⟹ "(+ 2 3 4)"

2:50 ppppaul: that's good enough for me

2:52 (re-match #"^\([\d+-*/]+\)" (str (flatten (read-string string)))

2:52 :)

2:55 LauJensen: ppppaul: You had a problem and you thought you would solve it with regexes :)

2:56 ppppaul: i have a problem with unmatched delimiters now :(

2:56 LauJensen: ...and now you have two problems

2:56 ppppaul: lol

2:56 with regex my code size shrunk a lot

2:57 without regex i need to make a big function for every

3:03 LauJensen: ppppaul: Didnt you see my set example ebove? about the same size as your regex

3:04 Raynes: amalloy: sexpy is running the latest clojail. What I just pushed mere moments ago.

3:05 I've got a little bathroom reading to do.

3:05 amalloy: Raynes: excellent

3:05 to both, i guess? :P

3:05 ppppaul: i needed more complexity than just (integer?)

3:06 i needed to test things about the number if it was an int, as well

3:06 needed an every? and some? nested

3:06 with (str and regex i just need that one line of code

3:06 LauJensen: &(number? 5.5)

3:06 sexpbot: ⟹ true

3:07 ppppaul: i need to make sure the integer? is 0-9

3:07 so, three functions

3:08 replaced by (str and regex

3:11 actually, str isn't playing well with flatten :(

3:13 (str (read-string "(+ 1 1)"))

3:13 "(+ 1 1)"

3:13 rosettacode.24game=> (str (flatten (read-string "(+ 1 1)")))

3:13 "clojure.lang.LazySeq@ee696f27"

3:13 how do i extact all of flatten?

3:13 (doall?

3:16 raek: ,(pr-str (flatten (read-string "(+ 1 1)")))

3:16 clojurebot: "(+ 1 1)"

3:16 ppppaul: thanks

3:17 what does 'pr' mean? it doesn't say in the docs

3:17 (doc pr-str)

3:17 clojurebot: "([& xs]); pr to a string, returning it"

3:19 Chousuke: (doc pr)

3:19 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

3:21 Raynes: LauJensen: You mean to tell me that 5 is a number?

3:21 No way man. No way. I can't accept it.

3:21 LauJensen: Raynes: Just dropping clues for ppppaul before he starts implementing Perljure

3:21 ppppaul: lol

3:21 Raynes: amalloy: I just checked on crisis1, and raynes.me is pointing at our VPS now. We hath been successful.

3:22 amalloy: cool. and i've finally got mongo doing almost what i want

3:22 :P

3:22 ppppaul: oh, is pr for serialization?

3:22 Raynes: amalloy: You're *still* working on getting mongo to work properly on that plugin?

3:22 Chousuke: Well, ghetto serialisation :P

3:22 amalloy: &((juxt pr print) "hi")

3:22 sexpbot: ⟹ "hi"hi[nil nil]

3:22 Raynes: &(doc pr)

3:22 sexpbot: ⟹ "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

3:22 Raynes: Oh, you already did that.

3:22 amalloy: Raynes: any watching tv :P

3:22 *and

3:23 Chousuke: it works for a bunch of things, but you can't print everything readably

3:25 Raynes: amalloy: Anyways, as soon as my ISP's cache wears out and I can navigate to raynes.me, I'll start moving my web related stuff over to crisis2.

3:25 amalloy: Raynes: i actually just solved the problem i was having earlier. now i'm having trouble getting update! to work, so i'm just gonna use the same destroy!/insert! hack the other plugins use

3:25 Raynes: congomongo has update!?

3:25 Well I'll be damned.

3:25 amalloy: sorta

3:25 Raynes: Also, don't call my code a hack. :(

3:26 amalloy: it's "take the entry whose id is x, and replace it with this object", more or less

3:26 Raynes: That's meh.

3:26 amalloy: man, you *know* destroy/update is a hack :P

3:26 but it's good enough for me, at this point

3:26 Raynes: It makes sense, but still meh.

3:27 I had somebody ask me how the plugins could see the mongo connection even though the mongo connection is opened at runtime in a totally different unrelated namespace. I didn't have an answer.

3:27 I'm still not sure how that works. congomongo in general is a hack.

3:27 :<

3:27 amalloy: yeah i guess

3:27 Raynes: Or magic, depending on whether your glass is half full or not.

3:28 LauJensen: They should have called it Mongojure, with emphasis on the 2nd o

3:28 jartur: Hmm, if I start a thread within a (binding ...) form will that thread have a global binding or local one?

3:29 Raynes: "I have before me a contract for a Ring book from the Pragmatic Press. (via @marick)" Oh my heavens, that's awesome.

3:30 It's almost as awesome as this here hotpocket I'm scarfing down.

3:30 jartur: Raynes: I read that @mmcgrana I think. Maybe it was retweet

3:30 Raynes: jartur: Maybe. I got it from disclojure.

3:30 LauJensen: Wow, cond-let doesnt support destructuring. Doesnt that make it almost totally useless?

3:31 Raynes: $sed -LauJensen s/almost//

3:31 sexpbot: <LauJensen> Wow, cond-let doesnt support destructuring. Doesnt that make it totally useless?

3:31 Raynes: No destructuring, no cookies.

3:31 amalloy: LauJensen: um, i'm pretty sure it does support destructuring, it's just that cond-let is a totally different type of thing than if-let, so the name is confusing

3:32 LauJensen: &(cond-let [[x y] [1 2]] (> x y) "bigger" (< x y) "smaller")

3:32 sexpbot: java.lang.Exception: Unable to resolve symbol: cond-let in this context

3:32 LauJensen: &(use 'clojure.contrib.cond)

3:32 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/cond__init.class or clojure/contrib/cond.clj on classpath:

3:32 LauJensen: All has failed me

3:33 ,(use 'clojure.contrib.cond),

3:33 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/cond__init.class or clojure/contrib/cond.clj on classpath:

3:33 amalloy: (cond-let [[a b]]

3:33 [1 2] {a b})

3:33 ==> {1 2}

3:33 Raynes: That confuses me so bad!

3:33 LauJensen: eh?! O_o

3:33 amalloy: LauJensen: i told you. cond-let does something totally different from if-let

3:33 Raynes: amalloy: Ever notice how some (SOME) contrib libs aren't available in the sandbox? ANY sandbox. clojurebot's, clj-sandbox, nor clojail.

3:33 LauJensen: That needs to be looked at imo

3:34 amalloy: LauJensen: it's actually a lot more useful this way

3:34 i think it should just be renamed

3:34 it takes a form to bind to, then a set of tests. whichever test succeeds, it binds to the form and evals the expr with those bindings

3:35 LauJensen: amalloy: no cookies

3:36 * amalloy is sad but doesn't know why

3:39 Raynes: amalloy: Can you hit raynes.me:10000 yet? I had a buddy hit it a moment ago, successfully. :>

3:39 jartur: Okay, new thread within binding will have global var value.

3:39 amalloy: Raynes: yes

3:39 Raynes: Everybody but me.

3:39 * Raynes cries

3:40 LauJensen: Raynes: Its hard to imagine Alabama not being one of the first priorities during an DNS change :)

3:41 Raynes: I know, right?

3:41 jartur: Raynes: in Vladivostok, Russia I can hit it.

3:42 Raynes: Meh, what's 7 hours or so.

3:42 amalloy: Raynes: i just called a buddy who lives on the moon

3:42 * Raynes lols

3:42 amalloy: getting great d/l speeds

3:42 LauJensen: Raynes: You need to get some security on that server now that the Russians have access

3:43 jartur: Mwahahaha

3:43 Raynes: :p

3:43 LauJensen: Its crazy - When you open a new VH somewhere, almost immediately, seconds after it gets an IP, the chinese start trying to get root

3:44 But I guess when you have the power to employ a hacker for each IP in the known universe, it would be silly not to exploit that fact

3:44 Raynes: amalloy: Did you ever buy a new domain last night? Or are you going to keep your old VPS and keep your old domain pointed wherever it was before and such?

3:44 amalloy: no, i ended up not doing it. couldn't find any fun ones for sale

3:44 might get akm.me or something, but eh

3:44 Raynes: Shame.

3:45 You should. Me, you, and fogus_ would all have matching domains.

3:45 jartur: What is idiomatic way in Clojure to do scheduled execution with fixed rate?

3:46 reify timertask and use Timer.scheduleatfixedRate ?

3:47 Raynes: amalloy: You know, I've implemented a Clojure sandbox in 141 lines of code. Including whitespace.

3:47 :D

3:47 Clojure is so awesome.

3:47 amalloy: probly about 200 lines without my help,eh? nudge nudge

3:47 Raynes: I want to go back to the conj and do a lightning talk about it.

3:48 amalloy: You cut me back 2 lines I think. Don't get snarky with me. s_s

3:48 It was at least 4. Maybe 5.

3:49 amalloy: well! now that you've given me that huge bump i won't have to get huffy

3:49 Raynes: Using symbols rather than class objects was borderline retarded, so I give you that.

3:49 amalloy: *laugh*

3:51 Raynes: I'm going to have to learn how to dump and restore a mysql database.

3:51 jartur: C'mon any pointers at least. =)

3:51 amalloy: Raynes: mysqldump

3:52 Raynes: I only use mysql for wordpress. I should really just transfer it over to wordpress.com, shouldn't I?

3:52 It's kind of silly to host my own blog. I gain nothing from it.

3:52 amalloy: i did say

3:52 i guess you gain "geek cred"

3:53 Raynes: And then I don't have to run mysql and can save memory. Not that we need memory now.

3:53 cemerick uses wordpress.com. He has all sorts of geek cred.

3:53 Of course, he has nREPL. But hey, I've got sexpbot and Clojail!

3:53 * amalloy is firmly entrenched in case anyone ever cares

3:54 Raynes: $dict entrenched

3:54 sexpbot: Raynes: preposition: dug in

3:54 ppppaul: $dict dug in

3:54 sexpbot: ppppaul: noun: A teat, pap, or nipple; -- formerly that of a human mother, now that of a cow or other beast.

3:54 Raynes: Duh

3:54 ppppaul: so...

3:54 amalloy: lolwut

3:55 ppppaul: firm nipple?

3:55 amalloy: *checks*

3:55 not telling

3:55 ppppaul: oh boy

3:55 Raynes: It didn't check 'in', by the way. It only checked 'dug'

3:56 amalloy: yeah, obv

3:56 ppppaul: i bet in is some sexual thing too

3:59 jartur: Ahh, TimerTask is class, can't reify

3:59 Sucks

3:59 amalloy: jartur: proxy?

4:28 esj: morning all

4:33 Raynes: esj: Morning.

4:33 kryft: esj: Huomenta.

4:34 esj: Raynes: I'm coming to visit your part of the world soon - Thanksgiving in Tennessee :)

4:34 Raynes: Never been.

4:34 Close enough though.

4:34 esj: My first experience was actually a UT / Alabama game...

4:37 Bahman: Hi all!

4:37 esj: Morning Bahman

4:38 Bahman: Morning esj.

4:39 kryft: Does anyone here happen to use vimpulse?

4:40 I'm wondering if it's a major/minor mode or if it works by somehow modifying whatever major/minor mode you happen to be in.

5:48 morphling: LauJensen: you there?

5:48 LauJensen: sure

5:48 This is #clojure, where else would I be? :)

5:48 morphling: hehe

5:49 i'm sfehrenbach on twitter

5:49 I don't get why (avg x y) would not work, but i don't think it would be a good idea anyway

5:49 i think it's too close to clojures function calls

5:50 LauJensen: morphling: If we're to implement a consumer of lists, you loose all excess to regular clojure, OR we need to implement factory fns for every single SQL function ever written. Which was pretty much the mistake of the old ClojureQL

5:50 s/excess/access/

5:50 sexpbot: <LauJensen> morphling: If we're to implement a consumer of lists, you loose all access to regular clojure, OR we need to implement factory fns for every single SQL function ever written. Which was pretty much the mistake of the old ClojureQL

5:51 morphling: ah, okay

5:51 but how would you do (avg (max a b))? :avg#:sum#a#b?

5:52 s/sum/max

5:52 sexpbot: <morphling> but how would you do (avg (max a b))? :avg#:max#a#b?

5:52 LauJensen: Right now you can do [[:a.b/max :as :m] :m/avg - But this whole discussion is to arrive at a superior format

5:53 (by right now I mean on my local snapshot, on the MASTER you still have the # syntax with no way to hit multiple fields)

5:58 morphling: do you think it'd be enough to just quote sql function calls, like '(avg :field)? you could still call clojure functions with backquote and unquote

6:00 LauJensen: Interesting idea - I'll try to play around with it a little

6:05 fliebel: morning

6:06 kzar: mornin'

6:06 belun: ellow :)

6:39 kzar: I've got a number like 56.00000000000001 and I want to check if it's basically 56 but I think something funny is happening? &|(- 56.00000000000001 56)|&

6:39 sexpbot: ⟹ 7.105427357601002E-15

6:43 jowag: kzar: http://floating-point-gui.de/

6:43 Chousuke: kmc: what's weird about that?

6:44 or well

6:44 it is weird, but not if you keep in mind they're floats :P

6:45 belun: can you cast to integer ?

6:45 or what u need requires floats ?

6:45 * Lajla sneaks up to Chousuke and lays his egs in kmc.

6:49 lenw: hi all

6:52 i am trying to uderstand where i am building up memory - i have a (for [t (range 1 10000)] (let [x (f t)] (process x))) and i OOM exceptions - isnt x gc'ed in the for statement above ?

6:52 kzar: Converting it into a float did the trick, thanks for the ideas everyone

6:54 Chousuke: lenw: for generates a lazy seq. are you sure you're not storing the whole seq in memory at once?

6:55 lenw: Chousuke: what alternative do i have to drive that ?

6:56 Chousuke: would that code above cause the whole seq to be in mem at once - its not what i want :)

6:56 Chousuke: lenw: it depends on what you do with the seq for returns

6:57 lenw: Chousuke: i am ignoring it ... its just driving the process

6:57 Chousuke: then you're misusing for

6:57 use doseq

6:57 lenw: i thought i might be thatnks

6:57 Chousuke: for is not for side-effects :)

6:57 lenw: :)

6:58 like writing to a mongodb ...

7:03 tormar: I want to consume a REST api using clojure, but I need to use digest authentication. Are there any client libs which has digest implemented? Not familiar with Java, but guess some interop will work for me. Any pointers?

7:04 For instance, has anyone done digest auth with clojure.contrib.http.agent?

7:57 roolio: help

7:58 belun: hit F1 :P

8:18 (defn show- me [& {:key s [what ] :or {:wha t "defa ult"}] what)

8:19 how do i talk to the bot ?

8:20 bartj: belun, hit a comma before the expression

8:20 there is also something called sexpbot here and you need to hit a "&" before your sexp

8:21 not sure how clojurebot is different from sexpbot

8:21 for eg: to invoke clojure bot here:

8:21 , (:a {:a 1 :b 2})

8:21 clojurebot: 1

8:21 belun: ,(defn show-me [& {:keys [what] :or {:what "what?"}} ] what)

8:21 clojurebot: DENIED

8:22 belun: :)

8:22 , (defn show-me [& {:keys [what] :or {:what "what?"}} ] what)

8:22 clojurebot: DENIED

8:22 bartj: belun, you cannot define functions here

8:22 belun: can i fn and use directly ?

8:22 LauJensen: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me {:what "hey"}))

8:22 sexpbot: java.lang.IllegalArgumentException: No value supplied for key: {:what "hey"}

8:23 LauJensen: bartj: actually you can, but you need letfn

8:23 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me))

8:24 bartj: belun, you need to remove the space before &, I think

8:24 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me "something"))

8:24 &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me "something"))

8:24 sexpbot: java.lang.IllegalArgumentException: No value supplied for key: something

8:24 belun: ya :)

8:24 Chousuke: you're using map destructuring

8:24 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me))

8:24 sexpbot: ⟹ nil

8:25 belun: i want try out named args

8:25 Chousuke: do (show-me :what "something")

8:25 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me {:what "anything"}))

8:25 sexpbot: java.lang.IllegalArgumentException: No value supplied for key: {:what "anything"}

8:25 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me :what "anything"))

8:25 sexpbot: ⟹ "anything"

8:26 belun: yay

8:26 yet so complicated

8:26 Chousuke: not complicated. :)

8:26 it's pretty simple if you know how destructuring works

8:26 belun: aint pretty

8:27 Chousuke: I don't know why the :or thing didn't work though.

8:27 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me :what))

8:27 sexpbot: java.lang.IllegalArgumentException: No value supplied for key: :what

8:27 belun: &(letfn [(show-me [& {:keys [what] :or {:what "what?"}}] what)] (show-me))

8:27 sexpbot: ⟹ nil

8:27 belun: (clojure-version)

8:27 &(clojure-version)

8:27 sexpbot: ⟹ "1.2.0"

8:28 Chousuke: ah

8:28 your or map was wrong

8:28 belun: how

8:28 Chousuke: it needs to be {symbol defvalue}

8:28 not :key defvalue

8:28 belun: &(letfn [(show-me [& {:keys [what] :or {what "what?"}}] what)] (show-me))

8:28 sexpbot: ⟹ "what?"

8:29 belun: yee

8:29 bartj: er, when should letfn be preferred over defn?

8:29 belun: er now :P

8:29 Chousuke: bartj: when you don't want to define a global function :P

8:29 belun: defn puts stuff in ur namespace

8:29 letfn just creates and uses

8:30 bartj: Chousuke, functions can also be defined within defn

8:30 Chousuke, or am I wrong ?

8:30 belun: &(show-me)

8:30 sexpbot: java.lang.Exception: Unable to resolve symbol: show-me in this context

8:30 Chousuke: bartj: with letfn

8:30 letfn is just sugar got let + fn

8:30 raek: bartj: not with defn (as you would in Scheme)

8:30 Chousuke: right.

8:30 if you do (defn foo ... (defn bar ...)) you're defining two global functions

8:31 ... and bar's definition will change whenever foo is called.

8:31 belun: which this sandbox doesnt let you :P

8:31 bartj: no, I mean (defn foo (let [ bar-fn (fn [] ) ] ...))

8:31 Chousuke: bartj: yeah

8:31 raek: the only time I use letfn is when I need a helper function for a lazy seq

8:31 Chousuke: bartj: letfn is some macro sugar for that.

8:32 raek: the fn name is visible inside the fn, which is not the case if you only use (let [f (fn [...] ...

8:32 bartj: Chousuke, hmm, ok!

8:32 Chousuke: (letfn [(foo [] ...)] ...) expands to (let [foo (fn foo [] ...)] ...)

8:33 raek: the second "foo" is what makes foo refer to the function itself inside the function

8:34 bartj: Chousuke, raek cool, thanks! I don't see myself declaring only functions in my lets, though

8:34 Chousuke: letfn also supports mutually recursive definitions I think

8:37 raek: ideal if you tend to implement Hofstadter's M and F functions as lazy seqences a lot... ;-)

8:37 fliebel: Chousuke: How so?

8:37 Chousuke: fliebel: hm?

8:37 how so what?

8:38 raek: ,(doc letfn)

8:38 clojurebot: "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the function...

8:38 fliebel: Chousuke: If letfn expands to a let, how could they be mutualy recursive?

8:38 raek: "All of the names are available in all of the definitions"

8:38 fliebel: raek: I see…

8:39 raek: hrm, I wonder what the resulting let looks like

8:39 fliebel: the magic seems to be inside letfn*

8:39 raek: ah, a special form?

8:39 fliebel: it's not in core at least

8:39 LauJensen: &(letfn [(od? [x] (if (pos? x) (eve? (dec x)) "odd")) (eve? [x] (if (pos? x) (od? (dec x)) "even"))] (odd? 5))

8:39 sexpbot: ⟹ true

8:40 LauJensen: oops

8:40 &(letfn [(od? [x] (if (pos? x) (eve? (dec x)) "even")) (eve? [x] (if (pos? x) (od? (dec x)) "odd"))] (od? 5))

8:40 sexpbot: ⟹ "odd"

8:40 LauJensen: :)

8:40 Chousuke: you can shadow globals, you know

8:41 LauJensen: yea I know

8:42 fliebel: Huh, where is letfn* comming from? It's not in core and no in special forms.

8:44 LauJensen: Compiler.java line 42

8:44 fogus_: fliebel: Usually starred things live in the Compiler. But not always.

8:45 jarpiain: letfn* is the true special form, the letfn macro just adds some syntax sugar

8:46 just like let macro adds destructuring to the let* special form

8:47 fliebel: I never thought of letfn as something special… more special than let.

8:48 fogus_: fliebel: I don't understand what you mean

8:48 jarpiain: in scheme it's possible to implement letfn using let because the bindings created with let are mutable

8:48 chouser: though in the case of letfn and let, along with many other "special forms", the macro input is the official and documented api. Don't rely on the behavior or even the existence of let* or letfn*

8:49 for example, 'if' has been a macro is some versions of clojure and a special form in others.

8:50 fliebel: chouser: a macro of what? What is it currently?

8:51 LauJensen: The only exception is Enlives emit* which I love too much to respect christophes warnings :)

8:52 hiredman: uh, I think it was a macro when rest was split into first/next

8:52 if expanded into a check to see if you were nil puning

8:52 er

8:52 rest/next

8:53 chouser: hiredman: right

8:53 fliebel: so temporarily the special form was if* and if was a macro that used it

8:53 fogus_: BTW, what is the canonical meaning of foo* (i.e. starness)

8:54 chouser: and now if is back to being a special form

8:54 hiredman: foo* is many times used to mean "a helper for implementing foo"

8:54 chouser: fogus_: I think it's like a "prime" quote in math. x' is somehow related to x

8:55 fogus_: chouser, hiredman: I see. That is what I expected. But there are some (list*) that are freely used, and others that are "off-limits"

8:55 hiredman: of course since we have a unicode enabled language we can also just use ′

9:00 jarpiain: list* is from Common Lisp but the naming doesn't seem to be consistent there either

9:01 chouser: yeah, list* does seem oddly named

9:02 fogus_: I propose changing the name to awesome-list

9:03 bartj: , (doc list*)

9:03 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

9:05 fogus_: ,(let [awesome-list list*] (awesome-list 1 2 3 4 [5 6 7 8]))

9:05 clojurebot: (1 2 3 4 5 6 7 8)

9:07 bartj: what are the "a" and "b" in the documentation of list* ?

9:07 , (list* 1 2 3 4) ;fails!

9:07 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

9:09 fogus_: bartj: a and b are just args. The last thing (args) is something that is seqable

9:10 see my use of awesome-list

9:11 bartj: hmm, is list* syntactic sugar too?

9:11 because (list* 1 2 3 4 (range 10)) = (into (list 1 2 3 4) (range 10))

9:11 fogus_: bartj: No. It's just a function https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L580

9:11 bartj: maybe not syntactic sugar exactly, but you get the drift.

9:13 Chousuke: ,(list* 1 2 3 4 (range 10))

9:13 clojurebot: (1 2 3 4 0 1 2 3 4 5 ...)

9:13 Chousuke: ,(into (list 1 2 3 4) (range 10))

9:13 clojurebot: (9 8 7 6 5 4 3 2 1 0 ...)

9:14 fliebel: ~seen Raynes

9:14 clojurebot: Raynes was last seen in #clojure, 279 minutes ago saying: Close enough though.

9:14 fogus_: ,[(list* 1 2 {:a 3 :b 4}) (list* 1 2 "abc") (list* 1 2 '#{a b c})]

9:14 clojurebot: [(1 2 [:a 3] [:b 4]) (1 2 \a \b \c) (1 2 a c b)]

9:15 bartj: Chousuke, am assuming order is not important while using lists

9:15 Chousuke: bartj: huh?

9:15 I just demonstrated that list* is not equal to the into thing :)

9:16 bartj: because the ordering of the list generated is different?

9:16 Chousuke: yes.

9:16 list* is a basic function anyway, not syntactic sugar

9:16 ~def list*

9:17 djpowell: there is a nice usage of using fingertrees for statistics here: http://blog.sigfpe.com/2010/11/statistical-fingertrees.html

9:18 bartj: Chousuke, thank you

9:24 fogus_: spread is fun too

9:24 ,(#'clojure.core/spread [1 2 3 [4 5 6]])

9:24 clojurebot: (1 2 3 4 5 6)

9:26 fogus_: Although I guess it's just the same as (apply list* [1 2 3 [4 5 6]])

9:34 Chousuke: fogus_: except list* uses spread :P

9:35 as does apply

9:37 fogus_: Chousuke: Minor implementation detail. ;-)

10:26 tonyl: morning

10:26 fliebel: morning

10:27 lauri`: use /nick laurioherd

10:28 stuartsierra: mollie

10:28 ignore

11:08 bartj: the definition of difference in clojure.set/difference seems very different to me

11:08 I thought it was (A - B) where A and B are two sets

11:10 sorry, wrong interpretation!

12:03 ohpauleez: technomancy: Are you a wondermark fan?

12:08 hiredman: ohpauleez: he is

12:08 ohpauleez: ahhh cool.

12:08 zmyrgel: I'm getting "unable to resolve classname" -error from my use my defrecord defined in other file

12:09 chouser: zmyrgel: if you want to use a defrecord constructor directly, in need to import the class, not just use the namespace

12:09 zmyrgel: chouser: ah, thought that there would be something like that

12:09 chouser: zmyrgel: it's generally recommended to provide your own function in that namespace that calls the ctor

12:10 doing that allows 'use' to be sufficient again, as well as giving you a place (in the function) to provide default args, etc.

12:11 zmyrgel: ok, gotta see that

13:13 jashmenn: i dont get this

13:13 ,(conj [1 2 3] "b")

13:13 clojurebot: [1 2 3 "b"]

13:13 jashmenn: ,(conj (lazy-seq [1 2 3]) "b")

13:13 clojurebot: ("b" 1 2 3)

13:14 stuartsierra: "conj" means "add to collection"

13:14 tonyl: lazy-seq returns a seq

13:14 amalloy: jashmenn: conj adds in whatever way is cheapest

13:14 tonyl: vectors are appended

13:14 seqs are added in the head

13:14 jashmenn: ah okay

13:14 thanks

13:15 chouser: ,(conj {:a 1 :c 3} [:b 2])

13:15 clojurebot: {:b 2, :a 1, :c 3}

13:15 hiredman: clojurebot: oracle is <reply>The sky is falling!

13:15 clojurebot: Roger.

13:16 amalloy: hiredman: oh, <reply> is a cute feature. does he have any other modifiers?

13:18 hiredman: no, <action> would be nice

13:18 there are also variables that can be filled in

13:18 amalloy: hiredman: like how?

13:18 hiredman: clojurebot: say goodbye is <reply>goodbye #who!

13:18 clojurebot: Ok.

13:18 hiredman: clojurebot: say goodbye

13:18 clojurebot: goodbye hiredman!

13:19 pjstadig: clojurebot: say goodbye

13:19 clojurebot: goodbye pjstadig!

13:19 amalloy: nice

13:19 stuartsierra: clojurebot: are you skynet?

13:19 clojurebot: excusez-moi

13:20 tonyl: oracle is

13:20 oracle is?

13:20 chouser: clojurebot: oracle!

13:20 clojurebot: The sky is falling!

13:21 tonyl: :P

13:21 * tonyl lunch time

13:39 Raynes: sexpbot: kill

13:39 sexpbot: KILL IT WITH FIRE!

13:42 amalloy: $sed -sexpbot s/FIRE/HUGS

13:42 sexpbot: <sexpbot> $sed -sexpbot s/HUGS/HUGS

13:42 amalloy: hm. that doesn't seem right

13:43 am i misremembering the sed syntax?

13:43 slyrus: missing trailing / ?

13:44 amalloy: slyrus: maybe, but i made the trailing / optional cause i kept forgetting it, so that would be a bug

13:44 Raynes: amalloy: Would you believe my ISP still hasn't cleared it's DNS cache? :<

13:44 amalloy: s/kept forgetting/hate

13:44 sexpbot: <amalloy> slyrus: maybe, but i made the trailing / optional cause i hate it, so that would be a bug

13:45 Raynes: amalloy: I think you broke sed.

13:45 amalloy: slyrus: yeah, that's not the problem. i suspect he just doesn't handle sedding his own messages quite as i'd expect

13:45 $sed Raynes s/broke/fixed

13:45 sexpbot: <> $sed Raynes s/fixed/fixed

13:45 amalloy: $sed -Raynes s/broke/fixed

13:45 sexpbot: <Raynes> amalloy: I think you fixed sed.

13:45 Raynes: No, you broke it. If sexpbot does something weird, it means you've broke it. Always. Period. No questions asked.

13:45 :p

13:45 amalloy: Raynes: no, everything still works, except he can't sed himself

13:46 Raynes: haha i think sexpbot does a lot of weird things on purpose

13:46 kzar: $sed -amalloy s/sed/***

13:46 awh shucks

13:46 amalloy: kzar: too slow :P

13:47 Raynes: I've got to leave for several hours. Have to drive my mother to an optometrist. <3

13:47 amalloy: Raynes: elbow any better?

14:06 fliebel: hrm, do I need to dig into Java for a timestap, or can Clojure give me that?

14:07 LauJensen: fliebel: like (System/nanoTime) ?

14:08 amalloy: &(System/currentTimeMillis)

14:08 sexpbot: ⟹ 1289416240923

14:08 fliebel: LauJensen: Yea, but I saw (now) being used in some libs, so I was wondering if that existed anywhere in Clojure.

14:08 LOPP: guys I have trouble understanding the Ant program by Rich Hickey in clojure

14:09 (defn evaporation [x](when running(send-off *agent* #'evaporation))(evaporate)(. Thread (sleep evap-sleep-ms))nil)

14:09 specifically this part

14:09 kotarak: ,(now)

14:09 clojurebot: java.lang.Exception: Unable to resolve symbol: now in this context

14:09 amalloy: LauJensen: nanoTime isn't necessarily good, depending on what he wants to use the timestamp for; ms might well be better

14:09 kotarak: fliebel: rather from some library

14:10 LauJensen: amalloy: not really

14:10 Chousuke: LOPP: that's an agent action that the agent sends to itself periodically

14:10 LOPP: if you are sendign off an agent in the start of the function, aren't you spamming the thread pool?

14:10 Chousuke: LOPP: no, the agent sends the action to itself

14:10 LOPP: I would understand if the agent send-off was the last call in the function

14:10 Chousuke: LOPP: so it just gets queued

14:10 LOPP: ah

14:10 hiredman: agent sends are held until the action completes

14:11 LOPP: so that thread sleep also delays the next execution

14:12 also why does he use quoting

14:12 #'evaporation

14:12 hiredman: you mean #'

14:12 which is not quoting

14:12 it means var

14:12 LOPP: right...

14:12 why

14:12 hiredman: there are several reasons to use a var instead of the function the var holds

14:12 Chousuke: LOPP: it sends the var to the agent as the action so that it can be redefined on the fly.

14:12 hiredman: right

14:12 that is the most common

14:12 LOPP: ok

14:12 Chousuke: LOPP: if it sent the function value, it couldn't be changed

14:13 LOPP: I've noticed this problem in my programs

14:13 Chousuke: LOPP: a var pointing to a function works just like the function when used as one

14:13 ,(#'+ 1 2) like this

14:13 clojurebot: 3

14:13 LOPP: I have a system of listeners in my program

14:14 and the thing is that if I use function values then listeners can't be changed by simple redef

14:14 if I use vars then I can't submit anonymous fns

14:15 Chousuke: you could use a id -> listener map

14:15 though hm

14:15 LOPP: hm let me take another look

14:16 let me get a paste bin going

14:18 http://pastebin.com/2FYJJ5vn

14:18 look at get-listener-results fn

14:19 hiredman: you can, infact, have anonymous vars

14:19 LOPP: is that var-get needed

14:19 hiredman: but you shouldn't

14:20 LOPP: I'm probably doing loads of stupid shit in that code

14:20 my first clojure program

14:22 (if (symbol? funx)((var-get funx) handler-result)(funx handler-result)))

14:22 is this needed?

14:22 Chousuke: is the fn ever going to be a symbol? :/

14:22 LOPP: well yes

14:22 Chousuke: also doesn't var-get take a var, not a symbol?

14:23 LOPP: maybe...I'm cofused as hell :P

14:23 seems to work well now

14:23 Chousuke: yeah, because that (symbol? ..) thing is never true :)

14:23 LOPP: I can either say (add-listener my-fun)

14:23 or (add-listener 'my-fun) and it works

14:24 second variant allows rebinding to work perfectly

14:24 Chousuke: (add-listener #'my-fun) would work too, even without the special casing

14:24 (doc var-get)

14:24 clojurebot: "([x]); Gets the value in the var object"

14:24 LOPP: yes that was my question

14:25 Chousuke: but #'my-fun is not a symbol

14:25 LOPP: ,(var-get 'first)

14:25 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Var

14:25 LOPP: it's a sybol

14:25 amalloy: &(class #'first)

14:25 sexpbot: ⟹ clojure.lang.Var

14:25 LOPP: I see

14:25 Chousuke: yeah, that's what I'm confused about :/

14:25 why would the var-get in your code ever work?

14:25 amalloy: &(class 'first)

14:25 sexpbot: ⟹ clojure.lang.Symbol

14:25 LOPP: it works if you do 'first instead of #'first

14:26 hiredman: no it doesn't

14:26 Chousuke: yeah, but then the (symbol? ...) is not true :)

14:26 hiredman: it passes 'first to var-get

14:26 Chousuke: and the var-get still doesn't get called.

14:26 LOPP: ah

14:26 well I guess I'm screwing this one up :/

14:26 hiredman: Chousuke: 'first is a symbol

14:26 Chousuke: but THEN it works because you can treat vars holding functions as functions

14:26 hiredman: I know

14:27 hiredman: I was talking about what his code does if he passes #'foo to the function

14:27 hiredman: so why wouldn't the var-get get called if he passed 'first?

14:27 Chousuke: and he said "it works if you pass 'first instead of #'first"

14:27 Chousuke: hm, then I read it the other way around

14:27 LOPP: what about non functions

14:28 Chousuke: LOPP: won't work

14:28 amalloy: LOPP: what about them?

14:28 LOPP: I mean...if I have a global var with some constant

14:28 Chousuke: you'll get an exception

14:28 LOPP: then I have a bunch of function using this global

14:28 how do I make it support rebinding

14:28 Chousuke: ah

14:29 no need

14:29 just redef it

14:29 amalloy: LOPP: you can (def) it again

14:29 LOPP: ordinarily the function defn will capture the then current global var value, right?

14:29 amalloy: no

14:29 Chousuke: that'll be what happens in 1.3 though

14:29 I think

14:29 amalloy: still not quite true, Chousuke

14:29 Chousuke: the problem in this case is what happens when you call (add-listener foo)

14:29 LOPP: because that was exactly what was happening to me here

14:30 amalloy: re-def will still work in 1.3; it's (binding) that will need more magic

14:30 Chousuke: foo is evaluated, and its value, the function, is passed to add-listener

14:30 so add-listener never sees the foo var

14:30 LOPP: right

14:30 Chousuke: but if you use foo in a defn someplace, it won't be replaced like that.

14:30 instead, it'll be a Var.get() call every time

14:30 so rebinding works

14:32 LOPP: hm

14:32 Chousuke: but if you call (add-listener #'foo), you're actually passing the var itself to act as the listener

14:32 so redefs work

14:32 LOPP: ok

14:32 so I need to be careful when passing things as arguments

14:33 but not when coding the fn itself

14:33 Chousuke: only if you need to redefine things dynamically :)

14:33 LOPP: and this only works for functions

14:33 ok

14:33 Chousuke: well, you can always do @somevar

14:33 to get its value

14:33 LOPP: @#'first

14:33 Chousuke: ,@#'first

14:33 clojurebot: #<core$first clojure.core$first@5d1647>

14:33 LOPP: ok

14:33 thanks a lot

14:34 clojure is hard :P

14:34 Chousuke: LOPP: nah. it just takes a while. :)

14:34 It's not the easiest language though.

14:34 LOPP: don't worry I like hard

14:34 I'm bored out of my mind with java

14:35 every code snippet is so trivial yet large programs are often intractable

14:35 I want things the other way around :p

14:35 Chousuke: hehe

14:36 amalloy: LOPP: the clojure code snippets are a lot less complicated than the equivalent java too, usually

14:36 fliebel: wohooo, I wrote my first sexpbot plugin! come check it out in #tempchan

14:36 amalloy: none of this fiddling around with for loop indexes every time you want to do something with a collection

14:36 Chousuke: I like apache refactoring example :P

14:36 where a 10-something line java method becomes a single line of Clojure code.

14:36 LOPP: today I was fixing a JSF page which had 5 different representations of the same document floating around session data at the same time

14:37 intractable

14:58 pppaul: rosetta code now has more clojure rep!

14:59 LLOP: why is clojure hard?

14:59 what examples are you guys talking about?

15:07 amalloy: pppaul: well, an example of clojure's brevity came up yesterday

15:08 someone wanted to write a function f so that (f + [1 2 3 4]) returns [1 3 6 10]

15:08 pppaul: &(second (re-find #" (\d{1,2}:\d{1,2}:\d{1,2}) UTC" (slurp "http://tycho.usno.navy.mil/cgi-bin/timer.pl")))

15:08 sexpbot: java.security.AccessControlException: access denied (java.net.SocketPermission tycho.usno.navy.mil:80 connect,resolve)

15:09 pppaul: sounds like a cool function

15:09 amalloy: try it in java, and then think about the clojure version

15:09 Chousuke: (def reductions)

15:09 amalloy: &(reductions + [1 2 3 4 5 6])

15:09 sexpbot: ⟹ (1 3 6 10 15 21)

15:09 pppaul: i don't touch java :P

15:09 * chouser whispers "reductions"

15:09 pppaul: javascript, maybe

15:09 amalloy: man i know, guys

15:09 Chousuke: ~def reductions

15:09 pppaul: (doc reductions)

15:09 clojurebot: "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

15:10 pppaul: reduction is sexy

15:11 (source reductions)

15:11 &(source reductions)

15:11 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

15:11 amalloy: $source reductions

15:11 sexpbot: reductions is http://is.gd/gUAFl

15:13 amalloy: pppaul: https://gist.github.com/e8c514dd7543d071fbf2

15:13 and it only works for ints :P

15:13 pppaul: &(reductions + (take 50 (repeat 1)))

15:13 sexpbot: ⟹ (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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50)

15:13 amalloy: and +

15:14 pppaul: reductions has so many restrictions?

15:14 amalloy: ?

15:14 no, the java version i slapped together does

15:14 pppaul: oh

15:14 oooooooh

15:15 how are you using array.clone()? i thought it was a protected method

15:15 oh wait

15:15 nm

15:15 amalloy: Object.clone is protected; arrays make it public

15:15 pppaul: but array.clone is a shallow clone, right?

15:15 amalloy: yes...but ints aren't references, so that doesn't matter

15:15 pppaul: or is clone fixed now?

15:16 ok

15:16 ints are pretty sexy

15:16 amalloy: you can't really "fix" clone to always deep-clone. the meaning of clone will vary by class

15:17 pppaul: the code seems pretty simple

15:17 amalloy: the java for intermediateSums, you mean?

15:17 pppaul: yes

15:18 also, the clone for java is broken cus it's protected, not because of wanting to deep-clone or not

15:18 amalloy: sure, it's not hard code. but java makes you deal with all the fiddly bits like array indexing, allcating the return value

15:19 pppaul: if i have a vector<fancy-obj> vec. vec.clone() will call Object.clone() not fancy-obj.clone()

15:19 amalloy: and you have to restrict yourself to a fixed type and a fixed operator

15:19 um, no it won't

15:19 pppaul: but vector is actually for Objects... so the whole collections framework is crap

15:19 amalloy: it won't call any .clone at all

15:19 pppaul: it wont?

15:19 i thought it would

15:20 what will vec.clone() do?

15:20 amalloy: it makes a new vector with new references to the same objects

15:20 pppaul: so only 1 .clone() method is called in total?

15:20 amalloy: indeed

15:20 pppaul: surprise

15:20 amalloy: which is pretty useful behavior, in fact

15:20 pppaul: what?

15:20 clojurebot: what is wrong with you

15:21 pppaul: i can see how it's useful to have that behaviour =

15:21 but, i want other behaviours too

15:21 doing a deep clone of a vector gave me a lot of problems

15:22 amalloy: pppaul: yeah. java's non-deep-cloning behavior means if you want that you have to iterate through the cloned vector's elements and clone each one in turn

15:22 not hard, but more fiddly bits

15:22 pppaul: it's a surprise

15:22 amalloy: meh

15:23 any behavior would be surprising some of the time

15:23 pppaul: just like how CL has shared objects and non-shared objects... sometimes that leads to surprises

15:23 devinus: (doc defmacro)

15:23 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Like defn, but the resulting function name is declared as a macro and will be used as a macro by the compiler when it is called."

15:24 pppaul: anyway, if you search google for people trying to deep-clone in java.... some people are doing crazy stuff, like serializing to clone.

15:26 so some people's surprises are another person's adventure to find out how they are supposed to solve the problem in an elegant way using the provided language features... and that leads to crazy stuff sometimes

15:27 tonyl: &(doc if-let)

15:27 sexpbot: ⟹ "Macro ([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"

15:29 tonyl: where is the test part in if-let

15:30 amalloy: "bindings => binding-form test"

15:30 fogus_: tonyl: in the value part of the binding

15:30 amalloy: &(if-let [a (inc 0)] a)

15:30 sexpbot: ⟹ 1

15:30 amalloy: &(if-let [a nil] a)

15:30 sexpbot: ⟹ nil

15:30 tonyl: ooh ok, all the values must be true then

15:30 amalloy: all of them?

15:31 tonyl: &(if-let [a false b 54] [a b])

15:31 sexpbot: java.lang.IllegalArgumentException: if-let requires exactly 2 forms in binding vector

15:31 tonyl: oh so only one

15:31 fogus_: ,(if-let [this-is-truthy :anything-that-is-truthy] this-is-truthy)

15:31 clojurebot: :anything-that-is-truthy

15:31 amalloy: &(if-let [[a b] [false 54]] [a b])

15:31 sexpbot: ⟹ [false 54]

15:31 amalloy: &(if-let [[a b] nil] [a b])

15:31 sexpbot: ⟹ nil

15:32 fogus_: amalloy: even better

15:33 amalloy: fogus_: not very good in general though. you can't bind b to 54 iff a is not falsey

15:34 fogus_: I'm not sure that I've ever needed to bind more than one thing in if-let

15:34 amalloy: fogus_: i've wanted to, just to shorten my (if foo (let [...])) forms

15:35 fogus_: It becomes too complicated to reason about

15:35 amalloy: but technomancy and i have different expectations for what this "would" do if it worked

15:35 so it's a good thing it doesn't :)

15:42 pppaul: &(#( % %) #(% %))

15:42 sexpbot: java.lang.StackOverflowError

15:42 pppaul: ^_^

15:44 tonyl: $sed -pppaul s/( %/(%/

15:44 sexpbot: tonyl: Format is sed [-<user name>] s/<regexp>/<replacement>/ Try <prefix>help sed

15:44 tonyl: $help sed

15:44 sexpbot: tonyl: Simple find and replace. Usage: sed [-<user name>] s/<regexp>/<replacement>/If the specified user isn't found, it will default to the last thing said in the channel. Example Usage: sed -boredomist s/[aeiou]/#/Shorthand : s/[aeiou]/#/

15:45 amalloy: tonyl: ( is special in regexes

15:45 tonyl: $sed -pppaul s/\( %/(%/

15:45 brain fart

15:45 amalloy: heh

15:46 tonyl: i'm guessing it only works with the last message

15:46 amalloy: tonyl: i'm certain it only works with the last message :)

15:46 since i'm the current maintainer of $sed :P

15:47 pppaul: :P

15:47 amalloy: $sed -pppaul s/P/D!

15:47 sexpbot: <pppaul> :D!

15:48 amalloy: turn that frown upside-down, matey

15:48 pppaul: =[

15:55 tonyl: lol

15:55 amalloy: do you have an open repo of the $sed?

15:55 $sed -pppaul s/\[/~\(/

15:55 sexpbot: <pppaul> =~(

15:56 amalloy: tonyl: yeah, it's in raynes' sexpbot

15:56 http://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/sed.clj

15:57 tonyl: cool, i wanted to check the code

15:59 amalloy: $sed -pppaul s/[[]/~(/

15:59 sexpbot: amalloy: Format is sed [-<user name>] s/<regexp>/<replacement>/ Try <prefix>help sed

15:59 amalloy: hm, that should parse

15:59 tonyl: brackets are special chars

15:59 amalloy: tonyl: i know, which is why i mangled it

15:59 [[] is the character class matching [

16:00 pppaul: &(#( % ) #(% ))

16:00 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: sandbox4153$eval6042$fn

16:00 amalloy: i was hoping to demonstrate that \[ wasn't the only way

16:00 tonyl: yeah that is weird

16:00 pppaul: &(#( % %) #(% ))

16:00 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: sandbox4153$eval6055$fn

16:00 pppaul: &(#( % %) #(% %))

16:00 sexpbot: java.lang.StackOverflowError

16:00 tonyl: weird

16:01 pppaul: has anyone programmed in chef?

16:02 ohpauleez: pppaul: As in the Ruby deployment tool?

16:03 pppaul: Chef is an esoteric programming language designed by David Morgan-Mar

16:04 tonyl: amalloy: that regex gives me an error here http://www.regexplanet.com/simple/index.html

16:04 amalloy: yeah, i must be wrong about [[]

16:05 tonyl: i thought only ^ was a special char inside the brackets

16:05 amalloy: ]^-\ are special

16:06 tonyl: so it is an implementation error, maybe

16:07 amalloy: tonyl: maybe. that's a conclusion that's more often jumped to than demonstrated

16:08 tonyl: yeah

16:08 amalloy: otoh it works in perl

16:08 $ perl -p -e 's/[[]/!/g;'

16:08 11[][[]]

16:08 11!]!!]]

16:09 &#"[[]"

16:09 sexpbot: java.util.regex.PatternSyntaxException: Unclosed character class near index 2[[] ^

16:09 amalloy: tonyl: okay, you win. java's regex compiler doesn't handle this right

16:10 pppaul: for [[]?

16:10 amalloy: yeah

16:10 pppaul: [\[]

16:10 tonyl: so in java you can have character classes inside char classes?

16:10 amalloy: i dunno

16:10 tonyl: ha interesting

16:10 testing time

16:10 amalloy: obviously you can get around it with \[, but that's not supposed to be required

16:11 pppaul: bug

16:11 amalloy: tonyl: php does, though, btw. the amusing character class [][] matches open or close brackets

16:11 chouser: ,(re-find #"[[]]]" "]")

16:11 clojurebot: "]"

16:11 chouser: weird

16:11 * tonyl mind blown at inconsistencies/weirdness

16:11 amalloy: way weird

16:12 chouser: that doesn't work in perl (and it shouldn't)

16:12 chouser: right

16:12 "work" in this case is a subset of "fails to work"

16:16 LOPP: you can get around special characters in groups if you put them into spots where they can't be

16:16 amalloy: LOPP: we're well aware. see my note about [][]. but java doesn't do it properly

16:20 pppaul: [.][.]

16:21 lancepantz: vector boobs.

16:24 pppaul: put a closure on it

16:36 anonymouse89: how do I eval a string? Something like (eval "[1 2 3]") -> [1 2 3]

16:36 chouser: anonymouse89: start with read-string

16:38 anonymouse89: chouser: ah, that's it. My only problem now is that I wrote maps to file and some of the values are strings. But they weren't written to file with quotes around them so {:name "bob"} becames "{:name bob}" when I read it back in.

16:40 chouser: anonymouse89: yeah, that's a problem. if you want to be able to "read" them later, you should use prn instead of println when printing

16:41 pppaul: (eval (read-string string))

16:42 anonymouse89: chouser: this is good. but it still fails for sequences of numbers

16:42 ,(prn {:a '(1 2 3)})

16:42 clojurebot: {:a (1 2 3)}

16:42 pppaul: look at my example on rosettacode for the A B problem

16:42 tonyl: anonymouse89: maybe (map) the map entries and replace format them accordingly

16:43 pppaul: (eval (read-string (str "(+ " (read-line) " )") ))

16:43 3 3

16:43 6

16:44 anonymouse89: tonyl: i don't quite understand what you mean

16:45 pppaul: look at rossetacode :24-game :A+B. clojuredocs is good too

16:46 chouser: ,(read-string (pr-str {:a '(1 2 3)}))

16:46 clojurebot: {:a (1 2 3)}

16:46 chouser: anonymouse89: what's the problem there?

16:48 tonyl: (map (fn [[k v]] [k (prn-str v)]) {:a foo :b bar})

16:48 &(map (fn [[k v]] [k (prn-str v)]) {:a foo :b bar})

16:48 sexpbot: java.lang.Exception: Unable to resolve symbol: foo in this context

16:49 anonymouse89: chouser: I guess nothing. I just thought I remembered doing something awhile ago where if "{:a (1 2 3)}" is written to a file and then read back in it says Integer not IFn

16:49 tonyl: &(map (fn [[k v]] [k (prn-str v)]) (read-string "{:a foo :b bar}"))

16:49 sexpbot: ⟹ ([:a "foo\n"] [:b "bar\n"])

16:49 hiredman: anonymouse89: evaling and reading are not the same thing

16:50 tonyl: &(into {} (map (fn [[k v]] [k (prn-str v)]) (read-string "{:a foo :b bar}")))

16:50 sexpbot: ⟹ {:a "foo\n", :b "bar\n"}

16:51 tonyl: &(into {} (map (fn [[k v]] [k (.replace (prn-str v) "\n" "")]) (read-string "{:a foo :b bar}")))

16:51 sexpbot: ⟹ {:a "foo", :b "bar"}

16:51 tonyl: there we go

16:51 somewhat wordy though

16:51 chouser: pr-str instead of prn-str

16:52 * tonyl facepalm

16:52 tonyl: &(into {} (map (fn [[k v]] [k (pr-str v)]) (read-string "{:a foo :b bar}")))

16:52 sexpbot: ⟹ {:a "foo", :b "bar"}

16:53 anonymouse89: tonyl: nice

16:53 tonyl: if it is a big map though, you might want to improve it

16:53 for performance because into and map makes it go double through the map

16:54 anonymouse89: it's not a big map

16:54 tonyl: alright

16:56 Chousuke: it doesn't go through the map twice.

16:56 map is lazy

16:56 amalloy: pppaul: http://rosettacode.org/wiki/24_game#Clojure is yours?

16:57 nm, i can see that it is :P

16:57 tonyl: oh so just once with into then

16:57 pppaul: hshshs

16:57 amalloy: why does (gen-new-game-nums) use 0-10 instead of 1-9?

16:57 pppaul: :D

16:58 um

16:58 isn't that part of the ruls? 0-9

16:58 amalloy: "four digits, each from one to nine, with repetitions allowed"

16:58 pppaul: oops

16:58 amalloy: even if 0-9 were right, you're giving 0-10 with your rand-int 11, no?

16:58 pppaul: time to fix that (0s made it hard to play anyway)

16:59 i never saw a 10 while testing

16:59 amalloy: &(take 100 (repeatedly #(rand-int 11)))

16:59 sexpbot: ⟹ (0 5 2 8 10 4 10 6 3 2 1 2 7 6 0 6 10 9 3 4 9 9 5 8 10 10 4 6 5 10 2 9 0 0 9 7 4 9 6 4 9 3 2 4 9 0 2 5 5 0 7 6 2 0 7 6 6 10 8 6 0 0 8 8 7 10 6 4 5 1 7 10 2 7 7 8 1 6 10 5 10 0 1 1 9 4 2 2 6 2 10 7 0 9 1 9 8 2 0 8)

17:01 amalloy: pppaul: and this will blow the stack if the user takes a few thousand tries to get the answer *chuckle*

17:02 pppaul: it'll blow the stack at like 30k tries

17:03 it may be possible to do that by giving it lots of newlines as input

17:03 amalloy: pppaul: rather than assume the stack is big enough, why not just use (recur)? you're in the tail position already

17:07 pppaul: cus i'm a believer that the JVM will have tail-call recursion sometime soon

17:07 lol

17:08 LOPP: that's optimistic

17:08 pppaul: also, i'm a newb and don't always know when i can use recur

17:10 so, i made the 2 bug fixes on rosetta code. thanks

17:13 are complex numbers in clojure?

17:13 &(1+2i)

17:13 sexpbot: java.lang.NumberFormatException: Invalid number: 1+2i

17:14 pppaul: guess not

17:17 amalloy: &(doc complex)

17:17 sexpbot: java.lang.Exception: Unable to resolve var: complex in this context

17:17 amalloy: clojure.contrib.complex-numbers

17:18 pppaul:

17:19 pppaul: thanks

17:20 http://richhickey.github.com/clojure-contrib/complex-numbers-api.html (there is no documentation yet)

17:37 LOPP: is there any special requirement for namespaces to be all in one file

17:37 can I make namespace2.clj which has (ns namespace1)

17:38 amalloy: LOPP: hm. well, don't take this as gospel truth, but

17:38 i believe you can do that, except that when someone (require)s your ns1, the runtime will look for it in ns1.clj

17:38 so in practice it's not useful

17:39 LOPP: ok

18:00 maacl: What would be an ideomatic way of writing a test of a database insert using lazytest? using do-it? does this work with contexts?

18:35 bhenry: i'm looking for something similar to map, but instead of mapping one function over a collection of things, i want to take a hash-map and a collection of functions. then i want back a collection of each function applied to the one hash-map

18:36 shouldn't be hard to write, but wanted to know if it existed.

18:36 amalloy: bhenry: juxt?

18:36 bhenry: ,(doc juxt)

18:36 clojurebot: "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, a...

18:36 amalloy: &((juxt quot rem) 20 6)

18:36 sexpbot: ⟹ [3 2]

18:37 amalloy: &(doc juxt)

18:37 sexpbot: ⟹ "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b... http://gist.github.com/671727

18:37 bhenry: &((juxt :a :b :c) {:a 1 :b 2 :c 3})

18:37 sexpbot: ⟹ [1 2 3]

18:38 bhenry: amalloy that's it thanks!

18:38 replaca: pppaul: the doc at richhickey.github.com is obsolete, pelase use clojure.github.com (though I think in that particular case the changes are only cosmetic)

18:38 amalloy: bhenry: welcome to the world of juxt

18:38 KirinDave: Is there an inverse to juxt?

18:38 dejuxt?

18:38 amalloy: KirinDave: ...what would it do?

18:38 replaca: KirinDave: what would that be?

18:38 KirinDave: Such that ((dejuxt :a :b c) [1 2 3]) ; => {:a 1 :b 2 :c 3}

18:39 replaca: KirinDave: juxt isn't a map function

18:39 amalloy: KirinDave: juxt is more general than that, but haven't you just reinvented zipmap?

18:39 replaca: it's a function combiner

18:39 KirinDave: amalloy: I'm asking if something exists.

18:39 replaca: No, I get that.

18:40 technomancy: combinernator

18:40 KirinDave: replaca: Sorry, I didn't mean literal hash

18:40 replaca: technomancy: I was exlicitly avoiding combinator :)

18:40 KirinDave: I meant something such that (retval :a) => 1

18:40 replaca: *explicitly

18:40 amalloy: technomancy: hey, look who's here. you have your client set up to highlight you when someone mentions juxt? :)

18:41 technomancy: amalloy: not yet, but that will soon change

18:41 KirinDave: Is this crazy?

18:41 amalloy: KirinDave: it sounds crazy to me, but i guess if you defined it more clearly it might turn out to be useful?

18:41 replaca: KirinDave: you mean a primitive function definition?

18:41 f(:a) => 1, etc.

18:41 KirinDave: Yeah

18:42 It'd be like constantly on steroids.

18:42 replaca: a literal hash map

18:42 KirinDave: Yeah, that'd do it.

18:42 replaca: does exactly that

18:42 KirinDave: yes

18:42 amalloy: KirinDave: right. zipmap

18:42 replaca: and Rich has taken pains that it fill that role

18:42 ,({:a 1, :b 2} :a)

18:42 amalloy: &((juxt :a :b) (zipmap [:a :b] [1 2]))

18:42 sexpbot: ⟹ [1 2]

18:42 clojurebot: 1

18:42 Cool story bro.

18:43 amalloy: tada!

18:43 pppaul: clojure.github.com bad url name :replaca

18:43 KirinDave: yeah.

18:43 amalloy: pppaul: www.github.com/clojure/clojure

18:44 replaca: pppaul: no, I meant this: http://clojure.github.com/clojure-contrib/complex-numbers-api.html

18:44 pppaul: where is the documentation ?

18:44 replaca: instead of the same with richhickey

18:44 KirinDave: I guess I just strongly associate juxt with the :key usage.

18:45 pppaul: replaca there isn't much a diff in those pages

18:45 amalloy: KirinDave: using juxt as sorta a multi-get?

18:45 replaca: KirinDave: yeah, that's an awesome use case, but it's also a great example of how keywords as functions gives you stuff for free

18:45 pppaul: why have 2 sets? are there plans to take down the older doc websites?

18:45 replaca: pppaul: nope, as I said in that case

18:45 KirinDave: amalloy: Yes. Which can be really nice in some cases.

18:46 I should use it more

18:46 So I've got several github messages

18:46 replaca: pppaul: but in general, I stopped updating richhickey... back in the summer and it will fall further behind over time

18:46 amalloy: KirinDave: hm

18:46 KirinDave: of people asking me, "Why should use use clothesline when I could just use ring."

18:46 I dunno if I should like super-extra-bold the readme

18:46 "Clothesline uses Ring" in like 90pt font

18:47 technomancy: ugh; people message you over that?

18:47 replaca: but (as yesterday) what people want to know, is why should I use clothesline + ring instead of ring by itself

18:47 KirinDave: technomancy: Yes.

18:48 technomancy: I had to add "personal email is not an appropriate avenue for bug reports" to the lein readme, so I guess I shouldn't act surprised.

18:48 KirinDave: replaca: That's sort of like asking why people use api frameworks over rack in the ruby world

18:48 danlarkin: technomancy: heresy!

18:48 KirinDave: replaca: Ring is just adapterware.

18:48 Don't get me wrong, it's hella useful if you have trivial stuff to bang out.

18:49 but then someone sends your service an OPTIONS request and you really should respond to that and you go augh.

18:49 replaca: yeah, I get that. But the response "Clothesline uses ring" doesn't address that

18:49 KirinDave: Also I guess the http 1.1 graph for webmachine terrifies people. :)

18:50 I wsa talking with some of the basho dudes about this. Considering adding fluffy bunnies as node bodies so that people will feel more at ease. ;)

18:52 replaca: KirinDave: I think it's just opaque to people have haven't yet suffered from the problem

18:52 KirinDave: It is definitely opaque.

18:52 That's the major issue to address with it going forward.

18:58 It's the same problem I had with Katamari tho.

18:58 It's quite useful when you need it, but very few people actually need it.

18:58 I should just make an open source distributed key-value store. I hear that sells well.

19:01 amalloy: KirinDave: no, sell a toolkit for developing such things. the people who actually made money during the gold rush were the equipment salesman

19:02 KirinDave: amalloy: I guess so.

19:02 I actually wonder if anyone in the world besides Powerset actually needed Katamari.

19:03 When your pitch starts off with, "Do YOU have 20 year old code that does something cool but can't tell stdio from stderr? Do YOU need to run thousands of instances of this while they crash and burn randomly and pretend you can meet an SLA? Well I have the project for you!"

19:04 amalloy: haha what is katamari? i must have missed out, aside from the video game

19:05 cemerick: KirinDave: LOL @ "…just use ring"

19:05 * cemerick facepalms

19:06 cemerick: KirinDave: This is what's called a "teaching moment" ;-)

19:06 KirinDave: amalloy: it was my erlang system that was the infrastructure that powerset.com's realtime query analysis/reformulation stuff

19:06 Every hit to powerset.com hit this stack a few times

19:06 It basically was some stuff to created a distributed cloud of heterogenous resources with a uniform calling convention using json-rpc

19:07 Most of the things it talked to had no multithreading, so they were put in read-respond mode on io lines. Lots of them run as separate processes on farm machines

19:08 Katamari would kill/restart these as necessary to keep the spice flowing, where the spice in this case was natural language analysis

19:08 amalloy: sounds like a blast

19:09 KirinDave: Ha

19:51 jartur: Can I somehow get a list of all of object's methods?

19:54 technomancy: jartur: C-c S-i in slime, clojure.contrib.repl-utils/show otherwise

20:05 amaevis: Is anyone here familiar with the Compiler.java implementation?

20:07 ping?

20:07 clojurebot: PONG!

20:07 amaevis: pong?

20:07 clojurebot: PONG YANG!

20:07 amalloy: fascinating

20:08 clojurebot: pong is <reply>ping?

20:08 clojurebot: Qinfengxiang!

20:08 amalloy: pong?

20:08 clojurebot: PONG YANG!

20:08 amalloy: jerk

20:08 (dec clojurebot)

20:08 sexpbot: ⟹ -2

20:08 amaevis: lol

20:08 amalloy: clojurebot: pong?

20:08 clojurebot: Qinfengxiang!

20:08 amalloy: wtf

20:09 amaevis: clojurebot: ping?

20:09 clojurebot: PONG!

20:09 amaevis: clojurebot: ping pong?

20:09 clojurebot: PONG!

20:10 amaevis: Sigh. I wish there were documentation on the Clojure compiler.

20:10 amalloy: amaevis: maybe the folks over at clojureclr have some

20:11 amaevis: I need the Java internals.

20:11 I'm trying to persist closures.

20:11 And the JVM offers no way to get the bytecode of a class after it's been defined.

20:12 amalloy: amaevis: i don't think that's true

20:12 amaevis: amalloy: Great! Do you know how?

20:13 amalloy: I've been looking everywhere, including on the Oracle forums.

20:13 amalloy: well, i could be wrong

20:13 amaevis: amalloy: Oh. :(.

20:13 amalloy: are you looking to get bytecode out of .class files?

20:14 or out of a running clojure program with no aot?

20:14 amaevis: No AOT.

20:15 I've built a durable ref - (dref <value> <name> <store>)

20:15 I want to make (fn)s durable.

20:17 technomancy: some functions are inherently unserializable

20:18 those that close over reference types or streams

20:18 amaevis: I was counting on using ASM magic for that.

20:19 Stateful functions wouldn't be allowed.

20:19 amalloy: amaevis: you could install a classloader that just logs all loaded classes and then delegates to a real loader?

20:19 amaevis: amalloy: I've tried that route, the issue is with ObjExpr - I can't figure out exactly where newInstance() is called.

20:20 technomancy: Stateful functions excepting those using durable identities, that is.

20:21 technomancy:

20:21 Otherwise it cuts out 75% of the utility

20:21 brb

20:43 jartur`: Dammit, clojure.contrib.sql sucks unfortunately.

20:44 amalloy: fightin' words, jartur`...i bet the person who wrote it is in here

20:44 coldhead: :(

20:44 jartur: I don't mean it personnaly

20:44 amalloy: anyway i haven't tried either, but you might give clojureql a try?

20:44 coldhead: are you sure your beef isn't with SQL per se?

20:44 i know mine is!

20:45 jartur: I need several persistent connection to different dbs

20:45 amalloy: laujensen has been boasting about it recently

20:45 coldhead: SELECT beef FROM sql;

20:46 jartur: It's not the question of SQL or DB philosophy

20:46 Simply a question of technical possibilities for nonstandard applications

20:47 Now I will have to use pure JDBC probably. Or just make a fork of contrib.sql which doesn't use bindings

20:48 I hate bindings, btw =)

20:49 Though i generally suck, so it doesn't matter much what i hate or like.

21:18 ClojureQL doesn't seem to be good at keeping persistent connections. Request takes much more time than the interval I need (> 1 sec)

21:18 (time @(-> players (cql/select (cql.p/< {:us_person_id 6}))))

21:18 "Elapsed time: 5037.438388 msecs"

21:24 Noting that sql query takes about 4 to 10 msecs while connection takes 5000 msces.

21:43 Derander: that is ridiculously long

21:51 jartur: Yes it is. Though establishing MySQL connections is a costly operation

21:52 Much more expensive than most simple queries in terms of latency.

21:56 dnolen: jartur: have you looked at https://github.com/brentonashworth/carte ?

21:57 jartur: dnolen: I will, thank you.

21:59 i wonder when github will add support for code browsing =)

21:59 Would be so nice

22:01 dnolen: Unfortunately it uses contrib.sql and (with-connection ...) Which means that connection is closed after each operation.

22:01 Looks like nobody needs several persistent connections to SQL databases =)

22:02 dnolen: jartur: with-connection does not close the connection

22:02 when you create the connection if you do w/ pooled connection you're fine

22:03 jartur: (defn with-connection*

22:03 "Evaluates func in the context of a new connection to a database then

22:03 closes the connection."

22:03 (with-open [con (get-connection db-spec)]

22:03 dnolen: http://dosync.posterous.com/22516635

22:03 I've done many tests

22:03 the connections do not get closed if you create the datasource properly

22:05 jartur: dnolen: Do you mean that calling .close() on a specifically configured connections do not actually close them?

22:05 dnolen: 10,000 writes a second for mysql, more than that for postgresql

22:06 on Amazon Compute Cluster

22:06 with little in the way of optimizing either dbs

22:07 jartur: dnolen: How did you achieve connection pooling with standard contrib.sql?

22:08 dnolen: jartur: mysql, https://github.com/swannodette/second-post/blob/master/src/second_post/mysql.clj

22:08 postgresql, https://github.com/swannodette/second-post/blob/master/src/second_post/postgres_pool.clj

22:09 jartur: Will it work with several different connections at the same time?

22:10 I mean to several different databases

22:14 lancepantz: jartur: yes, use c3p0, you can define as many connection pools as you'd like

22:15 jartur: lancepantz, dnolen, thank you. This is actually a solution I didn't even had an idea existed.

22:15 dnolen: jartur: np

22:16 lancepantz: jartur: if you're working with a webapp, you can actually define your connection pools as JNDI resources

22:16 http://docs.codehaus.org/display/JETTY/JNDI

22:36 amaevis: ping?

22:36 clojurebot: PONG!

22:36 amaevis: pong?

22:36 clojurebot: PONG YANG!

22:37 amaevis: (describe ns)

22:37 ,(describe ns)

22:37 clojurebot: java.lang.Exception: Unable to resolve symbol: describe in this context

22:38 amaevis: ,(doc ns)

22:38 clojurebot: "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use...

22:45 amaevis: Does anyone know if loaded classes ever get released by the JVM?

22:48 puredanger: amaevis: yes, but there are lots of caveats

22:50 amaevis: puredanger: Is there a GC-type thread for it?

22:51 puredanger: amaevis: classes are stored in permgen. how they're collected depends on the jvm and your gc settings

22:51 amaevis: there are some well-known problems with gc of classloaders and classes (many of which are being addressed in jdk 7)

22:52 on a quick google, here's a decent blog: http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java

22:53 amaevis: puredanger: I wonder what kind of implications this has for long-running Clojure instances.

22:53 puredanger: amaevis: the same as for any long-running JVM-based program pretty much

22:54 amaevis: puredanger: I'm building a Class cache using the Google Guava MapMaker with WeakReference keys.

22:54 puredanger: amaevis: ah, well that's delicate work but those are excellent tools to start with

22:54 amaevis: puredanger: Do the strong/weak reference rules apply for Class objects?

22:55 puredanger: amaevis: sure, although you are affected by strong references from Classloaders to the Class loaded by them

22:55 amaevis: puredanger: Non-dynamic class JVM programs won't get OOM errors on permgen, so that's a consideration for closure-heavy apps.

22:56 puredanger: amaevis: well that's not true. I've gotten plenty of oom on permgen and I know it's a common issue on JRuby too

22:56 amaevis: puredanger: That's fine; I just wanted to know if I should even bother with the WeakReferences. If they never get collected, there would be no point.

22:57 puredanger: Ah, I've never run into it. Is it more of a class size thing or a class count thing?

22:57 puredanger: amaevis: you should bother. we had something like this in Terracotta if you wanted to look at another (far more complicated) impl

22:58 amaevis: comes up if you do a lot of dynamic class work

22:59 amaevis: puredanger: Hmm, I would love to get your thoughts on what I'm working on.

22:59 puredanger: I'm trying to persist closures.

23:00 puredanger: amaevis: free to ping me at alexdmiler at yahoo if you want to move it out of here, happy to comment if I have a clue

23:00 amaevis: sorry alexdmiller !

23:01 amaevis: puredanger: Thanks! It's not proprietary or anything, though. It's an extension to Clojure core.

23:01 puredanger: ok

23:02 amaevis: I've been working on adding durability to Clojure identities.

23:02 I have versions of ref, atom, and agent that are durable and observe the other guarantees.

23:03 Durable refs are ACID, etc.

23:03 I've got the Clojure primitives and the persistent data structures all set.

23:03 The only thing left are functions, especially closures.

23:04 arohner: technomancy: what function does C-c S-i map to for you? mine is unbound

23:04 coldhead: you share your name with a wonderful logician and philosopher, alex miller

23:06 amaevis: I'm trying to capture the bytecode and serialize it. On deserialization, I need to transform the class to modify the name to ensure that there's no collision in canonical names.

23:06 And make sure that references to other classes hold.

23:07 How does Terracotta handle that?

23:33 jk_: does anyone think that Oracle is going to cause trouble for Clojure or any of the other open source JVM based languages?

23:34 dnolen: jk_: i don't see how.

23:35 jk_: well... the only way I thought of it by going forward with future enhancements only on their pay-to-play JVM and trying to isolate and deprecate OpenJDK

23:36 seancorfield: if an open source JVM becomes the norm, how can they control it?

23:37 dnolen: jk_: rhickey has said he's happy if the JVM changes slow down - that directly affects the surface that Clojure has to support for Java interop. Oracle doesn't seem that interested in the more interesting extensions anyway, tail call optimization and continuations

23:37 jk_: well they don't have to make the standardization tests available, like they did with Harmony. that would force them to diverge

23:39 hiredman: I am sick of hearing about it

23:39 jk_: has anyone every talked about porting clojure to parrot?

23:39 dnolen: jk_: the JVM ecosystem has a long life ahead of it, Oracle or no. Plenty of time to get Clojure-in-Clojure well underway for people have irrational issues with the JVM.

23:40 jk_: does parrot have anything remotely close the perf guarantees of the JVM?

23:40 s/close/close to

23:40 sexpbot: <dnolen> jk_: does parrot have anything remotely close to the perf guarantees of the JVM?

23:40 jk_: dnolen: i kind of agree... however i would be willing to bet that most clojure code today calls a lot of java

23:40 hiredman: at no point has oracle said anything accept a. openjdk/hotspot and jrockit will be merged b. the resulting jdk plus oracle bells and whistles which no one accept people who are already paying oracle for them use will cost money

23:41 jk_: dnolen: i doubt it. i was just wondering if it was batted around at all, just to try

23:41 hiredman: parrot is junk

23:41 jk_: hiredman: that's true about oracle but they made short work of opensolaris, for example

23:41 hiredman: right

23:41 they just came out and did it

23:42 which they haven't down with the jdk

23:42 done

23:42 in both cases they were very quick to let everyone know their plans

23:42 danlarkin: parrot really is junk (imnsho)

23:42 hiredman: and the plans are different

23:42 dnolen: jk_: I haven't heard much interest in that. LLVM seems more interesting, if it's starting to work for Haskell I don't see why it can't work for Clojure eventually.

23:43 jk_: i don't know much at all about parrot except reading the web site. llvm, parrot, just some free vm

23:43 free meaning not owned by a large company that can mess with it

23:43 hiredman: clojure's runtime is very thin and there is a big gap between where it stops and what the llvm provides

23:44 no

23:44 you want a vm that is backed by a large company

23:44 to get any kind of decent performance

23:44 dnolen: hiredman: big emphasis on "eventually"

23:45 jk_: hiredman: yes, i understand the point. you just take the risk that they will do something stupid with the platform if you end up competing with that company's own offerings

23:46 hiredman: sun and oracle have invested a lot in hotspot and jrockit

23:47 jk_: Oracle might not really give a crap about anyone but the Fortune 500's buying their server side jvm though

23:48 the sun luminaries are abandoning oracle

23:48 because oracle doesn't listen to them

23:49 danlarkin: jk_: you've spoken to them, have you?

23:49 hiredman: and nukes could fall on washington tomorrow

23:49 jk_: no i read their own words from interview

23:49 you can do the same

23:49 just google and read

23:49 danlarkin: I was trying on my curmudgeon hat

23:49 hiredman: http://blogs.oracle.com/henrik/2010/11/oracles_jvm_strategy.html

23:49 jk_: it's a little lopsided :)

23:51 dnolen: jk_: in anycase, I don't think Clojurians care that much. The JVM is solid tech and it ain't going anywhere anytime soon. I mean many Java apps are stuck to JDK 1.5 (2004)! including Clojure.

23:51 jk_: hiredman: apache harmony was to the the open, *unencumbered* implementation with nothing proprietary in it.

23:51 oracle effectively ended that by pulling ibm along with them

23:52 hiredman: jk_: *shrug* sun was ignoring harmony for many years before oracle came along

23:52 technomancy: clojurebot: oracle?

23:52 clojurebot: The sky is falling!

23:52 technomancy: ~botsnack

23:52 clojurebot: thanks; that was delicious. (nom nom nom)

23:52 jk_: lol

23:52 hiredman: suddenly oracle buys sun, then sun did no wrong, poor sun that had the misfortune of not making enough money and having to be sold

23:53 danlarkin: absolute worst case scenario is oracle discontinues all jvm development. So we're stuck with OpenJDK on java 6. When you think about it, that isn't actually all that bad

23:53 jk_: nobody believes sun did no wrong. sun was the one who was denying certification to apache

23:53 hiredman: right

23:53 jk_: but ibm agreed to leave it because they will get more power in the jcp, supposedly

23:53 hiredman: so really the situation has not changed on that front one bit

23:53 jk_: from what i read anyway

23:54 hiredman: you've asked ibm?

23:54 technomancy: what's changed is patent aggression

23:54 danlarkin: I'm with hiredman, it's just a bunch of talking heads trying to earn their keep selling pageviews

23:54 jk_: i just see that as an isolation strategy by oracle. no, there were a lot of articles about just that

23:54 technomancy: with Sun in charge you could have forked openJDK without having to flee the US

23:54 jk_: danlarkin: that might be true, and i certainly hope it is

23:55 hiredman: danlarkin: and spaming anything remotely interesting off of progreddit

23:55 technomancy: but forking openjdk was never really very appealing unless you were google anyway

23:55 jk_: i sure don't want anything to happen to diminish clojure, scala or any other such developments

23:55 hiredman: technomancy: well, apparently it didn't appeal to google either

23:56 since they didn't

23:56 technomancy: hiredman: exactly

23:56 but they were the only ones who could have

23:56 jk_: google was playing a different game though. they didn't want to dump an entire jvm into a phone

23:56 hiredman: I wish they had, then maybe you could get a phone with a real jvm on it

23:57 seancorfield: i'm amazed at how much airplay this whole oracle/jvm thing gets... :(

23:57 danlarkin: 640K of dalvik is enough for anyone

23:57 jk_: seancorfield: it's just that people are nervous about it

23:57 seancorfield: *some* people are nervous about it :)

23:57 dnolen: jk_: what people are nervous? Certainly not the millions of Java programmers.

23:57 jk_: seancorfield: right :)

23:57 * seancorfield is not nervous about it - and is tired of the noise about it

23:58 seancorfield: exactly dnolen

23:58 jk_: dnolen: java programmers by and large are just worried about not getting laid off :)

23:58 dnolen: jk_: point is who is nervous? Richard Stallman?

23:59 jk_: dnolen: google is your friend. i'm too lazy to do it for you right now. it's nothing new. it's talked about in the various java blogs and stack overflow, on the scala forums

23:59 etc

23:59 dnolen: people who iPhones and Androids should be nervous.

23:59 * dnolen includes himself in that list

Logging service provided by n01se.net