#clojure logs

2010-02-12

00:16Jomyootis there a clojure SQL library that supports handling 2 DB connections simultaneously?
00:19drewrclojureql can do it
00:19drewrc.c.sql can do it if you're willing to dig into sql/internal.clj
00:25Jomyootbeter than contrib?
00:28Jomyootdrewr: what is your recommendation on SQL for Clojure?
00:28Jomyootcontrib does not handle 2 DB connections simultaneously
00:36Jomyootdrewr: are you tehre?
00:36Jomyootdrewr: is there references on how to do so with c.c.sql?
00:51Jomyootdrewr: u gone?
01:00scgilardiJomyoot: 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)...)))
01:01Jomyootscgilardi: c.c.sql does not allow specifying connection as function parameter
01:01Jomyooteven if nested, it will probably use the inner one
01:02Jomyootplease note that i want to keep both connections open.
01:03scgilardiif it's required to keep both open, you're right with-connection is not sufficient.
01:03scgilardiunfortunately I need to go now. good luck finding a solution that works for you.
02:43qedIs there an easy way to do basic auth with clojure?
02:53piccolinoI made an hbase binding at http://github.com/davidsantiago/clojure-hbase. Would appreciate any feedback.
02:55piccolinoWhoops, screwed that link up. No period.
02:57qedwhere did clojure.http go?
02:58qednvm,
03:00avarusmorning *yawn
03:00qedmorning avarus
03:04avarushey qed
03:04qedavarus: any experience with using basic authentication?
03:04qedim trying to get enlive some https://* data to chew on
03:05qedhttp://github.com/technomancy/clojure-http-client/tree/1338ca03f11a9927aa96231ab07e6d344eed92f1
03:05avarusno, sorry, I'm not there yet :)
03:05qedah, bummer
05:15rrc7czis there any fn for converting a LazySeq to an InputStream?
05:23qedHow can I select something like <a name="random text"></a> using enlive?
05:38rrc7czqed: [:a (attr= :name "random text")]
06:08cgrandqed, rrc7cz: [[:a (attr= :name "random text")]] ; [:a (attr= :name "random text")] is a *[name="random text"] not a[name="random text"]
06:10qedcgrand: thanks much
06:10qedcgrand: could i get your advice briefly on scraping a site?
06:10qedhttp://clojure-log.n01se.net/date/2008-02-01.html
06:10opqdonutis (binding [*ns* 'foo] expr) ok?
06:10opqdonutusing in-ns is kinda ugly
06:11opqdonutah, i can use intern
06:11qedcgrand: 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
06:12qedlike [["chouser" "hello world"] ["rhickey" "yes hello hello" "testing 1 2 3"]]
06:14qedalso 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?
06:15cgrandqed: 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
06:16qedah-ha!
06:18qedcgrand: :> solved almost all my issues -- thanks for the great library
06:19cgrandyou're welcome
06:24cgrandqed: I would try (-> "http://clojure-log.n01se.net/date/2008-02-01.html&quot; java.net.URI. html-resource (select [:p :> [any-node (but-node [:a first-child])]])) + filter + partition-by
07:35rhickeydoes clojars offer a web listing of available archives? I only see search
07:36Jomyoothi
07:36Jomyootrhickey: is it possible to have 2 open db connection in contrib.sql?
07:38Jomyootdarn no one here
07:51avarusI am here :)
07:51avarusshould work
07:52avarusjust give it a different name and when you do sql/with-connection db, take the different name
07:52avarusrhickey: apparently there is no "view all" :>
07:52Jomyootavarus: can you elaborate?
07:53avarussure...
07:53avarusa sec
07:53Jomyoot(with-connection db
07:53Jomyoot(with-query-results rs) does not allow specifying connection
07:54JomyootI need to keep db1 and db2 open rather than closing/opening for each statement
07:54Jomyooti was hoping for (with-connection [db1 .. db2 ..]
07:54Jomyootthen (with-query-results rs db1 ...
07:55Jomyootbut with-query-results does not allow specifying connection
07:55avarusJomyoot: http://pastie.org/821665
07:55avarusah, a persistent connection you need
07:56Jomyootright persistent
07:56Jomyootif i am gonna be making 2,000 connections.
07:56Jomyootis closing/opening all the time gonna hurt?
07:57avaruscan'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
07:58Jomyootthere is no way out :(
07:59avarusI'd do a quick benchmark
07:59avarusor test in this case :)
08:00sparievJomyoot: try connection pool, it might help
08:00Jomyoothow?
08:00clojurebotwith style and grace
08:01avarushttp://www.mail-archive.com/clojure@googlegroups.com/msg17782.html <-- looks interesting, Jomyoot
08:01avarusmakes much sense to me..."clojure.contrib.sql can also use a datasource or jndi..."
08:02avarusvoila!
08:03qedwhere is partition-by at?
08:03qedis it in contrib?
08:03AWizzArdseq-utils
08:04qedty
08:05abrenkrhickey: http://clojars.org/repo is browseable
08:05Jomyootit solves my problem actually
08:05Jomyootwow
08:05qedand quite a bit of fun to play with
08:05sparievJomyoot: here's quick example using c3p0 - http://gist.github.com/302538
08:05Jomyooti wish there's more example for using connection pool with clojure
08:05qedi wish there were more examples in general
08:07avarusabrenk: ah, great :)!
08:08rhickeyabrenk: thanks
08:09sparievhow to say to leiningen that i'm currently offline, so it wont try to download stuff ?
08:10JomyootI 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?
08:10sparievthere's no such thing, as far as i know
08:11Jomyootso need to use c3p0?
08:12abrenkspariev: you can do so in ~/.m2/settings.xml
08:12abrenkspariev: <settings><offline>true</offline></settings>
08:13sparievJomyoot: yes, i would recommend c3p0 or apache DBCP
08:13sparievabrenk: oh, thanks. lein honors maven settings, great
08:14Jomyootthank you
08:14Jomyooti felt really excited
08:14Jomyootwow
08:15sparievJomyoot: np
08:15lpetitMigLayout is really cool !
08:15Jomyooti was so close to quitting clojure
08:15qedI 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?
08:16qedim not sure i understand how to properly use partition-by
08:17avarusJomyoot: 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
08:17_fogus_qed: What about split-at?
08:17chouserrhickey: 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?
08:18qed_fogus_: i will try it, thanks for the suggestion
08:18qedoh, _fogus_ -- this will not work because the number of "blah"s after Ghijkl: can be variable
08:19noidi,(apply map vector (partition 2 [:foo 1 :bar 2]))
08:19clojurebot([:foo :bar] [1 2])
08:19qedso it needs to match something like #".*:\s\Z"
08:19qedfor it to split on it
08:19noidiah, that's not what you meant
08:19Leafwabout 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.
08:20rhickeychouser: yes, I was going to try their agile planner this morning - hang on a sec...
08:20qedIt's like ("Foo: " "Some stuff\n" "more stuff\n" "even more stuff\n" "Bar: " "bar's stuff" "bar has more stuff" "Baz: " "...")
08:20chouserrhickey: ok, no rush. other things I should be doing...
08:21rhickeychouser: thanks for the help!
08:22qedyes! fogus and chouser! get thee to a publisher..ey?
08:23chouser,(use '[clojure.contrib.seq :only [partition-by]])
08:23clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath:
08:23chouser,(use '[clojure.contrib.seq-utils :only [partition-by]])
08:23clojurebotnil
08:23chouser,(map (partial apply concat) (partition 2 (partition-by keyword? [:a 1 2 3 4 :b 1 2 :c 5 6])))
08:23clojurebot((:a 1 2 3 4) (:b 1 2) (:c 5 6))
08:24chouserqed: ^^
08:24Jomyootdo you guys code with dark on light and light and dark?
08:24noidichouser, wow :)
08:24ChousukeLeafw: I don't think structural sharing makes sense for deftype
08:24noidichouser, I would've used a messy recursive function... I hope that you cover most of core and contrib in joy of clojure :)
08:24ChousukeLeafw: just copying every field is most likely going to be faster AND more memory efficient unless the deftype has dozens of fields.
08:25LeafwChousuke: 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?
08:25chouserLeafw: structural sharing doesn't really kick in on maps or vectors until you have at least 32 items anyway.
08:25avarusah apropos joy of clojure...still haven't read more than the intro :D
08:26chouserIf your deftype has more than 32 fields, you may need help in other ways.
08:26ChousukeLeafw: if you have so many fields that structural sharing becomes relevant, use a map :)
08:26Leafwchouser: no, I don't want more than 32 fields ... I see. Thanks for the insights.
08:26lpetit,(map (partial apply concat) (partition 2 (partition-by keyword? [:a 1 2 3 4 :b :c 1 2 :c 5 6])))
08:26clojurebot((:a 1 2 3 4) (:b :c 1 2) (:c 5 6))
08:26rhickeychouser: ok, there's a master ticket and several subtickets here: http://www.assembla.com/spaces/tickets/agile_planner/clojure
08:26lpetitchouser : ^^ :-(
08:26chouserlpetit: hmph.
08:27lpetitthere was a thread recently on this in the ml
08:28LeafwI 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)
08:28Leafwwithout the cost of a full clone.
08:28lpetitchouser, qed: search for "clojure kata" in the ml
08:29lpetitqed, chouser: there we are : http://groups.google.com/group/clojure/browse_thread/thread/49bd20eb4bcba20c/3565dbeabaef0748?lnk=gst&amp;q=clojure+kata#3565dbeabaef0748
08:29chouserrhickey: will generic vector replace PersistentVector?
08:30rhickeychouser: that's trickier, due to bootstrapping issues
08:30ChousukeLeafw: you can do that with types, can't you? they *are* persistent.
08:30qedlpetit: MUCH OBLIGED
08:30qedwhoa -- sorry about that
08:30ChousukeLeafw: it's just that for small types, doing a full clone is cheaper than any structural sharing scheme
08:31lpetitqed: np
08:32rhickeychouser: 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
08:33rhickeymuch easier when the only predefined thing you need is a cons cell with car and cdr
08:34LeafwChousuke: 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?
08:55qedhow do you clear a slime repl?
08:55noidiyou can scroll the old messages away by pressin C-l twice
08:56noidior just kill the buffer with C-x k and bring it back with C-c C-z
08:56noidimaybe there's a proper way to clear it but that's what I use :)
09:01oekC-c C-o will clear the output at least on my slime
09:01qedC-c M-o
09:01qedclears all output
09:02oekqed: and that clears everything up ;)
09:03qedoek: it washes the buffer clean
09:03qed"it's like power washing your buffer"
09:04lpetitbon 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 !
09:04lpetitwoops, nevermind
09:05lpetitwas a joke, of course. Wrong channel, BTW
09:05qedNe vous laissez pas tiré, lpetit
09:05lpetit:)
09:05qedlpetit: is that too formal for irc?
09:06lpetitqed: what ?
09:06qedlpetit: is vous too formal?
09:07lpetitqed: not if you don't know the person.
09:07qedlpetit: so you use vous usually on irc?
09:08qedlpetit: i guess im trying to find out where the threshold is for tu :)
09:09qedOn se tutoie?
09:09lpetitqed: do you want to date? (rofl)
09:09qedlol
09:10lpetitseriously, I must leave the channel, cu
09:10avarusif they have sex they still say "vous" :P
09:11qedhaha
09:11qedim just always so foggy on when i can use tu vs vous -- it's a difficult contextual piece of the puzzle
09:11qedi 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.
09:13avaruswe are all friends :P
09:17cgrandqed: on most public forums in french, tu is used so I guess it applies to irc too
09:18qedcgrand: good to know, thanks
09:19cgrandavarus: 50 years ago children were saying "vous" to their parents
09:20avarusglad my parents were/are so much more slack :)
09:21avarusmy dad is like a good friend to me
09:21avarusthat's really great
09:38abrenkHehe. Using 'lazy-cat' while my cat sits on my lap... *g*
09:42qedwhoa -- (ns my.class (:gen-class :implements [clojure.lang.IDeref])) (defn -deref [this] "Testing.. Testing..") @(my.class.)
09:42qedthat's neat
09:47bosiei am new to clojure/FP but isn't this a side effect: http://gist.github.com/302619 (and i am talking about calling testing2)
09:47AWizzArdbosie: yes.
09:48AWizzArdIt is a side effect.
09:48bosieinteresting
09:48qedwhy is it a side effect?
09:48AWizzArdqed: result of calling the function returns nil.
09:49AWizzArdBut when you call it you are interested in its side effect, not in its calculation which results constantly in nil.
09:50bosieAWizzArd: which function returns nil?
09:50AWizzArdokay, it returns "yes"
09:51AWizzArdThe top-level call of println however results in nil.
09:51qedim not sure why it's a side effect
09:51qedit seems the behavior is quite predictable
09:51bosieqed: println is automatically a side effect
09:52qedbosie: i know this, im just not 100% sure why yet :)
09:52AWizzArdA call to println prints something on your monitor
09:52bosieqed: because it has nothing to do with the actual function
09:52bosieqed: you couldn't use the function concurrently
09:53qedah right -- i see
09:54bosieAWizzArd: so i can only be side effect free if every single function is side effect free?
09:54bosieAWizzArd: i have a hard time wrapping my head around that because it sounds great but i can code like that in any language
09:55AWizzArdFP is mostly about state change. Clojure supports you to program with less state changes.
09:55qedbosie: you can be side effect free in particular pieces of an application without being completely side effect free
09:55AWizzArdBecause it does not directly offer you the operator = that you find in Java or C. int x = 8;
09:55dnolenbosie: 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)
09:56qedyou have discretion over where to use side effects
09:56AWizzArdInstead Clojure helps you to calculate new values, and under the hood it reuses your existing ones.
09:57bosiehm
09:57AWizzArdbosie: imagine you have a hashmap H with a million key/value pairs. When you add one element then you modify H.
09:57AWizzArdIn Clojure you can not add an element to H. Instead you "copy" H and add an element to this copy.
09:58AWizzArdUnder 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.
09:58AWizzArdBut 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.
09:59AWizzArdAnd Clojure supports you with concurrency by helping you to make state change safe.
09:59AWizzArdClojure is not about writing programs that can communicate with a user.
09:59AWizzArdcan't
09:59AWizzArdfunny ;)
09:59qedAWizzArd: what does your program see 5 k/v pairs later? 1,000,005 and (+ 1,000,005 1)?
10:00AWizzArdThe idea is not to limit you to simple programs that calculate the faculty
10:00AWizzArdqed: if you continue to add more elements, then you will always have a new map
10:00qedbut are all of those new elements preserved, GC'd?
10:00qedlike n+1, n+1+1, n+1+1+1...
10:01AWizzArdas long anyone is pointing on those the GC won't collect it.
10:01AWizzArdWhen all 5 pointers are gone, then the hashmap will be gone too
10:01qedwhen is it considered safe that someone is no longer pointing at it?
10:01qedwhat about futures?
10:02AWizzArdThe GC does that automatically. Seems to be pretty stable, now, after several hundreds of thousands of man-hours evolution.
10:03AWizzArdOne of the really extremly amazing things in Clojure are its fully persistent data structures.
10:03dnolenwhen there are no more global ||???????????????????????vars or locals referring to it, basic gc stuff.
10:03AWizzArdHickey implemented some very nice magic stuff.
10:03dnolenoops
10:03dnolensorry
10:04bosieAWizzArd: 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:05Apage43master thesis in what?
10:05AWizzArdbosie: if you want to do something non-trivial I can only suggest you to do this with Clojure.
10:05bosieApage43: computer science
10:05Apage43also what awizz said
10:05bosieApage43: or did you mean specifically?
10:06bosieAWizzArd: right
10:06Apage43well.. i don't think it matters as much now that i think of it
10:06Apage43because of what awizz said
10:06bosiefair enough
10:07Apage43if you use something else you'll just be exerting more effort
10:07AWizzArdbosie: 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:07Apage43Definitely especially so if you lean toward the theoretical end of CS
10:07bosiehow do you figure that? it will be text data mining
10:08Apage43bosie: well, how much processing are you doing to it? How complex/advanced are the algos you are applying?
10:10bosieApage43: 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:11bosiesorry if that was a bit too much information
10:12Apage43personally i would say that sounds like something clojure and/or lispy and functional languages in general would do well at.
10:13qedbosie: have you seen ato's wide finder 2?
10:13bosiethat's what i heard. and the processing will be done on an 160 core machine....
10:14Apage43for genetic algorithms particularly you'll wind up with more concise and more easily paralellizable code
10:14bosieqed: not yet
10:14qedbosie: http://meshy.org/2009/12/13/widefinder-2-with-clojure.html
10:14qedim guessing you'll enjoy that :)
10:15bosieqed: thanks. instapaper-ed it ;)
10:15qedbosie: also, if you're not already checking it out: http://planet.clojure.in/ && http://www.disclojure.org/
10:16qedtwo sites you will want to bookmark :)
10:24qedhttp://combinate.us/2010/02/09/pi-in-clojure/
10:43bosiethanks guys
10:43bosiei will go with a real side effects free FP language.... => haskell
10:43bosiekidding
10:46triyoyou mean a calculator
10:56_fogus_Even a calculator has M+ M- and MC
10:57slyphonso, i'm trying to figure out how one could design a callback mechanism using clojure
10:57slyphonhow do you hand a function to another function that can later be called when an event happens?
10:58chouserslyphon: it's the most common thing in the world. you pass functions to map, filter, etc. right?
10:58slyphonsure
10:59slyphonhrm
11:05jcromartieslyphon: forget the map implementation
11:05jcromartieslyphon: this is just a fundamental part of functional languages
11:05jcromartie,(fn [x] (+ 1 x))
11:05clojurebot#<sandbox$eval__7080$fn__7082 sandbox$eval__7080$fn__7082@1695ec4>
11:05jcromartiethat returns the fn itself
11:06slyphonah
11:06slyphonok, that's what i wanted to know
11:06jcromartie,(let [f (fn [x] (+ x 1))] (f 1))
11:06clojurebot2
11:06jcromartieand there is a shorthand too
11:06jcromartie,#(+ % 1)
11:06clojurebot#<sandbox$eval__7093$fn__7095 sandbox$eval__7093$fn__7095@16d9bf>
11:06slyphonohhhh
11:06slyphonok, i got it
11:08slyphonit's been a long time since i lisped
11:33aravinddnolen or cgrand: either of you around?
11:34dnolenaravind: hullo
11:34aravinddnolen: 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:34dnolenaravind: sure.
11:35aravinddnolen: 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:36aravinddnolen: would that be a good use case for that proposed enhancement?
11:37dnolenaravind: The thread is really more about a usability enhancement. Enlive can probably do what you want right now.
11:37aravindoh..
11:38aravindokay, nevermind then.. (back to scratching my head)
11:38dnolenaravind: are you just trying to figure out how to write the template?
11:40aravinddnolen: 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:40dnolenaravind: multiple location in the td?
11:40dnolenlocation -> locations
11:42aravinddnolen: yeah, so each loop of the clone-for would fill in one name:value pair into the table.
11:43cgrandaravind each-loop of the clone for must deal with a row
11:43aravinddnolen: oh.. name would go into the first <td>, value into the next <td> and then a </tr>
11:44cgrand(deftemplate tpl src [data] [:tr] (clone-for [[k v] data] [:td.name] (content k) [:td.value] (content k)))
11:45cgrandthe second (content k) should b (content v) you may need to call str on k or v if they aren't strings
11:46aravindcgrand: thanks!
11:49fdaoudcgrand: thank you for Enlive, it's excellent
12:05chouseris it wrong to want to know from (swap! a f) what value was finally successfully used as the input to f?
12:06chouseror is it mearly wrong to achieve it by use of another (local) atom? :-P
12:06chousermerely
12:07hiredmanaren't atoms synchronous?
12:07chouserthey spin, retrying
12:08arohner(swap! a f) @a is a race
12:08hiredmancan't you just look at a?
12:08chouserI have map in an atom, and I do (swap! a dissoc :foo)
12:08hiredmanarohner: so is @b if f is setting b
12:08chouserthen 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:09arohnerI 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:09arohnerit would be awesome if I could just point it at an existing function
12:09arohner(deftype foo [a b] IFn my-fn)
12:10chouserall implementations? how many do you have?
12:10arohnerrather than (invoke [obj]) (invoke [obj1 obj2]) ...
12:10arohnersorry, all methods on IFn
12:10arohnerand apply
12:14cgrandchouser: you're not alone, I too have already wanted to know the value passed to f.
12:15hiredmanwhat about a watch?
12:15chouserI 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:16chouserhm...
12:16cgrand,(let [a (atom [{} nil])] (swap! a (fn [[m]] [(assoc m :foo :bar) m]))) ;-(
12:16clojurebot[{:foo :bar} {}]
12:16chouserheh
12:19eyerisI 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:19cgrandchouser: but then you have a small memory leak
12:20hiredmanarohner: I don't think (swap! a f) @a is a race
12:20chouserfixed-size leak. which is more of .. a reservoir
12:20chouser?
12:21arohnerhiredman: you're not guaranteeed that @a will have the result of the swap you just did
12:21hiredmanatoms are synchronous, and their retries run on the same thread as the swap
12:21arohneranother thread can swap! between the two calls
12:21hiredmanoh
12:21hiredmanright
12:22cgrandchouser: 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:24arohnereyeris: do you have a paste you can show us?
12:25eyerisarohner: Sure, though you won't be able to run it because the two functions execute against a DB.
12:25eyerisGive me a sec.
12:26chouser(defn swap!-old [a f & args] (let [old (atom nil)] (swap! a #(do (reset! old %) (apply f args)))))
12:26chousercgrand: uglier, but can be used transparently on existing atoms.
12:26chouseroh, whoops
12:27chouser(defn swap!-old [a f & args] (let [old (atom nil)] (swap! a #(do (reset! old %) (apply f % args))) @old))
12:30eyerisarohner: http://pastebin.com/d2270e7bb
12:30cgrandchouser: I agree. Should we start lobbying for another swap! that returns [new-val old-val]?
12:31eyerisarohner: Look at line 31 and down
12:31chousermaybe. I've got another goofy use-case for atoms here ... trying to see if it could use such a swap! as well.
12:32arohnereyeris: is that clojureql?
12:32eyerisarohner: Yes
12:32esjis this perverse: https://gist.github.com/0290eae3912f095e1b77 ?
12:32arohnereyeris: I'm suspicious of the return type of (four-year-consent-data)
12:32arohneris that a sql result set?
12:32eyerisIt's a realized seq of results
12:32stuartsierraesj: not at all
12:33eyerisYou can see it evaluated on line 34
12:33esjstuartsierra: excellent ;)
12:33stuartsierraesj: I used the same technique in a GUI example
12:33esji've been puzzling over different ways of doing this all afternoon
12:33stuartsierraAlthough I did it with agents
12:33arohnereyeris: print the results of (set (four-year-consent-data)). My guess is the two runs will have different values
12:34stuartsierraesj: What exactly are you trying to achieve?
12:34esjjust have a function with side effects running until I tell it to stop
12:34arohnereyeris: oh, nm
12:35esjfrom a possibly different thread to where it was started
12:35eyerisBoth data functions return LazySeqs. The (set)s of those seqs are equal, as evidenced on line 50 of the paste.
12:36stuartsierraesj: Ok, here's how I did it: http://stuartsierra.com/2010/01/08/agents-of-swing
12:37stuartsierraesj: I'm worried that your version spins in an infinite loop even when the gate is "turned off"
12:38esjoh... why ?
12:38stuartsierraBecause spinning in a do-nothing loop wastes processor resources.
12:38stuartsierraI don't understand your example well enough to see if that's what it's doing.
12:38chouserwhere does it spin?
12:38arohnereyeris: did you try (= (set (four-year-consent-data)) (set (four-year-consent-data)))
12:38arohneri.e. both fns are the same type?
12:39stuartsierrachouser, esj: Oh, maybe it doesn't spin.
12:39esjhooray !
12:40eyerisarohner: That is on line 31.
12:40arohnereyeris: that's fycd vs. fycd-new
12:40stuartsierraesj: Yeah, I think this works. Not intuitive to my mind, but that's not saying much.
12:40eyerisOh I see.
12:40arohnerI'm asking about fycd vs. fycd, or fycd-new vs. fycd-new
12:40arohnerjust curious what happens
12:40eyerisYour expr evals to true
12:41eyerisBoth forms of it
12:42esjis there anything to recommend going directly : http://gist.github.com/302787 ?
12:44hiredmanall the second atom setting seems like a use case for watchers
12:46esjyeah. I'm scared of using them until they stop being alpha.
12:46hiredmanthey aren't aplha
12:46hiredmanalpha
12:46arohnereyeris: sorry, I don't know what's going on there
12:46arohnereyeris: and I have to run
12:46eyerisarohner: Thanks for trying.
12:46esjoops, behind the curve, as usual :)
12:46hiredmanthey are "experimental"
12:46eyerisI know I must be missing something simple.
12:47hiredmanesj: I was actually talking to chouser of 20 minutes ago about the atoms
12:48hiredmanugh
12:48hiredmanbusy wait
12:48arohnereyeris: one more idea
12:48arohnertry printing (class fycd) (class fycd-new)
12:48hiredmanuse a BlockingQueue and a watcher
12:49hiredmanthe watcher can (.put bq true) if the atom is set to true
12:49eyerisLazySeq
12:49stuartsierraesj: (defn run-until [r f] (loop [] (when @r (f) (recur))))
12:50eyerisAlthough, (class (first (fycd[-new]))) returns PersistentStructMap versus PersistentArrayMap
12:50esjstuartsierra: yes!
12:51stuartsierraesj: Careful, I'm not 100% sure that's right.
12:53eyerisIs there a way to convert a StructMap to an ArrayMap?
12:53esji'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:53stuartsierra:)
12:54stuartsierraesj: The thing is, run-until will never return until the gate closes.
12:55stuartsierraYou probably would want to start it in a separate thread.
12:55esji don't mind as the side effect is all I'm after
12:55stuartsierraOr use an agent.
12:55esjyeah, I'd future it
12:55stuartsierrathat works too
12:55esjthanks for the help, as ever.
12:55stuartsierrano problem
12:58triyo_fogus_: "Even a calculator has M+ M- and MC" -> Haskell with Monads
12:58arohnereyeris: really, one last idea
12:59arohnereyeris: try printing (.hashCode fycd) (.hashCode fycd-new)
12:59arohnerand a thing I just remembered, in java (int 1) and (long 1) have different hash codes
12:59arohnerso if your DB representation returns a long...
12:59arohnernow I'm really leaving
12:59eyerisarohner: ok
12:59eyerisTHanks
12:59chouserarohner: are you sure?
13:00arohnerchouser: I've been bitten by it several times
13:00chouser,(map hash [(int 1) (long 1) (bigint 1)])
13:00clojurebot(1 1 1)
13:00chouser,(map #(.hashCode %) [(int 1) (long 1) (bigint 1)])
13:00clojurebot(1 1 1)
13:00eyerisThe hash codes of my objects are the same.
13:00chouserthey may not be .equal, however. :-(
13:01chouser,(.equals (int 1) (long 1))
13:01clojurebotfalse
13:01arohnerchouser: ah, that's what it was
13:01Chousukechouser: vectors can't hold primitives. all those get converted to Objects :/
13:01hiredmanugh
13:01chouserChousuke: yes, but Objects of the appropriate type.
13:01hiredmanChousuke: primitives don't have a hashCode anyway
13:01eyerisYou're right, .equals = false
13:01chouser,(map class [(int 1) (long 1) (bigint 1)])
13:01clojurebot(java.lang.Integer java.lang.Long java.math.BigInteger)
13:01hiredmanthat is horrible
13:01arohneryes it is
13:01hiredmanunequal but the same hashCode
13:02hiredmanbad sun, bad!
13:02chouserand because they are not ".equals", they "must not" match when used as keys in a hash-map
13:02chouserhashCodes don't need to be unique
13:02eyerisI 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:03eyerisI just don't know how to turn them both into basic HashMaps
13:03chouser(into {} ...)
13:03chouserbut I doubt that's the problem
13:03hiredman,(= (array-map :a 1 :b 2) (array-map :b 2 :a 1))
13:03clojurebottrue
13:03hiredman,(= (array-map :a 1 :b 2) (array-map :b 2 :a 1 :a 3))
13:03clojurebotfalse
13:04chouserstop that.
13:04chouserif you make broken maps, you get broken results.
13:05cow-orkerAs "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:05hiredmansure
13:05cow-orker*dont* :-)
13:06eyerisYou're right, using (into {} ... does not fix it.
13:06hiredmancow-orker: have you seen ->>
13:07eyerisEven though that does cause them to .equal = true
13:07hiredman,(->> "foo" .getBytes (new String))
13:07clojurebot"foo"
13:07eyerisThis is so darn confusing.
13:08cow-orkersure, but except for "new" I'd like to insert into "first arguement slot"
13:08cow-orkerwhat I wanted was -> that supports new, not ->>
13:08hiredman,(-> "foo" .getBytes (->> (new String)))
13:08clojurebot"foo"
13:08hiredman:D
13:09cow-orkerright, that works :)
13:09chousereyeris: sorry, I haven't been paying attention. I see your paste -- you're expecting line 32 to be true?
13:09eyerisNo, line 3
13:09eyerisOh wait
13:10eyerisHere's a new paste: http://pastebin.com/d5d52a8f0
13:10eyerisThat more clearly explains what I don't understand.
13:10chouserah, ok
13:11chouserso is there any chance that some of those numbers are int and others long?
13:11eyerisThere is. Though the (= (first (fycd)) (second (fycd-new))) evals true
13:12chouseryou can't trust = here -- it's not what value comparison uses in a hash-set
13:12eyerisLikewise for the other combination, (= (second (fycd)) (first (fycd-new)))
13:12eyerisOh.
13:13chousertry .equals instead
13:13eyeris.equals evals false too
13:14chouserok, so that's your problem.
13:14eyerisIt is?
13:15chouseryes. if they're not .equal, they won't match in a hash-set
13:15chouserin 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:15eyerisOh, you meant on the maps. I did it on the sets. Hold on.
13:16chouserah, yes.
13:16eyerisRight, the maps don't .equals to true either.
13:17eyerisThey also don't .equals to true if I convert them both to normal maps using into {}
13:17chouserthe options I can think of are: use sorted-set with your own comparator, or convert all numerics to a consistent type.
13:18eyerisSo 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:18chouserrhickey: are you listening to this? are they any better options?
13:18chousereyeris: no, because the reader reads them all as Integers
13:18eyerisOh
13:19chouserit would have helped you identify the problem much more quickly if longs and ints printed differently.
13:19eyeris:)
13:19eyerisI can easily cast the int to a long.
13:19chouserok. do that. :-)
13:20eyerisThat worked.
13:37ninjuddis there a way to prevent the repl from traversing a specific sequence? perhaps a meta flag on the sequence
13:43chouserthat's an interesting idea. you can tweak the printer by adjusting the print-method multimethod.
13:47ninjuddchouser: ok, so i should just set :type in meta and write my own print-method
13:48chouserninjudd: sure, that'd be one approach
13:52ninjuddchouser: ok, thanks. that works
14:16Drakesonhow would you apply a function to the values of a map?
14:16chouserthis is the new FAQ #1
14:16chouser:-)
14:17chouser,(let [m {:a 1, :b 2, :c 3}] (zipmap (keys m) (map inc (vals m))))
14:17clojurebot{:c 4, :b 3, :a 2}
14:17Drakesonbut, wasn't there a function for this in one of the libs?
14:18hiredman,(use '[clojure.contrib.generic.functor :only (fmap)])
14:18clojurebotnil
14:18hiredman,(fmap inc {:a 1})
14:18clojurebot{:a 2}
14:18hiredman,(fmap inc {:a 1 :b 3 :c 4})
14:18clojurebot{:a 2, :b 4, :c 5}
14:18Drakesonthanks
14:19Drakesonwhy would you put :only there?
14:19Drakesonthere is nothing else in there
14:20chouserit documents where the fn is defined
14:20hiredmanDrakeson: I didn't know that
14:20chouseranyone looking at the log can see where fmap comes from
14:20hiredmanbut yes, :only is nice
14:20bosiewhat's the name of "'"? like (use 'clojure.....)
14:21Drakesonquote
14:21Drakesonchouser: isn't :require even nicer?
14:21hiredman,(macroexpand-1 ''(foo))
14:21clojurebot(quote (foo))
14:21bosieDrakeson: there is no name for that mechanism?
14:21hiredman,(macroexpand-1 (quote 'a))
14:21clojurebot(quote a)
14:21hiredmanbosie: it is called quoting
14:22hiredmanhttp://en.wikipedia.org/wiki/Lisp_%28programming_language%29#Self-evaluating_forms_and_quoting
14:26bosiehiredman: ok now i found it in the docs
14:26bosiethanks
14:28chouserDrakeson: 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:59eyerisIs 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:00chouserjuxt
15:00eyeris,(doc juxt)
15:00clojurebot"([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:00eyerisAh, so it's not in 1.0.0 :)
15:00chouserhm, no probably not. maybe 1.1
15:12cemerickchouser: what page count are you guys aiming for?
15:12chouserofficially 250-300
15:14cemerickchouser: any thought of including something on monads? I'm seeing more and more code in the wild that uses them.
15:15chouserhm. there's nothing in the outline on them yet.
15:15cemerick...which is why I mentioned it :-)
15:15chouserI guess I'd have to be more personally impressed with their usefulness before desiring to include them
15:15cemerickheh
15:16stuartsierraMonads are a solution in search of a problem.
15:16somnium~monad
15:16clojurebotmonad 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:16stuartsierra:)
15:16triyocemerick: any particular advantages of monads over more familiar constructs in clojure, in your opinion perhaps?
15:16cemerickthere's certainly nothing special about them -- closest thing to a pattern one sees in functional programming, perhaps.
15:17chouserI'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:25rhickeyI wouldn't consider monads part of the Art of Clojure
15:25rhickeynor Joy of CLojure
15:26chouserheh
15:27stuartsierraMonads are the Visiting In-Laws of Clojure.
15:27rhickeyplus I wonder how monads will fare in the context of Steele's "foldl considered harmful"
15:27rhickeymonads are inherently non-parallelizable
15:29triyoso whats your thoughts on continuations? just kidding...
15:31vySomebody was asking about how to transform a LazySeq into an OutputStream, any replies?
15:32hiredmanvy: an outputstream is something you write to, and a lazyseq is immutable, I don't see how that is supposed to work
15:32vySorry, I meant an InputStream.
15:32hiredmanyou just need to proxy inputstream
15:32stuartsierraby the way, foldl considered harmful is awesome: http://research.sun.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf [PDF]
15:34cemericktriyo: 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:35hiredmancemerick: are you talking about monads or continuations?
15:35cemerickmonads
15:36stuartsierraIs it intended for datatypes to be read-able?
15:37stuartsierra(read-string (pr-str (MyDatatype 1 2 3))) doesn't work
15:37rhickeystuartsierra: not yet
15:37chouserright, it's not meant to work currently.
15:42stuartsierraok
15:42stuartsierraBut it will eventually?
15:48rhickeystuartsierra: 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:49rhickeyanother is that in order to be able to round trip they'd need to print with a full namespace
15:49stuartsierraYes. I ask because this is a FAQ with StructMaps.
15:50rhickeyI completely understand the desire
15:50stuartsierraRead-able datatypes also opens the door to object literals!
15:51stuartsierra#:java.util.Date{:time 12345678}
15:51rhickeyyikes
15:51stuartsierraHeheh. :)
15:52hiredman,#=(java.util.Date. 1266008070)
15:52clojurebotEvalReader not allowed when *read-eval* is false.
15:52hiredmanbleh
15:52stuartsierraI guess you could write #=(MyDatatype 1 2 3)
15:53rhickeynot without a full ns
15:53stuartsierrayes, of course
15:53cemerickthat's what deflate is for anyway
15:54rhickeycemerick: your repl has deflate? :)
15:55cemerickrhickey: I deflate my code *when I write it* ;-)
15:55stuartsierraBuuuuuuut, 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:55rhickeyso, one question is, is printing readably only when *print-dup* acceptable?
15:55cemerickpreferable, I'd say
15:56stuartsierraI tend to assume that prn is readable, never really understood *print-dup*
15:56hiredmanditto
15:56hiredman,(doc pr)
15:56clojurebot"([] [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:57cemerick*print-dup* provides hooks for making arbitrary objects readable.
15:57cemericke.g.
15:57cemerick,(prn (java.util.ArrayList.))
15:57clojurebot#<ArrayList []>
15:57cemericknot so useful ^^
15:57stuartsierra,(binding [*print-dup* true] (prn (java.util.ArrayList.)))
15:57clojurebot#=(java.util.ArrayList. [])
15:58stuartsierraI'd prefer pr to always print read-ably, use print for human-readable cases.
15:58stuartsierraI think this would be possible with protocols.
15:59cemerickThat would require *print-dup* to be true by default. *bleh*
15:59piccolinoIs this #= new in 1.1?
15:59hiredmannope
15:59stuartsierracemerick: I want to ditch *print-dup* altogether.
16:00piccolinoI can't find anything about it in the reader docs.
16:00cemerickpiccolino: it's very underdocumented, and not particularly an official feature
16:00piccolinoAh.
16:00stuartsierra"very underdocumented" heh :)
16:00chouserintentally underdocumented, no less.
16:01cemerickstuartsierra: right, I mean have the effect of *print-dup* being true
16:01stuartsierrayes
16:01chouserthat's very noisy at the REPL
16:01cemerickI suppose that's fine by me as long as the repls do the right thing.
16:02hiredmanwhat happens if it cannot be printed readably?
16:02stuartsierrahiredman: Exception
16:02chouseryou still get #<> stuff
16:02cemerickstuartsierra: oh, no no
16:02hiredmanstuartsierra: that is a lot of exceptions
16:02LauJensenIs there anything in contrib which converts java.awt.Color to a #hex ?
16:02stuartsierra,(binding [*print-dup* true] (prn clojure.lang.RT))
16:02clojurebot#=clojure.lang.RT
16:02stuartsierraok, that works
16:03chouser,(binding [*print-dup* true] (prn (sorted-map :a 1 :b 2)))
16:03clojurebot#=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})
16:03stuartsierra,(binding [*print-dup* true] (prn *in*))
16:03clojurebotjava.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class clojure.lang.LineNumberingPushbackReader
16:03stuartsierraThat's the exception.
16:03chouseroh! indeed.
16:05chouserstuartsierra: this is for the APress book?
16:05stuartsierrayes
16:06_fogus_stuartsierra: For some reason I thought someone else was writing that
16:06stuartsierraLuke Vanderhart is writing about 2/3 of it.
16:06fdaoudstuartsierra: you are participating?
16:06stuartsierraOriginally I was doing only 2 chapters, but now I'm doing several more.
16:07fdaoudwhere's your name then?
16:07stuartsierraNot on the cover of the current PDF beta; I wasn't in on it yet.
16:07stuartsierraI 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:08stuartsierra_fogus_: Nice. Where's that?
16:09_fogus_DC/Metro area
16:09fdaoudunfortunately 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:09stuartsierra_fogus_: Cool, that's not far from New York, maybe I could come down some time.
16:09stuartsierrafdaoud: I was worried about that for a while, but it seems to be coming together.
16:10fdaoudthey are also a little too keen on 'Definitive Guide' - but, again, no offense to the authors
16:10mattrepl_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_fogus_stuartsierra: ^^
16:10_fogus_mattrepl: I was never able to make any of those unfortunately.
16:11fdaoudstuartsierra: good to hear!
16:12stuartsierraI might be able to come down in March.
16:12stuartsierraI'd like to meet "the other Stuart" too.
16:12_fogus_http://www.meetup.com/Cap-Clug/calendar/
16:12_fogus_Not sure if this is public
16:13fdaoudstuartsierra: what's your home page?
16:13chouserI 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:14stuartsierrafdaoud: you me my personal page? http://stuartsierra.com/
16:16fdaoudstuartsierra: 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:17mattrepl=)
16:17stuartsierra_fogus_: meaning...?
16:17hiredmanwe had a lot of python users at the seattle meetup
16:18_fogus_gotta go
16:24avarusevening!
16:25rhickeystuartsierra: where would Avro schemes go in print/read?
16:26rhickeyschemas
16:26stuartsierrarhickey: They wouldn't, it would be a separate thing.
16:26stuartsierraBut you could generate Avro schemas from datatypes.
16:26stuartsierraTo make a binary serialization format for Clojure.
16:27stuartsierraIf you're into that sort of thing.
16:36tayssirHi! 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:37patrkriswhere does leiningen get clojure-contrib from? which repository?
16:37stuartsierratayssir: printed output is the REPL buffer could confuse paredit
16:38tayssirstuartsierra: ah, i thought it worked once (just reinstalled slime and clojure), but maybe i'm just imagining things...
16:38stuartsierranever tried it myself
16:39tayssiryeah, actually i recalled it was the opposite; before it worked fine in the repl but not so good in the .clj buffer... ;)
17:32piccolinoIs there some way I can make an integer be interpreted as a long (unboxed)?
17:33Chousuke(long whatever)
17:33hiredman,(long (int (double 1)))
17:33clojurebot1
17:33piccolinoThat appears to box it, though.
17:33hiredmanit does not
17:34Chousukepiccolino: what are you passing it to?
17:34piccolino#=(java.util.Date. (long 1))
17:34hiredman,expression-info
17:34clojurebotjava.lang.Exception: Unable to resolve symbol: expression-info in this context
17:34piccolinoDoesn't work.
17:34Chousukepiccolino: that should work
17:35piccolinoIt says No matching ctor found for class java.util.Date.
17:35Chousuke,(java.util.Date. (long 1))
17:35clojurebot#<Date Wed Dec 31 16:00:00 PST 1969>
17:35piccolinoWhoa.
17:35hiredman,(java.util.Date. 1266014261)
17:35clojurebotjava.lang.IllegalArgumentException: No matching ctor found for class java.util.Date
17:35hiredman,(java.util.Date. (long 1266014261))
17:35clojurebot#<Date Thu Jan 15 07:40:14 PST 1970>
17:35hiredmanpiccolino: I think (long 1) is not evaluated in #=
17:35piccolinoI see.
17:37hiredman,(type 1266014261L)
17:37clojurebotInvalid number: 1266014261L
17:37hiredmanbah
17:42dnolenanybody been playing around with vector-of?
17:51chouseronly barely
17:55dnolenchouser: it's not supposed to be faster than regular vectors yet right?
17:57chousernot particularly. still has to box/unbox things
18:03dnolenchouser: I see.
18:04arohnerchouser: does that require more clojure work, or a new JVM?
18:04arohnerchouser: and vector-of has lower memory usage right now, right?
18:05rhickeyvector-of is often faster
18:05chouserI 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:06hiredmanchouser: map and reduce will need to be IMap and IReduce'ized
18:06slyphonwhat's '->' ?
18:06hiredmana macro
18:07slyphonok
18:07chouseroh that's right -- maybe with escape analysis and IReduce you can get unboxed speed for some things without primitive fn args
18:07chouseryou'd think I would be able to remember that from ... yesterday.
18:09hiredmanI don't think IReduce would need escape analysis
18:09hiredmanas long as the Fn supported taking primitives and that was discoverable
18:09chouseryou still pass in a clojure fn, right? and it has an invoke(Object, Object) method that returns an Object.
18:10rhickeythe tricky part is the return values
18:10hiredmanchouser: there could be an interface IDoubleFn
18:10rhickeyfns would have invoke(long) as well
18:11chouserI 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:11dnolenrhickey: 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:12slyphonthere was some toss-away line in the pragmatic-programmer clojure book, mentioning that you should always do (clojure.core/use 'clojure.core)
18:12hiredmanmap would call seq anyway
18:12chouserheh. a little like perl contexts. call the fn in an long context ...
18:12slyphonwhen moving to a new namespace
18:12rhickeydnolen: are you running lots of iterations? warmed-up jvm, -server etc?
18:12hiredmanslyphon: only if using in-ns
18:12slyphonoh, mm'kay
18:13hiredmanslyphon: the ns macro takes care of it for you
18:13slyphonah, allright
18:13hiredmanthere is also a short cut called refer-clojure
18:13dnolenrhickey: I am, lots of iterations, warmed up jvm.
18:13hiredman,(doc refer-clojure)
18:13clojurebot"([& filters]); Same as (refer 'clojure.core <filters>)"
18:13slyphonrhickey: btw, kudos!
18:13slyphona lisp that doesn't smell like old jazzmen
18:13rhickeyslyphon: on what?
18:14rhickeyah
18:14slyphonindeed
18:14chouserinstead, one that smells like fresh jasmine!
18:14rhickeygroan
18:14slyphonLive at Birdland, still my favorite
18:17dnolenrhickey: my unscientific numbers http://paste.lisp.org/display/94878
18:19chouserthere! Just finished all the unsupported j.u.Collection methods for vector-of
18:19rhickeychouser: whoa - awesome!
18:20chouserthe unsupported ones, not the ones that need code.
18:20rhickeyah
18:20chouser:-)
18:20chousersorry
18:20rhickeystill useful, thanks!
18:21chouserI should still use (Util/equiv ...) for item equality?
18:21rhickeydnolen: you should put each of those (time ...) in a (dotimes [_ 10] ...)
18:21chouseror just =
18:22rhickey=
18:22rhickeybut only when you mean equiv. When implementing j.u.Collection semantics you often need .equals
18:22rhickeysee the existing impls
18:23chousercontains currently uses equiv. I'll pay attention.
18:24rhickeyI'll not contend it's all perfect, but esp critical when defining equality so it's symmetric
18:26rhickeyanother 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:28dnolenrhickey: 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:29chouserbah. toArray returns Object[]
18:30rhickeydnolen: really, those benchmarks aren't very useful. You'd need to wrap everything in functions that were run many times etc.
18:30rhickeyalso many outlier times include a gc.
18:31rhickeyin a larger app, those gcs might be mich faster as there wouldn't be toms of tenured boxed numbers
18:31rhickeymuch, tons
18:31rhickeyin any case, not promising more than parity at present
18:32dnolenrhickey: good to hear that it's my naive understand on of the JVM at work again :) so will generic vectors support transient?
18:32dnolen understand -> understanding
18:32rhickeydnolen: yes, but transients are going to move into symbiosis with what I've been calling 'cells'
18:33LauJensenI'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:34dnolenrhickey: 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:35rhickeydnolen: that's one goal, another is parallel ops
18:35dnolenI loathe resorting to make-array
18:35dnolenrhickey: fantastic.
18:38rhickeythe Iterator interface dictates mutability
18:38chouseryes.
18:38rhickeybut yeah, that
18:38chouseris an atom ok here?
18:39rhickeyI encountered in Vec also, for hash caching
18:40rhickeychouser: maybe AtomicInteger
18:40chouserok
18:40rhickeyIf we never want to write Java, will need some story for these
18:42chouserhuh, look at that. The "favicon" on the java docs is a java cup now instead of a sun logo.
18:42rhickeysince second object overhead often unacceptable
18:53chouserok, now Collection is done.
19:15arohnerhow evil is this? http://gist.github.com/303136
19:30slyphonwhat's the significance of the '&' in a defn arg-list?
19:32arohnerslyphon: it means the fn can take extra args
19:32slyphonah
19:33arohnerthe variable after the & takes all of the "leftover" args, in a seq
19:33slyphonah
19:33slyphonso it's the varargs collector
19:33arohneryeah
19:33slyphonok
19:33slyphonty
20:33danlarkinTha'sa me!
21:30qedAnyone 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:31qedI thought it was basic auth, but that doesn't appear to be the case...
21:36dnolenqed: you should probably look into a Java lib, looking on StackOverflow seem to suggest using Apache HTTP components.
22:04qedmy paredit-mode is horribly horribly broken
22:10slyphonso, a proxy is essentially a way of subclassing a Java class?
22:10slyphon(one purpose of a proxy)
22:12chouseryes
22:13slyphoni'm trying to wrap PircBot, and i'm having trouble figuring out how to actually accomplish the task
22:13slyphoni did this in scala, but that's a different beast altogether
22:15qedanyone here know how to fix {} in paredit-mode?
22:21qedaghhh! paredit-mode, why have you failed me? Why dost thou curly braces fail to work?
22:29_mstI use: http://paste.lisp.org/display/94892
22:35RaynesOh 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:36JonSmithwho is steve dekorte?
22:36RaynesJonSmith: Lead developer of Io.
22:36JonSmithooh
22:36JonSmiththat is kind of a neat language
22:36qedIo is neat
22:37RaynesIt'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:37RaynesAnd even then, I'm not sure it's documented.
22:37qedIo was always a toy to me
22:37JonSmithoh
22:37qedwas he trying to make it a serious production language?
22:37RaynesIt could be more than a toy, but obviously they don't care enough to make it one.
22:38JonSmithwell not every language is meant to be deployed everywhere
22:38Raynesqed: There has been lots of talk about Io finding a niche.
22:38qedi learned a little bit about it when i was on a Ruby kick
22:38qedRaynes: I don't really see one beyond "fun to play with and learn about for a weekend" :X
22:38RaynesJonSmith: Io is supposed to be a general purpose programming language, and isn't just meant for embedding.
22:38qedwhy wouldnt you just use Ruby/JRuby?
22:39qed_mst: paredit-open-brace and close-brace are void function definitions
22:40JonSmithoz looks like a neat language too
22:40RaynesOla 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_mstqed: hmm... my paredit.el has: (define-paredit-pair ?\{ ?\} "brace")
22:41_mstI wonder if I hacked that in :)
22:41qed_mst: i needed paredit-open-curly
22:41qed /close-curly
22:41_mstah, right. Maybe version differences or something
22:45qedhere's a question...
22:45qedlet's say I type a [, paredit-mode gives me [|] function arg1
22:46qedi then type C-) to slurp function, then arg1
22:46qedi find it rather annoying that the result of this is [|function arg1]
22:47qedgranted 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:47somniumanyone seen coffeescript on github?
22:47somniumlanguage 'refurbishing' is an interesting approach
22:49JonSmithyeah is pretty clever technique
22:52qedsomnium: i havent seen it, got a link?
22:52somniumhttp://jashkenas.github.com/coffee-script/
22:57somniumcould 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:57JonSmithscriptjure is kind of like that
22:57JonSmithexcept it is more literally javascript with lisp syntax
22:57somniumscriptjure doesnt add any semantics does it?
22:58JonSmithi bet you could write some good scriptjure macros to add semantics
22:58JonSmithnope
22:58JonSmithi had to hack in aget myself :-P
22:58JonSmithi should upstream that
23:00somniumI wrote something in that vein, though its a bit overly complicated at this point
23:01somniumhttp://github.com/somnium/scryptica
23:01somniumit has TCO and varargs and other stuff, though its still rather quirky atm :/
23:02JonSmithyeah that is a similar vein
23:02qedthat is really cool stuff
23:02JonSmithhttp://github.com/arohner/scriptjure
23:02JonSmithyou got tco in there?
23:02JonSmithnice
23:02qedi really like the idea of cleaning up an old language and making it usable
23:02somniumand proper let scoping
23:03somniumthough sadly it doesnt solve the for-loop problem
23:03qedwhat's it called when you write a new syntax for expressing an existing language?
23:03JonSmithwhat is the for-loop problem?
23:04somniumif you create closures in a for loop, only the final value gets bound in all closures
23:04JonSmithooh
23:04somniumhave to double wrap, if ecmascript ever actually adds let to the language it will go away
23:04JonSmithyeah that is a problem
23:04somniumpita though
23:06slyphonis there a pub/sub framework in contrib?
23:07slyphoner "feeling"
23:07JonSmithin what way pub sub?
23:08slyphoncallbacks, like "when this event occurs, call these functions"
23:08slyphoni'm reading about agents and the concurrency features, i'm just not really sure how to piece it together yet
23:09JonSmithoh
23:11slyphoni'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:14chouseragents may or may not do what you want there.
23:15slyphonyeah, i'm not really sure, it *kinda* seems like it does what i want it to do
23:15chouserit's perfectly acceptible to use workflow management classes from java.util.concurrent
23:15slyphonhrm
23:15JonSmithyeah
23:15slyphonthat's a good idea
23:15JonSmithanother nice thing i've been playing with is the erlang java library
23:16JonSmithyou can do send/receive and stuff
23:16slyphonah
23:16JonSmithi have my clojure sending/receiving with yaws
23:16JonSmithit is hilarious
23:16slyphonyaws?
23:16JonSmithya
23:16JonSmitherlang web server?
23:17slyphonhttp://en.wikipedia.org/wiki/Yaws
23:17slyphonsounds painful
23:17JonSmithwas kind of a fun weekend project
23:17qedI 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:17qedI googled but couldn't find anything
23:18slyphonwell
23:18slyphonyou could use apache-httpclient
23:18JonSmithclojure starts, spawns yaws as a sub-process, configures itself as an app mod and then spawns threads from a threadpool for requests
23:18slyphonwhich is quite complete
23:18qedslyphon: is that a clojure library?
23:18slyphonqed: uh, no?
23:18JonSmithapache-http is good
23:18JonSmiththere is a clj-apache-http
23:18slyphonoh word?
23:18slyphonnice
23:19JonSmithhttp://github.com/rnewman/clj-apache-http
23:19slyphonJonSmith: wow, that's...pretty crazy
23:19slyphon:)
23:19JonSmithyeah seriously
23:19slyphonapache-http is cool, but it's like they took *every single word* in RFC 2616 and made it a class
23:19JonSmithi should polish it up and post it to github or something
23:20JonSmithyeah which is why you wrap it in macros endlessly
23:20qedthanks for the suggestion -- ill try it out
23:22slyphonit 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:25qedweird. 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:29somniumwow, Lau's latest blog post is truly truly awesome
23:30slyphonqed: stop using emacs?
23:30slyphoni keed! i keed!
23:32somniumhttp://www.bestinclass.dk/index.php/2010/02/my-tribute-to-steve-ballmer/
23:36JonSmithyeah that was pretty hilarious
23:37slyphonwow, macroexpand ftw
23:37technomancyslyphon: wow, long time no see.
23:37slyphontechnomancy: oh hai!
23:38slyphonhow goes?
23:38technomancynot too shabbily.
23:38slyphon:)
23:38technomancyhaven't seen you in what... four years? five?
23:38slyphonsomething like that
23:38slyphonyou used to hang out in #twisted, right?
23:39technomancy#ruby-lang, actually
23:39slyphonoh, right right
23:39technomancyaround 05-06
23:39technomancy"before it was cool"
23:39slyphonyeah, that's right when i made the jump
23:39slyphonhahahaha
23:39slyphonyeah, before all the railtards came in and ruined it
23:40technomancyhow's clojure treating you?
23:40slyphonpretty good
23:41slyphoni spent some time long ago getting insulted by the #cl guys, so i have some grounding in lisp
23:41technomancybattle scars, I see
23:41slyphon:)
23:41slyphonand 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:42slyphonhow about you?
23:51technomancyI'm working on leiningen, my build tool
23:51technomancyhope to get a release out soon
23:51slyphonoh nice
23:52slyphonohhhh
23:52slyphonnice, i saw this
23:52slyphoni remember the tagline :D
23:52Drakesonhow would you turn a map a url? {:a 10, :b 20, :c "xx yy"} -> a=10&b=20&c=xx+yy
23:53hiredmanreduce is the easiest way
23:53technomancyDrakeson: (str-join "&" (map (partial str-join "=") my-map))
23:53technomancystr-join coming from clojure.contrib.str-utils
23:53technomancyor c.c.string if you're following git master
23:53hiredmantechnomancy: keywords
23:53technomancyoh bugger, good point
23:54technomancyplus you'd need to URL-encode each value
23:54technomancywell I never pass up a good opportunity to use reduce
23:54hiredmanreduce it is!
23:54hiredmanreduce and format and URLEncoder/encode
23:55hiredmanand name
23:55DrakesonI see, thanks. Although I was hoping for one that is already made, instead of my possibly buggy version :p
23:56technomancyI'd be surprised if there wasn't something in compojure, but I've only played with it briefly
23:57Drakesongood point, I was sifting through clojure-contrib