#clojure log - Jul 29 2010

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

0:16 _rata_: hi

0:21 qbg: Why did I only just recently notice that clojure.contrib.datalog exists?

0:22 Contrib is huge

0:24 technomancy: daaku: there is radagast, but it's very primitive

0:24 clojurebot: google clojure radagast

0:24 clojurebot: First, out of 12 results is:

0:24 fmu's Profile - GitHub

0:24 http://github.com/fmu

0:24 technomancy: clojurebot: that's terrib

0:24 le

0:24 clojurebot: excusez-moi

0:24 technomancy: clojurebot: botsmack

0:24 clojurebot: clojurebot evades successfully!

0:24 technomancy: http://github.com/technomancy/radagast

0:25 that guy doesn't even have any repositories

0:25 daaku: cool, thanks technomancy -- i'll play with it

0:25 technomancy: daaku: it only does fn-level coverage, not branch-level

0:26 the latter would necessitate compiler hacks

0:26 daaku: technomancy: cool -- i found a namespace tracer thingy this morning too

0:35 Lajla: ablokzijl, I love you.

0:38 slyrus: is (first (filter ...)) the best way to find a single object that matches pred? I keep find myself looking for cl:find.

0:42 scottj: yeah, there's a find-first in contrib not sure if it's been promoted, it's implemented that same way

0:42 tomoj: no promotion

0:48 _rata_: filter is lazy even when the input collection isn't? (newbie question, I know)

0:49 Drakeson: which html parser would you recommend?

0:49 is tagsoup good?

0:51 tomoj: _rata_: tricky question

0:52 _rata_: tomoj, why?

0:52 tomoj: if the sequence is chunked, weird things can happen

0:52 like (first (filter nil? (map println (range 10))))

0:52 daaku: Drakeson: i've heard good things about http://about.validator.nu/htmlparser/ -- but haven't used it myself

0:52 tomoj: but ignoring chunked sequences, yes, filter is lazy even if the input collection isn't

0:52 (first (filter ...)) will stop and return as soon as it can

0:55 _rata_: lazy is so cool :)

0:56 scottj: Drakeson: if you're consuming html from other people chances are it's malformed so I'd use tagsoup

1:05 slyrus: thanks scottj

1:06 (first (filter #(....)) = a lot more typing than (find item sequence :test bogosity), for instnace... but OK.

1:14 _rata_: tomoj, btw what's the problem with (first (filter nil? (map println (range 10)))) ?

1:22 Drakeson: scottj, daaku: thanks

1:23 tomoj: _rata_: try it out

1:23 it prints all ten even though it only returns the first

1:23 because range is chunked

1:23 Drakeson: scottj: is the fact that tagsoup breaks long strings into shorter ones a bug, desired, or just not important?

1:23 _rata_: yes, I tried it out first and didn't see anything wrong

1:23 tomoj: oh, depends on your clojure version

1:24 _rata_: 1.1.0

1:24 tomoj: ,(first (filter nil? (map println (range 10))))

1:24 clojurebot: 0 1 2 3 4 5 6 7 8 9

1:25 scottj: Drakeson: no clue

1:25 _rata_: the problem is that every number in range got printed?

1:30 tomoj: yeah

1:30 ,(first (map println (range 100)))

1:30 clojurebot: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

1:36 _rata_: mmm... ok

1:41 sorry, but what's the reason for that behavior? what does it means that a sequence is chunked?

1:41 tomoj: see how it printed only the first 32 elements?

1:42 qbg: _rata_: Reduced overhead

1:42 tomoj: if you did instead (nth (map println (range 100)) 32) it would print the first 64

1:42 so it realizes the sequence 32 elements at a time instead of 1 at a time

1:43 when you ask for the first one, it gets the first 32 ready. then when you get done with those and ask for the 33rd, it gets the next 32, etc

1:43 daaku: is there a version of if-let that allows for multiple bindings and tests?

1:44 _rata_: tomoj, ok, I understand it know :)

1:44 can you set the "size of the chunk"?

1:45 qbg: ,(doc chunk-buffer)

1:45 clojurebot: "([capacity]); "

1:45 qbg: That isn't very useful...

1:46 _rata_: if instead of println the function would have been very costly to compute, would Clojure still be getting them in 32 elements chunks?

1:47 tomoj: yep

1:48 ,(time (first (map #(do (Thread/sleep 100) %) (range 100))))

1:48 clojurebot: java.lang.Exception: No such namespace: Thread

1:48 tomoj: eh

1:48 well, it takes a little over 3.2s since it sleeps for 100ms for each of the 32 in the chunk, even though you only ask for the first

1:49 there's some function on someone's blog somewhere for forcing one-at-a-time semantics

1:49 _rata_: buuu... then lazy is not so cool

1:50 tomoj: it doesn't cause trouble as much as you might think

2:45 cais2002: hi, I have two functions named convert-to_ and convert_to- , it seems that the naming caused some problem such that when ran in a standalone jar, the code has problem locating the right function to invoke

3:00 Belaf: Hi, I'd need to contact the author of r0man/appengine-clj on github, does anybody know if he's reading this channel or how to reach him? I don't seem to find any contact information on github...

3:03 ataggart: cais2002: that may be due to the fact that dashes are converted to underscores in compiled code

3:05 cais2002: ataggart: that's what I suspect. but it failed on a standalone jar without using :gen-class, too..

3:05 anyway, the problem went away after i rename the functions

3:37 cpfr: hey is this the best place to ask incanter questions?

3:46 Nikelandjelo: Is it good practice to use destructuring in function in params part? Or is it better to use "let" inside function for destructuring?

3:50 sid3k: hi all, it seems gen-and-load-class is deprecated, where can I use information about this change?

3:51 the tutorial in wikibooks still includes some examples using this function

3:54 any ideas)

3:54 ?

3:59 Chousuke: Nikelandjelo: I think using let is better if the destructuring isn't very simple

4:00 Nikelandjelo: and remember that the argument vector shows up as is in the documentation unless you override the metadata

4:02 sid3k: how can I load a java class using clojure?

4:02 clojurebot: "[Clojure ...] feels like a general-purpose language beamed back from the near future."

4:02 sid3k: clojurebot: thanks, yo

4:02 Nikelandjelo: Chousuke: Yes, actually I ask because of this :) Thanks for advice

4:02 clojurebot: excusez-moi

4:02 Chousuke: sid3k: what do you mean?

4:02 sid3k: you can directly use any java class that is in the classpath

4:03 sid3k: it seems gen-and-load-class function is deprecated, I'm looking for its replacement

4:03 Chousuke: so you want to create a class in clojure?

4:03 sid3k: some examples in wikibooks uses this function

4:03 Chousuke: exactly

4:03 Chousuke: there are many ways, depending on what you need.

4:03 sid3k: http://en.wikibooks.org/wiki/Clojure_Programming/Concepts

4:04 check out the example mentioining about user defined exception classes

4:04 I just need to find replacement of gen-and-load-class

4:04 Chousuke: there's the :gen-class directive for the ns macro (see doc for gen-class), there's proxy for quick implementing of interfaces, and reify in 1.2.

4:05 or was reify in 1.1 already? hm

4:05 * Chousuke clearly needs coffee

4:05 sid3k: all right, but as you see, I'm a newbie trying to learning from a tutorial already

4:05 could you check out the example in the page I've given?

4:06 Chousuke: right, the wikibooks tutorial is probably horrendously outdated if it still mentions gen-and-load-class

4:06 that was deprecated even before 1.0

4:06 sid3k: rigt

4:06 is there any document about the deprecation?

4:06 Chousuke: not really

4:07 sid3k: why its so hard to continue a tutorial written for 1.0

4:07 anyway, I'm checking out that manual, I hope that will help

4:08 Chousuke: sid3k: check out this one http://java.ociweb.com/mark/clojure/article.html

4:08 it's up to date and comprehensive

4:08 the wikibooks one seems pretty much useless :/

4:09 sid3k: hmm, thanks

4:09 Chousuke: (it still says that (rest ()) returns nil :P)

4:09 sid3k: it was a nice beginning for me

4:09 Chousuke: it wouldn't be so bad if it were kept up to date

4:10 sid3k: arright

4:10 Chousuke: the best documentation is usually on clojure.org but it's not in tutorial form

4:11 sid3k: I'm on the article you've linked, it looks great

4:11 many thanks

4:41 Belaf: r0man: Hi, are you the one of appengine-clj ?

4:41 r0man: yup

4:42 Belaf: Can I ask you some info about its state?

4:42 r0man: yes, for sure

4:43 Belaf: The submission to clojars seems to be broken for 0.4-SNAPSHOT, the jar is missing.

4:43 Is 0.4-SNAPSHOT meant to be released?

4:44 r0man: yes, someone mentioned this to me as well 2 days ago. i'll take a look at this maybe tonight or tomorrow

4:45 Belaf: Is there an official way to report issues ? I couldn't find any contact information on github.

4:45 r0man: yes, i want to release that one soon. i thought about adding validations and some lifecyle methods, but i think i'll put those features in another release ...

4:47 i just enabled the "issues" checkbox on github. i wasn't aware that i have to enable it

4:47 you can try this one now ...

4:47 Belaf: Ok, I'm going to try it now :-)

4:47 r0man: for what are you using appengine-clj?

4:49 Belaf: Well, for the time being I'm trying to find out how I can use it to write a web application. Still learning.

4:50 r0man: ok, nice

4:50 Belaf: My problem is that I'm getting at much new things at the same time: clojure, compojure and appengine... so I never know how much one thing can be a problem or just me misunderstanding it.

4:51 Possibly I will end up with a real web application sooner or later, but I'm still trying to understand whether the appengine solution is the one I really need, for instance.

4:52 callen-nyc: Belaf: well what are you trying to do that makes you think you need app engine specifically?

4:52 not being confrontation, just inquiring and trying to grok what you're doing.

4:53 confrontational

4:55 Belaf: Well, honestly one of the things I liked was its "free to start" paying scheme. So I wanted to use it to experiment

4:55 callen-nyc: Belaf: true that, but that's also what the dev machine is for.

4:56 Belaf: don't get me wrong, app engine is cool, but contorting yourself into bending over backwards while having to learn a whole language + web framework and then throw an unfamiliar deployment method into that that is unnatural to the environment seems a little

4:56 what's the word? masochistic.

4:56 Belaf: perhaps you could cool your jets, get your feel with clojure and compojure locally, get comfortable, worry about deployment/app engine testing when you're grokking your code.

4:57 Belaf: Oh, sure, it seems a wise advice :) On the other side I still haven't committed to anything, and I'm trying to learn things :)

5:00 I'm getting aware of the issues with appengine (funny database, startup times, etc), but it seems to also have interesting things... On the other side in the end I could turn to try a more normal setup.

5:02 r0man: do I need a github login to add an issue ?

5:06 r0man: Belaf: could be. i'm not sure

5:07 Belaf: i would also not suggest starting with app engine.

5:08 Belaf: Thanks for your advice :)

5:08 r0man: i played around a with it some while but there are still some tiny things that i don't know how to do.

5:09 and since the java version is not really open sourced it's sometimes hard to figure out to do things

5:09 bulk loading for example

5:09 Belaf: I see.

5:18 r0man: Ok, it looks like I made it :-) (it took a while to guess the formatting...) I hope the issue description makes sense.

5:31 callen-nyc: which are the main drawbacks of using appengine?

5:31 r0man: Belaf: thy

5:31 Belaf: r0man: to you :)

5:32 r0man: Belaf: i'll take a look into this the next days

5:33 Belaf: Sure, no need to hurry. I just wanted to know whether the thing is released and if there's a way to communicate back.

5:34 As I said, I'm not committed to it, but I'll keep playing around.

5:44 old_sound: hi, are there any libs for XMPP besides this one: http://github.com/zkim/xmpp-clj ?

5:49 ragnard: raek: I remember you asking about 'killing' a running agent that is blocking somewhere... Did you find a solution?

6:59 krunaldo: Hi! I'm having some problems with lein... Ran lein new test1; cd test1; lein deps got this output http://pastebin.org/427714

7:00 I did change the version number from beta to 1.1.0 as the beta threw the first error

7:50 raek: ragnard: one option would be to use future-cancel (i was using futures for doing the blocking parts), but I haven't investigated if that would work in my case

9:03 neotyk: ,(doc flatten)

9:03 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

9:04 neotyk: ,(flatten nil)

9:04 clojurebot: ()

9:04 neotyk: how come?

9:09 gregh: what else would you expect it to do?

9:10 raek: the docstring ^^^ says it should return nil :)

9:10 neotyk: ,(doc flatten)

9:10 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

9:11 gregh: nil is the same thing as ()

9:11 Chousuke: nope

9:11 nil is not ()

9:11 raek: not in clojure

9:11 neotyk: gregh: not at all

9:11 raek: ,(class nil)

9:11 clojurebot: nil

9:11 raek: ,(class ())

9:11 clojurebot: clojure.lang.PersistentList$EmptyList

9:11 gregh: er, maybe I'm mixing up my lisps again

9:11 * gregh takes notes

9:12 raek: it works somewhat like nil in certain circumstances, though

9:12 defn: ,(= nil ())

9:12 clojurebot: false

9:12 defn: ,(rest ())

9:12 clojurebot: ()

9:13 raek: i think the rationale basically is that there are many collection types which have empty values

9:13 () [] {} #{} etc

9:13 ,(next ())

9:13 clojurebot: nil

9:14 defn: ,(letfn print-seq [s] (when s (prn (first s)) (recur (next s))))

9:14 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

9:14 defn: blurg

9:15 raek: (letfn (print-seq [s] ...

9:15 defn: oh righ

9:15 raek: (letfn [(print-seq [s] ... even

9:19 bOR_: ,(source flatten)

9:19 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

9:19 neotyk: ~flatten

9:19 clojurebot: flatten is clojure.contrib.seq-utils/flatten

9:20 neotyk: (defn flatten

9:20 "Takes any nested combination of sequential things (lists, vectors,

9:20 etc.) and returns their contents as a single, flat sequence.

9:20 (flatten nil) returns nil."

9:20 {:added "1.2"}

9:20 [x]

9:20 (filter (complement sequential?)

9:20 (rest (tree-seq sequential? seq x))))

9:20 ,(rest nil)

9:20 clojurebot: ()

9:21 neotyk: ,(filter false nil)

9:21 clojurebot: ()

9:21 neotyk: ,(next nil)

9:21 clojurebot: nil

9:21 raek: aha

9:21 neotyk: and if filter would do when-let before lazy-seq it would return nil

9:22 Chousuke: hmm

9:23 ,(sequential? nil)

9:23 clojurebot: false

9:23 raek: imho, to get a fully lazy sequence, the if that returns nil should be inside lazy-seq

9:23 neotyk: ,(lazy-seq)

9:23 clojurebot: ()

9:24 raek: ,(sequential? #{1 2 3})

9:24 clojurebot: false

9:24 raek: ,(sequential? (sorted-set 1 2 3))

9:24 clojurebot: false

9:36 edbond: how to setup java_options when I run 'lein swank'? I want -server etc.

9:38 neotyk: ,((fn [& {:as a}] (println a)))

9:38 clojurebot: nil

9:38 neotyk: but what if I want in general case to use this "a" to be passed to another fn with &{:as..

9:39 (flatten (seq a))

9:39 should do the job

9:39 chouser: what are you asking?

9:39 neotyk: as long as there is data in *a*

9:39 chouser: (fn [& a] ...)

9:40 neotyk: (fn [& {:as a}] ...)

9:40 chouser: isn't that the same?

9:40 oh, it's not

9:40 huh

9:40 neotyk: ,((fn [& a] (println a)) :a 1)

9:40 clojurebot: (:a 1)

9:41 neotyk: ,((fn [& {:as a}] (println a)) :a 1)

9:41 clojurebot: {:a 1}

9:41 neotyk: so I have fns f and g both with same &{:as a}

9:41 chouser: ugh

9:41 neotyk: how do I pass *a* from f to g

9:42 chouser: some of these new bits of clojure don't feel quite as clean as most of the old bits.

9:42 neotyk: it is nicer for user of f

9:42 but if f has to use g it is pain

9:42 raek: (apply g a)

9:42 chouser: (apply g (apply concat a))

9:43 raek: aw

9:43 neotyk: for now I do something like (if (empty? a) (g a) (g))

9:43 but it feels just wrong

9:43 chouser: neotyk: (apply g (apply concat a))

9:43 but I agree it doesn't feel very right.

9:44 raek: this uses keyword arguments and passes them around: http://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj

9:44 chouser: I assume you're using 'a' as a map in f as well?

9:44 neotyk: yep

9:44 bOR_: edbond - relatively easy to add in the lein bin file.

9:45 chouser: neotyk: I might collect both forms, just to avoic (apply concat a)

9:45 bOR_: or set Java_CMD

9:46 neotyk: raek: it doesn't do & {:as ...}

9:46 chouser: I dont think this would work for nil case

9:46 chouser: (fn f [& as] (let [a (apply array-map as)] ... (apply g as) ...))

9:46 raek: hrm, yeh

9:46 chouser: neotyk: why not?

9:47 neotyk: ,(apply concat nil)

9:47 clojurebot: ()

9:47 neotyk: chouser: it does work for nil case

9:49 chouser: ,(apply interleave ((juxt keys vals) {:a 1 :b 2}))

9:49 clojurebot: (:a 1 :b 2)

9:50 sid3k: ,(str "hello" "world" "yo")

9:50 clojurebot: "helloworldyo"

9:51 neotyk: ,((fn [& {:as a}] (apply (fn [& {:as a}] (println a)) a)) :a 1)

9:51 clojurebot: java.lang.IllegalArgumentException: No value supplied for key: [:a 1]

9:52 neotyk: would it be possible to make & {:as a} take also map as argument?

9:52 sid3k: I'm a newbie started learning clojure today and it's like I'm trying my new bike

9:52 chouser: sid3k: :-) welcome

9:52 sid3k: thanks :)

9:52 neotyk: normally :a 1 is converted to {:a 1} but if one would provide a map {:a 1} to it

9:53 chouser: neotyk: users will call your g function as well?

9:53 as in, it's public not a internal helper?

9:53 neotyk: yes, they might

9:54 Chousuke: neotyk: I don't think it's possible.

9:54 but you can always do it manually.

9:54 neotyk: I have to layers of api, one easy to use GET, POST and alike, and underling prepare-request execute-request

9:55 Chousuke: I know it is not possible now

9:55 I would like to know what would be consequences of having it like that

9:55 would it makes sense

9:55 there would be nice symmetry in it

9:57 you pass :a 1 it gets converted via & {:as a} to map, but you could also use map as argument to it

9:57 so (f :a 1) would be same as (f {:a 1}) if (fn f [& {:as a}] ...)

9:58 raek: I think it would make sense to design the functions that way, at least

9:58 keyword args will always have an even number of args

9:58 and keyword-args-as-map will always be just one arg

10:00 (fn [& opts] (let [opt-map (if (even? (count opts)) (apply array-map opts) (first opts))] ...))

10:00 Chousuke: that's probably too slow

10:03 neotyk: where does this & {:as a} destructuring happen?

10:03 I mean where in code?

10:03 Chousuke: in two places actually

10:04 the destructure function and the fn macro definition

10:19 Bahman: Hi all!

10:39 cemerick: neotyk: what you're suggesting would require a check (consisting of multiple conditionals) on every fn call

10:46 neotyk: cemerick: isn't there already a check?

10:46 it is hard to tell for me by looking at source of clojure.core/destructure

10:47 Chousuke: no, the conditionals you're seeing are macroexpand-time checks

10:48 it just checks if the & is followed by a map form or not.

10:48 then if it is, it generates the map-building code.

10:49 cemerick: neotyk: what Chousuke said. You can selectively get the behaviour you want with a simple wrapping fn though.

10:51 Chousuke: something like (defn map-apply [f map & other-args] (apply f (apply concat other-args map)))

10:51 ? :P

10:52 too bad the arg order has to be reversed like that.

10:52 neotyk: i do now (apply f (apply concat arg)

10:52 cemerick: I think it can be generalized.

10:53 Depends a lot on what exactly neotyk wants. :-)

10:54 neotyk: cemerick: I have fns f and g both have [& {:as a}]

10:54 f calls g

10:54 would like to pass a from f to g

11:01 cemerick: neotyk: https://gist.github.com/71a50c1628d856d3a74d

11:02 that should be generally-applicable...so you can pass kwargs or a map, in addition to positional args.

11:03 It'd be nice if the original fn metadata were retained, etc. but that's a start.

11:05 neotyk: cemerick: looks like magic to me, have to get some time to digest it

11:05 cemerick: heh. No magic, I promise. :-)

11:08 neotyk: I believe you

11:09 _rata_: hi

11:11 raek: hrm, I would like it to check the number of args passed instead of looking at the type of the last arg

11:11 (f :a {...}) should be possible too, imho

11:11 if the fn is called with kw args, then there will be an even number of args

11:12 chouser: actually, you should be able to use :inline and get no performance cost on direct calls

11:12 cemerick: raek: that's a fundamentally ambiguous situation, at least for a wrapper-fn impl.

11:13 raek: is it? the arg count is 1 for kw args passed as a map, and an even number for kw args passed directly

11:13 cemerick: chouser: you still need to spelunk into the & args going in, and then destructure or not, no?

11:14 raek: or am I missing something?

11:16 chouser: (foo a b) has to be one case and (foo a) the other, doesn't it?

11:16 only (apply foo x) is ambiguious at compile time

11:17 * cemerick has to run...looks forward to reading the logs upon his return :-)

11:18 raek: (also, the fn that does the wrapping needs to know how many fixed arguments there are)

11:19 (foo {:a 1, :b 2, :c 3}) => odd number of args (1), (foo :a 1, :b 2, :c 3) => even number of args (6)

11:19 that was what I thought

11:20 only the condition in cemerick's code would have to change

11:21 https://gist.github.com/96d7618e294c5278c90f

11:22 - (-> args last map?)

11:22 + (-> args count odd?)

11:35 pdk: is the :else keyword in a cond form mandatory for it to work as expected

11:35 or will it fall back on the last form in there either way

11:35 (doc cond)

11:35 clojurebot: "([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil."

11:36 pdk: ypu're so enlightening clojure bot

11:36 oh shit it returns nil

11:36 that's a bit of a downer after writing it all out

11:36 ,(cond)

11:36 clojurebot: nil

11:36 pdk: or is that just for cond with no args, looks like it

11:37 ,(cond 1 "guess so")

11:37 clojurebot: "guess so"

11:37 pdk: ,(cond false "first form!" "something else!")

11:37 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: cond requires an even number of forms

11:37 pdk: BAH

11:37 fine cond you can have your :else

11:38 Chousuke: you need the :else. or anything truthy, really

11:38 :i-dont-like-else works too

11:38 pdk: yeah

11:38 i'll say things about its mother in the last keyword

11:39 mfex: ,(cond (= 0 2) :zero (= 1 2) :one)

11:39 clojurebot: nil

11:40 pdk: wow

11:40 cond hates keywords!

11:40 mfex: when no clause matches and no last keyword clause cond returns nil

11:55 raek: "truthy" is a neat word...

12:01 pdk: can (keys map) and (vals map) both be guaranteed to come out in the same order that the key-value pairs are stored in the map

12:04 raek: you mean if (keys map) and (vals map) will be in the same order as (seq map)?

12:05 I think the printer uses seq

12:05 pdk: yeah

12:05 hmmmm

12:05 raek: I would suspect so...

12:05 pdk: i didnt think to use seq but that would fit the bill

12:06 Chousuke: pdk: if you neeed to go over both then probably safest is to iterate the key-value pairs instead

12:06 pdk: yeah that was what i was lookin for

12:06 forgot about it i guess :p

12:06 raek: ok, then seq does that

12:06 Chousuke: pdk: it's very likely the seqs will have the same order but it's not guaranteed anywhere so in theory you can't rely on it :)

12:42 pdk: yknow what's awesome

12:42 random null pointers with no documentation

12:47 fogus: pdk: Sounds like to need a Maybe :p

12:56 pdk: ok so

12:56 http://pastebin.com/KSUKvZVa

12:56 with this code

12:57 hazard a guess as to why the (inc (get successors :total-count line would give you a null pointer error

12:58 chouser: if successorts has no :total-count

12:58 ,(inc (get {} :total-count))

12:58 clojurebot: java.lang.NullPointerException

12:59 jfields: is there any way to put logic in the in the dispatch-val of a defmethod? For example if you want the defmethod to match any value in a set? something like: (defmethod foo #{:bar, :baz} [m] ()); where the caller uses (foo {:type :bar}) or (foo {:type :baz}) to call the method?

12:59 pdk: all maps within this structure are struct-maps of a defstruct i made that includes :total-count

12:59 and i had the (if (nil? successors bit so it wouldn't try to get from nothing

13:00 chouser: hm, so the value of :total-count would have to be nil I think.

13:03 dnolen: jfields: not really, but rhickey has spoken about wanting support things like that.

13:04 jfields: dnolen, cool. thanks.

13:07 fogus: Hmmmm, you know it would be nice to do this: (defmethod foo [1 2] :as x [v] (println "I dispatched on" x))

13:08 pdk: chouser i have two functions that initialize and insert items into the structure

13:09 they ensure that :total-count has a positive numeric value except when the structure is empty in which case :total-count at the root level will be 0

13:10 ,(get {} :test)

13:10 clojurebot: nil

13:11 raek: ,(inc nil)

13:11 clojurebot: java.lang.NullPointerException

13:11 raek: ,(inc (get {} :test 0))

13:11 clojurebot: 1

13:13 raek: pdk: the NPE did not come from 'get', but from 'inc'

13:13 pdk: yeah the thing that's vexing me is

13:14 since the inc is within the else clause of that (if (nil? successors block why is it being reached and doing this if successors is nil

13:15 raek: successors is a map (not nil) but does not have the key :total-count (nil)

13:15 pdk: now that's odd

13:15 raek: contains? checks if it has a key

13:16 acutally, successors can be anything truthy at that point

13:16 pdk: thing is all of the additions to the structure are being done through this http://pastebin.com/GSPCRRWu

13:16 raek: i.e. anything but nil and false

13:17 pdk: which is making every map added a struct-map that contains :total-count

13:17 raek: ,(get (ref {:a 1}) :a)

13:17 clojurebot: nil

13:17 raek: it's not wrapped in something?

13:18 pdk: what do you mean exactly

13:18 ,(get @(ref {:a 1}) :a)

13:18 clojurebot: 1

13:18 pdk: though come to think of it

13:19 maybe the fact that the get within new-total-count right there defaults to nil instead of 0

13:19 that may explain the error

13:19 ummmm

13:19 or not

13:20 raek: can you do a (do (println successors) (if (nil? sucessors) ...

13:21 that would make it simpler to diagnose

13:21 to see if successors is really a map, and if so whether it contains the key

13:22 pdk: sure

13:23 oh no wonder

13:24 the values of the keys outside of those defined in the defstruct

13:24 are REFS to maps

13:24 and i forgot that

13:24 so this all came down to not having a lowly @

13:26 changing (inc (get successors :total-count and (rand-key (seq successors to add a @ to both fixes it it seems

13:27 raek: the values you let could be functions

13:28 that would make the code easier to test

13:28 one shouldn't generally have to inject printlns

13:29 (let [successors ... -> (defn sucessors [ ...

13:35 pedroteixeira: can we have function overload with protocols?

13:35 [same name, different arity]

13:36 raek: no, protocol methods have vars in the namespace, just like functions

13:37 pedroteixeira: raek: ok, thanks.

13:37 aldebrn: Any general advice on converting an XML tree into a specific document (viz., Latex)? After parsing the XML file into a map structure, I recursively converted each tag into a string using a multimethod, but I think that's ham-fisted and I wonder if I should be using zip-filter or xml-zip to properly walk the tree

13:40 hiredman: general structure for that sort of thing seems to be: (-> create-tree transform1 transform2 collapse)

13:43 edbond: how to profile clojure code?

13:43 aldebrn: Thanks hiredman, I'll study ->

13:43 pdk: (doc do)

13:43 clojurebot: Huh?

13:43 pdk: fk

13:44 edbond regular java profilers can be used on a running clojure session it sounds like

13:44 there's a bit mentioned in the getting-started section of clojure.org

13:46 raek: aldebrn: (-> e f3 (f2 c d) (f1 a b)) becomes (f1 (f2 (f3 e) c d) a b)

13:47 edbond: tried c.c.profile but it doesn't works, empty table only

13:48 raek: that one requires you to put (prof ...) in your code

13:57 aldebrn: Thanks raek. Seeing how to use zippers and -> to transform xml trees wholesale will need some thinking, the online examples I've found are small-scale specifics

14:13 edbond: raek: no, it doesn't require prof, http://richhickey.github.com/clojure-contrib/profile-api.html example doesn't work

14:14 1.2 beta

14:15 hm, my fault. didn't see that prof stuff

14:16 raek: there are "real" profilers too

14:16 I tried jvisualvm briefly once

14:17 https://visualvm.dev.java.net/

14:18 any java profiler will work, but the classes might have funny names

14:18 like

14:18 ,(fn [])

14:18 clojurebot: #<sandbox$eval500580$fn__500581 sandbox$eval500580$fn__500581@7c06b2>

14:18 raek: those kind of names

14:19 edbond: raek: thanks, will try yourkit

14:27 lozh: you probably alerady have jvisualvm if you're using a recent jdk, should be in the bin folder

14:40 raek: I'm philosophizing about whether I should use defrecord, deftype or reify

14:41 in this case, the fields would not be of any use to the user directly

14:42 anyone have any examples of cases for each one where it would be no doubt that it is the best fit?

14:47 rhudson: raek, little direct experience, but my take is reify for one-offs, defrecord for most things, deftype if your name is Hickey

14:55 aldebrn: Is there a latest vim clojure tool somewhere? There's so many outdated things online, and mine doesn't autoindent >.>

14:59 raek: since I have a separate "constructor function" for my defrecord and never access the fields from the outside, i'm thinking about calling reify in the constructor fn instead

15:10 patrickdlogan: aldebrn: re: XML to other doc formats - what I've been doing lately is a basic XML to RDF then use Jena and SPARQL "construct" queries to build the graph I want, then spit out the appropriate doc format from that.

15:10 (heckalot easier than anything else I've ever done)

15:15 hiredman: aldebrn: the point is not -> but that you get a tree, you put the tree through transformation stages, then you collapse or output the tree, or whatever

15:15 zippers are very useful for the transformation pipeline, but I dunno how useful they would be for the end

15:38 arohner: on a sorted set, is there a way to get the index of an element?

15:39 dakrone: arohner: you could use clojure.contrib.seq-utils' "indexed" function

15:40 arohner: dakrone: thanks, but I'm looking for simple, fast lookup

15:41 tomoj: sorted sets don't implement any interfaces that look useful

15:41 arohner: i.e. (index-of :c #{:a, :b, :c,:d}) => 2

15:41 tomoj: iow I think you're stuck with O(n)

15:42 arohner: :-(

15:42 chouser: arohner: you need a finger tree

15:43 Nikelandjelo: arohner: ,(doc positions)

15:43 ,(doc positions)

15:43 clojurebot: "clojure.contrib.seq-utils/positions;[[pred coll]]; Returns a lazy sequence containing the positions at which pred is true for items in coll."

15:43 chouser: arohner: I haven't tried it yet: http://functionaljava.googlecode.com/svn/artifacts/2.21/javadoc/fj/data/fingertrees/FingerTree.html

15:43 Nikelandjelo: ,(positions #(= 4 %) (tree-set 5 4 3 2 1))

15:43 clojurebot: java.lang.Exception: Unable to resolve symbol: positions in this context

15:44 Chousuke: positioning is undefined for a set

15:45 Nikelandjelo: Chousuke: It works for me

15:45 arohner: Chousuke: I specified a sorted set

15:45 chouser: sorted sets can't get by index better than O(n)

15:45 Nikelandjelo: It's still O(n), but it's not very long to write

15:45 chouser: you need child count info on each node of the tree, and clojure sorted sets don't do that.

15:45 finger trees can

15:46 Nikelandjelo: arohner: Do you need speed or simplicity? :)

15:46 arohner: Just wondering

15:46 arohner: Nikelandjelo: sub O(n)

15:48 I can clojure.set/index the collection, but that changes the datastructure. I could keep the results of set/index in metadata or something

15:48 chouser: arohner: finger trees!

15:49 you keep ignoring me and I'll have to solve this for you myself. :-P

15:49 arohner: chouser: maybe I'll keep ignoring you then :-P

15:49 Nikelandjelo: chouser: Is there implementation in clojure?

15:50 chouser: Nikelandjelo: yes, though it's not ready for prime time.

15:57 wow. pain.

16:06 Bjering: What is the idiomatic clojure way to make a discrete event based simulation? In another language I would make a priority queue, post events to it, and have a thread-pool of workers working away at it (with complex locking on my part). I want to get rid of the locking thanks to the STM, but I am unsure how/what to map the thread-pool too.

16:09 chouser: the thread pool is probably a java Executor and the queue is probably a java BlockingQueue

16:10 jstirrell`: is

16:10 Bjering: Alright, so if I was planning to use Netty in the same app (for the I/O) I could/should just go along and use the same pool for simulation part?

16:10 jstirrell`: is there an easy way to do make all nested elements of a seq top level?

16:11 raek: flatten

16:12 chouser: Bjering: not sure. I don't know what Netty's thread pool looks like

16:12 jstirrell`: sweet thanks raek

16:12 chouser: Bjering: I'd probably make my own Executor instance so that I could tweak it's parameters without messing with Netty's behavior at the same time.

16:12 Bjering: chouser: But in principle as long as it is a java thread clojure is fine with it? Nothing speciial is needed (such as registering with the STM or so?)

16:13 chouser: right

16:14 Bjering: thanks, sounds good, I'll walk down this path and see where it leads.

16:15 pdk: (doc rand-int)

16:15 clojurebot: "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)."

16:15 pdk: ,(rand-int 0)

16:15 clojurebot: 0

16:16 chouser: arohner: I take it back. Unless I'm missing something functionaljava's finger trees are missing support for 'split' which you'd need to get sorted-set behavior.

16:16 weissj: i'm having some trouble figuring out ->>. I think this fn is a good candidate for using ->> but i can't figure out how to turn it inside out: (defn gather-tests [testfilter nslist]

16:16 (filter testfilter (vals (apply concat (map ns-publics nslist)))))

16:17 chouser: arohner: you could try to use my finger-tree, but it's probably not worth it.

16:18 weissj: try: (defn gather-tests [testfilter nslist] (->> nslist (map ns-publics) (apply concat) vals (filter testfilter)))

16:18 weissj: chouser: thanks!

16:18 that is what i had, but it didn't look right for some reason

16:20 chouser: run your copious unit-tests on it to gain a sense of comfort that it's correct. :-)

16:24 pdk: with a struct-map the keys declared in the defstruct are always lumped at the start of the map's sequence form right

16:24 ,(doc struct-map)

16:24 clojurebot: "([s & inits]); Returns a new structmap instance with the keys of the structure-basis. keyvals may contain all, some or none of the basis keys - where values are not supplied they will default to nil. keyvals can also contain keys not in the basis."

16:24 pdk: ,(doc defstruct)

16:24 clojurebot: "([name & keys]); Same as (def name (create-struct keys...))"

16:24 pdk: ,(doc create-struct)

16:24 clojurebot: "([& keys]); Returns a structure basis object."

16:25 raek: i don't know if one can rely on that the struct's own keys always will be first

16:25 pdk: hm

16:25 raek: if it doesn't say it in the docs

16:25 pdk: well the code to skip iterating over the keys already in the struct is already there so we can deal

16:32 "A struct map will retain its base keys in order."

16:57 aldebrn: patrickdlogan, thanks for the pointers on converting XML to templated doc formats, I'll look into them. I know I want to transform nearly every tag into a document representation, so a walk makes more sense than a set of queries, but I'll think about it

16:59 hiredman, after puzzling over the zipper docs, it looks like a zipper is one good structure to use for a walk through the tree, applying transformations that might rely on a node's ancestors and descendants (e.g., in reST-to-XML, <section> tags are used to denote chapters, sections, subsections, etc., which Latex differentiates between)

17:00 I'm trying to decide how to transform a node object into a string, and build that alongside a zipper (or whatever walker is used)

17:01 patrickdlogan: aldebrn: sure thing - though it may work well. look at sparql "construct" queries (and you can do that over in-memory graphs - v.lightweight)

17:03 jkkramer: does anyone have an emacs config that supports nice indentation for defrecord and friends?

17:03 raek: i've been looking for that too

17:04 technomancy: patches please!

17:04 * technomancy doesn't actually use defrecord

17:07 jkkramer: it seems like a tricky thing to deal with, since it's context-sensitive

17:07 rhudson: aldebrn: you might want to look at XSLT, at least for inspiration. It's a pure functional language specifically designed for doc transformations

17:07 raek: jkkramer: how?

17:09 jkkramer: raek: from what i can tell, most indentation rules can be specified per the first symbol -- e.g., by telling it that defn indents like defn

17:09 raek: but for defrecord method bodies, the first symbol in the form changes

17:09 raek: ah

17:10 jkkramer: if all your defrecord methods are on one line like most examples, it's fine, but not for multiline methods

17:10 raek: yeah, I see the issue

17:11 letfn has the same problem

17:14 also, anyone else think that def contents should be indented 2 spaces too?

17:15 so the contents of a map replacing a function is to the left

17:15 jkkramer: raek: agreed...i was just about to make that change to clojure-mode.el

17:16 * raek stamps a "raek seal of approval" on jkkramer's efforts

17:16 technomancy: yay, patches. =)

17:18 raek: technomancy: any rationale on the current indentation of 'def'?

17:19 in case we just dug up some "this has been discussed thorougly before" issue...

17:21 technomancy: raek: nope, 100% legacy

17:21 that is to say, I didn't write it, I inherited it.

17:24 raek: was the backtracking-indent inherited by you too?

17:24 technomancy: aye; no idea what it does.

17:25 raek: jkkramer: the backtracking-indent knows about proxy, which should be indented like defrecord and friends

17:25 iirc

17:25 maybe it's just a matter of adding defrecord/deftype/reify to that list

17:26 jkkramer: raek: ya, could be; will experiment. my emacs lisp skills are poor

17:26 raek: mine too

17:26 now, how do I activate an elisp defcustom?

17:29 okay, letfn indents well with M-x customize-variable clojure-mode-use-backtracking-indent

17:38 pdk: ,(= (seq [1 2 3]) (seq '(1 2 3)) (list 1 2 3))

17:38 clojurebot: true

17:38 pdk: ,(seq [1 2 3])

17:38 clojurebot: (1 2 3)

17:45 jkkramer: raek: yup, after figuring out how to recompile clojure-mode.el, adapting the proxy indent rule for defrecord, and enabling backtracking-indent, it works! sweet

17:45 still can't get def to indent 2 spaces though

17:48 raek: jkkramer: add (def 'defun) over (defn 'defun)

17:48 (put 'defrecord 'clojure-backtracking-indent '(4 4 (2)))

17:48 (put 'deftype 'clojure-backtracking-indent '(4 4 (2)))

17:48 (put 'reify 'clojure-backtracking-indent '((2)))

17:48 these are the changes I made

17:50 oh, forgot defprotocol

17:50 tomoj: raek: that fixes defrecord??!

17:50 I didn't think it was possible with the way clojure-mode currently indents

17:50 jkkramer: raek: oh, there we go. i didn't restart proprely

17:50 raek: yes, if one activates clojure-mode-use-backtracking-indent

17:50 tomoj: awesome!

17:50 raek: which is experimental

17:50 jkkramer: that should be enabled by default

17:51 seems to work well enough

17:51 tomoj: raek: thanks!

17:51 qbg: What is backtracking-indent?

17:51 raek: a feature of clojure-mode

17:52 that the old maintainer started to work on

17:52 jkkramer: which has apparently laid dormant until now

17:52 qbg: How is it different than the normal indent that clojure-mode provides?

17:52 raek: it can indent letfn, proxy and defrecord better

17:52 qbg: Sounds nice

17:52 I hate indenting them by hand

17:52 raek: 23:07 < jkkramer> raek: from what i can tell, most indentation rules can be specified per the first symbol -- e.g., by telling it that defn indents like defn

17:52 23:07 < jkkramer> raek: but for defrecord method bodies, the first symbol in the form changes

17:53 jkkramer: could you add defprotocol '(4 (2)) too?

17:53 or, should you or I do the patch?

17:54 jkkramer: raek: feel free to go ahead. i didn't fork or anything yet

17:54 raek: ok, I have a fork

17:57 StartsWithK: any one using c.c.error-kit or c.c.except?

18:02 jkkramer: oh man, this is so much better now, with proper auto-indents

18:04 raek: i fixed future to indent like do, too

18:05 it's bad when the try and future forms are next to each other, and the indentation differs with one space

18:05 also, I wanna remove the special indentation for assoc

18:05 I think special indent should be reserved for macros

18:06 any comments?

18:07 technomancy: raek: let's leave it alone for now.

18:08 jkkramer: i never noticed that one before

18:10 technomancy: while we're fixing clojure-mode, if somebody could make it so delete-trailing-whitespace doesn't kill commas et the end of the line that'd be great too. =)

18:10 maybe it'd be better just to not treat commas as a whitespace syntax class

18:12 raek: technomancy: assoc? future too?

18:12 jkkramer: maybe multiline docstring indentation, too?

18:12 technomancy: raek: just assoc. future sounds good.

18:12 raek: k

18:14 I won't change the default setting for clojure-mode-use-backtracking-indent

18:15 since I don't want to potentially break the clojure community's indentation over a night

18:17 lozh: can fix the preferred ^Class hint too by adding ("\\^\\sw+" 0 font-lock-type-face) towards the end of clojure-font-lock-keywords

18:18 only #^Class gets highlighted as it stands

18:19 and I've no idea whey #?^\\sw+ doesn't match both patterns

18:23 raek: lozh: which line?

18:25 lozh: between 513 and 514 as I'm looking in github now

18:27 raek: found it

18:27 lozh: cool, was halfway through cloning it :)

18:29 raek: that regex matches both

18:29 but I had to restart clojure-mode

18:30 lozh: Doesn't work in mine, odd, even though it did in re-builder

18:30 I'll double check restarting it

18:33 Definetely doesn't work for me, just doing (defn test ^String a]) into a blank buffer doesn't highlight with #?^\\sw+

18:34 but #^String does

18:37 cmihai: Is there any official Clojure documentation, specs and / or API I can download for offline use (such as pdf or zipped html formats)? I could mirror the whole website with httrack or wget or grab the urls from the front page source, but that's probably not very nice.

18:38 pdk: i highly doubt there's any large files on there to make people worried about bandwidth

18:38 lozh: I don't think wget would be too painful, there's not that many pages linked

18:38 pdk: it's practically all text

18:38 cmihai: Same goes for the blip.tv videos, I can easily grab the flv, but that is rather taxing on my time :-)

18:39 technomancy: cmihai: fixed the curl-related bug you found yesterday btw.

18:39 cmihai: Hm... I just grabbed the source, ran an emacs macro and curl-ed it locally, looks readable... but no saved pictures and stuff and would need more cleanup.

18:39 technomancy: oh, cool :-)

18:39 lozh: Wonder if clojure-mode makes more sense in the languages customisation group rather than application

18:39 cmihai: %s/curl/wget/g ? :P

18:39 technomancy: cmihai: eh; it was actually a bug involving both.

18:43 cmihai: technomancy: ah, the -fail flag. Epic :-)

18:50 lozh: raek: do you still have clojure-mode handy - line 323 could do with a ? after the # too - fixes up (def^{:doc "foo"} bar) to highlight bar

18:51 I daresay the one on 465 could too, but I don't know what that affects yet

18:53 StartsWithK: so, here is a small lib that can be used to define custom exceptions http://paste.pocoo.org/show/243227/

18:54 you can (defexception Foo) that will create a real java class

18:55 like in error-kit, exceptions can have extra data attached to them

18:57 raek: lozh: ok

18:57 lozh: ty

18:58 raek: http://github.com/raek/clojure-mode/commits/master

18:58 this is what I have so far

19:01 technomancy: enjoy the patches!

19:01 technomancy: wheeeee

19:01 raek: I have a high-priority fix coming out soon in Lein 1.2.1; hope to get to my elisps soon after.

19:02 raek: no worries

19:03 lozh: jkkramer: thanks for the help!

19:04 anyone know how to disable tab characters in emacs?

19:05 I want them *gone*!

19:05 jlf: M-x customize-variable RET indent-tabs-mode

19:06 Raynes: technomancy: Write an Emacs clone in Clojure configurable in Clojure.

19:06 technomancy: down with tabs!

19:06 jlf: and C-x h M-x untabify

19:06 * jlf distributes torches

19:06 Raynes: I shouldn't joke. Knowing you, you'll actually do it and kill yourself. ._.

19:06 technomancy: Raynes: nope, I'll just get Clojure to compile to Emacs bytecode.

19:06 much less work

19:07 Raynes: Cute.

19:07 * technomancy glances around nervously

19:07 technomancy: I've said too much.

19:08 raek: jlf: thanks

19:08 jlf: np

19:09 raek: technomancy: that patch I submitted some months ago for fixing name-space -> name_space in clojure-test-mode.el... it contained a tab character....

19:09 *ashamed*

19:10 * raek goes re-indenting some of his libs

19:11 technomancy: raek: it's ok, this indentation code has paid the penance. =)

19:16 * technomancy idly wonders why dissoc and disj are separate functions

19:23 pdk: (doc dissoc)

19:23 clojurebot: "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."

19:23 pdk: (doc disj)

19:23 clojurebot: "([set] [set key] [set key & ks]); disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s)."

19:23 pdk: voila

19:25 technomancy: conj works on sets and maps (as well as vectors, lists, etc); I don't see why disj should be different.

19:26 (minor point of course)

19:28 raek: I guess it's just a matter of naming symmetry

19:28 assoc-dissoc, conj-disj

19:37 slyrus_: technomancy: thanks for the lein manual install instructions!

19:37 to get it fully working however, I had to do: cp lib/dev/swank-clojure-1.2.1.jar lib/

19:37 oh, and I like the ideas about the hooks

20:16 weissj: if i want a try/catch/finally block to return a map, and one of the items in the map is the "end time" of the block execution, how do i add that? the finally seems to only be for side effects.

20:17 i guess i could just assoc it after the whole block

20:41 gfrlog: what's the clojure word for zip?

20:41 as in (zip [1 2 3] [:a :b :c]) => ([1 :a] [2 :b] [3 :c])

20:42 rhudson: (map vector coll1 coll2)

20:42 gfrlog: very good

20:42 technomancy: ,(seq (zipmap [1 2 3] [:a :b :c]))

20:42 clojurebot: ([3 :c] [2 :b] [1 :a])

20:43 technomancy: not quite the same, but if you want a map back...

20:43 gfrlog: oh

20:43 well that still gives a seq back...

20:43 ooh

20:43 no it doesn't

20:53 polypus: is it possible to typehint the return type of an anonymous fn?

21:05 gfrlog: how do you find out if a vector contains a value?

21:05 or list, I guess

21:08 ,(any? #(= 10) [1 2 5 10 23])

21:08 clojurebot: java.lang.Exception: Unable to resolve symbol: any? in this context

21:08 rhudson: The usual idiom is (some #{x} coll)

21:08 gfrlog: ah yes

21:08 rhudson: ,(some #{10} [1 2 5 10 23])

21:08 clojurebot: 10

21:09 gfrlog: ,(some #{nil} [1 4 nil 2 3])

21:09 clojurebot: nil

21:09 gfrlog: ,(some #{nil} [1 2 3 4])

21:09 clojurebot: nil

21:09 gfrlog: let's hope one isn't looking for nil then

21:10 rhudson: (some #(= % nil) ...) works in that case

21:10 gfrlog: yep

21:10 wait

21:10 ,(some #(= % nil) [1 2 3])

21:10 clojurebot: nil

21:10 rhudson: But I'm always surprised when I type any? and it isn't there

21:10 gfrlog: ,(some #(= % nil) [1 nil 3])

21:10 clojurebot: true

21:11 gfrlog: ,(def any? some)

21:11 clojurebot: DENIED

21:11 gfrlog: oh that hurt

21:11 rhudson: clojurebot doesn't like def's

21:12 gfrlog: ,(apply def [x 10])

21:12 clojurebot: DENIED

21:12 gfrlog: what a jerk

21:12 tomoj: -> (def any? some)

21:12 sexpbot: => #'net.licenser.sandbox.box3508/any?

21:12 tomoj: -> (any? #{4} [1 2 3 4])

21:12 sexpbot: => 4

21:12 polypus: ,(eval '(def any? some))

21:12 clojurebot: DENIED

21:12 polypus: figures

21:13 gfrlog: ,(println "DENIED")

21:13 clojurebot: DENIED

21:13 rhudson: :)

21:13 gfrlog: did it work? we'll never know...

21:13 polypus: ,

21:13 clojurebot: EOF while reading

21:14 polypus: ,

21:14 clojurebot: EOF while reading

21:14 gfrlog: (let [x (java.util.ArrayList.)] (.add x 12) (.add x x) x)

21:14 dang

21:15 ,(let [x (java.util.ArrayList.)] (.add x 12) (.add x x) x)

21:15 clojurebot: #<ArrayList [12, (this Collection)]>

21:15 gfrlog: oh weird

21:16 tomoj: huh, clojurebot's sandbox sucks

21:17 ,foo

21:17 clojurebot: bar

21:17 rhudson: gotcha!

21:19 That (this Collection) thing isn't clojurebot; it's Clojure itself

21:19 pretty clever, I think

21:20 gfrlog: ruby does that too, I found out yesterday

21:20 it's a weird thing that you can only get with mutable data types

21:20 rhudson: Well, for an immutable collection there's not (obvious) way to get it to contain itself

21:21 tomoj: seems like it's java, not clojure

21:21 gfrlog: it's whoever's turning the thing into a string

21:21 ,(.toString (java.util.ArrayList.))

21:21 clojurebot: "[]"

21:22 gfrlog: ,(.toString (java.util.arrayList [2 34 4]))

21:22 clojurebot: java.lang.ClassNotFoundException: java.util.arrayList

21:22 gfrlog: ,(.toString (java.util.ArrayList [2 3 33 333]))

21:22 clojurebot: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn

21:22 gfrlog: gosh dangit

21:22 ,(.toString (java.util.ArrayList. [2 3 33 333]))

21:22 clojurebot: "[2, 3, 33, 333]"

21:23 rhudson: Yeah, the (this Collection) thing turns up in Groovy too, so kudos Java

21:23 gfrlog: ,(.toString (let [x (java.util.ArrayList. [3])] (.add x x) x))

21:23 clojurebot: "[3, (this Collection)]"

21:24 gfrlog: python catches it too

21:25 tomoj: ,(+ 2 2)

21:25 clojurebot: 5

21:25 gfrlog: ,(+ 2 2)

21:25 clojurebot: 4

21:25 tomoj: ;)

21:25 gfrlog: I think that makes you a witch

21:26 tomoj: I'm surprised sexpbot's been abused by clojurebot fans

21:26 clojurebot seems defenseless

21:26 gfrlog: ,(System/getProperties)

21:26 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)

21:27 rhudson: clojurebot: here's a botsnack

21:27 clojurebot: thanks; that was delicious. (nom nom nom)

21:30 gfrlog: why does he claim it is delicious, in the past tense, and only then proceed to nom on it?

21:30 rhudson: postprandial lipsmacking?

21:30 gfrlog: I question clojurebot's integrity

21:31 ,(Thread/sleep 10)

21:31 clojurebot: java.lang.Exception: No such namespace: Thread

21:44 defn: i would like to put into question your question of clojurebot's integrity

21:45 Hmmm, this Seph language looks sort of neat

21:48 gfrlog: how do I get the first item in a list that satisfies a predicate?

21:49 rhudson: (first (filter pred? coll))

21:49 gfrlog: easy!

21:49 man it's hard to think lazily

21:50 rhudson: Takes a while but it opens up whole new vistas

21:50 cmihai: Does clojurebot support reverse polish sausage noming?

21:53 defn: only if it's unadulterated

21:56 tomoj: defn: where do I see it?

21:56 I only lightly skimmed the blog post and gave up when there was no code

22:01 gfrlog: dangit what's clojure for reduce?

22:01 rhudson: uh, reduce?

22:01 gfrlog: (doc reduce)

22:01 clojurebot: "; "

22:02 gfrlog: huh?

22:02 I don't see it on clojure.org/api

22:02 rhudson: ,(clojure-version)

22:02 clojurebot: "1.2.0-master-SNAPSHOT"

22:02 rhudson: For some reason reduce documentation disappeared in some of the 1.2.0 snapshots

22:02 gfrlog: is reduce deprecated?

22:02 oh ok

22:02 rhudson: It's there in beta1

22:02 gfrlog: I was gonna say

22:02 rhudson: -> (doc reduce)

22:02 sexpbot: => ------------------------- clojure.core/reduce ([f coll] [f val coll]) f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, ... http://gist.github.com/499722

22:03 gfrlog: -> (clojure-version)

22:03 sexpbot: => "1.2.0-beta1"

22:03 TheBusby: it is interesting that reduce doesn't show up in the docs for core

22:05 gfrlog: Rich has thought of something better

22:05 rhudson: user=> (doc reduce)

22:05 -------------------------

22:05 clojure.core/reduce

22:05 ([f coll] [f val coll])

22:05 f should be a function of 2 arguments. If val is not supplied,

22:05 returns the result of applying f to the first 2 items in coll, then

22:05 applying f to that result and the 3rd item, etc. If coll contains no

22:05 items, f must accept no arguments as well, and reduce returns the

22:05 result of calling f with no arguments. If coll has only 1 item, it

22:05 is returned and f is not called. If val is supplied, returns the

22:05 result of applying f to val and the first item in coll, then

22:05 applying f to that result and the 2nd item, etc. If coll contains no

22:05 items, returns val and f is not called.

22:05 gfrlog: like extend

22:05 rhudson: I don't know why the docstring for reduce is so volatile, but I can't imagine it going away any time soon

22:05 TheBusby: Understand it's there, just why not here? http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/reduce

22:06 slyrus: it's probably in the special forms page

22:06 gfrlog: it can't be a special form

22:07 TheBusby: doesn't appear in the index either...

22:09 rhudson: In the current source reduce is defined early on without a docstring, but with a comment that it's gonna be redefined later after internal-reduce is defined. But that later def is commented out (with #_ ) So it's there, but doesn't show up in the doc because there's not docstring.

22:11 In between, it's used in about a zillion places

22:12 So I take it to mean that internal-reduce (whatever that is) and/or the definition of reduce in terms of it, isn't quite baked yet

22:14 the two api doc branches are 'master' (the bleeding edge) and '1.1' (stable release).

22:14 It's a little unfortunate there isn't a '1.2-beta1' branch

22:14 chouser: are we in beta now?

22:15 rhudson: You would know better than me. There's a 1.2.0-beta1 download

22:18 gfrlog: I'm having an awful time constructing a large binary tree without blowing the stack.

22:18 I tried using lazy-seq around the recursive calls, but that just delayed the stack blowing until the seq was resolved

22:19 I feel like I'm missing something easy

22:19 rhudson: Is it something you can build from the bottom up?

22:19 gfrlog: that'd be a bit strange I think

22:20 rhudson: Well, depends on what you're trying to do. What are you trying to do?

22:21 gfrlog: well, say you have a number. like 42.

22:21 rhudson: I like 42

22:21 gfrlog: I would like to turn 42 into

22:21 ,(* (* (+ (+ (*) (*)) (*)) (+ (* (+ (*) (*)) (+ (+ (*) (*)) (*))) (*))) (+ (*) (*)))

22:21 clojurebot: 42

22:22 rhudson: ok. btb you do know that + and * are n-ary, right?

22:22 gfrlog: yeah

22:22 rhudson: just checking, sorry

22:22 gfrlog: it's just simpler code to do it binary

22:24 this is crazy. I can't think of any way of doing this.

22:25 tomoj: hmm

22:25 ,(* (* (+ (+ (*) (*)) (*)) (+ (* (+ (*) (*)) (+ (+ (*) (*)) (*))) (*))) (+ (*) (*)))

22:25 clojurebot: 42

22:25 tomoj: wtf?

22:25 oh, heh, I accidentally left my repl with the + that always returns 5

22:26 gfrlog: ha!

22:26 rhudson: what's the representation -- what's the boring form with all the (*) added together?

22:27 gfrlog: huh?

22:27 rhudson: 6*7? 2*3*7? 3*7+3*7 ?

22:27 gfrlog: oh I dunno

22:27 :) it's something

22:28 it works out evidently

22:28 rhudson: i.e., what's your method for turning a number into that form?

22:28 gfrlog: well the one I've been trying is to check if the number is divisible by anything in (2..12)

22:28 if so you create a (* d (/ n d))

22:29 otherwise decrement and try again

22:29 (creating a (+ (*) (dec n))

22:29 tomoj: what the heck are you really trying to do? O_o

22:30 gfrlog: I was gonna create this gigantic bunch of crazy code that would make clojurebot say something silly and then everybody would think I was clever

22:30 or had too much time

22:30 but now I'm genuinely interested in why this seems to be so hard to do in clojure

22:31 the only way I can possibly imagine doing this is with mutable data types

22:38 oh well

22:38 rhudson: This might be a job for clojure.zip

22:39 start with (vector-zip [42]) and start transforming it.

22:41 or maybe (seq-zip '(42))

22:47 slyrus: hrmm... anyone using fnparse3?

22:51 tomoj: I wish

22:52 slyrus: why?

22:52 clojurebot: http://clojure.org/rationale

22:52 slyrus: silly bot

22:54 tomoj: I've tried reading the source but still don't get it

22:55 weissj: i'm trying to write a recursive function that traverses a tree (checking "dependencies" and keeping track of them to catch circulars), but I am a little stumped on how to recur in a loop. can someone point me to an example?

22:56 (when i say recur in a loop, i mean call recur multiple times)

22:58 slyrus: tomoj: I guess the question is fnparse2 or fnparse3? or keep doing this #^&^*! parsing by hand

22:59 weissj: hm i guess i don't use "recur" at all, just call the function in the "normal" stack consuming way. my tree should be shallow enough for that to work.

23:00 rhudson: weissj: you can call recur in any tail position in the loop. That would typically be the result expressions of 'if or 'cond

23:00 weissj: rhudson: but this is a tree recursion - so my original call to the fn should spawn multiple recurs, which themselves could spawn multiple recurs etc

23:01 how do i do multiple recurs? doseq doesn't seem right

23:01 since it is for side-effects

23:02 tomoj: you can't

23:02 weissj: tomoj: this is a pretty common scenario, what's the idiomatic way?

23:02 lancepantz: anyone happen to know what unit jetty returns time in within the statistics handler?

23:02 weissj: just consume the stack?

23:03 tomoj: trampolines might help

23:03 often better to just rethink the way you're doing it

23:04 rhudson: Would tree-seq work for you?

23:05 weissj: rhudson: i don't know, will it handle circles? i doubt it. my code needs to catch circular deps

23:06 let me check if trampoline will work

23:06 rhudson: maybe clojure.contrib.graph ?

23:09 weissj: i dunno, there's gotta be a standard way of doing this. i'm just traversing a tree

23:09 tomoj: tree-seq does a depth-first traversal

23:09 weissj: tomoj: but i want to write the recursive function myself

23:09 tomoj: maybe you should look at tree-seq's source, then?

23:09 weissj: how is the recursion in a tree done, normally?

23:10 yeah i guess that's what i should do :)

23:10 rhudson: If there's loops in it, it's not a tree

23:10 weissj: rhudson: yeah, i just want to throw an exception if i find a loop

23:10 tomoj: if you pass something with a cycle to tree-seq I think you'd get an infinite seq back

23:11 and you'd have to walk the seq collecting what you find to check for dups

23:11 rhudson: Well, you could make a set of all the nodes you've seen in the tree walk, and barf if you find one you've already seen

23:11 weissj: rhudson: yeah that was my plan

23:12 rhudson: Without looking at the source, I imagine wraps the recursive calls with lazy-seq

23:12 [I imagine => I imagine tree-seq]

23:13 tomoj: yep

23:13 weissj: rhudson: yeah, it recurs the old fashioned way, just by calling itself

23:14 so i guess that's what i'll do. thanks :)

23:16 rhudson: lancepantz, don't know about jetty stats specifically, but most Java time stuff is msec

23:17 lancepantz: rhudson: you are correct, i eventually found it

23:32 technomancy: reduce's metadata disappearing was due to a bug.

23:32 there was a more performant version of reduce that used protocols; somehow its definition overwrote the metadata on the original

23:32 I think that reduce got disabled for 1.2 though

23:40 defn: fogus is my hero: seq-utils

23:40 err: http://www.fogus.me/fun/unfix/

23:40 awesome.

Logging service provided by n01se.net