#clojure log - Jun 06 2010

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

0:39 technomancy: ,(apply (fn [& args] (meta args)) (with-meta [1 2 3] {:hello :world})) ; <= there's no way to make this work, is there?

0:39 clojurebot: nil

0:39 technomancy: metadata doesn't seem to survive apply/varargs restructuring

0:39 you'd have to be a little bit crazy to expect that it would, I suppose

0:42 Chousuke: maybe with :as somehow?

1:22 * technomancy is toying with the idea of generalizing clojure.test's fixtures

2:03 defn: technomancy: like what?

2:03 Also, does anyone know when 1.2 is expected to be released?

2:23 replaca: defn: when it's ready... Rich hasn't committed to a date, but he's trying to get a first beta out in the next few weeks, I think. Then he'll see how stable it seems for folks before going to RC and then Release

2:24 it feels to me like we're on track to release late July or August, but that's completely my read of what's going on and not an official position at all

2:25 defn: replaca: ya, im not anxious about it per se, to be honest there's a lot of stuff in there that I still have yet to use :X

2:26 replaca: at the same time I'm finding it rather annoying that a large swath of libraries have not been refactored for 1.2.0, or do not have 1.2.0 releases

2:26 replaca: ,(apply (fn [& args] (meta args)) (with-meta [1 2 3] {:hello :world})) ; <= there's no way to make this work, is there?

2:26 clojurebot: nil

2:26 defn: half of them have...have of them haven't

2:27 replaca: ermm, im not sure what you want to do...

2:27 what do you expect it to returbn

2:27 return*

2:27 replaca: i'm playing with what technomancy was doing before

2:27 ,(apply (fn [& args] (meta first args)) (with-meta [1 2 3] {:hello :world})) ; <= there's no way to make this work, is there?

2:27 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$meta

2:27 replaca: arg, no paredit in irc

2:27 defn: :)

2:28 replaca: ,(apply (fn [& args] (meta (first args))) (with-meta [1 2 3] {:hello :world})) ; <= there's no way to make this work, is there?

2:28 clojurebot: nil

2:28 replaca: oh, I see what he was thinking now

2:28 that's crazy!

2:28 * defn is confused

2:28 defn: please explain

2:29 replaca: technomancy posted the original thing to try to make metadata pass through apply, but I was confused about what he meant

2:29 defn: and i stil am :)

2:29 replaca: but he meant adding metadata to the *whole* arg vector

2:30 and grabbing it in the func that was applied

2:30 but that can't happen

2:30 defn: could you illustrate a real world example?

2:30 replaca: no, cause it was his thing

2:30 i was just trying to figure out what he was trying to accomplish

2:31 but *why* you'd want to do that is another thing altogether :-)

2:31 defn: lol okay just trying to imagine but yeah, i got nothin

2:32 replaca: defn: I know what you mean about being in a no man's land between 1.1 and 1.2. I'm suffereng from that too

2:36 quizme: how do you make an event loop?

2:36 like to make a real time system

2:36 without eating up all the CPU

2:37 defn: replaca: yeah, isn't it a bummer? I like to just peruse disclojure, grab some random new library, plug it into an existing project, try it, play with it, maybe keep it, maybe not -- but half the time my project is 1.1 and the lib is 1.2 or vice versa

2:38 * defn needs some automatic "refactor for 1.1" or "refactor for 1.2"

2:38 defn: in most cases it's just a matter of changing a bunch of clojure.contrib names, it might not work all the time, but i bet it'd work at least 40% of the time

2:39 replaca: this release is a much bigger thing than we've tackled before with a much higher standard of correctness

2:39 so it's taking longer to bake

2:39 defn: it's awfully hard to be angry about that

2:39 i really would like to contribute to clojure, but my clj-fu is so weak compared to the geniuses working on it

2:39 replaca: in particular, there's a *lot* more community discussion and involvement

2:40 defn: i feel like id just get in the way or make more work for other people

2:40 replaca: 1.1 was just rich with help from chouser

2:41 defn: yeah, i guess i am just seeing all of the contrib stuff funnel through

2:41 replaca: for 1.2, stu holloway is organizing everything, but I'd bet that there are contributions at some level from between 25 and 30 people and major contributions from ~10 poeple

2:41 defn: i gotta say i always love stuart H's views on clojure stuff

2:41 naming, etc.

2:41 really love his approach

2:42 replaca: well, that's part of it. but all of that is being sifted through very carefully to see what we want to live with

2:42 yes, we're lucky to have people with very good taste around (probably attracted by the fact that Rich has such good taste)

2:43 defn: im sort of a "taste" guy myself -- there has to be some damn flavor or i'm bored

2:44 replaca: Chouser and Stu leap quickly to mind, but it includes many others. For example I continue to be impressed by the group here in the bay area

2:44 KirinDave: replaca: How did the meetup go?

2:45 replaca: KirinDave: well. it was a good group - always a little uneven because we welcome folks with vastly different levels of experience

2:45 KirinDave: Huh.

2:46 replaca: in the past, we had done almost totally presos but this time I tried to have a collaborative session

2:46 KirinDave: Hum

2:46 replaca: When is the next one?

2:46 I will try and make time to come.

2:46 replaca: well, some folks have done a ton of Clojure and some folks are just interested

2:46 KirinDave: That's sort of the lisp divide, I guess.

2:46 replaca: they're about every month - 1 mo in SF, the next in Mt. View

2:47 so the next one in SF should be in august

2:47 Amit Rathore figures out the dates

2:47 KirinDave: replaca: Have you thought of splitting to a hackfest and a preso?

2:47 replaca: I was just thinking about that today actually

2:48 what occured to me was lead off with a preso on something interesting to all then split into to groups, one hacking, one covering an introductory topic

2:48 *to => two

2:48 tomoj: hopefully I will be in SF in a year or so /me hopes vigorously

2:49 replaca: tomoj: where are you now?

2:49 tomoj: austin

2:49 defn: replaca: where was the meetup?

2:49 replaca: there are worse places :-)

2:49 tomoj: certainly

2:49 3 people here interested at meetup.com

2:49 defn: i started a meetup group in Madison, WI -- already have a few people

2:49 KirinDave: replaca: You know what would be pretty amazing as a way to do a hackfest?

2:49 replaca: at Weatherbill in SoMa

2:49 KirinDave: shoot

2:49 KirinDave: replaca: Oh man, this'd be a hackfest just to make an awesome tool for a collab hackfest.

2:49 replaca: Have a remote jvm that opens up repls on demand.

2:50 replaca: And then a visualization that can run locally on your machine showing what's changing in that vm

2:50 And everyone could build a short term project onto the vm in situ.

2:50 replaca: KirinDave: that's pretty serious for a hackfest :-)

2:50 defn: i want a collaborative real time hacking tool -- a remote pairing tool

2:50 tomoj: screen? :P

2:50 KirinDave: replaca: It might take a few meetings to get the actual tool done

2:50 defn: tomoj: more features please

2:50 KirinDave: replaca: But you have to admit that'd be a cool thing.

2:51 replaca: defn: the sonian guys live in screen/emacs and they've been doing similar stuff at Seajure

2:51 KirinDave: indeed I do

2:51 defn: tomoj: built in video conferencing, no need to use the same editor, users can choose whether they want vim or emacs bindings, etc.

2:51 tomoj: hmm

2:51 have to virtualize the files I guess?

2:52 or use something like obby maybe which can be supported by different editors

2:52 replaca: defn: that's tough, cause if you want emacs, you don't want just the bindings

2:52 defn: replaca: yeah i know, it's sort of a weird idea i guess, i just always picture github, but with a more direct community involvement in code

2:52 tomoj: presumably this thing is not an editor, but something you hook your editor to

2:53 defn: instead of checking out, submitting the pull request and such, you edit the project there, online, in real time, with other people

2:53 take some of the barriers to contribution away, make it more social

2:53 replaca: tomoj, defn: yeah, that would be cool. I've never seen anything like it

2:54 tomoj: I guess it's kinda like wave but focused on code?

2:54 defn: ive seen collaborative editing tools, but not one that leveraged git and sort of built it into the whole distributed project thingamajig

2:54 tomoj: yeah, only i see needing some backend hooks for git

2:55 replaca: it doesn't seem too hard in principle, but in practice there are a ton of details to get it to work with legacy editor

2:55 (and despite what technomancy thinks, emacs is a legacy editor :-))

2:55 defn: :D

2:55 * defn is a filthy emacs user due to technomancy

2:56 replaca: I think I might have been using it before he was born, but I know legacy when I see it :-)

2:56 defn: actually i sort of fell into clojure because i wanted to learn emacs, and then i wanted to learn lisp as a result, and then i wanted a lisp which i could actually /use/, and here we are

2:56 anyways, back to the idea, if you dont mind chatting about it im trying to flesh a couple details out

2:56 replaca: KirinDave: I saw you tweet that you were having some success using wave for collaboration. What sort of stuff are you doing with it?

2:57 defn: np

2:57 hiredman: screen works very well

2:57 replaca: hiredman: I've been doing the conversion to tmux

2:57 KirinDave: defn: Common lisp is pretty usable.

2:58 hiredman: some of the guys are using tmux

2:58 I've been using screen for a long time

2:58 tmux has some different behaviour for sharing screens

2:59 with screen the window you are looking at is independent, with tmux so far it seems like you get yanked around and everyone in a session always sees the same window

2:59 I've seen some weird kind of hangs here and there, dunno what causes them

2:59 tmux may be nicer for single purpose use, but I think screen is nicer for multiuser stuff

3:00 (but easier to just use one for both)

3:01 defn: I imagine this being the story: User A goes to website (think github in its current incarnation). User A goes to project such-and-such. User B is already on project such-and-such doing some hacking. User A "snoops" in on User B actively editing files. User A watches for awhile, sees User B write some ugly function. User A rewrites the function while User B moves on to other matters. User A and B are not the project owner so they automatically are ...

3:01 ... forced into working on a branch which is magically created for each editing session. When a session is ended by all participants explicitly clicking "end session", the session is ended. Or, when all users leave the session (timeout, etc.), the session is ended. Project Owner can then browse these branches in their browser and merge changes.

3:01 tomoj: defn: seen this? http://github.com/technomancy/conspire

3:01 defn: Yeah I have, conspire is very dated now. Rudel was the successor

3:02 tomoj: oh, does rudel use git too?

3:02 defn: I've used Rudel but it is rather buggy and still forces using Emacs which I think presents a large barrier for collaborative editing. Users should be able to have a "good enough" editor in their browser to socially code. The editor in the browser could allow plugins to be written for it.

3:02 replaca: hiredman: yeah, I mostly colloborate with myself with tmux (that is, I just use it so I can be attached from home, work and the various cafes in North Beach)

3:02 tomoj: just obby I guess

3:02 defn: tomoj: yeah, no git

3:02 tomoj: rudel shouldn't force emacs ideally

3:03 defn: agreed. I think that's the author's plan. I spoke to him awhile ago.

3:03 tomoj: e.g. at http://www.emacswiki.org/emacs/Rudel you see emacs + gobby

3:03 defn: He was planning on implementing it in all sorts of ways.

3:03 make it very editor agnostic, etc.

3:03 tomoj: it already is, isn't it? just support obby and your editor is good to go, no?

3:04 defn: tbqh I don't really know

3:05 replaca: ok, time for me to go to bed. g'night all.

3:05 defn: g'night replaca -- good talkin to you

3:05 replaca: u too

4:21 Licenser: Raynes: to the defense of my defense, I didn't know the difference between cdr and second since I did not know what cdr is at all :P

4:25 defn: is cdr like rest?

4:25 where second is (first (rest coll))

4:25 $(rest [1 2 3 4])

4:25 sexpbot: => (2 3 4)

4:26 defn: $(first (rest [1 2 3 4]))

4:26 sexpbot: => 2

4:26 defn: $(cons [1] [2])

4:26 sexpbot: => ([1] 2)

4:26 defn: $(cons 1 2)

4:26 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

4:27 defn: $(cons [1 2] [3 4])

4:27 sexpbot: => ([1 2] 3 4)

4:27 defn: $(cons [1 2] 3)

4:27 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

4:27 defn: $(cons 0 [1 2])

4:27 sexpbot: => (0 1 2)

4:27 defn: $(first (cons 0 [1 2]))

4:27 sexpbot: => 0

4:27 defn: $(rest (cons 0 [1 2]))

4:27 sexpbot: => (1 2)

4:28 defn: $(first (rest (cons 0 [1 2])))

4:28 sexpbot: => 1

4:28 defn: $(second (cons 0 [1 2]))

4:28 sexpbot: => 1

4:28 defn: i think that's right...right?

4:28 oh god -- didn't know I was in #clojure, thought I was in #clojure-casual, sorry for the spam all

4:29 tomoj: I don't think you can easily compare cdr to something in clojure

4:30 (cdr '(1 2 3)) is '(2 3), so sorta like rest

4:30 but (cdr (cons 1 2)) is 2, which doesn't make any sense in clojure

4:31 on lists, anyway, it's like rest

4:42 defn: does cons behave differently in clojure?

4:43 in lisp could you (cons 1 '(1 2 3))

4:44 tomoj: yeah

4:45 but cons in lisp returns a tuple, really

4:45 and a list is just a tuple where the second element is another list

4:45 defn: wait wait... so in '(1 2 3), 2 is a list?

4:45 tomoj: not really much different from first/rest I guess, but you can stick anything in the second element in CL

4:47 no, '(1 2 3) is an abbreviation for '(1 . (2 . (3 . nil)))

4:47 i.e. (cons 1 (cons 2 (cons 3 nil)))

4:47 defn: ohhhh! ah-ha

4:47 is that what happens in clojure also?

4:47 or is the sequence abstraction what makes the diff.?

4:47 tomoj: it's pretty similar to clojure's first/rest, I guess

4:47 * defn goes to read first and rest in clojure.core

4:47 tomoj: but (cons 1 2) won't work

4:48 in lisp you can build whatever kinds of crazy things you want out of cons cells

4:48 in clojure we have nice abstractions :)

4:48 defn: yeah ive seen crazy mixtures of cons and such in lisp

4:48 always scared the **** out of me

4:48 gregh: everything is a tree!

4:48 defn: is this IRC channel a tree?

4:49 gregh: yes. mutable, too.

4:49 defn: i can't change this statement.

4:55 tomoj: the channel is an identity, not a value

5:52 defn: im not clear on identity still...

6:17 tomoj: very difficult to get clear on identity outside programming languages :)

6:17 (er, outside programming languages and other formal or nearly formal contexts..)

6:36 defn: tomoj: could you try to give me some idea

6:37 i've watched rich, and im 100% on state and time, but identity has me a bit confused, or...well...maybe not

6:37 esj: i like the idea of people as identity

6:37 Borkdude: What would be the most idiomatic way to keep a number in a function that remembers the amount of time it has been called?

6:37 defn: "no man can cross the same river twice"

6:37 esj: "Rich" is an identity

6:37 defn: Borkdude: don't do that!

6:38 Borkdude: metadata

6:38 Borkdude: sorry I thought you were saying you were going to keep track of "time" in your function

6:39 Borkdude: let me put it another way. I want to construct a finite lazy-seq of elements with a fn that knows when to stop

6:40 How would I do that?

6:41 defn: like based on a predicate or something?

6:41 im not sure i follow

6:42 ,(class (lazy-seq (into [] (repeatedly (fn [] (rand-int 10))))))

6:42 clojurebot: clojure.lang.LazySeq

6:43 defn: ,(lazy-seq (into [] (repeatedly (fn [] (rand-int 10)))))

6:43 clojurebot: Execution Timed Out

6:43 defn: err duh

6:43 ,(lazy-seq (into [] (repeatedly 10 (fn [] (rand-int 10)))))

6:43 clojurebot: (6 1 0 6 2 9 5 6 2 9)

6:43 defn: ,(class (lazy-seq (into [] (repeatedly 10 (fn [] (rand-int 10))))))

6:43 clojurebot: clojure.lang.LazySeq

6:43 Borkdude: hmm, let me go back one step more

6:44 I want to construct an example of a lazy-seq with the last element causing a side effect, like printing "boom!"

6:44 and the difference with and without doall

6:46 defn: ohhhhhhh

6:46 oh man -- i remember a discussion about this...

6:46 * defn searches through logs

6:48 Borkdude: maybe I can just do (lazy-cat (repeat 100 :foo) (fn [] (print "boom!")))

6:51 (let [l (lazy-cat (repeat 100 :foo) (print

6:51 "boom!"))] (take 10 l))

6:53 defn: lazy-cat is deprecated

6:54 err sorry i was thinking lazy-cons

6:54 ,(lazy-cat (repeat 10 :foo) (fn [] (print "boom!")))

6:54 clojurebot: Don't know how to create ISeq from: sandbox$eval__8883$fn__8886$fn__8887

6:55 defn: ,(lazy-cat (repeat 10 :foo) [(fn [] (print "boom!"))])

6:55 clojurebot: (:foo :foo :foo :foo :foo :foo :foo :foo :foo :foo #<sandbox$eval__8891$fn__8894$fn__8895 sandbox$eval__8891$fn__8894$fn__8895@145974f>)

6:55 tomoj: defn: have you read http://clojure.org/state ?

6:55 defn: ,(lazy-cat (repeat 10 :foo) ["boom!"])

6:55 clojurebot: (:foo :foo :foo :foo :foo :foo :foo :foo :foo :foo "boom!")

6:55 defn: tomoj: I have yeah

6:56 tomoj: well, "a stable logical entity associated with a series of different values over time"

6:56 defn: I think I understand the whole thing but haven't externalized it

6:56 tomoj: ah, yeah

6:57 ,((fn countdown [n] (lazy-seq (if (pos? n) (cons n (countdown (dec n))) (println "BOOM!")))) 10)

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

6:57 tomoj: where's the boom? :(

6:58 defn: can't println it i dont think

6:58 tomoj: $((fn countdown [n] (lazy-seq (if (pos? n) (cons n (countdown (dec n))) (println "BOOM!")))) 10)

6:58 sexpbot: => BOOM! (10 9 8 7 6 5 4 3 2 1)

6:58 defn: oh, there ya go

6:58 nice

6:58 tomoj: $(take 5 ((fn countdown [n] (lazy-seq (if (pos? n) (cons n (countdown (dec n))) (println "BOOM!")))) 10))

6:58 sexpbot: => (10 9 8 7 6)

7:00 defn: ,(let [[a b] (repeat 10 :foo) #(println "boom!")] [a b])

7:00 clojurebot: java.lang.IllegalArgumentException: let requires an even number of forms in binding vector

7:00 defn: err

7:00 Borkdude: Is there an iterate that takes n?

7:00 defn: ,(let [[a b] [(repeat 10 :foo) #(println "boom!")]] [a b])

7:00 clojurebot: [(:foo :foo :foo :foo :foo :foo :foo :foo :foo :foo) #<sandbox$eval__8913$fn__8914 sandbox$eval__8913$fn__8914@48a7d7>]

7:00 Borkdude: like (iterate 100 inc 0)

7:00 defn: ,(let [[a b] [(repeat 10 :foo) #(println "boom!")]] [a] b)

7:00 clojurebot: #<sandbox$eval__8919$fn__8920 sandbox$eval__8919$fn__8920@9f69e0>

7:03 Borkdude: Or maybe there is something as a lazy while or loop?

7:04 tomoj: "iterate that takes n"?

7:04 I guess you don't mean this:

7:04 ,(take 5 (iterate inc 0))

7:04 clojurebot: (0 1 2 3 4)

7:05 Borkdude: tomoj, no I wanted to do: (lazy-cat (iterate 100 inc 0) (println "boom!"))

7:07 tomoj: I don't think you're going to be able to do it without lazy-seq

7:07 Borkdude: (def l (lazy-cat (range 1 100) (print

7:07 "boom!")))

7:07 tomoj: the println returns nil and presumably you don't want that nil returned in the seq

7:07 Borkdude: That one works.

7:08 tomoj: oh, heh, yeah

7:08 ,(lazy-cat [1 2 3] nil)

7:08 clojurebot: (1 2 3)

7:09 Borkdude: Sorry: (def l (lazy-cat (range 1 100) (do (print

7:09 "boom!") [100])))

7:09 tomoj: I liked the previous one better

7:09 Borkdude: (last l) => "boom!"100

7:09 tomoj: ,(last (lazy-cat (range 1 101) (println "boom!")))

7:09 clojurebot: 100

7:09 boom!

7:09 Borkdude: yeh ok

7:10 defn: $(let [l (lazy-cat (range 1 100) (do (print "boom") [100])))

7:10 sexpbot: java.lang.Exception: Unmatched delimiter: )

7:10 defn: $(let [l (lazy-cat (range 1 100) (do (print "boom") [100]))))

7:10 sexpbot: java.lang.Exception: Unmatched delimiter: )

7:10 defn: grrr

7:10 Borkdude: defn, you're missing a ]

7:10 defn: $(let [l (lazy-cat (range 1 100) (do (print "boom") [100])]))

7:10 sexpbot: java.lang.Exception: Unmatched delimiter: ]

7:11 defn: lol *sigh*

7:11 it's late.

7:11 tomoj: no need for do or adding an extra value on the end

7:11 as long as whatever does the booming returns nil, it's ignored

7:11 Borkdude: And now I want it to not print anything, but only seeing the side effect printed

7:11 tomoj: I mean, it won't affect the seq returned, anyway

7:12 huh?

7:12 Borkdude: so how do I do that with (lazy-cat (range 1 101) (println "boom!"))?

7:12 defn: $(let [l (lazy-cat (range 1 100) v (print "boom"))] l v)

7:12 sexpbot: java.lang.Exception: Unable to resolve symbol: v in this context

7:12 defn: okay i quit, time for bed -- night all :)

7:12 tomoj: $(dorun (lazy-cat (range 10) (println "boom!")))

7:12 sexpbot: => boom! nil

7:14 Borkdude: ah right, the difference between dorun and doall

7:14 ok I know enough now... tnx, gtg

7:14 tomoj: doall still only prints "boom!"

7:14 you're just seeing the return value printed at the repl

7:15 Borkdude: ah right, return vals

7:15 bye!

8:23 Licenser: cookies

9:39 awsome: http://www.youtube.com/watch?v=b6YTQJVzwlI

9:46 raek: wow.

9:46 Licenser: yea my thought

9:47 especially since it's a live demo and not some lab preset movie thing

9:48 defn: How do I get (11 32 45) from (10 11 30 32 41 45)?

9:48 basically i want every other item in a seq

9:48 axi: with re-matches, how would I enable DOTALL on this regex "(?<=\\<p\\>).*?(?=\\</p\\>)"

9:49 I read (?s). goes somewhere, but I can't get it to work..

9:50 MayDaniel: defn: (map second (partition 2 [10 11 30 32 41 45]))

9:50 Licenser: axi: (?s) should work in the beginning

9:57 rfg: ,(take-nth 2 (rest [10 11 30 32 41 45]))

9:57 clojurebot: (11 32 45)

9:57 axi: weird, (re-matches #"(?<=\\<p\\>).*?(?=\\</p\\>)" "<p>test</p>") returns nil

9:59 Licenser: defn: actualy It hink this would be an excelent way to write a lazy seq funciton

10:02 axi: that regex works in java, actionscript, javascript etc.. so what's clojure expecting differently?

10:13 Twey: axi: I'm guessing Clojure uses POSIX regexes

10:18 Licenser: Twey: nope they use the java ones

10:19 axi: http://github.com/Licenser/clj-highlight/blob/master/src/clj_highlight/syntax/java.clj#L50

10:19 Twey: Huh.

10:19 Licenser: there is how I use (?s:)

10:19 Twey: Then if it works in Java, it must work in Clojure too

10:20 Licenser: it does as you see in the link I posted I use (?s and it works fine :)

10:23 axi: your problem is another one

10:23 \\ is the problem

10:23 it was too obviouse to see right ahead ;)

10:24 ,(re-find #"(?<=<p>).*?(?=</p>)" "<p>test</p>")

10:24 clojurebot: "test"

10:24 Licenser: there :)

10:28 djpowell: hmm - what is (let [] ...) all about?

10:29 in the latest checkin

10:31 Lajla: ,(let [x 3] 3)

10:31 clojurebot: 3

10:32 djpowell: in rich's latest checkin he has replaced (do ...) with (let [] ...) in a few places - ie with empty bindings

10:32 Lajla: ,(let [yo-momma 3 my-fatha 4] (+ yo-momma my-fatha))

10:32 clojurebot: 7

10:33 djpowell: perhaps it has something to do with locals clearing

10:35 Licenser: djpowell: I think let does not clear locals it keeps the outer ones

10:36 perhaps it is a performance thingy

10:36 perhaps let is faster then do?

11:23 rhickey: cemerick: ping

11:23 cemerick: rhickey: Morning. :-)

11:25 rhickey: cemerick: so, you balked at make-Foo ctor fn, due to namespace pollution. We have (record ::Foo ...) ready, but I'm having second thoughts

11:25 cemerick: rhickey: I'll do my best to talk you off the ledge.

11:26 rhickey: having a universal multimethod like that is a modularity problem. But I wanted to hear your argument against (Foo-record ...)

11:26 cemerick: whoo.

11:27 rhickey: back when it was (Foo ...) no one seemed to have a problem

11:27 cemerick: well, people were explicitly naming things Foo.

11:27 rhickey: true

11:28 cemerick: I mean, this is why (assoc record :slot 42) is a good idea -- you wouldn't want (Foo-set-slot record 42) and such junk.

11:29 People shouldn't have to have a mental model of some poorly-defined var name templating going on in the language's innards.

11:29 rhickey: cemerick: I don't see a strong analogy there. Should it be (run :map (apply run :filter ...))

11:29 ?

11:31 Why should there be a universal ctor fn?

11:31 cemerick: *if* we didn't have kw access for slots + an Associative impl, then you'd have to generate an accessor fn per slot.

11:32 axi: Licenser, a-ha. but why does it work for re-find but not re-matches?

11:32 cemerick: rhickey: I think Lau and AWizzArd were pushing for that hardest, to enable apply.

11:32 but...

11:32 AWizzArd: hmm

11:32 Licenser: axi: it does too your problem is you added \\

11:32 don#t know why but it works

11:33 cemerick: rhickey: why is it a modularity problem? Wouldn't (record ::Foo ...) represent the same degree of polymorphism you get with assoc'ing on a record?

11:33 AWizzArd: Well, I think it would not hurt to have a universal ctor fn. My point however would be: I am not so much interested in a constructor, but more in a factory.

11:33 axi: (re-matches #"(?<=<p>).*?(?=</p>)" "<p>test</p>") returns nil

11:33 rhickey: cemerick: associng on a record is local, not global

11:33 cemerick: rhickey: isn't (record ::Foo ...) just creating a new Foo?

11:34 and ::Foo is namespaced, no?

11:34 (FWIW, if it's doable, I think (record Foo ...) would be preferable, but that's another topic.)

11:35 rhickey: cemerick: you are missing 'record' there, but ::Foo doesn't have a local notion of how to make one, record holds a global mapping

11:35 chouser: axi: re-matches doesn't use a regex the same way as re-find

11:35 ,(re-matches #"bar" "foobar")

11:35 clojurebot: nil

11:35 rhickey: the meaning of (assoc foo ...) is with foo, not assoc

11:36 axi: ic

11:36 cemerick: rhickey: From everyone else's perspective other than yours, the same applies to record IIUC.

11:36 rhickey: I don't see how Foo implies (record ::Foo ...) any more or less than it implies (record-Foo ...). You have to know the rules

11:37 AWizzArd: btw, could the universal constructor be made in such a way, that it accepts key/value pairs and initializes keys that were not mentioned with nil? For a (defrecord Foo [a b c]) one could then (record ::Foo :b 14, :a 3) ==> Foo{:a 3, :b 14, :c nil}

11:37 cemerick: AWizzArd: I think that'd just be an implicit into.

11:37 (i.e. probably not going to happen)

11:37 chouser: why not a static method, (Foo/record ...) ?

11:38 cemerick: chouser: not easily apply-able

11:38 AWizzArd: chouser: yes, that would be nice, plus user-defined factories

11:38 rhickey: chouser: I like that for this, but it opens up static methods in general, and all they imply

11:39 cemerick: I'm also thinking k v k v might be suboptimal if all people ever do is apply it, versus (Foo-record amap)

11:39 cemerick: rhickey: *nothing* in clojure works by defining vars like do-something-with-a-Foo. Everything does work by looking for the generic fn.

11:40 Licenser: (re-matches #"(?<=<p>).*?(?=</p>)" "<p>test</p>")

11:40 ,(re-matches #"(?<=<p>).*?(?=</p>)" "<p>test</p>")

11:40 clojurebot: nil

11:41 Licenser: axi: good point I

11:41 m

11:41 not entirely sure

11:41 rhickey: cemerick: but these things really aren't true functions of names, as (record ::Foo ...) implies, forcing it into that shape makes record a universal map

11:41 (Foo. ...) is a true function of the args

11:41 Licenser: I think it is a bug or a java thing axi

11:42 rhickey: but we don't want to type-overload (Foo. ...)

11:42 cemerick: rhickey: again, that "universal map" is an impl detail that only you'd know about.

11:42 rhickey: so this is a different function, of different args, needs different name

11:42 cemerick: rhickey: is this not a specific case of trying to make ctors apply-able?

11:43 rhickey: cemerick: no it's not, you want to insert ::Foo as an arg to a universal function where none need exist

11:43 just to avoid naming a function

11:43 a la (run ::map ...)

11:43 cemerick: rhickey: no, it's to avoid having vars named implicitly.

11:44 I remember one of my biggest frustrations with CLOS was trying to figure out what slew of junk it spilled into my environment when I defined a class.

11:44 rhickey: cemerick: so (defrecord Foo [a b c] :ctor 'make-foo) is better?

11:45 cemerick: heh

11:45 rhickey: if that came with the ability to define any number of factory fns, then yes

11:45 it that :ctor val is just to get people to give a name to what you would otherwise implicitly define, then probably not :-)

11:46 Back to the (perhaps general?) problem, I often see people wanting to do stuff like (apply com.foo.Bat. ....), so if a solution to that can be found, then this is irrelevant.

11:47 rhickey: this is trying to provide an easy way to create a record given an existing map with some or all of its keys, getting away from the positionality of the ctor

11:47 cemerick: rhickey: shortsighted suggestion?: ensure all records have a no-arg ctor, and then (into (Foo.) my-map)

11:48 rhickey: and providing a universal recipe rather than people making a bunch of variants themselves. could also be used for print/read

11:48 cemerick: hrm, I thought #Foo{:a 5 :b 6} was the target for reading?

11:48 AWizzArd: But still, why is a constructor which just sets fields to some argument values so important, vs. a factory fn which will actually do some calculatios on the arguments and include some logic on how to init the fields?

11:49 rhickey: cemerick: the problems with (into (Foo.) ...) are: what to build it on, and how to make efficient

11:49 cemerick: #Foo{...} is just an unreadable placeholder right now

11:49 cemerick: The efficiency question is already out the window if you're getting away from positionality, no?

11:49 right, I thought that was to become readable :-)

11:50 rhickey: cemerick: no, still a big difference between pulling the keys out once for a ctor call and a succession of assoces

11:50 cemerick: sure

11:51 rhickey: AWizzArd: because when you are correctly using records for information, there should be a way to create from data directly. Who will know about your special factory fns? No generic code

11:54 well, there are two things here. First is to move away from struct-map style k v k2 v2 style init

11:54 second is what to call the factory

11:54 AWizzArd: last time you came up with a nice definition of factory

11:55 rhickey: AWizzArd: all I am saying is these are two separate issues. You can write your own factory fns whenever you want and call them anything you like

11:55 AWizzArd: if i remember correctly it was basically: constructors init all fields with the values of its paramater list, while factories can work on the given args and then construct an instance

11:55 yes

11:56 cemerick: rhickey: why does record have to have a 'universal map' of factory fns? chouser's idea of having Foo/record (probably preferably Foo/_record or somesuch) seems good, where (record Foo ...) turns into (Foo/_record ...).

11:56 rhickey: there's the interop case for being able to define factory fns, but that's another discussion.

11:56 rhickey: cemerick: you are talking about static Foo/record?

11:56 cemerick: yes

11:57 rhickey: answered above, my first preference, were it not to introduce the complexities of statics everywhere. Should it not, then very 'special'

11:57 AWizzArd: I just imagine that people will use factories in most cases, because there is some logic behind their objects. They want the factory to throw exceptions whatever. So, in the end I see most people ending up using the factories in their code, and so maybe not too much energy needs to go into the mere constructors. In principle Foo. would be enough. With that user-defined factories can be built.

11:58 cemerick: back in a sec

11:58 rhickey: AWizzArd: I disagree, (make-Foo an-init-map) an important facility

11:59 AWizzArd: it sounds very useful

11:59 to write my own factory fns

12:00 rhickey: cemerick: given (Foo/record ...) who needs (record Foo ...)?

12:03 AWizzArd: one minor objection regarding make-Foo is the uppercase "F" :)

12:03 cemerick: rhickey: Foo/record being the entry point doesn't address apply, is functionally the same as Foo-record, and takes up real estate you may want for honest-to-goodness interop stuff that would have to be static.

12:04 AWizzArd: that's *exactly* the sort of backdoor naming templating junk people shouldn't have to think about :-)

12:04 rhickey: cemerick: that's not the question, if you had Foo/record would you need record Foo and why?

12:05 applying static methods a separate general question

12:08 cemerick: rhickey: Big difference between need and prefer. Functional equivalence isn't sufficient, right? :-)

12:08 What if someone wants to define a static factory fn called 'record'?

12:08 Needing to know about Foo/record is the same as needing to know about make-Foo

12:08 rhickey: cemerick: until they are added, static snot available for records

12:08 statics not

12:09 cemerick: right, but I'm keeping an eye out -- they seem pretty inevitable

12:09 rhickey: cemerick: everything you are saying points to :ctor my-ctor-name

12:10 i.e. dominated by name collision avoidance

12:11 or inversion, where everything becomes a function of a name

12:11 chouser: I can imagine general code that would have to use reflection to get at Foo/record, use str and resolve for record-Foo, and a simple function call for (record ::Foo ...)

12:12 cemerick: stupid wifi

12:12 My immediate thought to that is, why only one?

12:12 rhickey: cemerick: one what?

12:12 cemerick: ctor

12:13 * cemerick is playing devil's advocate just a bit

12:13 rhickey: cemerick: it has one definition, making a Foo from a map

12:13 else we are into type-overloading

12:13 chouser: we already have desire for at least two, right? (? 1 2 3) and (? :a 1 :b 2 :c 3), and/or (? {:a 1 :b 2 :c 3})

12:13 rhickey: now, making it user-defined is another thing

12:13 cemerick: Honestly, I don't see why this is a different issue than assoc.

12:14 rhickey: (run :assoc m k v)

12:14 cemerick: rhickey: I didn't grok the argument from that shorthand before, either. :-)

12:14 rhickey: assoc is leveraging the universal var map you are trying to prevent me using :)

12:15 cemerick: I am?

12:15 I thought the universal map you were talking about was the set of all defrecord ctor fns, not the available namespaces, etc.

12:16 rhickey: there is a function we are trying to name. It takes a map and returns a Foo. I want to call it Foo-something, you want to look it up in the record map using ::Foo as a key

12:16 cemerick: I have zero attachment to ::Foo

12:17 rhickey: using something as a key

12:17 cemerick: sure

12:17 I have a very, very strong attachment to using the names that I tell the language I want to use.

12:17 rhickey: so, not directly naming the thing, as assoc is directly named, not looked up as some function of the word assoc

12:17 cemerick: ah, I see the rub

12:18 chouser: cemerick: what about ((factory Foo) :a 1 :b 2) ?

12:18 cemerick: In this case, *no one* will think of this Foo-record as a separate fn.

12:18 chouser: I mean, how does that strike you?

12:18 cemerick: chouser: basically fine by me, but the HOF flavour will throw many for a loop.

12:18 chouser: (apply (factory Foo) :a 1 :b 2)

12:19 er

12:19 (apply (factory Foo) [:a 1 :b 2])

12:19 AWizzArd: hmm

12:19 rhickey: chouser: are you serious or is this just a straw man?

12:20 chouser: not sure. I'm not actually advocating it (yet), just exploring the space.

12:20 rhickey: chouser: it has the same problems as record Foo

12:21 but highlights the 2-step indirect nature

12:21 chouser: except in my two little examples there, factory could be a macro that expands to either record-Foo or Foo/record

12:22 AWizzArd: what about having a universal constructor fn "record" plus an optional create-foo, named by the user?

12:22 chouser: I guess I was wondering if the discomfort of generating extra vars was at all mitigated by having a standard mechanism for finding them based on the class name.

12:22 rhickey: ah

12:23 well, any such mechanism would have the modularity problem

12:23 cemerick: user=> (ns-interns *ns*) ..... WTF is record-Foo?! :-)

12:23 * rhickey is slowly trying to remove modularity issues without adding more

12:23 chouser: I don't think I understand the modularity problem yet.

12:24 rhickey: cemerick: I don't see the huge surprise issues if defrecord is documented to define a set of vars, really

12:26 AWizzArd: i agree, it will be a well known common mechanism

12:26 rhickey: chouser: multimethods with universal registration will hold all classes forever. We can move away from that with pr* by going to protocols, but 'record' cannot be a protocol

12:27 chouser: ahh

12:27 modularity of the multi-classloader variety

12:27 rhickey: cemerick: are you holding that no defblah should ever def more than one var, or be required to take the names for all such vars explicitly?

12:27 cemerick: rhickey: it's exposing implementation details, unnecessarily IMO.

12:27 rhickey: cemerick: what is?

12:29 chouser: if (factory Foo) just found (at compile-time?) the appropriate fn at a well-known place, I don't see the modularity problem.

12:30 rhickey: chouser: trust me, if (factory Foo) was built on make-Foo or Foo/create, and required compile-time resolution, few would use it outside of macros

12:31 it's not much more than the helper for str + resolve you mentioned before

12:35 cemerick: rhickey: I would cautiously assert that, yes.

12:35 rhickey: and I would contend if defrecord was documented to create a factory from map call Foo-something, unless you overrode the name with :factory my-name, few would use the latter, even though it would save them from surprises and namespace injections

12:36 cemerick: I have no doubt that you are entirely right. Not sure that's an argument for Foo-something, though. :-)

12:36 rhickey: presuming we came up with a good factory fn name

12:37 cemerick: would such an override appease you? :factory-name my-name ?

12:37 would you use it?

12:37 I;m trying to tease out the two separate issues, namespace injection and data-driven calls

12:38 cemerick: rhickey: probably not, no. I'd just shake my head every time I typed Foo-something. :-/

12:39 rhickey: cemerick: even though Foo-maker was ready to go for HOFs, vs #(record Foo %)?

12:39 I would expect a lot of the latter with record Foo

12:41 cemerick: I'd perhaps hope for (app record Foo), but yes, I'd still shake my head.

12:42 rhickey: cemerick: and were we to work on apply-able ctors for Java stuff, would you want (constructor String)?

12:42 cemerick: ha

12:42 rhickey: er, (app constructor String)

12:43 because that's what it seems you are asking for with records here

12:44 AWizzArd: rhickey: I would use that override key if it eliminates the uppercase letter from create-Foo

12:44 rhickey: AWizzArd: then call your type foo

12:44 please

12:46 another option is to try to finesse the arities so there can be a single ctor set

12:47 cemerick: that sounds unpleasant

12:47 rhickey: but it seems finicky

12:48 well, I contend that defrecord will be producing at least 2 functions, and both deserve names. One is the type ctor itself, and that is taking the provided name. The other (factory from map) needs a name provided, or to generate one

12:49 record Foo is not a name

12:49 cemerick: user=> (defrecord Foo [a b])

12:49 user.Foo/Foo-record

12:49 :-P

12:50 rhickey: who shares cemerick 's disdain for this?

12:50 * cemerick waits for the crickets ;-)

12:50 rhickey: heh

12:51 cemerick: It's all rigged! Surveying on a sunday afternoon.... :-D

12:51 rhickey: hah

12:51 chouser: It makes me uncomfortable

12:52 cemerick: rhickey: defblah defining one and only one var is a pretty tough idiom to break for such a minor thing.

12:52 chouser: I don't have cemerick's experience with CLOS, and perhaps because of this my resolve isn't as hardened.

12:53 Honestly, Foo-record bothers me quite a bit less than record-Foo. Perhaps that just shows how shallow my understanding is of the issues at hand.

12:54 cemerick: That's a long time ago, and wasn't for long. Similar experience with all the not-so-well-hidden junk in python objects.

12:54 chouser: oh, but I love hidden junk! Exposed junk perhaps less so.

12:55 I'd be happy to have a whole bevy of automatically-provided, high efficiency static factory methods in defrecord classes.

12:56 maybe each defrecord should create a namespace and put extra fns in there. :-)

12:56 cemerick: chouser: I almost suggested that. :-P

12:56 even crazier, of course

12:56 chouser: user.Foo/record as a var instead of a statid method

12:57 AWizzArd: urgs

12:58 cemerick: I keep coming back to a no-arg ctor with a single-operation merge/into.

12:58 rhickey: I'd thought a bit about that. I'm somewhat paranoid about the package/namespace/class trichotomy

12:58 cemerick: that would be a pattern?

12:58 chouser: It's not paranoia if it's true.

12:59 actually, I'm surprised it doesn't come up more often. I think things "just work" often enough that people can get a lot done without knowing exactly what's happening.

13:00 rhickey: in any case user.Foo is already a class name

13:00 so a bad ns name

13:00 cemerick: rhickey: perhaps generally-useful. I have a record, I want its slots to be the same as the same-named slots in this map over here. Make it fast.

13:00 chouser: we are seeing some questions about why (use 'foons) when foons has (defrecord Foo) isn't sufficient to say (Foo. ...)

13:00 cemerick: (merge-record (Foo.) {...}) (bad name)

13:01 rhickey: cemerick: I really hate uninitialized data like that

13:01 Nikelandjelo: Is there a way to get values in let binding as vector?

13:01 chouser: it could be a transient. largely unusable until it gets some data and is persistent!.

13:02 cemerick: rhickey: that's just the relevant usage for this particular case. In other cases, it'd be (merge-record my-well-used-and-populated-Foo {...})

13:02 rhickey: (Fooify {...})

13:02 cemerick: :-D

13:02 Chousuke: arrgh

13:03 chouser: Nikelandjelo: not really. You could write a macro that takes a let-like vector of inits and provides those values as another vector.

13:04 Nikelandjelo: (mylet foo [a 1 b 2] (prn foo)) ;=> [1 2]

13:05 rhickey: chouser: transients are different types than their persistents

13:06 Nikelandjelo: chouser: Thanks

13:06 rhickey: (Foo-from amap) (into-Foo amap)

13:06 * cemerick recuses himself

13:06 chouser: rhickey: yes, so the package would get "polluted" with classnames like __transient_Foo. Which is completely different than polluting a namespace with record-Foo

13:07 rhickey: chouser: but (Foo.) can't return anything but a Foo

13:07 chouser: Oh. duh.

13:12 cemerick: rhickey: remember that defrecord names aren't usually as tidy as Foo, so you'd be looking at FormDefinition-from and into-FormDefinition, etc. (using one of our defrecord names in this case).

13:19 rhickey: cemerick: ok, still shorter than record FormDefinition

13:20 cemerick: ha

13:21 I wasn't really thinking about comparative length. Whatever reasonable thing you prepend or append to record names is likely to be dwarfed by the record name.

13:22 rhickey: cemerick: then people might use :factory ?

13:23 cemerick: so the factory fn will either be called FormDefinition-from, or whatever the author of the record decides otherwise. :-/

13:23 AWizzArd: but please make it create-Foo, not make-Foo

13:29 LauJensen: cemerick: Did you release the results of your poll ?

13:30 cemerick: LauJensen: tomorrow or Tuesday. I'm wrapped up with something for a little bit.

13:30 LauJensen: ok, np

13:30 cemerick: (mostly trying to keep rhickey on the side of the light, actually ;-))

13:32 rhickey: so, if there were factories for positional args, keyvals, and another map, what names would distinguish them? This is orthogonal to record Foo vs Foo-record

13:33 i.e. imagine you don't get Foo. positional ctor

13:34 rec, rec-map rec-from ?

13:35 AWizzArd: +1

13:36 cemerick: Seems like rec-from would delegate to rec-from pretty quickly?

13:37 LauJensen: ?

13:37 rhickey: to rec-map, yes

13:37 cemerick: right, sorry

13:38 LauJensen: I dont think the leaving out of 'ord' is a good thing, record-from isn't quite common lisp style verbose

13:42 cemerick: bbl (maybe :-))

15:07 LauJensen: Chousuke: P pushes to origin - what if I want to push to another remote?

15:08 Chousuke: hm, doesn't it let you choose? :/

15:08 LauJensen: no, it assumes - I think it asked me the very first time

15:09 Chousuke: maybe C-u P?

15:09 LauJensen: ah yes ofc - thanks :)

15:18 hsjunnesson: Quick question, how do I instance a class pointed out by a var? Like I want to do something like (def s String) (new s)

15:18 "Unable to resolve classname: s"

15:19 opqdonut: (def s String) (.newInstance s)

15:19 or somesuch

15:19 see the api doc for the Class class

15:20 hsjunnesson: Ah yes of course.

15:20 Thanks.

15:42 bendlas: hey folks

15:42 LauJensen: Hey

15:42 bendlas: quick question: can you tell me what happened to clojure.test/thrown? in 1.1 ?

15:46 or is it yet to be added in 1.2?

16:44 StartsWithK: how can i use clojure.core/import*?

16:45 a_strange_guy: You shouldn't

16:45 it's an primitive internal special form

16:46 StartsWithK: i know

16:46 but i need to use it

16:47 a_strange_guy: why?

16:47 clojurebot: why not?

16:47 a_strange_guy: lawl ^^

16:48 StartsWithK: clojure.core/import* isn't a function

16:49 so you cannot use it to import classes dynamically

16:49 StartsWithK: how is deftype doing it?

16:50 a_strange_guy: deftype is a macro

16:50 StartsWithK: i see, they are all macros

16:50 hmm, inconvenient

16:51 a_strange_guy: i think there is a method in a namespace object

16:51 which can be used to import classes

16:51 but that is your own risk

16:51 StartsWithK: i need to generate a bytecode and import my class after that

16:52 and i made all the generators as functions

16:52 well.. back to the old drawing bord

16:52 a_strange_guy: be evil, use eval

16:53 StartsWithK: hehe, eval will not work as

16:54 (defclass Foo) (use-Foo) and if defclass expands to (do (make-a-bytecode) (eval (import)) (use-Foo)

16:54 use-Foo will not see Foo

16:55 a_strange_guy: actually it might

16:56 'do at toplevel works like in a lisp interpreter

16:58 StartsWithK: it worked :)

16:58 a_strange_guy: but it will only at toplevel

16:58 StartsWithK: wait :)

17:00 it worked as (do (eval '(import javax.swing.JFrame))) (println (JFrame. "hi"))

17:00 hmm, but i will need to make it a macro to get that

17:00 pff

17:01 a_strange_guy: it won't AOT though

17:01 Afaik AOT is the reason, why import is not a function anymore

17:02 if you don't want to use eval

17:02 StartsWithK: it compiled

17:02 a_strange_guy: try: (do (.importClass *ns* full.class.Name) (use-Name))

17:03 really?

17:03 StartsWithK: (defn foo [] (eval '(import javax.swing.JFrame))) (foo) (println (JFrame. "hi"))

17:04 i'll use this for now, easy to fix later

17:04 a_strange_guy: didn't mean it that way

17:04 StartsWithK: thanks

17:04 a_strange_guy: have fun

17:05 and hope nobody will see that hack xD

17:07 StartsWithK: :)

17:24 hsjunnesson: Okay, so I have a class I want to dynamically instance by picking out its constructor and calling newInstance on it. Problem is this constructor has mixed primitive and object arguments.

17:24 This is when it gets tricky.

17:26 So I'm trying something like (.newInstance c (into-array Object [foo bar])) and get an IllegalArgumentException.

17:26 _brian2_: any congomongo users out there?

17:26 a_strange_guy: clojure.lang.Reflector

17:27 Rich built the hacks, so you don't have to

17:27 hsjunnesson: I'll take a look, thanks :)

18:13 _brian2_: noob question > I would like to use the 'partition' function in the contrib library 'string' , however the docs say to use : (require '[clojure.contrib.string :as s]) , but there is no string.class in my contrib jar file

18:17 this doesn't seem to work either : (use '[clojure.contrib.str_utils])

18:18 a_strange_guy: what version are you using?

18:20 _brian2_: clojure-contrib-1.0-20091212.214557-33.jar

18:20 clojure-contrib-1.0-20091212.214557-33.jar

18:20 clojure-contrib-1.0-20091212.214557-33.jar

18:20 sorry

18:30 Lajla: ,((set "ab") a)

18:30 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

18:30 Lajla: Eurr

18:30 ,((set "ab") #\a)

18:30 clojurebot: No dispatch macro for: \

18:30 a_strange_guy: ,((set "ab") \a)

18:30 clojurebot: \a

18:30 Lajla: a_strange_guy, merci.

18:35 Raynes: http://gist.github.com/427949 Anybody have any clue what might cause something like this to explode? I can't read that error to save my life, and I'm running out of options. The relevant code is in this area: http://github.com/Raynes/sexpbot/blob/master/src/sexpbot/respond.clj#L91

18:36 What's weird about it, is this error only occurs when sexpbot isn't ran inside an REPL. If you run it in an REPL, everything works smoothly.

18:37 What is happening, is sexpbot is trying to reload all of the plugins (quite literally, it's requiring all of the plugins with :reload), and then it's calling a function in all of the plugins that the defplugin macro creates. It's inside this function, I believe, where everything is blowing up. The error doesn't make any sense to me.

18:37 Licenser and I have been trying to work it out, but we're lost. :\

18:38 The most insane thing is that it works if sexpbot is ran in the REPL, but not if ran via java -cp "lib/*:src/" clojure.main -e "(use 'sexpbot.run)"

18:40 When sexpbot starts up, most of this happens. When it starts up, require-plugins is called, followed by stuff to create bots for each server in the configuration, and both load-plugins and load-modules are called on these. So, it works the first time everything is loaded, but not when it's reloaded.

18:40 * Raynes is getting a headache.

18:40 rhickey: Raynes: are you on the latest Clojure? Is anything AOT compiled?

18:40 Raynes: rhickey: I actually haven't grabbed the latest snapshot in a couple of days, but I am running 1.2, and nothing is AOT compiled.

18:40 rhickey: try the latest

18:41 Raynes: This will take a little while. /me is on dialup.

18:41 * programble points and laughs

18:41 programble: uh

18:41 * programble didn't do that >.<

18:42 programble: s/</>/

18:42 sexpbot: uh

18:42 programble: ...

18:42 sed doesn't work with actions?

18:42 on purpose or accident

18:42 on purpose makes sense actually

18:42 for example

18:42 * programble sucks his thumb

18:43 programble: s/his thumb/<insert dirty object here>/

18:43 sexpbot: for example

18:43 programble: anyway

18:43 i should shut up now

18:43 _brian2_: can anyone tell me if contrib 'strings' is now str_utils ?

18:53 I'm trying to use the string library 'partition' function, but when I run the example : (partition #\"[a-z]+\" \"abc123def\") , I get No dispatch macro for: \

18:56 Twey: Is there a function (comp eval (partial cons 'hash-map)) defined in the standard library somewhere?

18:56 programble: _brian2_: why do you have the slash?

18:57 Twey: (actually, there's probably a function (comp eval (partial cons)) somewhere, isn't there?)

18:57 programble: _brian2_: (partition #"[a-z]+" "abc123def")

18:57 Twey: Oh, no ‘partial’ allowed there? Okay

18:58 _brian2_: the slash is in the example

18:59 Twey: Ah, ‘apply’

18:59 programble: _brian2_: well it shouldn't be

18:59 Twey: Okay ☺ I guess there's not much need for a (partial (apply 'hash-map)) somewhere, then.

18:59 _brian2_: For example: (partition #\"[a-z]+\" \"abc123def\") returns: (\"\" \"abc\" \"123\" \"def\")"

19:03 programble: _brian2_: remove all those \s

19:04 _brian2_: ok

19:04 you mean \ 's ?

19:05 programble: yes

19:05 i have no idea why they are there

19:05 but they shouldnt be

19:06 _brian2_: ok

19:06 thnks!

19:07 Raynes: rhickey: Same thing.

19:07 I guess I've superbroke this thing. I break things a lot, that isn't surprising. The confusing part is how it works when sexpbot is run in an REPL, but not otherwise. That's the part that has me beating my head against a wall.

19:10 hiredman: Raynes: have you lein clean'ed lately?

19:10 * Raynes notes that he forgot to do that before lein deps.

19:11 * Raynes tries that.

19:13 Raynes: Yeah, that didn't help.

19:14 hiredman: Raynes: is sexpbot.respond$defplugin$fn__3456 the same all the time?

19:15 Raynes: Er, I'm not entirely certain what that is.

19:15 hiredman: it's a class name

19:16 is it always the same in the exception?

19:16 Raynes: Let me check.

19:16 hiredman: did you not just rerun it after doing the clean?

19:16 Raynes: hiredman: No. It changes.

19:16 hiredman: mmm

19:16 interesting

19:17 Raynes: It's insane.

19:17 At least, it's driving me insane.

19:17 hiredman: and how do you know line 91 is the line you are looking for?

19:19 at sexpbot.plugins.spellcheck$eval3699$load_this_plugin__3700.invoke(spellcheck.clj:37)

19:19 Raynes: Because after everything has been reloaded, the bot calls a function that the macro creates in each of the plugins, and this sets up the commands and such. It's in this function where everything explodes. I know, because I placed two printlns in there; one before the dosync, and one as the first thing in the dosync. The first one always executes, but the second one never does, so apparently the dosync is blowing up.

19:19 hiredman: ,(str (fn []))

19:19 clojurebot: "sandbox$eval__8952$fn__8953@d85839"

19:20 Raynes: hiredman: spellcheck is the first plugin that sexpbot is trying to load.

19:20 hiredman: the stacktrace says it is on line 37, and 37 is a macro

19:20 Raynes: http://github.com/Raynes/sexpbot/blob/master/src/sexpbot/respond.clj#L129

19:20 hiredman: the macro is like 118

19:21 rhickey asked about aot, right?

19:21 Raynes: Yeah.

19:21 None of that is going on.

19:22 hiredman: and which line in the macro is the exception happening?

19:23 Raynes: I suspect it's the line that I linked to above. Like I said, I can put a println right before the dosync, and it executes and prints right. Anything in the doseq never happens.

19:23 dosync*

19:25 hiredman: really?

19:25 Raynes: Totally.

19:25 hiredman: prove it

19:25 Raynes: hiredman: http://gist.github.com/427949

19:25 "Works!!!"

19:26 hiredman: Raynes: missing a gist with the altered code

19:26 Raynes: http://gist.github.com/427949

19:26 Oops.

19:26 Wrong link.

19:26 http://gist.github.com/428024

19:28 hiredman: you are doing this on a fresh run of the code right?

19:28 Raynes: Yessir.

19:28 Every time.

19:28 hiredman: really?

19:29 Raynes: I promise.

19:29 :\

19:29 hiredman: at sexpbot.plugins.spellcheck$eval3699$load_this_plugin__3700.invoke(spellcheck.clj:37) is the exact same in this exception

19:29 er

19:29 wrong line

19:29 sexpbot.respond$defplugin$fn__3456

19:29 Raynes: I'll do a fresh run right now.

19:30 hiredman: that may not be much of indicator, because gensym may use successive numbers

19:30 Raynes: http://gist.github.com/428028

19:30 hiredman: so you would always get the same one in the same place unless you add a new call to gensym

19:32 can you aot compile it?

19:33 Raynes: Everything?

19:33 hiredman: if you remove the dosync block, do you still get the exception?

19:33 Raynes: hiredman: Nope. If I remove the dosync, no exception happens.

19:33 I tested that way earlier.

19:34 Guess I should have mentioned that.

19:34 hiredman: oh

19:34 you are using #() inside a macro expansion

19:34 don't do that

19:34 Raynes: Okay.

19:38 hiredman: well?

19:38 Raynes: That didn't fix it.

19:38 Were you wanting me to AOT compile this?

19:38 hiredman: and the exception is still the same?

19:38 Raynes: Yup.

19:39 http://gist.github.com/428035

19:39 hiredman: can you put in a (println m-name#) before the dosync

19:40 Raynes: Kay.

19:41 http://gist.github.com/428036

19:41 That seems to be in proper working order.

19:44 hiredman: have you tried intern instead of def

19:44 _brian2_: I have a re-seq question, I want to parse out "{aa}{bb}" ->"aa" "bb" but this (re-seq #"\{.+\}" "{aa}{bb}") yields ("{aa}{bb}")

19:45 hiredman: has this code ever worked?

19:45 Raynes: hiredman: Instead of using defn to create load-this-plugin? No, I haven't tried this.

19:45 hiredman: The code changed a little, but it used to work.

19:45 hiredman: what changed?

19:46 Raynes: hiredman: I got rid of the global commands, modules, and hooks refs, and put them all in the irc ref that is passed to the function. Also, the function is new.

19:47 hiredman: Raynes: that doesn't sound like a little

19:48 Raynes: hiredman: The only real thing that has changed is that things are stored in a single ref instead of many global refs, and the stuff that actually stores it is wrapped in a function. It's really not that different.

19:50 As a side note, the same thing happens when intern is used.

19:51 I guess I've just borked things beyond repair.

19:51 I just don't understand how. :\

19:51 hiredman: so some how a string with "sexpbot.respond$defplugin$fn__3456" in it is being passed to read-string

19:52 well, RT/readString

19:52 ,(read-string "sexpbot.respond$defplugin$fn__3456")

19:52 clojurebot: sexpbot.respond$defplugin$fn__3456

19:52 hiredman: grrr

19:52 something like that, but it throws an exception

19:53 user=> (clojure.lang.RT/readString "#=sexpbot.respond$defplugin$fn__3456")

19:53 java.lang.RuntimeException: java.lang.ClassNotFoundException: sexpbot.respond$defplugin$fn__3456 (NO

19:53 _SOURCE_FILE:0)

19:53 user=>

19:56 you may want to look at the macro expansion of defplugin and the contents of irc

19:56 Raynes: What annoys me the most is how it works fine in an REPL, but not outside of one.

19:56 I'd much prefer that it not work anywhere.

19:57 At least then it would be easier to test.

20:00 zakwilson: I'm having difficulty using Swank remotely with leiningen. As far as I can tell, it can't find dependencies that are in jars when I try to use them in my code.

20:01 Raynes: http://gist.github.com/428048

20:02 korre: zakwilson: are you doing a war project?

20:03 zakwilson: I should add that I'm starting Swank by connecting over ssh and running "lein swank" manually. I briefly tried remote-swank, but it didn't seem to work.

20:04 korre: I don't know what a war project is. What I'm doing originally was going to be for appengine, and has a war directory.

20:04 korre: zakwilson: butt it is using a custum lib path?

20:07 zakwilson: korre: yes

20:08 korre: zakwilson: try to copy the jars a lib folder on your project root and restart the swank server

20:08 zakwilson: korre: there's already a symlink to the lib directory in the project root. Should I remove the custom lib path in project.clj?

20:09 korre: zakwilson: yea and run lein deps agen

20:11 zakwilson: korre: tried that, still get FileNotFoundException

20:23 No difference when using an ssh tunnel

20:26 korre: so you hawe time to github it??

20:26 hiredman: Raynes: the value of :cleanup looks suspicious

20:27 Raynes: hiredman: It's the only thing that I haven't tried commenting out so far.

20:28 hiredman: Okay, changing it to (fn [] 0) caused the error to not occur.

20:28 hiredman: cleanup is the culprit.

20:28 Now, I need to figure out why.

20:29 hiredman: it's a an object that can't be read

20:29 Raynes: ~ is passing it to readString?

20:29 clojurebot: Gabh mo leithscéal?

20:29 Raynes: clojurebot: Shush, we're trying to fix your sister.

20:29 clojurebot: It's greek to me.

20:31 zakwilson: korre: was that directed at me?

20:32 korre: yea

20:34 zakwilson: http://github.com/zakwilson/test-classpath <-- this actually seems to fail locally too

20:35 korre: zakwilson: only a project.clj file on github :p

20:37 zakwilson: korre: correct. I tried to make it is simple as possible. One should be able to "lein deps", "lein repl" and (use 'compojure.http)

20:37 korre: zakwilson: if you hawe the newest version of swank you dont need the lein swank plugin

20:38 zakwilson: korre: I had some reason for keeping it around. I think it wasn't working without it.

20:39 Hmm... works without it now.

20:39 But (use 'compojure.http) fails

20:41 korre: there is no compojure.http in this version!

20:41 patrik-karlins-MacBook-Pro:lib patrikkarlin$ unzip compojure-0.4.0-20100308.145053-8.jar

20:41 Archive: compojure-0.4.0-20100308.145053-8.jar

20:41 inflating: META-INF/MANIFEST.MF

20:41 inflating: meta-inf/maven/compojure/compojure/pom.xml

20:41 inflating: meta-inf/maven/compojure/compojure/pom.properties

20:41 inflating: compojure/route.clj

20:41 inflating: compojure/response.clj

20:41 inflating: compojure/core.clj

20:41 inflating: compojure/.response.clj.swp

20:41 inflating: compojure/.route.clj.swp

20:41 inflating: project.clj

20:41 patrik-karlins-MacBook-Pro:lib patrikkarlin$

20:43 zakwilson: Then it seems that the contents the jar changed

20:43 korre: mush of compojure has been refractord out i think..... what did you whant from the http libary?

20:45 zakwilson: I think it was defroutes and defserver. I was also using compojure.html, which isn't there either.

20:46 korre: no theres a diferent libary for the html dsl

20:46 arbscht: hiccup

20:46 korre: defroutes is in compojure.core

20:49 zakwilson: This is what I get for using an unstable version. Not sure why I did that. I got a trivial web version of my app working and then left it alone for a while as I tried to chase down parallelism performance issues

20:49 korre: [hiccup "0.2.5"]

20:49 durka42: anyone using penumbra? i'm having trouble with textures

20:50 Raynes: hiredman: Problem was a missing syntax quote. ._.

20:52 zakwilson: korre: thanks for the help. It might have taken me forever to notice the changes to compojure otherwise.

20:53 arbscht: zakwilson: try #compojure too, btw

20:53 zakwilson: It has its own channel?

20:54 arbscht: yes

20:55 Raynes: hiredman: Thanks for all the help. I appreciate you taking the time to work with me on this one. It was a tough one. <3

21:04 zakwilson: So I have some code I started on about a month ago and it uses the params function. Compojure was recently restructured, and that function is not in compojure.core. Where has it gone, or what has it been replaced by?

21:07 korre: zakwilson: what did it do?

21:08 zakwilson: http://github.com/weavejester/compojure/blob/master/src/compojure/core.clj compojure isent that big :p

21:09 zakwilson: korre: it looked up query parameters

21:09 korre: zakwilson: query ..... you mean url parameters ?

21:10 zakwilson: korre: yes

21:10 korre: zakwilson: its in ring.middleware

21:11 (:use [ring.middleware params cookies]

21:13 zakwilson: Great... now Emacs seems to have locked up

21:17 korre: this hasn't given me back the params function, though it's obvious that ring.middleware.params is for doing stuff with params. Oh, there's actually documentation for this. Cool. I wonder where I might find decent example code though.

21:18 korre: zakwilson: http://github.com/mmcgrana/ring/blob/master/ring-core/test/ring/middleware/params_test.clj

21:20 zakwilson: This is more verbose than the old params function. I wonder what prompted the change.

21:22 Oh, wait. I see. It's gone because the Right Thing is to specify the params in the route.

22:25 brehaut: im trying to get the emacs-starter-kit going on my mac; only problem so far is git complaining during clone with "Cannot obtain needed blob 94a9ed024d3859793618152ea559a168bbcbb5e2

22:25 while processing commit 6b38e16eaf847cee27c8b3fdf58d8bb88af5caf3.

22:25 fatal: Fetch failed." – does anybody know how to fix/route around this?

22:28 rava: what's an elegant way of returning a json array of json objects from a list of maps?

22:28 but without returning a lazy list (compojure's render doesn't like it :/ )

22:31 zakwilson: It seems that Compojure used to have a serve-file function, and this is now gone. What's the idiomatic way to serve a static file now?

22:39 rava: set headers and return the file?

23:08 trptcolin: how can i access a java enum with clojure?

23:09 i can get it as a class: org.apache.cassandra.thrift.ConsistencyLevel

23:10 but none of the access mechanisms that i can think of work (.ONE org.apache.cassandra.thrift.ConsistencyLevel) or (org.apache.cassandra.thrift.ConsistencyLevel.ONE)

23:11 hrm, actually this seems to work: (. org.apache.cassandra.thrift.ConsistencyLevel ONE)

23:11 i'd thought that was just syntactic sugar...

23:22 rava: trptcolin: what did you think was sugar?

23:22 chouser: did you try org.apache.cassandra.thrift.ConsistencyLevel/ONE

23:23 trptcolin: chouser: ah, much better :)

23:23 thx

23:24 that makes sense, so enum members are treated just like statics...

23:25 rava: the bare .

23:37 rava: trying to join the return of mapping a function across a items in a list to an existing string..any nice way of doing that?

23:41 trptcolin: ,(str "existing string" (clojure.contrib.str-utils/str-join "" [1 2 3]))

23:41 clojurebot: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.str-utils

Logging service provided by n01se.net