#clojure log - Nov 01 2009

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

1:11 Raynes-: I set the Paredit cheatsheet as my desktop background. :>

1:48 notallama: just redid pointfree library with arrows. everything still works for functions, though. http://github.com/hclarke/pointfree-clojure

2:13 piccolino: Is there some way to have a private binding in a namespace? There's no def-, as far as I can find.

2:18 tomoj: piccolino: (def #^{:private true} foo ...)

2:18 piccolino: Ah, OK, thanks.

2:18 tomoj: though, I think there is a def- or something like it in contrib

2:18 well, there's defvar- in clojure.contrib.def

4:10 mikem`: ~re-split

4:10 clojurebot: It's greek to me.

4:11 mikem`: ~def re-split

5:09 gerry_: (defyte Person [name age] [java.lang.Runnable] (.run [] (println (str "hello " name ))))

5:31 how to make repl auto-indent on console?

5:31 i'm using lrwrap

5:32 tomoj: not an emacs user by chance are you?

5:33 gerry_: tomoj: sometimes i like using console not emacs

5:34 tomoj: peculiar

5:34 gerry_: what's it

5:34 clojurebot: what is wrong with you

5:35 gerry_: you don't play on console?

5:36 just type clj and hack in clojure,that's not bad

5:40 it seems reify doc dont hooked in new branch?

5:41 (doc reify)

5:41 java.lang.Exception: Unable to resolve var: reify in this context (NO_SOURCE_FILE:1)

5:43 ,(doc reify)

5:43 clojurebot: Pardon?

5:43 gerry_: ,(doc new)

5:43 clojurebot: Pardon?

5:43 gerry_: ,(+ 1 2)

5:43 clojurebot: 3

5:44 gerry_: ,(doc conj)

5:44 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

5:44 gerry_: hmm

5:46 ,*clojure-version*

5:46 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}

5:46 gerry_: ,(doc deftype)

5:46 clojurebot: "clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being

5:46 hiredman: well, reify is not a var, so you can;t have a docstring on it

5:46 reify is a special form, and I guess it hasn't been added to the special forms list

5:47 or else you would get similar output to (doc let)

5:47 gerry_: but, i shouldn't get error msg

5:47 hiredman: sure

5:48 doc by default just looks in the vars metadata

5:48 there is no var named reify

5:48 so you get an error if you try to look at the metadata of a var that doesn't exist

5:49 gerry_: right

5:50 hiredman: let is actually a macro that uses the let* special form

5:50 (doc let*) gets you the same error

5:50 clojurebot: Pardon?

5:50 hiredman: clojurebot: dork

5:50 clojurebot: Gabh mo leithscéal?

5:52 gerry_: newnew seems support define methods which isn't interface bound?

5:53 why reify not support it?

6:07 spuz: How do you convert a lazy sequence to a string? At the moment when I try to print the sequence I just get clojure.lang.LazySeq@d1ee3a14

6:07 I've tried using (str theseq) but it doesn't seem to work...

6:08 ,(str "Range: " (range 1 10))

6:08 clojurebot: "Range: clojure.lang.LazySeq@fe1f9924"

6:08 gerry_: ,(str "range" (doall (range 1 10)))

6:08 clojurebot: "rangeclojure.lang.LazySeq@fe1f9924"

6:09 gerry_: ,(println (range 1 10))

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

6:11 spuz: ,(str "Range: " (with-out-str (println (range 1 10))))

6:11 clojurebot: "Range: (1 2 3 4 5 6 7 8 9)\n"

6:11 spuz: is that really the best way to do it?

6:13 ,(str "Range: " (str (range 1 10)))

6:13 clojurebot: "Range: clojure.lang.LazySeq@fe1f9924"

6:15 gerry_: str seems using .toString method inside

6:16 ,(.toString (range 1 10))

6:16 clojurebot: "clojure.lang.LazySeq@fe1f9924"

6:16 gerry_: (.toString (doall (range 1 10)))

6:16 ,(.toString (doall (range 1 10)))

6:16 clojurebot: "clojure.lang.LazySeq@fe1f9924"

6:17 gerry_: is this a bug?

6:18 spuz: gerry_: I don't think so, that looks like the correct toString for a lazy seqence

6:18 if the sequence happened to be infinite then toString would never return

6:19 gerry_: then (doall lazyseq)return what?

6:19 still lazyseq?

6:20 spuz: doall will execute any side effects that walking the sequence may have, then it just returns the head of the seqence

6:20 ah, I know...

6:20 (apply str (range 1 10))

6:20 ,(apply str (range 1 10))

6:20 clojurebot: "123456789"

6:23 hiredman: ,(pr-str (range 10))

6:23 clojurebot: "(0 1 2 3 4 5 6 7 8 9)"

6:23 spuz: or there is clojure contrib's str-join

6:23 but still, a bit cumbersome to write our own to string for sequences

6:23 hiredman: it's called pr-str

6:24 spuz: hiredman: ah thanks

6:27 modulus: hey, i'm trying to apply a function to all the elemtns of a list in turn

6:27 i'm sure this must exist, just no idea how it may be called

6:27 hiredman: ,(doc map)

6:27 modulus: something like

6:27 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

6:27 hiredman: ,(doc reduce)

6:27 clojurebot: "([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, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns the r

6:27 adityo: how do i enable code-completion inside a file (using slime), its available inside the repl buffer bit not when i edit a file

6:27 modulus: no

6:27 hiredman: ,(doc doseq)

6:27 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

6:27 modulus: i need something like

6:28 (fun + x l) where it does (+ x ...) for each item in l and returns a new l

6:28 hiredman: ,(map (partial + 1) (range 3))

6:28 clojurebot: (1 2 3)

6:29 modulus: ah, interesting

6:29 thx

6:29 hiredman: did you read the docstrings at all?

6:29 modulus: yes but i think i misunderstood the doc

6:30 pao: can anyone help me add type tags to this micro bench? http://paste.pocoo.org/show/148086/

6:30 I'd like to know if it is the fastest solution

6:30 hiredman: ,(seq (reduce #(conj %1 (+ 1 %2)) [] (range 3)))

6:30 clojurebot: (1 2 3)

6:30 modulus: in fact i still don't undrestand that docstring now

6:31 hiredman: it's map

6:31 http://en.wikipedia.org/wiki/Map_%28higher-order_function%29

6:31 it has its own wikipedia article

6:33 hmmm

6:33 ,((comp seq reduce) (partial (flip conj) (partial +1)) [] (range 3))

6:33 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$partial

6:34 hiredman: ,((comp seq reduce) (partial (flip conj) (partial + 1)) [] (range 3))

6:34 clojurebot: java.lang.ClassCastException

6:34 spuz: hiredman: what exactly are you trying to do?

6:34 doesn't modulus just want something like:

6:34 '(map #(* % %) (range 10))

6:34 hiredman: ,((partial (flip conj) 1) [])

6:34 clojurebot: [1]

6:34 spuz: ,(map #(* % %) (range 10))

6:34 clojurebot: (0 1 4 9 16 25 36 49 64 81)

6:35 hiredman: oh

6:35 nuts

6:36 spuz: ,(doc flip)

6:36 clojurebot: "([x]); takes a function and returns a function that takes arguments in the opposite order"

6:37 spuz: flip doesn't appear to be a documented function :p

6:37 modulus: also is there a function to generate set products?

6:37 * works only for numbers it seems

6:38 spuz: modulus: take a loop at for

6:38 look* :)

6:38 hiredman: ,((partial (comp seq reduce) (comp (partial apply conj) (juxt first (comp (partial + 1) second)) list) []) (range 10))

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

6:39 hiredman: flip just something that happens to be in clojurebot's sandbox at the moment

6:40 ,(doc flip)

6:40 clojurebot: "([x]); takes a function and returns a function that takes arguments in the opposite order"

6:40 hiredman: and it is documented :P

6:44 spuz: hiredman: are you seeing how complicated you can make a function that returns (range 10)?

6:44 hiredman: it's doesn't return range 10

6:44 ,(range 10)

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

6:44 hiredman: ,((partial (comp seq reduce) (comp (partial apply conj) (juxt first (comp (partial + 1) second)) list) []) (range 10))

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

6:45 spuz: ,(nth (iterate (inc %) 10)

6:45 clojurebot: EOF while reading

6:45 spuz: ,(nth (iterate (inc %) 10))

6:45 clojurebot: java.lang.Exception: Unable to resolve symbol: % in this context

6:45 spuz: > ,(nth (iterate #(inc %) 10))

6:46 doh :(

6:46 hiredman: no

6:46 (iterate inc 0) is what you want there

6:46 and you want take, not nth

6:47 spuz: (take 10 (iterate inc 1))

6:47 that's what I meant

6:47 pao: hmmm... I guess #^double type annotation doesn't work with clojure 1.0.0... where do I download a more recent one?

6:47 hiredman: yes, but that doesn't add one to every element in a list

6:48 which is what modulus asked about

6:48 spuz: well, map + range then

6:49 pao: I'm pretty sure 1.0.0 supports #^double

6:49 hiredman: ,((partial map (partial + 1)) (range 10)

6:49 clojurebot: EOF while reading

6:49 hiredman: ,((partial map (partial + 1)) (range 10))

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

6:49 spuz: I'm not sure why you need the partials...

6:50 hiredman: you don't, but it makes a nice pointfree function

6:50 which is what I also did with the reduce version

6:50 ,((partial (comp seq reduce) (comp (partial apply conj) (juxt first (comp (partial + 1) second)) list) []) (range 10))

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

6:51 pao: sputz I get: IllegalArgumentException: Unable to resolve classname: double (test.clj:10)

6:51 hiredman: you don't type hint primitives like that

6:51 (double x)

6:52 in a let

6:52 ~performance

6:52 clojurebot: http://clojure.org/java_interop#toc46

6:52 spuz: Ah yes, it's #^doubles not #^double

6:52 and yeah, use coersion to force the use of primitives

6:53 pao: hiredman: thanks

6:53 spuz: thanks

6:53 Licenser: (,doc =not)

6:53 ,(doc =not)

6:53 clojurebot: Titim gan éirí ort.

6:53 hiredman: not=

6:53 spuz: ,(doc not=)

6:53 clojurebot: "([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"

6:54 hiredman: or (comp not =)

6:54 Licenser: spuz: thank you

6:54 I always want to use !=

6:54 spuz: heh ditto :)

6:55 _ato: Licenser: then (def != not=) and use it :)

6:55 Licenser: yes I know but that's against the law

6:55 _ato: haha

6:55 hiredman: ,((complement =) 1 2)

6:55 clojurebot: true

6:56 modulus: ok many thx, map and for work for what i was trying to do

6:57 spuz: modulus: cool

6:58 modulus: how could you use the map without the partial though?

6:58 i guess you could do

6:58 hiredman: however you want

6:58 it just takes a function

6:58 modulus: ,(map (inc 1) (list 1 2 3 4 5))

6:58 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

6:58 modulus: maybe not

6:58 hiredman: anonymous or named

6:58 _ato: ,(map inc (list 1 2 3))

6:58 clojurebot: (2 3 4)

6:59 hiredman: ,(map #(+ 1 %) (range 10))

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

6:59 _ato: ,(map (fn [_] 2) (list 1 2 3))

6:59 clojurebot: (2 2 2)

7:00 modulus: hmm, isn't using the anon function same thing as partial?

7:00 hiredman: partial just creates a new function

7:00 similar

7:00 more or less, but partial is a nice higher order function

7:00 you get can use it to get nice pointfree functions

7:01 gbt: hiredman: I'm new to clojure and functional programming. Are pointfree functions a good thing to learn? You seem to use them a lot :)

7:01 hiredman: without having to think up pesky variable names

7:01 Chousuke: gbt: it depends :P

7:01 gbt: hehe

7:01 hiredman: I just hate having to name variables

7:01 Chousuke: they're not as nice in clojure as they are in haskell

7:02 gbt: it was a haskell example I was looking at, but I don't know haskell so its tough going ;)

7:03 modulus: somehow this sequence things seem a bit odd

7:03 Chousuke: well, in haskell composition is just f . g and partial is just (f arg1) (if f takes 2 arguments)

7:03 so it's much more compach

7:03 hiredman: ,(pl (inc · dec 1))

7:03 clojurebot: 1

7:03 Chousuke: compact :P

7:04 _ato: ,(doc pl)

7:04 clojurebot: "([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right"

7:04 hiredman: pl is another thing that just happens to be loaded in clojurebot's namespace

7:04 Chousuke: you won't find it anywhere else :D

7:05 gbt: I'm enjoying the functional side, (coming from c languages) but I still haven't had the eureka moment were I really get it

7:05 hiredman: ,(pl (↕map range $ 10 (call · ⌽+ 1)))

7:05 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

7:05 hiredman: ,(pl (↕map range $ 10 (call · (⌽+ 1))))

7:05 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

7:05 hiredman: bah

7:06 pao: Chousuke: Hi! would you mind giving a look to http://paste.pocoo.org/show/148088/ ? is that the fastest that I can get?

7:07 spuz: gbt: I don't think there's a moment exactly, but the more you learn about higher order functions the more and more things you realise you can do that you couldn't do in C

7:08 Chousuke: pao: probably not.

7:08 hiredman: ,(pl (↕map range $ 10 call · ⌽+ $ 1))

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

7:08 Chousuke: pao: handwritten loops are usually faster than lazy seqs

7:09 pao: Chousuke: good I'll try to rewrite with loop

7:09 modulus: lazy seqs are confusing as hell

7:09 tomoj: :)

7:09 hiredman: modulus: how so?

7:09 Chousuke: modulus: only sometimes :)

7:09 modulus: hehe

7:09 _ato: ,(pl (quote pl $ pl))

7:09 clojurebot: (pl pl)

7:09 modulus: well, i've been reading a few docs and i find it hard to remember what the deal is with keeping the head or not etc

7:10 _ato: ,(pl pl ? pl)

7:10 clojurebot: java.lang.Exception: Can't take value of a macro: #'sandbox/pl

7:10 modulus: and when things may not get printed

7:10 spuz: modulus: they are just like iterators in java... cursors in SQL, or perhaps you're more familiar with streams...?

7:10 modulus: hmm

7:10 pao: I'm little bit puzzled ... :-( standard naive python implemetation for that micro-bench is 3 times faster than clojure and 2 times faster than haskell ... I'm desperately trying to get rid of python without success :-)

7:11 modulus: strange, python being fast

7:11 _ato: maybe python has a faster rand?

7:11 pao: modulus: I was expecting it as well

7:12 hiredman: pao: how are you timing it?

7:12 pao: hiredman: with unix time

7:12 hiredman: *snort*

7:12 the jvm takes at least 30 seconds to start

7:13 pao: hiredman: to trigger jit?

7:13 _ato: pao: try: (time (dorun ...))

7:13 Chousuke: pao: no. just to start.

7:13 pao: are you timing both the creation of the array and the summing?

7:13 pao: Chousuke: yep

7:14 hiredman: python runtime isn't fast to startup either

7:14 Chousuke: it's a lot faster than the JVM.

7:14 hiredman: pao: I doubt it takes as long as the jvm

7:14 the jvm loads a ton of stuff at start up

7:14 pao: "Elapsed time: 36836.235 msecs"

7:14 real 0m39.620s

7:14 user 0m56.235s

7:14 sys 0m2.357s

7:15 the startup was 3 seconds approximately

7:15 mikem`: what's the clojure way to store data strucutures in a file for future use?

7:15 hiredman: prn

7:15 pao: python:

7:15 real 0m14.617s

7:15 user 0m13.793s

7:15 sys 0m0.477s

7:16 Chousuke: you're using a lot of lazines... that will slow you down.

7:16 hiredman: sure

7:16 Chousuke: laziness*

7:16 also try mapping into a vector instead of an array

7:17 pao: Chousuke: I've already tried with vectors and it is _ways_ slower

7:17 Chousuke: you're using 1.0.0 still?

7:17 pao: Chousuke: I get the problem is that vector put a lot of pressure on gc

7:17 Chousuke: yep

7:17 _ato: pao: just out of curiosity can you pastebin your Python version?

7:17 hiredman: you are generating at least 6 seqs

7:17 Chousuke: right. no wonder :)

7:17 vu3rdd: Hello folks. I am a clojure newbie and am trying to setup slime/swank on debian.

7:17 modulus: something wrong with 1.0?

7:17 pao: Chousuke: should I try what?

7:17 Chousuke: well, not really.

7:17 git master is just faster .P

7:18 hiredman: pao: uh, I would seriously doubt that

7:18 vu3rdd: I am using the instructions at <http://riddell.us/tutorial/slime_swank/slime_swank.html>

7:18 hiredman: pao: that this code would put pressure on the gc

7:18 pao: _ato: http://paste.pocoo.org/show/148089/

7:19 vu3rdd: I followed and setup slime and get the prompt in the slime-repl buffer

7:19 mikem`: hiredman: ok, so prn prints the data structure... how to get it back?

7:19 vu3rdd: but if I say (+ 2 2), it hangs.

7:19 pao: hiredman: whith array the heap required is exactly 80Mb

7:19 _ato: mikem`: (read some-string)

7:19 vu3rdd: OTOH, the inferior-lisp buffer works fine

7:19 _ato: ,(read "[1 2 3]")

7:19 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.io.PushbackReader

7:19 vu3rdd: any idea what could be the problem?

7:19 _ato: gah

7:19 pao: hiredman: vector requires much more

7:20 _ato: oh that's right you need to pass it a reader

7:20 gbt: vu3rdd: I'm new too, I used epla and clojure-mode. did anything for me

7:20 pao: I could try to estimate the exact heap size required with vec

7:20 hiredman: pao: have you tried using vectors?

7:20 vu3rdd: gbt: I setup according to the instructions on an Ubuntu machine, just fine.

7:20 pao: hiredman: yep

7:20 hiredman: let me try again

7:20 _ato: ,(read-string "[1 2 3]")

7:20 clojurebot: [1 2 3]

7:20 vu3rdd: I am trying to set it up on a debian machine, which is my primary machine at home

7:21 mikem`: _ato: great, thanks :)

7:21 vu3rdd: but it is refusing to give the result back into the repl buffer

7:21 sbcl works just fine

7:22 _ato: vu3rdd: strange. Is it printing anything in the *inferior-lisp* buffer?

7:22 Chousuke: hmm, I got 30 seconds using vectors

7:23 pao: Chousuke: how much using arrays?

7:23 vu3rdd: _ato: no. it doesn't. It just says "Connection opened on local port 48662"

7:23 and also gives "#<ServerSocket ServerSocket[addr=,port=0,localport=48662]>"

7:24 I am able to type on the *inferior-lisp* buffer and get the results just fine

7:25 Chousuke: pao: didn't try yet.

7:25 vu3rdd: is there any way to turn on some debugging messages on swank/slime?

7:25 Chousuke: 30 seconds with only lazy seqs, too (vectors a bit slower)

7:25 pao: Chousuke: java.lang.OutOfMemoryError: Java heap space with -Xmx 200m

7:26 Chousuke: I have git clojure

7:26 pao: Chousuke: that was with replacing #(into-array Double/TYPE) with vec

7:26 Chousuke: so (vec huge-thing) doesn't actually create as many vectors as huge-thing has items

7:26 pao: Chousuke: I'll try with head (is there a particulare branch you would suggest)

7:27 Chousuke: just master

7:27 pao: Chousuke: could you elaborate on (vec huge-thing)?

7:28 _ato: vu3rdd: ah... that sounds familiar. At one point I was having issues like that and it was that the version of SLIME I was using was not compatible with the version of swank

7:28 Chousuke: pao: it uses transients internally

7:28 pao: with the array I got almost exactly the same result as with vectors

7:29 pao: Chousuke: are you saying that (vec huge-thing) is master is faster thatn in 1.0.0 beacouse of transients?

7:29 Chousuke: it's just 19ms faster

7:29 yes.

7:29 pao: Chousuke: I'll try master

7:29 vu3rdd: _ato: My slime and swank are from the git repos

7:29 hiredman: lisppaste8: url?

7:29 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

7:30 _ato: vu3rdd: yeah, when I had that issue SLIME was too new, clojure swank hadn't been updated

7:30 lisppaste8: hiredman pasted "untitled" at http://paste.lisp.org/display/89637

7:30 _ato: vu3rdd: I don't know whether that's still the case, that was a couple of months ago though, you might be having a different issue

7:30 Chousuke: because what it actually does is create an editable version of an empty vector, then mutably stuff things into that, and then finally it transforms the editable thing into a persistent one again and returns it

7:30 hiredman: pao: I don't know python but I think that is an accurate transliteration of your code

7:31 _ato: vu3rdd: http://www.mail-archive.com/clojure@googlegroups.com/msg05284.html

7:31 hiredman: whoops

7:31 extra prn in the first doseq

7:32 Chousuke: aren't the fors the wrong way around?

7:32 pao: hiredman: yep, it is... would you consider it idiomatic? ... I'm going to time it...

7:33 Chousuke: it's creating a 100000 small vecs instead of a 100 large vecs.

7:33 vu3rdd: _ato: Ok. thanks for the tip

7:34 _ato: I removed the slime debian package from my machine. That seem to have solved the issue.

7:34 _ato: ah cool. :)

7:34 vu3rdd: _ato: Thanks a lot.

7:34 hiredman: pao: depends, I don't use for a lot

7:35 patricius_: Hi. I am making a toy-disk scheduler in Clojure. Imagine that we have a lot of processes that want to access certain cylinders on a disk. Any such request for access goes through a disk scheduler, and the processes has to block when they have made a request until the disk scheduler allows the process to access the cylinder. The scheduler runs over batches of requests; it starts by sorting the requests currently waiting, and th

7:35 letting the processes gain access in the sorted order. My question is how to get processes to block until they receive access to a cylinder?

7:35 hiredman: for is a fairly hairy macro

7:36 patricius_: don't block, use refs and the stm

7:36 :P

7:37 patricius_: hiredman: i guess you are right

7:37 hiredman: there are many ways you can block

7:37 call .take on an empty blockingqueue

7:38 deref a future or a promise

7:38 await an agent

7:38 patricius_: hiredman: thanks, i didn't know about blockingqueue and promises

7:38 i'll look into those

7:38 hiredman: BlockingQueue from j.u.concurrent

7:39 you could implement your own executor service per cylinder

7:39 patricius_: hiredman: thanks

7:40 hiredman: yeah... but it goes against the problem definition. On the other hand, I'm trying to demonstrate Clojure's concurrency features through the disk scheduler example, and maybe the problem definition shouldn't be taken literally in that case.

7:40 the problem definition is worded in a traditional "threads-and-locks-way"

7:41 hiredman: why not? it would be a sort of grand central dispatch approach

7:41 each cylinder has a queue of jobs waiting on it

7:41 patricius_: hiredman: you are suggesting that I have a service per cylinder?

7:41 hiredman: sure

7:42 patricius_: hmm.... let me think a little

7:42 hiredman: they could all use the same threadpool

7:42 actually, hey, you can just use agents

7:43 _ato: pao: http://gist.github.com/223515

7:43 about the same speed as python on my PC

7:43 patricius_: hiredman: yeah, you're thinking since the actions sent to agents are waiting in a queue to be executed

7:43 _ato: assuming I haven't broken the benchmark

7:43 hiredman: patricius_: correct

7:44 pao: _ato: thanks ... are you using 1.0.0 or master?

7:44 patricius_: hiredman: my original plan was to also represent processes as agents, but I still don't know how to have them "block" and wait for cylinder access

7:44 Chousuke: _ato: I get similar results. though my JVM runs out of memory with 100k arrays

7:44 patricius_: hiredman: originally i had "processes" pass a long a function (closure) that should be called when access was given

7:44 Chousuke: but I get about a tenth of that with 10k

7:44 hiredman: patricius_: you can use promise/deliver

7:45 _ato: pao: master

7:45 patricius_: hiredman: i'll read about them right now

7:45 Chousuke: _ato: what happens if you remove the vec call?

7:45 patricius_: hiredman: are these concurrency primitives part of clojure?

7:45 hiredman: (let [result (promise)] (send-off cyl1 (fn [cyl] (deliver result (read-date cyl)))) @result)

7:45 patricius_: hiredman: or java?

7:45 hiredman: patricius_: yes

7:46 ,(doc promise)

7:46 clojurebot: "([]); Experimental. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block. All subsequent derefs will return the same delivered value without blocking."

7:46 Chousuke: ,(ancestors (promise))

7:46 clojurebot: nil

7:46 hiredman: patricius_: whats the difference

7:46 ,(ancestors (class (promise)))

7:46 clojurebot: #{clojure.lang.IFn java.io.Serializable java.lang.Object clojure.lang.IProxy clojure.lang.AFn clojure.lang.IMeta clojure.lang.IDeref java.util.concurrent.Callable clojure.lang.IObj :clojure.contrib.generic/any clojure.lang.Obj java.lang.Runnable}

7:46 patricius_: hiredman: just where to look for documentation

7:46 Chousuke: right. :)

7:47 hiredman: huh

7:47 promises are IFns?

7:47 ~def promise

7:47 patricius_: ahr... thanks - excuse me, but I'm very new to clojure

7:48 hiredman: neat

7:48 Chousuke: ,(let [x (promise)] (deliver x inc) (x 2))

7:48 clojurebot: java.lang.IllegalStateException: Multiple deliver calls to a promise

7:48 Chousuke: oh, heh

7:48 so it was deliver instead of forwarding

7:48 patricius_: i guess its not part of clojure 1.0 then?

7:48 pao: Chousuke: without vec you you get a list instead of a vec at the end, right?

7:49 Chousuke: pao: well, a lazy seq, but yes.

7:49 hiredman: oh, was promise post 1.0?

7:49 Chousuke: ,(let [x (promise)] (x 2) @x)

7:49 clojurebot: 2

7:49 patricius_: i can't find any documentation for it, so I guess it's not official or whatever yet

7:50 pao: _ato: with 1.0.0 and s/vec/into-array Double/TYPE

7:50 "Elapsed time: 22362.154 msecs"

7:50 real 0m24.406s

7:50 user 0m34.712s

7:50 sys 0m4.364s

7:50 python was

7:50 real 0m15.487s

7:50 user 0m14.121s

7:50 sys 0m0.509s

7:50 good

7:50 I'll try master

7:50 Chousuke: pao: try removing the (into-array ...) entirely

7:51 ie. just let it be a lazy seq

7:51 pao: Chousuke: but the lazy-seq gets progressively reified into a list, right?

7:51 hiredman: pao: and what's the time on an already running vm?

7:51 Chousuke: yes.

7:52 pao: but I don't see the point in actually putting those things in arrays in your benchmark :)

7:52 unless you want to test array creation

7:53 pao: Chousuke: what I want to "bench-mark" is "immutable double array" memory efficiency and naive processing

7:53 hiredman: well

7:53 arrays are not immutable

7:54 Chousuke: pao: hm

7:54 pao: hiredman: the double quotes were for that reason ... I don't really care about the underlying rapresentation... unless is memory and access efficient

7:54 _ato: hmm got it down to four seconds, by making the inner loop eager instead of lazy and explicitly using transients

7:54 pao: Chousuke: with lazy seq (without vec) -> OutOfMemoryError ... got to compile master...

7:55 _ato: ! :-)

7:55 modulus: hmm gtg

7:55 pao: _ato: would you mind pasting it?

7:55 _ato: pao: http://gist.github.com/223515

7:55 Chousuke: _ato: so basically the creation of the arrays were the bottleneck, not the reduce

7:56 _ato: Chousuke: I think all the temporary seqs

7:56 probably driving the GC crazy

7:57 pao: _ato: can you confirm that with this implementation vectors are not collected as soon as they are reduced?

7:58 hiredman: uh

7:58 Chousuke: pao: nothing is ever collected because you (def ...) them :P

7:58 pao: there's a reference to the vectors so they can't be collected.

7:59 if you want collectable vectors, you need to make a function that generates the vectors (and sums) and call it like (map (partial reduce +) (sums (make-vectors))

8:00 er, wait. got confused :P

8:00 pao: Chousuke: good... I didn't want them to be collected

8:00 hiredman: better to use locals

8:01 Licenser: 20% of the time seem to be the print too - at least for me

8:01 * pao got to go to eat.... thanks everyone

8:01 hiredman: IO is slow

8:01 Licenser: I know especially when run in netbeans :P

8:02 so I feel my system sucks, I get 10s even without print :.(

8:54 pao: Chousuke: are you a clojure committer?

8:59 hiredman: I am pretty sure Chousuke is atleast a contrib commiter

9:03 pao: thanks hiredman

9:03 Clojure 1.1.0-alpha-SNAPSHOT

9:03 user=>

9:04 that should be it

9:11 wack ... master is definitely speedy

9:12 vec are only slightly slower than unboxed arrays

9:18 avital: Hello. Is anyone here comfortable with monads both in Clojure and in Haskell? I am trying to learn Haskell for the first time (specifically monads) by comparing it to the monads library in clojure-contrib. I can't figure out how you tell a do statement in Haskell which monad to use (in Clojure domonad takes a monad as a first argument).

9:19 pao: avital: in haskell the monad is inferred ... is there is no context the expression is polymorphic

9:19 *if

9:20 avital: in other term the expression "return 1", if not given any more context, is parametric in the type of monad

9:20 avital: Interesting... I'm trying to compare the efficiency of monads in Clojure and Haskell so I'm just trying to write some sample code in Haskell. How would I write something using the Maybe monad, for example? Or the state monad? (The online haskell monad tutorials aren't helping me well enough...)

9:20 pao: Prelude> :t return 1

9:20 return 1 :: (Num t, Monad m) => m t

9:21 avital: I can help you out

9:21 just tell me what you want to achive

9:21 avital: Great!

9:21 pao: in general the monad should be "enforced" somehow...

9:21 or by explicit type annotation

9:22 Prelude> :t (return 1) :: Maybe Int

9:22 (return 1) :: Maybe Int :: Maybe Int

9:22 avital: I'm trying to write something equivalent to (domonad writer-t [a (m-result 3) _ (write "Hello") b (m-result (* a a))] b)

9:22 pao: or by "running" it

9:24 let me try do "decode" the clojure syntax :-)

9:24 just a second

9:27 avital: sorry, my example is broken

9:27 let me write a working one

9:27 pao: yep

9:28 avital: (domonad (writer-m empty-vector) [a (m-result 2) _ (write "hello") b (m-result 3) _ (write "also") c (m-result (+ a b))] c)

9:29 I may not be using the clojure-contrib monads library properly with my calls to m-result all the time..

9:30 pao: you get a vec of string in the writer?

9:31 avital: write-m receives an empty accumulator and returns a monad whose monadic values are vectors like [result ["first-string-written" "second-string-written"]]...

9:31 pao: avital: yep

9:31 I know :-)

9:32 avital: so sorry what was the question?

9:32 pao: run the monad pls ...

9:32 and give me the result

9:32 avital: [5 ["hello" "also"]]

9:32 pao: perfect

9:33 *Main> main

9:33 Loading package syb ... linking ... done.

9:33 Loading package base- ... linking ... done.

9:33 Loading package mtl- ... linking ... done.

9:33 (5,["Hello","also"])

9:33 http://paste.pocoo.org/show/148104/

9:33 that's the exact transliteration of you

9:34 *of your code

9:34 avital: thanks! how much do i owe you?

9:34 :)

9:34 pao: some helps with monads in clojure when I will need :-)

9:35 avital: hehe sure.

9:35 !

9:35 pao: please note the te last two lines in the do are redundant

9:36 return (a+b) >>= return is equivalent to return (a+b)

9:36 avital: you mean c <- return (a + b); return c; instead of just return (a+b)?

9:36 Aha yeah./

9:36 pao: that holds also for clojure code

9:36 avital: of course

9:37 patricius_: I may be a complete idiot, but why does the following block?: (dosync (alter (ref []) conj (promise)))

9:38 hiredman: the printing blocks

9:38 patricius_: hiredman: what do you mean?

9:38 hiredman: dosync returns the last expression, like do, and alter returns the new value of the ref

9:39 patricius_: arch!

9:39 (that was a guttural sound)

9:39 hiredman: so the value of that expression is [(promise)]

9:39 patricius_: hiredman: thanks again man

9:39 hiredman: a promise is an IDeref, and by default when the repl prints an IDeref it derefs it

9:40 pao: avital: does the contrib library also supports monad transformers?

9:40 avital: pao: Yes, but I haven't gotten an example using transformers to work yet - documentation is scarce and example are almost non-existant.

9:41 pao: avital: I would suggest trying with StateT s [] a

9:41 avital: pao: What? :)

9:41 pao: a list monad wrapper by a state-t transformer

9:42 avital: Aha. I'll try that.

9:43 Also, I'm trying to compile your code with ghc but it can't find Control.Monad.Writer

9:43 Given that I this is my first try with Haskell,

9:43 what do I have to do? ...

9:44 pao: hmmm ... in theory nothing

9:44 how do you installed ghc? os?

9:45 avital: synaptic on linux

9:50 pao: avital: search for mtl

9:50 clojurebot: for is not a loop

9:51 avital: pao: ok cool thanks

9:51 pao: avital: # dpkg -l |grep mtl

9:51 ii libghc6-mtl-dev

9:51 then compile with

9:51 ghc --make test.hs

9:52 how do "clojure friendly" profile the jvm heap ?

9:52 any suggestion?

9:52 avital: grea thanks!

9:52 great

9:54 never done that... i don't think there are any specialized tools other than standard jvm profilers...

9:54 pao: avital: as a standard heap profiler what would you suggest? I'm very new to jvm world...

9:54 avital: http://clojure.org/getting_started#toc6

9:55 There is also a built-in one that comes with the Sun JDK I think

9:55 pao: avital: great, thanks

9:55 avital: but it's been a long time since I've used that

10:00 pao: Is there an easy way in Haskell to time how long it takes to run something 10000000 times, for example? [In clojure it's (time (dotimes [_ 1000000] (f)))]

10:01 pao: there the timeit package

10:01 *there is

10:01 but you should install the haskell platform to install the package

10:04 avital: http://stackoverflow.com/questions/1516808/writing-a-time-function-in-haskell

10:07 pao: avital: it's not so "trivial" to write micro bench in haskell... becouse _everything_ is by default lazy there... (also * or conj for example)... and it's not so trivial to force evaluation deep enough

10:08 avital: my personal experience is that idiomatic haskell is as fast as a good interpreted language (python is the example that I closely know)

10:08 avital: optimizing haskell is quite tricky and you generally loose its amazing elegance

10:10 notallama: i thought haskell was generally pretty close to c++/java speed. or is that only if you do tricky stuff?

10:10 pao: avital: I wouldn't choose haskell for performance

10:10 avital: I'm trying to check it

10:10 pao: notallama: I would definitely say yes

10:15 notallama: http://www.opensubscriber.com/message/haskell-cafe@haskell.org/2996376.html

10:15 notallama: still relevant

10:19 Chousuke: hiredman: nah, I'm not a committer for anything :P Chouser is

10:22 pao: Chousuke: that is what misled me

10:22 :-)

11:13 churib: can anybody give some quick help? the following gives me a reflection warning: (defn int-log10 [x] (.intValue #^Double (/ (Math/log x) (Math/log 10))))

11:15 Math.log returns a double...

11:23 ambient: and it takes a double

11:23 ,(class 10)

11:23 clojurebot: java.lang.Integer

11:27 churib: same with (.intValue #^Double (Math/log Math/E))

11:28 ambient: ,(class Math/E)

11:28 clojurebot: java.lang.Double

11:28 ambient: try (int (Math/log (double Math/E))

11:30 churib: (int ..) cuts the decimal places, i want something that returns 1 when 0.99 is given

11:30 ambient: Math/round

11:32 churib: that works, thanks!

11:59 slashus2: , (str "Range: " (seq (range 1 10)))

11:59 clojurebot: "Range: (1 2 3 4 5 6 7 8 9)"

12:13 yason: Does contains? compare value or identity?

12:15 I'm wondering why this doesn't work:

12:15 ,(let [x (list (list))] (contains? x (first x)))

12:15 clojurebot: false

12:15 yason: same with a list of structs (maps)

12:16 Chousuke: ~contains?

12:16 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains

12:17 yason: uh, no wonder I didn't find it :)

12:18 Chousuke: This is one of the most frequently asked questions :P

12:19 yason: How about wrapping .contains into a (has? coll value)

12:19 java interop is nice but primitive coll/seq stuff ought to be lispy

12:20 Chousuke: well, you could just use (some #{value} coll)

12:22 yason: ,(let [x (list (list))] (some #{(first x)} x))

12:22 clojurebot: ()

12:23 yason: ,(let [x (list (list))] (every? #{(first x)} x))

12:23 clojurebot: true

12:24 Chousuke: both answers are boolean true :)

12:24 some returns the first item that matches the predicate and is not nil or false

12:25 yason: Oh, right

12:25 I'm so used to () being equal to nil.

12:27 raek: ,(nil? ())

12:27 clojurebot: false

12:27 raek: ,(nil? (seq ()))

12:27 clojurebot: true

12:35 adityo: ~max people

12:35 clojurebot: max people is 187

12:43 spuz: slashus2: So that's another way to convert a sequence to a string?

12:44 If (range) returns a sequence, then what exactly is does seq on a range do?

12:45 ,(str "Range: " (range 10))

12:45 clojurebot: "Range: clojure.lang.LazySeq@9ebadac6"

12:45 spuz: ,(str "Range: " (seq (range 10)))

12:45 clojurebot: "Range: (0 1 2 3 4 5 6 7 8 9)"

12:45 spuz: (class (seq (range 10)))

12:45 ,(class (seq (range 10)))

12:45 clojurebot: clojure.lang.ChunkedCons

12:46 spuz: hmm....

12:47 ,(class (range 10))

12:47 clojurebot: clojure.lang.LazySeq

13:07 chouser: ,(range 0)

13:07 clojurebot: ()

13:07 chouser: ,(seq (range 0))

13:07 clojurebot: nil

13:40 danlarkin: given a map with keys :a, :b, :c and :d, is there a function that returns a map with only the keys (and their values) I specify and everything else dissoc'ed?

13:40 making sure I'm not missing the idiomatic function

13:41 arbscht: ,(doc select-keys)

13:41 clojurebot: "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

13:41 danlarkin: there it is!

13:42 arbscht: thanks

15:57 chouser: huh. ruby has rational numbers.

15:59 djork: they're not that easy though

16:00 ,(println "Not like " (/ 1 2))

16:00 clojurebot: Not like 1/2

16:00 chouser: no. They have this handy Rational(1, 2) syntax.

16:00 ambient: ,(/ (/ 1 2) (/ 3 7))

16:00 clojurebot: 7/6

16:00 djork: oh, even better

16:01 ,1/2

16:01 clojurebot: 1/2

16:01 ambient: ,(sqrt -1)

16:01 clojurebot: java.lang.Exception: Unable to resolve symbol: sqrt in this context

16:01 chouser: ruby: 4/5 ==> 0 ; whee!

16:01 djork: ,(Math/sqrt -1)

16:01 clojurebot: NaN

16:02 djork: yeah it's kind of annoying to have to deal with that in ruby

16:02 ambient: would be nice if the answer was i :)

16:02 although complex numbers aren't used that often

16:02 modulus: common lisp has a nice syntax for complex

16:02 #c(a,b)

16:03 where the number is a+bi

16:03 djork: too bad we can't make new reader dispatch macros :)

16:03 ambient: we can, if we fork the source :2

16:03 MakoryuOnIce: Pester rhickey for something

16:04 ,1+1

16:04 clojurebot: Invalid number: 1+1

16:04 MakoryuOnIce: ,2i

16:04 clojurebot: Invalid number: 2i

17:29 technomancy: sweet; Clojure is the #1 most-watched Java project on Github: http://github.com/languages/Java

17:31 dublindan: nice

17:33 technomancy: would any ant pros be able to translate something for me?

17:34 wondering what the "mapper" element in this example means in code: http://maven.apache.org/ant-tasks/examples/dependencies.html

17:37 never mind; found it

18:09 krumholt: hi i have a java class MyClass containing a public enum MyEnum {Foo, Bar}; how can i get an objet from this enumeration in clojure? In java i would do MyClass.MyEnum.Foo

18:11 _ato: hmm.. possible MyClass$MyEnum/Foo, that's what you'd do for an inner class

18:13 hiredman: clojurebot: nachos?

18:13 clojurebot: Titim gan éirí ort.

18:13 hiredman: clojurebot: nachos | are | delicious

18:13 clojurebot: Ok.

18:13 hiredman: clojurebot: nachos?

18:13 clojurebot: nachos are delicious

18:15 Raynes: Is there a function to return all but the last element of a sequence?

18:15 hiredman: ,(doc butlast)

18:15 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"

18:15 Raynes: hiredman: Thanks. <3

18:23 krumholt: _ato, thanks that was it

19:50 dakrone: is there an easy way to create java classes with annotations in clojure?

20:07 skillet-thief: the standard clojure xml parsers all want streams or uris: I want to parse xml that is already in a string. What to do?

20:11 dakrone: skillet-thief: in clojure.contrib.lazy-xml the parse-seq function takes a string

20:11 skillet-thief: dakrone: ok, I must have read wrong. Thanks.

20:12 dakrone: skillet-thief: oh wait, nevermind, that's my mistake

20:12 skillet-thief: it is only a URI

20:12 chouser: it's because the Java xml parsers want streams.

20:12 You can open a stream on a string.

20:12 skillet-thief: dakrone: yeah, that is what I thought.

20:13 chouser: all right, I'm going to look at that.

20:16 dakrone: it'd be (def stream (StringReader. foo)), where foo is the string right?

20:19 chouser: skillet-thief: sorry, had to step awawy

20:20 lazy-xml includes an example that parses a string.

20:20 (lazy-xml/parse-trim (java.io.StringReader. "<foo />")) should do it

20:21 I think clojure.xml requires you wrapper a org.xml.sax.InputSource around that

20:21 skillet-thief: chouser: ok, just found that example.

20:22 my java is weak, so my eyes usually glaze over when I see stuff with streams...

20:22 chouser: yeah, java IO is relatively featureful but so convoluted.

20:26 _ato: there's two things that drive make crazy about the JVM, startup-time and IO

20:26 IO is just seriously lacking, like you can't select() on a file, only on a socket that is opened in a special way

20:30 skillet-thief: great, finally got my string parsed (after resolving stupid namespace problems). Thanks guys!

20:30 abedra: is there a way to turn a string into a function call?

20:32 _ato: ,(eval (read-string "(+ 1 2"))

20:32 clojurebot: DENIED

20:32 _ato: aww

20:32 but that'd do it

20:32 abedra: just use eval?

20:33 yep that works

20:33 thanks

20:39 hiredman: ,((resolve (symbol "+")) 1 2)

20:39 clojurebot: 3

20:43 falkor: How does one create a simple java array (like the equiv of String[] arr = new String[4])?

20:45 wooby: ,(resolve (symbol "+"))

20:45 clojurebot: #'clojure.core/+

20:45 _ato: ,(make-array String 4)

20:45 clojurebot: #<String[] [Ljava.lang.String;@1cf7e4a>

20:45 falkor: _ato: thanks

20:46 _ato: or if you want to create it from an existing list or vector:

20:46 ,(into-array String ["a" "b" "c"])

20:46 clojurebot: #<String[] [Ljava.lang.String;@1e90fee>

20:47 falkor: ,(println "thanks ;) ")

20:47 clojurebot: thanks ;)

21:20 abedra: is there a way to find the arity of a function?

21:21 hiredman: abedra: not really

21:22 well

21:22 actually

21:23 abedra: all i really want to do is not send an additional argument to a function if it doesn't take any args

21:23 hiredman: ,(-> (fn [x] x) class .getDeclaredMethods seq)

21:23 clojurebot: (#<Method public java.lang.Object sandbox$eval__6708$fn__6710.invoke(java.lang.Object) throws java.lang.Exception>)

21:23 hiredman: ,(-> (fn [x] x) class .getDeclaredMethods first)

21:23 clojurebot: #<Method public java.lang.Object sandbox$eval__6714$fn__6716.invoke(java.lang.Object) throws java.lang.Exception>

21:24 hiredman: ,(-> (fn [x] x) class .getDeclaredMethods first .getParameterTypes)

21:24 clojurebot: #<Class[] [Ljava.lang.Class;@1d6be00>

21:24 hiredman: ,(-> (fn [x] x) class .getDeclaredMethods first .getParameterTypes count)

21:24 clojurebot: 1

21:24 abedra: interesting

21:24 hiredman: ,(-> (fn [x y] x) class .getDeclaredMethods first .getParameterTypes count)

21:24 clojurebot: 2

21:25 hiredman: if you use defn type metadata is stuck on the var that ends up holding the fn

21:26 abedra: cool

21:26 hiredman: clojurebot: nachos?

21:26 clojurebot: nachos are delicious

21:26 abedra: lol

21:26 hiredman: clojurebot: forget nachos |are| delicious

21:26 clojurebot: I forgot that nachos are delicious

21:26 hiredman: clojurebot: nachos?

21:26 clojurebot: Gabh mo leithscéal?

21:39 abedra: hiredman: that worked great thanks!

22:50 danlarkin: clojurebot: exceptions

22:50 clojurebot: http://paste.lisp.org/display/74305

Logging service provided by n01se.net