#clojure log - Feb 12 2010

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

0:16 Jomyoot: is there a clojure SQL library that supports handling 2 DB connections simultaneously?

0:19 drewr: clojureql can do it

0:19 c.c.sql can do it if you're willing to dig into sql/internal.clj

0:25 Jomyoot: beter than contrib?

0:28 drewr: what is your recommendation on SQL for Clojure?

0:28 contrib does not handle 2 DB connections simultaneously

0:36 drewr: are you tehre?

0:36 drewr: is there references on how to do so with c.c.sql?

0:51 drewr: u gone?

1:00 scgilardi: Jomyoot: I think c.c.sql's with-connection can do it. You would have one call nested within another. Something like: (with-connection db1 ...(let [i read...] (with-connection db2 (write i)...)))

1:01 Jomyoot: scgilardi: c.c.sql does not allow specifying connection as function parameter

1:01 even if nested, it will probably use the inner one

1:02 please note that i want to keep both connections open.

1:03 scgilardi: if it's required to keep both open, you're right with-connection is not sufficient.

1:03 unfortunately I need to go now. good luck finding a solution that works for you.

2:43 qed: Is there an easy way to do basic auth with clojure?

2:53 piccolino: I made an hbase binding at http://github.com/davidsantiago/clojure-hbase. Would appreciate any feedback.

2:55 Whoops, screwed that link up. No period.

2:57 qed: where did clojure.http go?

2:58 nvm,

3:00 avarus: morning *yawn

3:00 qed: morning avarus

3:04 avarus: hey qed

3:04 qed: avarus: any experience with using basic authentication?

3:04 im trying to get enlive some https://* data to chew on

3:05 http://github.com/technomancy/clojure-http-client/tree/1338ca03f11a9927aa96231ab07e6d344eed92f1

3:05 avarus: no, sorry, I'm not there yet :)

3:05 qed: ah, bummer

5:15 rrc7cz: is there any fn for converting a LazySeq to an InputStream?

5:23 qed: How can I select something like <a name="random text"></a> using enlive?

5:38 rrc7cz: qed: [:a (attr= :name "random text")]

6:08 cgrand: qed, rrc7cz: [[:a (attr= :name "random text")]] ; [:a (attr= :name "random text")] is a *[name="random text"] not a[name="random text"]

6:10 qed: cgrand: thanks much

6:10 cgrand: could i get your advice briefly on scraping a site?

6:10 http://clojure-log.n01se.net/date/2008-02-01.html

6:10 opqdonut: is (binding [*ns* 'foo] expr) ok?

6:10 using in-ns is kinda ugly

6:11 ah, i can use intern

6:11 qed: cgrand: see above link: I'm trying to capture who said the text, and then the text, without the timestamp -- so ideally I'd like every line i take to have two elements: the name of the person speaking, and the text they spoke -- when someone says something twice in a row id like to know that the text belongs to user X

6:12 like [["chouser" "hello world"] ["rhickey" "yes hello hello" "testing 1 2 3"]]

6:14 also cgrand -- perhaps im missing something obvious here -- but if i would like the text found directly within the :p tag and no deeper -- i would use text-node yes?

6:15 cgrand: qed: text-node but with :> in front of it (you want the text node right under not all text nodes which happen to descend of the current node

6:16 qed: ah-ha!

6:18 cgrand: :> solved almost all my issues -- thanks for the great library

6:19 cgrand: you're welcome

6:24 qed: I would try (-> "http://clojure-log.n01se.net/date/2008-02-01.html" java.net.URI. html-resource (select [:p :> [any-node (but-node [:a first-child])]])) + filter + partition-by

7:35 rhickey: does clojars offer a web listing of available archives? I only see search

7:36 Jomyoot: hi

7:36 rhickey: is it possible to have 2 open db connection in contrib.sql?

7:38 darn no one here

7:51 avarus: I am here :)

7:51 should work

7:52 just give it a different name and when you do sql/with-connection db, take the different name

7:52 rhickey: apparently there is no "view all" :>

7:52 Jomyoot: avarus: can you elaborate?

7:53 avarus: sure...

7:53 a sec

7:53 Jomyoot: (with-connection db

7:53 (with-query-results rs) does not allow specifying connection

7:54 I need to keep db1 and db2 open rather than closing/opening for each statement

7:54 i was hoping for (with-connection [db1 .. db2 ..]

7:54 then (with-query-results rs db1 ...

7:55 but with-query-results does not allow specifying connection

7:55 avarus: Jomyoot: http://pastie.org/821665

7:55 ah, a persistent connection you need

7:56 Jomyoot: right persistent

7:56 if i am gonna be making 2,000 connections.

7:56 is closing/opening all the time gonna hurt?

7:57 avarus: can't say :). I believe it could be a bit slower compared to keeping the connection up but I also believe it's only a small overhead

7:58 Jomyoot: there is no way out :(

7:59 avarus: I'd do a quick benchmark

7:59 or test in this case :)

8:00 spariev: Jomyoot: try connection pool, it might help

8:00 Jomyoot: how?

8:00 clojurebot: with style and grace

8:01 avarus: http://www.mail-archive.com/clojure@googlegroups.com/msg17782.html <-- looks interesting, Jomyoot

8:01 makes much sense to me..."clojure.contrib.sql can also use a datasource or jndi..."

8:02 voila!

8:03 qed: where is partition-by at?

8:03 is it in contrib?

8:03 AWizzArd: seq-utils

8:04 qed: ty

8:05 abrenk: rhickey: http://clojars.org/repo is browseable

8:05 Jomyoot: it solves my problem actually

8:05 wow

8:05 qed: and quite a bit of fun to play with

8:05 spariev: Jomyoot: here's quick example using c3p0 - http://gist.github.com/302538

8:05 Jomyoot: i wish there's more example for using connection pool with clojure

8:05 qed: i wish there were more examples in general

8:07 avarus: abrenk: ah, great :)!

8:08 rhickey: abrenk: thanks

8:09 spariev: how to say to leiningen that i'm currently offline, so it wont try to download stuff ?

8:10 Jomyoot: I am going to get real dumb here: is there built-in connection pool for java, or do I need to resort to things like c3p0?

8:10 spariev: there's no such thing, as far as i know

8:11 Jomyoot: so need to use c3p0?

8:12 abrenk: spariev: you can do so in ~/.m2/settings.xml

8:12 spariev: <settings><offline>true</offline></settings>

8:13 spariev: Jomyoot: yes, i would recommend c3p0 or apache DBCP

8:13 abrenk: oh, thanks. lein honors maven settings, great

8:14 Jomyoot: thank you

8:14 i felt really excited

8:14 wow

8:15 spariev: Jomyoot: np

8:15 lpetit: MigLayout is really cool !

8:15 Jomyoot: i was so close to quitting clojure

8:15 qed: I have a structure which looks like: ("Xyz: " "Hello frank reynolds.\n" "Ghijkl: " "Tommy guns!" "Lots of them!") -- I'd like to partition it so Xyz... and Ghikl... are two separate lists -- how would I accomplish this?

8:16 im not sure i understand how to properly use partition-by

8:17 avarus: Jomyoot: yesterday I had a fight with clojure and pgsql; i wasn't able to insert values for timestamp fields :P...really...I was about to quit, too :P

8:17 _fogus_: qed: What about split-at?

8:17 chouser: rhickey: I added IFn to Vec last night, and can work on j.u.Collection methods. Do you want one or more tickets to hang patches on?

8:18 qed: _fogus_: i will try it, thanks for the suggestion

8:18 oh, _fogus_ -- this will not work because the number of "blah"s after Ghijkl: can be variable

8:19 noidi: ,(apply map vector (partition 2 [:foo 1 :bar 2]))

8:19 clojurebot: ([:foo :bar] [1 2])

8:19 qed: so it needs to match something like #".*:\s\Z"

8:19 for it to split on it

8:19 noidi: ah, that's not what you meant

8:19 Leafw: about deftype: altering any of the 'fields' of an instance should return a new instance that shares all other fields of the old one, except that one? I hope that's the case.

8:20 rhickey: chouser: yes, I was going to try their agile planner this morning - hang on a sec...

8:20 qed: It's like ("Foo: " "Some stuff\n" "more stuff\n" "even more stuff\n" "Bar: " "bar's stuff" "bar has more stuff" "Baz: " "...")

8:20 chouser: rhickey: ok, no rush. other things I should be doing...

8:21 * chouser looks guiltily at _fogus_

8:21 rhickey: chouser: thanks for the help!

8:22 qed: yes! fogus and chouser! get thee to a publisher..ey?

8:23 chouser: ,(use '[clojure.contrib.seq :only [partition-by]])

8:23 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath:

8:23 chouser: ,(use '[clojure.contrib.seq-utils :only [partition-by]])

8:23 clojurebot: nil

8:23 chouser: ,(map (partial apply concat) (partition 2 (partition-by keyword? [:a 1 2 3 4 :b 1 2 :c 5 6])))

8:23 clojurebot: ((:a 1 2 3 4) (:b 1 2) (:c 5 6))

8:24 chouser: qed: ^^

8:24 Jomyoot: do you guys code with dark on light and light and dark?

8:24 noidi: chouser, wow :)

8:24 Chousuke: Leafw: I don't think structural sharing makes sense for deftype

8:24 noidi: chouser, I would've used a messy recursive function... I hope that you cover most of core and contrib in joy of clojure :)

8:24 Chousuke: Leafw: just copying every field is most likely going to be faster AND more memory efficient unless the deftype has dozens of fields.

8:25 Leafw: Chousuke: would be great to have the access speed of fields, but with the structural sharing capabilities of a map. Is there such combination, now that defstruct is being phased out?

8:25 chouser: Leafw: structural sharing doesn't really kick in on maps or vectors until you have at least 32 items anyway.

8:25 avarus: ah apropos joy of clojure...still haven't read more than the intro :D

8:26 chouser: If your deftype has more than 32 fields, you may need help in other ways.

8:26 Chousuke: Leafw: if you have so many fields that structural sharing becomes relevant, use a map :)

8:26 Leafw: chouser: no, I don't want more than 32 fields ... I see. Thanks for the insights.

8:26 lpetit: ,(map (partial apply concat) (partition 2 (partition-by keyword? [:a 1 2 3 4 :b :c 1 2 :c 5 6])))

8:26 clojurebot: ((:a 1 2 3 4) (:b :c 1 2) (:c 5 6))

8:26 rhickey: chouser: ok, there's a master ticket and several subtickets here: http://www.assembla.com/spaces/tickets/agile_planner/clojure

8:26 lpetit: chouser : ^^ :-(

8:26 chouser: lpetit: hmph.

8:27 lpetit: there was a thread recently on this in the ml

8:28 Leafw: I just cherished the idea of never ever having declare a clone method, yet having a built-in "undo" just by keeping the previous map when altering a map (or a reified ob, whatever)

8:28 without the cost of a full clone.

8:28 lpetit: chouser, qed: search for "clojure kata" in the ml

8:29 qed, chouser: there we are : http://groups.google.com/group/clojure/browse_thread/thread/49bd20eb4bcba20c/3565dbeabaef0748?lnk=gst&q=clojure+kata#3565dbeabaef0748

8:29 chouser: rhickey: will generic vector replace PersistentVector?

8:30 rhickey: chouser: that's trickier, due to bootstrapping issues

8:30 Chousuke: Leafw: you can do that with types, can't you? they *are* persistent.

8:30 qed: lpetit: MUCH OBLIGED

8:30 whoa -- sorry about that

8:30 Chousuke: Leafw: it's just that for small types, doing a full clone is cheaper than any structural sharing scheme

8:31 lpetit: qed: np

8:32 rhickey: chouser: while ccinc is straightforward, cinc has issues with needing some fundamental data structures up front, so these that are defined using so much of Clojure pose a bootstrapping question

8:32 * chouser still hasn't read Lisp In Small Pieces

8:33 rhickey: much easier when the only predefined thing you need is a cons cell with car and cdr

8:34 Leafw: Chousuke: ok, so it's all just vocabulary clashes. An instance of a type then is all final, and the values of its fields cannot be changed?

8:55 qed: how do you clear a slime repl?

8:55 noidi: you can scroll the old messages away by pressin C-l twice

8:56 or just kill the buffer with C-x k and bring it back with C-c C-z

8:56 maybe there's a proper way to clear it but that's what I use :)

9:01 oek: C-c C-o will clear the output at least on my slime

9:01 qed: C-c M-o

9:01 clears all output

9:02 oek: qed: and that clears everything up ;)

9:03 qed: oek: it washes the buffer clean

9:03 "it's like power washing your buffer"

9:04 lpetit: bon alors je retourne au boulot, sinon je vais me faire virer si on voit que je fais des reductions de maps au lieu de faire du miglayout !

9:04 woops, nevermind

9:05 was a joke, of course. Wrong channel, BTW

9:05 qed: Ne vous laissez pas tiré, lpetit

9:05 lpetit: :)

9:05 qed: lpetit: is that too formal for irc?

9:06 lpetit: qed: what ?

9:06 qed: lpetit: is vous too formal?

9:07 lpetit: qed: not if you don't know the person.

9:07 qed: lpetit: so you use vous usually on irc?

9:08 lpetit: i guess im trying to find out where the threshold is for tu :)

9:09 On se tutoie?

9:09 lpetit: qed: do you want to date? (rofl)

9:09 qed: lol

9:10 lpetit: seriously, I must leave the channel, cu

9:10 avarus: if they have sex they still say "vous" :P

9:11 qed: haha

9:11 im just always so foggy on when i can use tu vs vous -- it's a difficult contextual piece of the puzzle

9:11 i never speak french on irc so i always wonder: are we friends? am i formal? this is only irc. should i be really casual? etc.

9:13 avarus: we are all friends :P

9:17 cgrand: qed: on most public forums in french, tu is used so I guess it applies to irc too

9:18 qed: cgrand: good to know, thanks

9:19 cgrand: avarus: 50 years ago children were saying "vous" to their parents

9:20 avarus: glad my parents were/are so much more slack :)

9:21 my dad is like a good friend to me

9:21 that's really great

9:38 abrenk: Hehe. Using 'lazy-cat' while my cat sits on my lap... *g*

9:42 qed: whoa -- (ns my.class (:gen-class :implements [clojure.lang.IDeref])) (defn -deref [this] "Testing.. Testing..") @(my.class.)

9:42 that's neat

9:47 bosie: i am new to clojure/FP but isn't this a side effect: http://gist.github.com/302619 (and i am talking about calling testing2)

9:47 AWizzArd: bosie: yes.

9:48 It is a side effect.

9:48 bosie: interesting

9:48 qed: why is it a side effect?

9:48 AWizzArd: qed: result of calling the function returns nil.

9:49 But when you call it you are interested in its side effect, not in its calculation which results constantly in nil.

9:50 bosie: AWizzArd: which function returns nil?

9:50 AWizzArd: okay, it returns "yes"

9:51 The top-level call of println however results in nil.

9:51 qed: im not sure why it's a side effect

9:51 it seems the behavior is quite predictable

9:51 bosie: qed: println is automatically a side effect

9:52 qed: bosie: i know this, im just not 100% sure why yet :)

9:52 AWizzArd: A call to println prints something on your monitor

9:52 bosie: qed: because it has nothing to do with the actual function

9:52 qed: you couldn't use the function concurrently

9:53 qed: ah right -- i see

9:54 bosie: AWizzArd: so i can only be side effect free if every single function is side effect free?

9:54 AWizzArd: i have a hard time wrapping my head around that because it sounds great but i can code like that in any language

9:55 AWizzArd: FP is mostly about state change. Clojure supports you to program with less state changes.

9:55 qed: bosie: you can be side effect free in particular pieces of an application without being completely side effect free

9:55 AWizzArd: Because it does not directly offer you the operator = that you find in Java or C. int x = 8;

9:55 dnolen: bosie: side effect free code certainly isn't the "point" of clojure, any real world clojure program is going to have side effects (graphics, file I/O, etc)

9:56 qed: you have discretion over where to use side effects

9:56 AWizzArd: Instead Clojure helps you to calculate new values, and under the hood it reuses your existing ones.

9:57 bosie: hm

9:57 AWizzArd: bosie: imagine you have a hashmap H with a million key/value pairs. When you add one element then you modify H.

9:57 In Clojure you can not add an element to H. Instead you "copy" H and add an element to this copy.

9:58 Under the hood there really is not a copy. So this operation won't cost you 20 seconds, but instead will run in some few microseconds.

9:58 But for your program it looks like as if you have two hashmaps now, one with a million k/v-pairs, the other one with one more.

9:59 And Clojure supports you with concurrency by helping you to make state change safe.

9:59 Clojure is not about writing programs that can communicate with a user.

9:59 can't

9:59 funny ;)

9:59 qed: AWizzArd: what does your program see 5 k/v pairs later? 1,000,005 and (+ 1,000,005 1)?

10:00 AWizzArd: The idea is not to limit you to simple programs that calculate the faculty

10:00 qed: if you continue to add more elements, then you will always have a new map

10:00 qed: but are all of those new elements preserved, GC'd?

10:00 like n+1, n+1+1, n+1+1+1...

10:01 AWizzArd: as long anyone is pointing on those the GC won't collect it.

10:01 When all 5 pointers are gone, then the hashmap will be gone too

10:01 qed: when is it considered safe that someone is no longer pointing at it?

10:01 what about futures?

10:02 AWizzArd: The GC does that automatically. Seems to be pretty stable, now, after several hundreds of thousands of man-hours evolution.

10:03 One of the really extremly amazing things in Clojure are its fully persistent data structures.

10:03 dnolen: when there are no more global ||???????????????????????vars or locals referring to it, basic gc stuff.

10:03 AWizzArd: Hickey implemented some very nice magic stuff.

10:03 dnolen: oops

10:03 sorry

10:04 bosie: AWizzArd: hope not too much magic. i am trying to figure out whether or not i should learn clojure and use it for my master thesis or go python/java

10:05 Apage43: master thesis in what?

10:05 AWizzArd: bosie: if you want to do something non-trivial I can only suggest you to do this with Clojure.

10:05 bosie: Apage43: computer science

10:05 Apage43: also what awizz said

10:05 bosie: Apage43: or did you mean specifically?

10:06 AWizzArd: right

10:06 Apage43: well.. i don't think it matters as much now that i think of it

10:06 because of what awizz said

10:06 bosie: fair enough

10:07 Apage43: if you use something else you'll just be exerting more effort

10:07 AWizzArd: bosie: you can have a complex data structure and use it concurrently in multiple threads and "modify" it there. The other threads won't see your modifications, and each cpu core can work with consistent data.

10:07 Apage43: Definitely especially so if you lean toward the theoretical end of CS

10:07 bosie: how do you figure that? it will be text data mining

10:08 Apage43: bosie: well, how much processing are you doing to it? How complex/advanced are the algos you are applying?

10:10 bosie: Apage43: a lot actually. the small data set will be around 45000 documents and i will apply preprocessing on them to extract the feature set. probably based on word entropy and/or genetic algorithms. after that it goes off to an SVM (which i will not implement myself)

10:11 sorry if that was a bit too much information

10:12 Apage43: personally i would say that sounds like something clojure and/or lispy and functional languages in general would do well at.

10:13 qed: bosie: have you seen ato's wide finder 2?

10:13 bosie: that's what i heard. and the processing will be done on an 160 core machine....

10:14 Apage43: for genetic algorithms particularly you'll wind up with more concise and more easily paralellizable code

10:14 bosie: qed: not yet

10:14 qed: bosie: http://meshy.org/2009/12/13/widefinder-2-with-clojure.html

10:14 im guessing you'll enjoy that :)

10:15 bosie: qed: thanks. instapaper-ed it ;)

10:15 qed: bosie: also, if you're not already checking it out: http://planet.clojure.in/ && http://www.disclojure.org/

10:16 two sites you will want to bookmark :)

10:24 http://combinate.us/2010/02/09/pi-in-clojure/

10:43 bosie: thanks guys

10:43 i will go with a real side effects free FP language.... => haskell

10:43 kidding

10:46 triyo: you mean a calculator

10:48 * qed passes on monads

10:56 _fogus_: Even a calculator has M+ M- and MC

10:57 slyphon: so, i'm trying to figure out how one could design a callback mechanism using clojure

10:57 how do you hand a function to another function that can later be called when an event happens?

10:58 chouser: slyphon: it's the most common thing in the world. you pass functions to map, filter, etc. right?

10:58 slyphon: sure

10:59 hrm

10:59 * slyphon goes to read the "map" implementation

11:05 jcromartie: slyphon: forget the map implementation

11:05 slyphon: this is just a fundamental part of functional languages

11:05 ,(fn [x] (+ 1 x))

11:05 clojurebot: #<sandbox$eval__7080$fn__7082 sandbox$eval__7080$fn__7082@1695ec4>

11:05 jcromartie: that returns the fn itself

11:06 slyphon: ah

11:06 ok, that's what i wanted to know

11:06 jcromartie: ,(let [f (fn [x] (+ x 1))] (f 1))

11:06 clojurebot: 2

11:06 jcromartie: and there is a shorthand too

11:06 ,#(+ % 1)

11:06 clojurebot: #<sandbox$eval__7093$fn__7095 sandbox$eval__7093$fn__7095@16d9bf>

11:06 slyphon: ohhhh

11:06 ok, i got it

11:08 * slyphon is still orienting himself to clojure

11:08 slyphon: it's been a long time since i lisped

11:33 aravind: dnolen or cgrand: either of you around?

11:34 dnolen: aravind: hullo

11:34 aravind: dnolen: hi! hey, if you have some time, I'd like to ask some questions about http://groups.google.com/group/enlive-clj/browse_thread/thread/9f979c8e3f4ecc99

11:34 dnolen: aravind: sure.

11:35 aravind: dnolen: I am new to enlive/compojure and was trying to parse that thread and its left me more confused than I was. I came to when I was trying to write a template to fille in name:values pairs into a table (from a map).

11:36 dnolen: would that be a good use case for that proposed enhancement?

11:37 dnolen: aravind: The thread is really more about a usability enhancement. Enlive can probably do what you want right now.

11:37 aravind: oh..

11:38 okay, nevermind then.. (back to scratching my head)

11:38 dnolen: aravind: are you just trying to figure out how to write the template?

11:40 aravind: dnolen: well.. so I have html like <td><td> and I have to loop over a map and fill in name, value pairs into that table. I don't see an easy way to applying clone-for to fill values into multiple locations in one iteration. I thought that the thread was about that.

11:40 dnolen: aravind: multiple location in the td?

11:40 location -> locations

11:42 aravind: dnolen: yeah, so each loop of the clone-for would fill in one name:value pair into the table.

11:43 cgrand: aravind each-loop of the clone for must deal with a row

11:43 aravind: dnolen: oh.. name would go into the first <td>, value into the next <td> and then a </tr>

11:44 cgrand: (deftemplate tpl src [data] [:tr] (clone-for [[k v] data] [:td.name] (content k) [:td.value] (content k)))

11:45 the second (content k) should b (content v) you may need to call str on k or v if they aren't strings

11:46 aravind: cgrand: thanks!

11:49 fdaoud: cgrand: thank you for Enlive, it's excellent

12:05 chouser: is it wrong to want to know from (swap! a f) what value was finally successfully used as the input to f?

12:06 or is it mearly wrong to achieve it by use of another (local) atom? :-P

12:06 merely

12:07 hiredman: aren't atoms synchronous?

12:07 chouser: they spin, retrying

12:08 arohner: (swap! a f) @a is a race

12:08 hiredman: can't you just look at a?

12:08 chouser: I have map in an atom, and I do (swap! a dissoc :foo)

12:08 hiredman: arohner: so is @b if f is setting b

12:08 chouser: then I want to know if I was the thread that did the dissoc or not, because I have side-effects to accomplish if I was.

12:09 arohner: I have a deftype that I want to implement IFn. Do I have to write out all the implementations by hand, or is there a shortcut?

12:09 it would be awesome if I could just point it at an existing function

12:09 (deftype foo [a b] IFn my-fn)

12:10 chouser: all implementations? how many do you have?

12:10 arohner: rather than (invoke [obj]) (invoke [obj1 obj2]) ...

12:10 sorry, all methods on IFn

12:10 and apply

12:14 cgrand: chouser: you're not alone, I too have already wanted to know the value passed to f.

12:15 hiredman: what about a watch?

12:15 chouser: I could use an agent instead of an atom, and do my side-effects in the action. But 99% of the time I expect there to be no contention on this at all, so the thread overhead of agents seems unfortunate.

12:16 hm...

12:16 cgrand: ,(let [a (atom [{} nil])] (swap! a (fn [[m]] [(assoc m :foo :bar) m]))) ;-(

12:16 clojurebot: [{:foo :bar} {}]

12:16 chouser: heh

12:19 eyeris: I have two functions. They both return a list of maps. I want to compare whether the list contain the same maps. (= (set (f1)) (set (f2))) evals to false. However if I eval (f1) and (f2) and then copy the returns back into the original expr and re-eval, it returns true. What am I missing here?

12:19 cgrand: chouser: but then you have a small memory leak

12:20 hiredman: arohner: I don't think (swap! a f) @a is a race

12:20 chouser: fixed-size leak. which is more of .. a reservoir

12:20 ?

12:21 arohner: hiredman: you're not guaranteeed that @a will have the result of the swap you just did

12:21 hiredman: atoms are synchronous, and their retries run on the same thread as the swap

12:21 arohner: another thread can swap! between the two calls

12:21 hiredman: oh

12:21 right

12:22 cgrand: chouser: you can take care of this leak by doing another swap! to set the second item to nil when the pair is identical to the one the first swap! returned

12:24 arohner: eyeris: do you have a paste you can show us?

12:25 eyeris: arohner: Sure, though you won't be able to run it because the two functions execute against a DB.

12:25 Give me a sec.

12:26 chouser: (defn swap!-old [a f & args] (let [old (atom nil)] (swap! a #(do (reset! old %) (apply f args)))))

12:26 cgrand: uglier, but can be used transparently on existing atoms.

12:26 oh, whoops

12:27 (defn swap!-old [a f & args] (let [old (atom nil)] (swap! a #(do (reset! old %) (apply f % args))) @old))

12:30 eyeris: arohner: http://pastebin.com/d2270e7bb

12:30 cgrand: chouser: I agree. Should we start lobbying for another swap! that returns [new-val old-val]?

12:31 eyeris: arohner: Look at line 31 and down

12:31 chouser: maybe. I've got another goofy use-case for atoms here ... trying to see if it could use such a swap! as well.

12:32 arohner: eyeris: is that clojureql?

12:32 eyeris: arohner: Yes

12:32 esj: is this perverse: https://gist.github.com/0290eae3912f095e1b77 ?

12:32 arohner: eyeris: I'm suspicious of the return type of (four-year-consent-data)

12:32 is that a sql result set?

12:32 eyeris: It's a realized seq of results

12:32 stuartsierra: esj: not at all

12:33 eyeris: You can see it evaluated on line 34

12:33 esj: stuartsierra: excellent ;)

12:33 stuartsierra: esj: I used the same technique in a GUI example

12:33 esj: i've been puzzling over different ways of doing this all afternoon

12:33 stuartsierra: Although I did it with agents

12:33 arohner: eyeris: print the results of (set (four-year-consent-data)). My guess is the two runs will have different values

12:34 stuartsierra: esj: What exactly are you trying to achieve?

12:34 esj: just have a function with side effects running until I tell it to stop

12:34 arohner: eyeris: oh, nm

12:35 esj: from a possibly different thread to where it was started

12:35 eyeris: Both data functions return LazySeqs. The (set)s of those seqs are equal, as evidenced on line 50 of the paste.

12:36 stuartsierra: esj: Ok, here's how I did it: http://stuartsierra.com/2010/01/08/agents-of-swing

12:37 esj: I'm worried that your version spins in an infinite loop even when the gate is "turned off"

12:38 esj: oh... why ?

12:38 stuartsierra: Because spinning in a do-nothing loop wastes processor resources.

12:38 I don't understand your example well enough to see if that's what it's doing.

12:38 chouser: where does it spin?

12:38 arohner: eyeris: did you try (= (set (four-year-consent-data)) (set (four-year-consent-data)))

12:38 i.e. both fns are the same type?

12:39 stuartsierra: chouser, esj: Oh, maybe it doesn't spin.

12:39 esj: hooray !

12:40 eyeris: arohner: That is on line 31.

12:40 arohner: eyeris: that's fycd vs. fycd-new

12:40 stuartsierra: esj: Yeah, I think this works. Not intuitive to my mind, but that's not saying much.

12:40 eyeris: Oh I see.

12:40 arohner: I'm asking about fycd vs. fycd, or fycd-new vs. fycd-new

12:40 just curious what happens

12:40 eyeris: Your expr evals to true

12:41 Both forms of it

12:42 esj: is there anything to recommend going directly : http://gist.github.com/302787 ?

12:44 hiredman: all the second atom setting seems like a use case for watchers

12:46 esj: yeah. I'm scared of using them until they stop being alpha.

12:46 hiredman: they aren't aplha

12:46 alpha

12:46 arohner: eyeris: sorry, I don't know what's going on there

12:46 eyeris: and I have to run

12:46 eyeris: arohner: Thanks for trying.

12:46 esj: oops, behind the curve, as usual :)

12:46 hiredman: they are "experimental"

12:46 eyeris: I know I must be missing something simple.

12:47 hiredman: esj: I was actually talking to chouser of 20 minutes ago about the atoms

12:47 * esj scrolls up...

12:48 hiredman: ugh

12:48 busy wait

12:48 arohner: eyeris: one more idea

12:48 try printing (class fycd) (class fycd-new)

12:48 hiredman: use a BlockingQueue and a watcher

12:49 the watcher can (.put bq true) if the atom is set to true

12:49 eyeris: LazySeq

12:49 stuartsierra: esj: (defn run-until [r f] (loop [] (when @r (f) (recur))))

12:50 eyeris: Although, (class (first (fycd[-new]))) returns PersistentStructMap versus PersistentArrayMap

12:50 esj: stuartsierra: yes!

12:51 stuartsierra: esj: Careful, I'm not 100% sure that's right.

12:53 eyeris: Is there a way to convert a StructMap to an ArrayMap?

12:53 esj: i'll play with it, thanks. The problem with this language is the longer you work on something the shorter the code becomes... so at some point somebody is going to create a singularity.

12:53 stuartsierra: :)

12:54 esj: The thing is, run-until will never return until the gate closes.

12:55 You probably would want to start it in a separate thread.

12:55 esj: i don't mind as the side effect is all I'm after

12:55 stuartsierra: Or use an agent.

12:55 esj: yeah, I'd future it

12:55 stuartsierra: that works too

12:55 esj: thanks for the help, as ever.

12:55 stuartsierra: no problem

12:58 triyo: _fogus_: "Even a calculator has M+ M- and MC" -> Haskell with Monads

12:58 arohner: eyeris: really, one last idea

12:59 eyeris: try printing (.hashCode fycd) (.hashCode fycd-new)

12:59 and a thing I just remembered, in java (int 1) and (long 1) have different hash codes

12:59 so if your DB representation returns a long...

12:59 now I'm really leaving

12:59 eyeris: arohner: ok

12:59 THanks

12:59 chouser: arohner: are you sure?

13:00 arohner: chouser: I've been bitten by it several times

13:00 chouser: ,(map hash [(int 1) (long 1) (bigint 1)])

13:00 clojurebot: (1 1 1)

13:00 chouser: ,(map #(.hashCode %) [(int 1) (long 1) (bigint 1)])

13:00 clojurebot: (1 1 1)

13:00 eyeris: The hash codes of my objects are the same.

13:00 chouser: they may not be .equal, however. :-(

13:01 ,(.equals (int 1) (long 1))

13:01 clojurebot: false

13:01 arohner: chouser: ah, that's what it was

13:01 Chousuke: chouser: vectors can't hold primitives. all those get converted to Objects :/

13:01 hiredman: ugh

13:01 chouser: Chousuke: yes, but Objects of the appropriate type.

13:01 hiredman: Chousuke: primitives don't have a hashCode anyway

13:01 eyeris: You're right, .equals = false

13:01 chouser: ,(map class [(int 1) (long 1) (bigint 1)])

13:01 clojurebot: (java.lang.Integer java.lang.Long java.math.BigInteger)

13:01 hiredman: that is horrible

13:01 arohner: yes it is

13:01 hiredman: unequal but the same hashCode

13:02 bad sun, bad!

13:02 chouser: and because they are not ".equals", they "must not" match when used as keys in a hash-map

13:02 hashCodes don't need to be unique

13:02 eyeris: I know why that is. It's because one of them is an ArrayMap and the other is a StructMap. They have the same keys, but the ArrayMap requires the same key order

13:03 I just don't know how to turn them both into basic HashMaps

13:03 chouser: (into {} ...)

13:03 but I doubt that's the problem

13:03 hiredman: ,(= (array-map :a 1 :b 2) (array-map :b 2 :a 1))

13:03 clojurebot: true

13:03 hiredman: ,(= (array-map :a 1 :b 2) (array-map :b 2 :a 1 :a 3))

13:03 clojurebot: false

13:04 chouser: stop that.

13:04 if you make broken maps, you get broken results.

13:05 cow-orker: As "new" and "->" and play nicely, and I like "new", I tried this: http://paste.pocoo.org/show/177196/ . Are there any problems with this macro? (It seems to work for trivial forms)

13:05 hiredman: sure

13:05 cow-orker: *dont* :-)

13:06 eyeris: You're right, using (into {} ... does not fix it.

13:06 hiredman: cow-orker: have you seen ->>

13:07 eyeris: Even though that does cause them to .equal = true

13:07 hiredman: ,(->> "foo" .getBytes (new String))

13:07 clojurebot: "foo"

13:07 eyeris: This is so darn confusing.

13:08 cow-orker: sure, but except for "new" I'd like to insert into "first arguement slot"

13:08 what I wanted was -> that supports new, not ->>

13:08 hiredman: ,(-> "foo" .getBytes (->> (new String)))

13:08 clojurebot: "foo"

13:08 hiredman: :D

13:09 cow-orker: right, that works :)

13:09 chouser: eyeris: sorry, I haven't been paying attention. I see your paste -- you're expecting line 32 to be true?

13:09 eyeris: No, line 3

13:09 Oh wait

13:10 Here's a new paste: http://pastebin.com/d5d52a8f0

13:10 That more clearly explains what I don't understand.

13:10 chouser: ah, ok

13:11 so is there any chance that some of those numbers are int and others long?

13:11 eyeris: There is. Though the (= (first (fycd)) (second (fycd-new))) evals true

13:12 chouser: you can't trust = here -- it's not what value comparison uses in a hash-set

13:12 eyeris: Likewise for the other combination, (= (second (fycd)) (first (fycd-new)))

13:12 Oh.

13:13 chouser: try .equals instead

13:13 eyeris: .equals evals false too

13:14 chouser: ok, so that's your problem.

13:14 eyeris: It is?

13:15 chouser: yes. if they're not .equal, they won't match in a hash-set

13:15 in some cases you can skirt this issue by using a sorted-set instead. unfortunately the default comparator doesn't do hash-maps, so doesn't help you here.

13:15 eyeris: Oh, you meant on the maps. I did it on the sets. Hold on.

13:16 chouser: ah, yes.

13:16 eyeris: Right, the maps don't .equals to true either.

13:17 They also don't .equals to true if I convert them both to normal maps using into {}

13:17 chouser: the options I can think of are: use sorted-set with your own comparator, or convert all numerics to a consistent type.

13:18 eyeris: So the reason that copy-pasting the results back into the original expr in my works is because the reader converts them both to ArrayMaps

13:18 chouser: rhickey: are you listening to this? are they any better options?

13:18 eyeris: no, because the reader reads them all as Integers

13:18 eyeris: Oh

13:19 chouser: it would have helped you identify the problem much more quickly if longs and ints printed differently.

13:19 eyeris: :)

13:19 I can easily cast the int to a long.

13:19 chouser: ok. do that. :-)

13:20 eyeris: That worked.

13:37 ninjudd: is there a way to prevent the repl from traversing a specific sequence? perhaps a meta flag on the sequence

13:43 chouser: that's an interesting idea. you can tweak the printer by adjusting the print-method multimethod.

13:47 ninjudd: chouser: ok, so i should just set :type in meta and write my own print-method

13:48 chouser: ninjudd: sure, that'd be one approach

13:52 ninjudd: chouser: ok, thanks. that works

14:16 Drakeson: how would you apply a function to the values of a map?

14:16 chouser: this is the new FAQ #1

14:16 :-)

14:17 ,(let [m {:a 1, :b 2, :c 3}] (zipmap (keys m) (map inc (vals m))))

14:17 clojurebot: {:c 4, :b 3, :a 2}

14:17 Drakeson: but, wasn't there a function for this in one of the libs?

14:18 hiredman: ,(use '[clojure.contrib.generic.functor :only (fmap)])

14:18 clojurebot: nil

14:18 hiredman: ,(fmap inc {:a 1})

14:18 clojurebot: {:a 2}

14:18 hiredman: ,(fmap inc {:a 1 :b 3 :c 4})

14:18 clojurebot: {:a 2, :b 4, :c 5}

14:18 Drakeson: thanks

14:19 why would you put :only there?

14:19 there is nothing else in there

14:20 chouser: it documents where the fn is defined

14:20 hiredman: Drakeson: I didn't know that

14:20 chouser: anyone looking at the log can see where fmap comes from

14:20 hiredman: but yes, :only is nice

14:20 bosie: what's the name of "'"? like (use 'clojure.....)

14:21 Drakeson: quote

14:21 chouser: isn't :require even nicer?

14:21 hiredman: ,(macroexpand-1 ''(foo))

14:21 clojurebot: (quote (foo))

14:21 bosie: Drakeson: there is no name for that mechanism?

14:21 hiredman: ,(macroexpand-1 (quote 'a))

14:21 clojurebot: (quote a)

14:21 hiredman: bosie: it is called quoting

14:22 http://en.wikipedia.org/wiki/Lisp_%28programming_language%29#Self-evaluating_forms_and_quoting

14:26 bosie: hiredman: ok now i found it in the docs

14:26 thanks

14:28 chouser: Drakeson: either seems fine. require with a namespace alias, use with :only. either way the usage of a fn points to an form in the 'ns' that indicates the defining namespace.

14:59 eyeris: Is there a std function that takes a value x and a list of functions [f1 f2 f3] and returns [f1(x) f2(x) f3(x)]?

15:00 chouser: juxt

15:00 eyeris: ,(doc juxt)

15:00 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, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"

15:00 eyeris: Ah, so it's not in 1.0.0 :)

15:00 chouser: hm, no probably not. maybe 1.1

15:12 cemerick: chouser: what page count are you guys aiming for?

15:12 chouser: officially 250-300

15:14 cemerick: chouser: any thought of including something on monads? I'm seeing more and more code in the wild that uses them.

15:15 chouser: hm. there's nothing in the outline on them yet.

15:15 cemerick: ...which is why I mentioned it :-)

15:15 chouser: I guess I'd have to be more personally impressed with their usefulness before desiring to include them

15:15 cemerick: heh

15:16 stuartsierra: Monads are a solution in search of a problem.

15:16 somnium: ~monad

15:16 clojurebot: monad is "yea, though I should walk in the valley of imperative code, I shall fear no evil, for your monad comforts me" - seen in #haskell

15:16 stuartsierra: :)

15:16 triyo: cemerick: any particular advantages of monads over more familiar constructs in clojure, in your opinion perhaps?

15:16 cemerick: there's certainly nothing special about them -- closest thing to a pattern one sees in functional programming, perhaps.

15:17 chouser: I've stumbled on a couple of contexts where I suspect a monad may be a good solution. I suppose I should persue that and see how it turns out.

15:18 * somnium digs the state monad

15:25 rhickey: I wouldn't consider monads part of the Art of Clojure

15:25 nor Joy of CLojure

15:26 chouser: heh

15:27 stuartsierra: Monads are the Visiting In-Laws of Clojure.

15:27 rhickey: plus I wonder how monads will fare in the context of Steele's "foldl considered harmful"

15:27 monads are inherently non-parallelizable

15:29 triyo: so whats your thoughts on continuations? just kidding...

15:31 vy: Somebody was asking about how to transform a LazySeq into an OutputStream, any replies?

15:32 hiredman: vy: an outputstream is something you write to, and a lazyseq is immutable, I don't see how that is supposed to work

15:32 vy: Sorry, I meant an InputStream.

15:32 hiredman: you just need to proxy inputstream

15:32 stuartsierra: by the way, foldl considered harmful is awesome: http://research.sun.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf [PDF]

15:32 * _fogus_ todo - remove monads chapter :p

15:34 cemerick: triyo: without a type system backing you up, it ends up being just another way to compose operations and control function application. I'd just consider them a particular programming style.

15:35 hiredman: cemerick: are you talking about monads or continuations?

15:35 cemerick: monads

15:36 stuartsierra: Is it intended for datatypes to be read-able?

15:37 (read-string (pr-str (MyDatatype 1 2 3))) doesn't work

15:37 rhickey: stuartsierra: not yet

15:37 chouser: right, it's not meant to work currently.

15:42 stuartsierra: ok

15:42 But it will eventually?

15:45 * the-kenny needs to learn more about deftype

15:48 rhickey: stuartsierra: one issue is that if you've printed some deftype instances and re-read in another session, you'll need to have loaded the deftype again first

15:49 another is that in order to be able to round trip they'd need to print with a full namespace

15:49 stuartsierra: Yes. I ask because this is a FAQ with StructMaps.

15:50 rhickey: I completely understand the desire

15:50 stuartsierra: Read-able datatypes also opens the door to object literals!

15:51 #:java.util.Date{:time 12345678}

15:51 rhickey: yikes

15:51 stuartsierra: Heheh. :)

15:52 hiredman: ,#=(java.util.Date. 1266008070)

15:52 clojurebot: EvalReader not allowed when *read-eval* is false.

15:52 hiredman: bleh

15:52 stuartsierra: I guess you could write #=(MyDatatype 1 2 3)

15:53 rhickey: not without a full ns

15:53 stuartsierra: yes, of course

15:53 cemerick: that's what deflate is for anyway

15:54 rhickey: cemerick: your repl has deflate? :)

15:55 cemerick: rhickey: I deflate my code *when I write it* ;-)

15:55 stuartsierra: Buuuuuuut, if datatypes support introspection (and they must, since they're Classes) you could write a wrapper that generates Apache Avro serialization specs for them.

15:55 rhickey: so, one question is, is printing readably only when *print-dup* acceptable?

15:55 cemerick: preferable, I'd say

15:56 stuartsierra: I tend to assume that prn is readable, never really understood *print-dup*

15:56 hiredman: ditto

15:56 ,(doc pr)

15:56 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"

15:57 cemerick: *print-dup* provides hooks for making arbitrary objects readable.

15:57 e.g.

15:57 ,(prn (java.util.ArrayList.))

15:57 clojurebot: #<ArrayList []>

15:57 cemerick: not so useful ^^

15:57 stuartsierra: ,(binding [*print-dup* true] (prn (java.util.ArrayList.)))

15:57 clojurebot: #=(java.util.ArrayList. [])

15:58 stuartsierra: I'd prefer pr to always print read-ably, use print for human-readable cases.

15:58 I think this would be possible with protocols.

15:59 * stuartsierra is writing a chapter about datatypes and protocols

15:59 cemerick: That would require *print-dup* to be true by default. *bleh*

15:59 piccolino: Is this #= new in 1.1?

15:59 hiredman: nope

15:59 stuartsierra: cemerick: I want to ditch *print-dup* altogether.

16:00 piccolino: I can't find anything about it in the reader docs.

16:00 cemerick: piccolino: it's very underdocumented, and not particularly an official feature

16:00 piccolino: Ah.

16:00 stuartsierra: "very underdocumented" heh :)

16:00 chouser: intentally underdocumented, no less.

16:01 cemerick: stuartsierra: right, I mean have the effect of *print-dup* being true

16:01 stuartsierra: yes

16:01 chouser: that's very noisy at the REPL

16:01 cemerick: I suppose that's fine by me as long as the repls do the right thing.

16:02 hiredman: what happens if it cannot be printed readably?

16:02 stuartsierra: hiredman: Exception

16:02 chouser: you still get #<> stuff

16:02 cemerick: stuartsierra: oh, no no

16:02 hiredman: stuartsierra: that is a lot of exceptions

16:02 LauJensen: Is there anything in contrib which converts java.awt.Color to a #hex ?

16:02 stuartsierra: ,(binding [*print-dup* true] (prn clojure.lang.RT))

16:02 clojurebot: #=clojure.lang.RT

16:02 stuartsierra: ok, that works

16:03 chouser: ,(binding [*print-dup* true] (prn (sorted-map :a 1 :b 2)))

16:03 clojurebot: #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})

16:03 stuartsierra: ,(binding [*print-dup* true] (prn *in*))

16:03 clojurebot: java.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class clojure.lang.LineNumberingPushbackReader

16:03 stuartsierra: That's the exception.

16:03 chouser: oh! indeed.

16:05 stuartsierra: this is for the APress book?

16:05 stuartsierra: yes

16:06 _fogus_: stuartsierra: For some reason I thought someone else was writing that

16:06 stuartsierra: Luke Vanderhart is writing about 2/3 of it.

16:06 fdaoud: stuartsierra: you are participating?

16:06 stuartsierra: Originally I was doing only 2 chapters, but now I'm doing several more.

16:07 fdaoud: where's your name then?

16:07 stuartsierra: Not on the cover of the current PDF beta; I wasn't in on it yet.

16:07 I need to bug them to make a new PDF.

16:08 _fogus_: He lives somewhere in my area. I'm hoping to see him around at the upcoming Clojure UGs

16:08 stuartsierra: _fogus_: Nice. Where's that?

16:09 _fogus_: DC/Metro area

16:09 fdaoud: unfortunately Apress is too agressive in announcing their books so it's hard to trust their dates; I've seen them announce books before the author even started, and the book never came out

16:09 stuartsierra: _fogus_: Cool, that's not far from New York, maybe I could come down some time.

16:09 fdaoud: I was worried about that for a while, but it seems to be coming together.

16:10 fdaoud: they are also a little too keen on 'Definitive Guide' - but, again, no offense to the authors

16:10 mattrepl: _fogus_: he was at a few of the clojure study groups that predate cap-clug

16:10 _fogus_: You'd be welcome. The next meetup is next Thursday. The one in March will have Halloway speaking

16:10 stuartsierra: ^^

16:10 mattrepl: I was never able to make any of those unfortunately.

16:11 fdaoud: stuartsierra: good to hear!

16:12 stuartsierra: I might be able to come down in March.

16:12 I'd like to meet "the other Stuart" too.

16:12 _fogus_: http://www.meetup.com/Cap-Clug/calendar/

16:12 Not sure if this is public

16:13 fdaoud: stuartsierra: what's your home page?

16:13 chouser: I met the other Stuart, last time I was in Boston.

16:14 _fogus_: I "met" him by sitting in on one of his talks in the area and chatting afterwards (well, by chatting I mean I said maybe 2 words)

16:14 stuartsierra: fdaoud: you me my personal page? http://stuartsierra.com/

16:16 fdaoud: stuartsierra: yes that's what I meant :)

16:16 _fogus_: The DC/VA meetup in March is at the same time as the Pragmatic Workshop, so I'm trying to convince a special guest to come and join us also. (hint hint nudge nudge... say no more)

16:17 mattrepl: =)

16:17 stuartsierra: _fogus_: meaning...?

16:17 hiredman: we had a lot of python users at the seattle meetup

16:18 _fogus_: gotta go

16:24 avarus: evening!

16:25 rhickey: stuartsierra: where would Avro schemes go in print/read?

16:26 schemas

16:26 stuartsierra: rhickey: They wouldn't, it would be a separate thing.

16:26 But you could generate Avro schemas from datatypes.

16:26 To make a binary serialization format for Clojure.

16:27 If you're into that sort of thing.

16:36 tayssir: Hi! Does anyone know why Paredit might work worse in the REPL than in a .clj file buffer? (In the REPL, [] and {} aren't handled like ().)

16:37 patrkris: where does leiningen get clojure-contrib from? which repository?

16:37 stuartsierra: tayssir: printed output is the REPL buffer could confuse paredit

16:38 tayssir: stuartsierra: ah, i thought it worked once (just reinstalled slime and clojure), but maybe i'm just imagining things...

16:38 stuartsierra: never tried it myself

16:39 tayssir: yeah, actually i recalled it was the opposite; before it worked fine in the repl but not so good in the .clj buffer... ;)

17:32 piccolino: Is there some way I can make an integer be interpreted as a long (unboxed)?

17:33 Chousuke: (long whatever)

17:33 hiredman: ,(long (int (double 1)))

17:33 clojurebot: 1

17:33 piccolino: That appears to box it, though.

17:33 hiredman: it does not

17:34 Chousuke: piccolino: what are you passing it to?

17:34 piccolino: #=(java.util.Date. (long 1))

17:34 hiredman: ,expression-info

17:34 clojurebot: java.lang.Exception: Unable to resolve symbol: expression-info in this context

17:34 piccolino: Doesn't work.

17:34 Chousuke: piccolino: that should work

17:35 piccolino: It says No matching ctor found for class java.util.Date.

17:35 Chousuke: ,(java.util.Date. (long 1))

17:35 clojurebot: #<Date Wed Dec 31 16:00:00 PST 1969>

17:35 piccolino: Whoa.

17:35 hiredman: ,(java.util.Date. 1266014261)

17:35 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.util.Date

17:35 hiredman: ,(java.util.Date. (long 1266014261))

17:35 clojurebot: #<Date Thu Jan 15 07:40:14 PST 1970>

17:35 hiredman: piccolino: I think (long 1) is not evaluated in #=

17:35 piccolino: I see.

17:37 hiredman: ,(type 1266014261L)

17:37 clojurebot: Invalid number: 1266014261L

17:37 hiredman: bah

17:42 dnolen: anybody been playing around with vector-of?

17:51 chouser: only barely

17:55 dnolen: chouser: it's not supposed to be faster than regular vectors yet right?

17:57 chouser: not particularly. still has to box/unbox things

18:03 dnolen: chouser: I see.

18:04 arohner: chouser: does that require more clojure work, or a new JVM?

18:04 chouser: and vector-of has lower memory usage right now, right?

18:05 rhickey: vector-of is often faster

18:05 chouser: I think rhickey has plans for fns to support args and return values of long and double. Then you should be able to unboxed speed out of primitive vectors

18:06 hiredman: chouser: map and reduce will need to be IMap and IReduce'ized

18:06 slyphon: what's '->' ?

18:06 hiredman: a macro

18:07 slyphon: ok

18:07 * slyphon hasn't gotten that far in the book yet

18:07 chouser: oh that's right -- maybe with escape analysis and IReduce you can get unboxed speed for some things without primitive fn args

18:07 you'd think I would be able to remember that from ... yesterday.

18:09 hiredman: I don't think IReduce would need escape analysis

18:09 as long as the Fn supported taking primitives and that was discoverable

18:09 chouser: you still pass in a clojure fn, right? and it has an invoke(Object, Object) method that returns an Object.

18:10 rhickey: the tricky part is the return values

18:10 hiredman: chouser: there could be an interface IDoubleFn

18:10 rhickey: fns would have invoke(long) as well

18:11 chouser: I think you need one or the other -- fns that return primitives so you can do (get myvec i) and get an int, or escape analysis+IReduce so that hotspot can see boxing isn't needed.

18:11 dnolen: rhickey: perhaps I'm doing the wrong thing? I see that count is faster, nth seems slower. map seems to be identical. instantiation slower, conj a bit slower.

18:12 slyphon: there was some toss-away line in the pragmatic-programmer clojure book, mentioning that you should always do (clojure.core/use 'clojure.core)

18:12 hiredman: map would call seq anyway

18:12 chouser: heh. a little like perl contexts. call the fn in an long context ...

18:12 slyphon: when moving to a new namespace

18:12 rhickey: dnolen: are you running lots of iterations? warmed-up jvm, -server etc?

18:12 hiredman: slyphon: only if using in-ns

18:12 slyphon: oh, mm'kay

18:13 hiredman: slyphon: the ns macro takes care of it for you

18:13 slyphon: ah, allright

18:13 hiredman: there is also a short cut called refer-clojure

18:13 dnolen: rhickey: I am, lots of iterations, warmed up jvm.

18:13 hiredman: ,(doc refer-clojure)

18:13 clojurebot: "([& filters]); Same as (refer 'clojure.core <filters>)"

18:13 slyphon: rhickey: btw, kudos!

18:13 a lisp that doesn't smell like old jazzmen

18:13 rhickey: slyphon: on what?

18:14 ah

18:14 * rhickey misses Coltrane

18:14 slyphon: indeed

18:14 chouser: instead, one that smells like fresh jasmine!

18:14 rhickey: groan

18:14 slyphon: Live at Birdland, still my favorite

18:17 * slyphon goes back to lurking

18:17 dnolen: rhickey: my unscientific numbers http://paste.lisp.org/display/94878

18:19 chouser: there! Just finished all the unsupported j.u.Collection methods for vector-of

18:19 * chouser pats self on back and goes to dinner.

18:19 rhickey: chouser: whoa - awesome!

18:20 chouser: the unsupported ones, not the ones that need code.

18:20 rhickey: ah

18:20 chouser: :-)

18:20 sorry

18:20 rhickey: still useful, thanks!

18:21 chouser: I should still use (Util/equiv ...) for item equality?

18:21 rhickey: dnolen: you should put each of those (time ...) in a (dotimes [_ 10] ...)

18:21 chouser: or just =

18:22 rhickey: =

18:22 but only when you mean equiv. When implementing j.u.Collection semantics you often need .equals

18:22 see the existing impls

18:23 chouser: contains currently uses equiv. I'll pay attention.

18:24 rhickey: I'll not contend it's all perfect, but esp critical when defining equality so it's symmetric

18:26 another nice thing about normalizing to Long will be the option of doing away with equiv. == should be the numeric-type-ignoring comparison, never used in collections

18:28 dnolen: rhickey: ok, done, results pretty much the same. tho map does seems a tad faster which is cool since that is the more common case.

18:29 chouser: bah. toArray returns Object[]

18:30 rhickey: dnolen: really, those benchmarks aren't very useful. You'd need to wrap everything in functions that were run many times etc.

18:30 also many outlier times include a gc.

18:31 in a larger app, those gcs might be mich faster as there wouldn't be toms of tenured boxed numbers

18:31 much, tons

18:31 in any case, not promising more than parity at present

18:32 dnolen: rhickey: good to hear that it's my naive understand on of the JVM at work again :) so will generic vectors support transient?

18:32 understand -> understanding

18:32 rhickey: dnolen: yes, but transients are going to move into symbiosis with what I've been calling 'cells'

18:33 * rhickey working on cells right now

18:33 LauJensen: I've written a small tribute to Steve Ballmer on behalf of you guys: http://www.bestinclass.dk/index.php/2010/02/my-tribute-to-steve-ballmer/ :)

18:34 dnolen: rhickey: oh yeah, so many new things hard to keep track ;) but I get the feeling that the goal is to get it so that math ops on vectors of primitives can compete with Java arrays eventually? no?

18:35 rhickey: dnolen: that's one goal, another is parallel ops

18:35 dnolen: I loathe resorting to make-array

18:35 rhickey: fantastic.

18:37 * chouser glares at the mutable field in Iterator

18:38 rhickey: the Iterator interface dictates mutability

18:38 chouser: yes.

18:38 rhickey: but yeah, that

18:38 chouser: is an atom ok here?

18:39 rhickey: I encountered in Vec also, for hash caching

18:40 chouser: maybe AtomicInteger

18:40 chouser: ok

18:40 * chouser stops using a seq

18:40 rhickey: If we never want to write Java, will need some story for these

18:42 chouser: huh, look at that. The "favicon" on the java docs is a java cup now instead of a sun logo.

18:42 rhickey: since second object overhead often unacceptable

18:53 chouser: ok, now Collection is done.

19:15 arohner: how evil is this? http://gist.github.com/303136

19:30 slyphon: what's the significance of the '&' in a defn arg-list?

19:32 arohner: slyphon: it means the fn can take extra args

19:32 slyphon: ah

19:33 arohner: the variable after the & takes all of the "leftover" args, in a seq

19:33 slyphon: ah

19:33 so it's the varargs collector

19:33 arohner: yeah

19:33 slyphon: ok

19:33 ty

20:33 danlarkin: Tha'sa me!

21:30 qed: Anyone know how to do SSL connections with clojure? I'm trying to connect to an https site which has a l/p so I can scrape it with enlive.

21:31 I thought it was basic auth, but that doesn't appear to be the case...

21:36 dnolen: qed: you should probably look into a Java lib, looking on StackOverflow seem to suggest using Apache HTTP components.

22:04 qed: my paredit-mode is horribly horribly broken

22:10 slyphon: so, a proxy is essentially a way of subclassing a Java class?

22:10 (one purpose of a proxy)

22:12 chouser: yes

22:13 slyphon: i'm trying to wrap PircBot, and i'm having trouble figuring out how to actually accomplish the task

22:13 i did this in scala, but that's a different beast altogether

22:15 qed: anyone here know how to fix {} in paredit-mode?

22:21 aghhh! paredit-mode, why have you failed me? Why dost thou curly braces fail to work?

22:29 _mst: I use: http://paste.lisp.org/display/94892

22:35 Raynes: Oh noes. I think I've offended Steve Dekorte. It's not my fault his language is 8 years old, but still looks as if was released last Saturday. :\

22:36 JonSmith: who is steve dekorte?

22:36 Raynes: JonSmith: Lead developer of Io.

22:36 JonSmith: ooh

22:36 that is kind of a neat language

22:36 qed: Io is neat

22:37 Raynes: It's just, in my opinion, a language should just give up if it's been around for 8 years and nobody knows how to deploy an application outside of embedding it.

22:37 And even then, I'm not sure it's documented.

22:37 qed: Io was always a toy to me

22:37 JonSmith: oh

22:37 qed: was he trying to make it a serious production language?

22:37 Raynes: It could be more than a toy, but obviously they don't care enough to make it one.

22:38 JonSmith: well not every language is meant to be deployed everywhere

22:38 Raynes: qed: There has been lots of talk about Io finding a niche.

22:38 qed: i learned a little bit about it when i was on a Ruby kick

22:38 Raynes: I don't really see one beyond "fun to play with and learn about for a weekend" :X

22:38 Raynes: JonSmith: Io is supposed to be a general purpose programming language, and isn't just meant for embedding.

22:38 qed: why wouldnt you just use Ruby/JRuby?

22:39 _mst: paredit-open-brace and close-brace are void function definitions

22:39 * Raynes really likes Ioke, but feels that no focus at all on performance will really kill the mood.

22:40 JonSmith: oz looks like a neat language too

22:40 Raynes: Ola Bini kind of jumps back and forth about whether or not he intends to speed Ioke up any at all. A while back he said he would focus on it for a while after about a year or two, but he's pretty convinced that Ioke will never perform well in the slightest.

22:41 _mst: qed: hmm... my paredit.el has: (define-paredit-pair ?\{ ?\} "brace")

22:41 I wonder if I hacked that in :)

22:41 qed: _mst: i needed paredit-open-curly

22:41 /close-curly

22:41 _mst: ah, right. Maybe version differences or something

22:45 qed: here's a question...

22:45 let's say I type a [, paredit-mode gives me [|] function arg1

22:46 i then type C-) to slurp function, then arg1

22:46 i find it rather annoying that the result of this is [|function arg1]

22:47 granted all i have to do is C-d to get rid of that extra space, but it seems like it should slurp without that extra space in front

22:47 somnium: anyone seen coffeescript on github?

22:47 language 'refurbishing' is an interesting approach

22:49 JonSmith: yeah is pretty clever technique

22:52 qed: somnium: i havent seen it, got a link?

22:52 somnium: http://jashkenas.github.com/coffee-script/

22:57 could use a little less syntax and some kind of metaprogramming, but its impressive what was done with a fresh parser and a few macro(like-thing)s

22:57 JonSmith: scriptjure is kind of like that

22:57 except it is more literally javascript with lisp syntax

22:57 somnium: scriptjure doesnt add any semantics does it?

22:58 JonSmith: i bet you could write some good scriptjure macros to add semantics

22:58 nope

22:58 i had to hack in aget myself :-P

22:58 i should upstream that

23:00 somnium: I wrote something in that vein, though its a bit overly complicated at this point

23:01 http://github.com/somnium/scryptica

23:01 it has TCO and varargs and other stuff, though its still rather quirky atm :/

23:02 JonSmith: yeah that is a similar vein

23:02 qed: that is really cool stuff

23:02 JonSmith: http://github.com/arohner/scriptjure

23:02 you got tco in there?

23:02 nice

23:02 qed: i really like the idea of cleaning up an old language and making it usable

23:02 somnium: and proper let scoping

23:03 though sadly it doesnt solve the for-loop problem

23:03 qed: what's it called when you write a new syntax for expressing an existing language?

23:03 JonSmith: what is the for-loop problem?

23:04 somnium: if you create closures in a for loop, only the final value gets bound in all closures

23:04 JonSmith: ooh

23:04 somnium: have to double wrap, if ecmascript ever actually adds let to the language it will go away

23:04 JonSmith: yeah that is a problem

23:04 somnium: pita though

23:06 slyphon: is there a pub/sub framework in contrib?

23:07 * slyphon has a eeling he's being daft

23:07 slyphon: er "feeling"

23:07 JonSmith: in what way pub sub?

23:08 slyphon: callbacks, like "when this event occurs, call these functions"

23:08 i'm reading about agents and the concurrency features, i'm just not really sure how to piece it together yet

23:09 JonSmith: oh

23:09 * slyphon sees "add-watch"

23:11 slyphon: i'd normally have a "dispatch" thread, so events would get added to a queue, and the dispatch thread would call the handler in a worker pool

23:14 * slyphon sees the function "trampoline" and decides he may have had enough for one night

23:14 chouser: agents may or may not do what you want there.

23:15 slyphon: yeah, i'm not really sure, it *kinda* seems like it does what i want it to do

23:15 chouser: it's perfectly acceptible to use workflow management classes from java.util.concurrent

23:15 slyphon: hrm

23:15 JonSmith: yeah

23:15 slyphon: that's a good idea

23:15 JonSmith: another nice thing i've been playing with is the erlang java library

23:16 * slyphon 's mind explodes

23:16 JonSmith: you can do send/receive and stuff

23:16 slyphon: ah

23:16 JonSmith: i have my clojure sending/receiving with yaws

23:16 it is hilarious

23:16 slyphon: yaws?

23:16 JonSmith: ya

23:16 erlang web server?

23:17 slyphon: http://en.wikipedia.org/wiki/Yaws

23:17 sounds painful

23:17 JonSmith: was kind of a fun weekend project

23:17 qed: I asked this in here earlier but I lost my buffer. Does anyone know how to connect to an https:// SSL site with clojure? I'm trying to scrape a site with enlive that is https.

23:17 I googled but couldn't find anything

23:18 slyphon: well

23:18 you could use apache-httpclient

23:18 JonSmith: clojure starts, spawns yaws as a sub-process, configures itself as an app mod and then spawns threads from a threadpool for requests

23:18 slyphon: which is quite complete

23:18 qed: slyphon: is that a clojure library?

23:18 slyphon: qed: uh, no?

23:18 JonSmith: apache-http is good

23:18 there is a clj-apache-http

23:18 slyphon: oh word?

23:18 nice

23:19 JonSmith: http://github.com/rnewman/clj-apache-http

23:19 slyphon: JonSmith: wow, that's...pretty crazy

23:19 :)

23:19 JonSmith: yeah seriously

23:19 slyphon: apache-http is cool, but it's like they took *every single word* in RFC 2616 and made it a class

23:19 JonSmith: i should polish it up and post it to github or something

23:20 yeah which is why you wrap it in macros endlessly

23:20 qed: thanks for the suggestion -- ill try it out

23:22 slyphon: it saved my ass writing this data importer, i kept running out of open sockets (they got left in TIME_WAIT), but apache-http's threadpool/socket managment does a really awesome job

23:25 qed: weird. paredit with my curly fix now at least lets me insert {} with a {, but i can now delete the } and the { wont be affected. Any ideas?

23:29 somnium: wow, Lau's latest blog post is truly truly awesome

23:30 slyphon: qed: stop using emacs?

23:30 * slyphon ducks

23:30 slyphon: i keed! i keed!

23:32 somnium: http://www.bestinclass.dk/index.php/2010/02/my-tribute-to-steve-ballmer/

23:36 JonSmith: yeah that was pretty hilarious

23:37 slyphon: wow, macroexpand ftw

23:37 technomancy: slyphon: wow, long time no see.

23:37 slyphon: technomancy: oh hai!

23:38 how goes?

23:38 technomancy: not too shabbily.

23:38 slyphon: :)

23:38 technomancy: haven't seen you in what... four years? five?

23:38 slyphon: something like that

23:38 you used to hang out in #twisted, right?

23:39 technomancy: #ruby-lang, actually

23:39 slyphon: oh, right right

23:39 technomancy: around 05-06

23:39 "before it was cool"

23:39 slyphon: yeah, that's right when i made the jump

23:39 hahahaha

23:39 yeah, before all the railtards came in and ruined it

23:40 technomancy: how's clojure treating you?

23:40 slyphon: pretty good

23:41 i spent some time long ago getting insulted by the #cl guys, so i have some grounding in lisp

23:41 technomancy: battle scars, I see

23:41 slyphon: :)

23:41 and the thought of a lisp that a) understands that there's "a whole world out there" and b) can use java libs is pretty sweet

23:42 how about you?

23:51 technomancy: I'm working on leiningen, my build tool

23:51 hope to get a release out soon

23:51 slyphon: oh nice

23:51 * slyphon read that as "Lenin Gen"

23:52 slyphon: ohhhh

23:52 nice, i saw this

23:52 i remember the tagline :D

23:52 Drakeson: how would you turn a map a url? {:a 10, :b 20, :c "xx yy"} -> a=10&b=20&c=xx+yy

23:53 hiredman: reduce is the easiest way

23:53 technomancy: Drakeson: (str-join "&" (map (partial str-join "=") my-map))

23:53 str-join coming from clojure.contrib.str-utils

23:53 or c.c.string if you're following git master

23:53 hiredman: technomancy: keywords

23:53 technomancy: oh bugger, good point

23:54 plus you'd need to URL-encode each value

23:54 well I never pass up a good opportunity to use reduce

23:54 hiredman: reduce it is!

23:54 reduce and format and URLEncoder/encode

23:55 and name

23:55 Drakeson: I see, thanks. Although I was hoping for one that is already made, instead of my possibly buggy version :p

23:56 technomancy: I'd be surprised if there wasn't something in compojure, but I've only played with it briefly

23:57 Drakeson: good point, I was sifting through clojure-contrib

Logging service provided by n01se.net