#clojure log - Sep 21 2009

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

1:56 tomoj: so say you want to read n bytes from an InputStream. is (take n (repeatedly #(.read input-stream)) safe?

1:58 I guess repeatedly isn't chunked, huh

2:06 mudphone`: Hey folks was wondering if anyone could help me with a question about this anonymous function syntax: (fn []> (+ 1 2))

2:06 I'm wondering what the ">" is for.

2:06 hiredman: does nothin

2:06 typo or a mispaste

2:07 mudphone`: ah, must be a typo, since I got it from a book

2:08 So, i guess the follow-up is, why isn't it cause an error?

2:08 doesn't it

2:09 hiredman: > is a valid value

2:09 ,>

2:09 clojurebot: #<core$_GT___4136 clojure.core$_GT___4136@1d281f1>

2:09 hiredman: and fns have an implicit do

2:10 ,(do > (+ 1 2))

2:10 clojurebot: 3

2:10 hiredman: ,(do :foo 5 9 'c (+ 1 2))

2:10 clojurebot: 3

2:10 Makoryu: , ((fn [] 'foo 'bar 'baz 'quux :IWouldLikeToOrderALargePizza 5))

2:10 clojurebot: 5

2:11 mudphone`: Does that work with other foods?

2:11 :)

2:11 hiredman: thanks

2:11 Makoryu: mudphone`: Basically, you can put anything you want in between the [] and the 5, and it will be evaluated. If it doesn't have any side effects, it might as well not be there

2:11 mudphone`: Makoryu: thanks

2:12 Makoryu: And yeah, you can use other foods ;)

2:12 mudphone`: Interesting, so a function like > without arguments just returns true, in this case.

2:14 hiredman: eh?

2:14 no

2:14 not at all

2:14 mudphone`: ah, so it's not evaluating, it's a valid value, like you said

2:14 hiredman: it is evaluating, it's evaluating to the function object

2:15 () is needed for calling the function

2:15 mudphone`: ah, ok

2:15 Makoryu: mudphone`: The function evaluates to itself. You have to call a function (eg. (>)) for it to be applied to any arguments (or zero arguments)

2:15 , >

2:15 clojurebot: #<core$_GT___4136 clojure.core$_GT___4136@1d281f1>

2:15 Makoryu: , 'pizza

2:15 clojurebot: pizza

2:16 Makoryu: , (>)

2:16 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$-GT-

2:16 Makoryu: ,(> 5)

2:16 clojurebot: true

2:16 mudphone`: So, with the implicit do, the > is evaluated to itself, and then not used.

2:16 Makoryu: Yep

2:16 It's simply discarded.

2:17 mudphone`: ah ok

2:17 dare I ask why functions have the implicit do?

2:17 Chousuke: mudphone`: so that you can have more than one expression in them

2:18 Makoryu: mudphone`: Partly for the side effects, of course.

2:18 , (do (println "Sup") 5)

2:18 clojurebot: 5

2:18 Sup

2:18 Chousuke: if they didn't have a do, you wouldn't be able to write (defn foo [] (print "debug") "result")

2:19 mudphone`: oh, so, hiredman meant the anonymous function's implicit do

2:19 I was thinking of the ">"

2:19 Chousuke: oh, and the > is not evaluated to itself! remember, it's a symbol :)

2:19 mudphone`: Chousuke: so > is evaluated to the function

2:20 Makoryu: mudphone`: People accustomed to certain other programming languages (which I will not name) would frown on this implicit do. However, Lisp has always had it even when it was called PROGN, and Clojure still has it now.

2:20 Chousuke: mudphone`: yeah. when evaluated, symbols are looked up to see if they name a var, then the var is dereferenced to get the actual value

2:20 Makoryu: (It used to serve the double purpose of allowing docstrings, but now we have the defn macro (and metadata) for that)

2:21 , pizza

2:21 clojurebot: java.lang.Exception: Unable to resolve symbol: pizza in this context

2:21 mudphone`: Chousuke: thanks, got it

2:21 Makoryu: is there a down-side to this implicit do?

2:22 Chousuke: mudphone`: not with functions :/

2:22 mudphone`: I'm assuming perhaps, the side effects?

2:22 hiredman: the implicit do doesn't make side effects, it only allows them if you put them there

2:23 mudphone`: hiredman: right, so is that why the implicit do is fowned upon? is my question

2:23 hiredman: uh

2:23 mudphone`: frowned upon

2:24 hiredman: what gave you that impression?

2:24 Makoryu: mudphone`: Not by Clojure programmers :p Ignore what I said earlier.

2:24 mudphone`: ah, ok

2:25 Chousuke: I didn't get your last comment.

2:26 Chousuke: Well, Clojure has fewer uses of implicit do/progn than common lisp. for example, cond expressions in CL have an implicit do

2:26 as a result, it needs an extra pair of parens for each expression :)

2:27 mudphone`: oh, ok, I see... I thought you were talking about vars

2:27 (and symbols)

2:33 Makoryu: Implicit do/PROGN is generally a good thing in Lisps like Common Lisp, which is much more procedural than functional

2:33 In Clojure, they're just redundant

2:49 tomoj: why is there no byte-array function?

2:52 Chousuke: there's into-array

3:33 mudphone`: Anyone know how to get something like (read-line) working from the Emacs Slime-REPL Clojure?

3:33 (read-line) as in getting user input?

3:36 Fossi: hi

3:48 megane: in gen-class, can i someway declare an array return type? when i try this: (ns testa (:gen-class :methods [[getA [int] int[]]])) , i get an inconvertible types error when i try to use that class from java. javac thinks getA's return type is int.

3:48 using clojure 1.0

3:51 Chousuke: megane: of course, int[] is just the symbol int followed by an empty vector :)

3:51 megane: I think you want Integer/TYPE

3:51 wait, no... hmm

3:51 "[I" or something? :/

3:54 megane: :methods [[getA [int] "[I"]] ?

3:55 AWizzArd: ~ max people

3:55 clojurebot: max people is 164

4:00 LauJensen: Good morning guys

4:00 arbscht: morning lau

4:01 licoresse: hello

4:02 Chousuke: megane: try it. I don't really know much about gen-class :/

4:03 megane: java.lang.ClassNotFoundException: java/lang/[I

4:04 Chousuke: hmmh

4:04 ,(class (int-array))

4:04 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$int-array

4:04 Chousuke: ,(class (int-array 1))

4:04 clojurebot: [I

4:04 megane: Integer[] gives similar results as int[]

4:04 Chousuke: yeah, the Integer[] is not the right syntax.

4:05 as I said, it's just a symbol followed by a vector :)

4:05 try "ints"?

4:07 megane: java.lang.ClassNotFoundException: java.lang.ints

4:07 Chousuke: hmm. maybe #=(Class/forName "[I")

4:08 (#= is read-time eval and that should return the class object for an integer array)

4:08 this really needs better syntax :/

4:09 megane: java.lang.ClassNotFoundException: Class

4:09 :methods [[getA [int] #=(Class/forName "[I")]]

4:10 Chousuke: :(

4:23 megane: i got around it by using :methods [[getA [int] Object]] , returning (int-array ...) in getA, and at java side i casted the return value to int[]

4:41 pixelman_: mudphone`: use jline to get arrow up etc in the repl, here's my launch script http://followthedata.wordpress.com/2009/09/03/setting-up-clojure/

4:54 licoresse: .

4:59 vy: Is there a reader macro for writing bits? (E.g. As #b100101 in CL.)

5:05 Chousuke: hmm

5:05 ,0b01010

5:05 clojurebot: Invalid number: 0b01010

5:05 Chousuke: there was some way to get an arbitrary radix...

5:05 ,2r01010

5:05 clojurebot: 10

5:13 lisppaste8: vy pasted "filter-by-bitmap" at http://paste.lisp.org/display/87426

5:13 vy: Chousuke: Thanks.

5:14 Chousuke: Is that some Java reader notation?

5:14 Can anybody help me to figure out why does filter-by-bitmap in http://paste.lisp.org/display/87426 returns ()?

5:18 (Integer/reverse 2r110)

5:24 Chousuke: vy: what do you want it to do?

5:24 vy: Return items in coll by filtering agains turned on bits in the given number.

5:25 Chousuke: so 2r1010 would select items 0 and 2?

5:25 vy: Chousuke: Yup.

5:25 tomoj: I don't get it..

5:25 Chousuke: the bit-and with i is redundant

5:26 lisppaste8: vy annotated #87426 "filter-by-bitmap (via loop)" at http://paste.lisp.org/display/87426#1

5:26 Chousuke: :when (= 1 (bit-and 1 (bit-shift-right bits (- n i 1)))) works for me

5:27 vy: Oops! Silly me.

5:27 What does "recur arg for primitive local: bits must be matching primitive" error mean?

5:28 Hrm... It has some mapping problem too.

5:29 lisppaste8: vy annotated #87426 "filter-by-bitmap (via loop, fixed bit filtering)" at http://paste.lisp.org/display/87426#2

5:29 Chousuke: this sounds like an awfully compicated way of selecting items from a vector

5:30 vy: Chousuke: You mean "loop/recur" derivative instead of "for"?

5:30 Chousuke: both :P

5:30 vy: So what's your suggestion?

5:31 Chousuke: well, what are you doing this for? :/

5:32 vy: I'll filter the elements in a coll by looking at the turned on bits in a number.

5:33 Chousuke: it might be easier if you make a bit-pattern->lazy-seq function

5:36 lisppaste8: vy annotated #87426 "subsets" at http://paste.lisp.org/display/87426#3

5:41 Chousuke: hmm

5:49 vy: Chousuke: And guess what? It performs orders of magnitude better than existing clojure.contrib.combinatorics/subsets.

5:50 Chousuke: it depends on the count though :/

5:50 ~def subsets

5:50 apparently so does that implementation. hm

5:51 tomoj: why are the elements wrapped in a vector?

5:55 huh

5:56 every once in a while c.c.combinatorics/subsets takes 10 times longer than usual

5:56 Chousuke: do you have escape analysis enabled?

5:56 tomoj: I don't even know what that means

5:57 Chousuke: I guess you don't then :P

5:57 it's a new JVM feature that IME seems to cause somewhat uneven performance behavious

5:57 behaviour*

5:58 lisppaste8: vy annotated #87426 "combinations" at http://paste.lisp.org/display/87426#4

6:01 vy: Chousuke: Moreover, while (clojure.contrib.combinatorics/subsets 21) throws some "GC foo bar limit exceeded error" (count (subsets (range 21))) returns in 799msecs.

6:03 tomoj: I don't think it's orders of magnitude better

7:13 somnium: is there any way to prevent the reader from choking on % outside of a string literal? :100% '100% ?

7:18 Fossi: what's the best way to join (take 2 "foo) back together?

7:18 "foo"

7:26 xdp: hello

7:26 AWizzArd: Hi xdp

7:27 noidi_: ,(apply str (take 2 "foo"))

7:27 clojurebot: "fo"

7:27 xdp: where is parallel.clj?

7:28 i want it to improve performance of my application

7:28 i'm using 1.1.0

7:29 ok, i found it in clj dir

7:30 what's diffs between clojure.core/pmap and parallel?

7:31 i'm now using pmap, i don't know if i should use parallel lib

7:32 any ideas?

7:35 cgrand: xdp: parallel.clj builds on the fork/join api, it should be smarter in how the load is distributed amongst cores

7:39 Fossi: yeah, we arrived at apply str as well, but deemed it unnecessary, so now we check the length

7:46 gerry_: parallel need jsr166y.jar support,right?

7:47 cgrand: gerry_: use the jsr166y.jar in the file section of the clojure group

7:47 rhickey: gerry_: yes, for clojure.parallel you can use the jar in the downloads section of the google group

7:48 new work is going on in the par branch on github, in which case you should use the jar in the downloads section there

7:48 gerry_: oops, i have downloaded it from gee.cs.oswego.edu, but it seems not work

7:49 rhickey: that's a moving target

7:49 gerry_: ok,thx

7:49 rhickey: thus the downloads

7:49 also the version on the google group will be the last to support JDK 1.5, they've stopped supporting it for ForkJoin

7:50 so par moving forward will be Java 6+

7:50 gerry_: so, i have to wait?

7:51 rhickey: gerry_: wait for what?

7:51 gerry_: how about performance of clojure.core/pmap to parallel stuff?

7:51 wait jsr166y.jar

7:51 rhickey: gerry_: pmap is unique in not needing the entire collection. OTOH, it is limited if your work-per-unit is small.

7:52 eevar2: speaking of the zip on google; where do I end up clicking 'download' on clojure.org, and then 'source'

7:52 rhickey: gerry_: you don't have to wait, just be aware that Java 5 is a dead end for jsr166y stuff

7:52 gerry_: ok

7:53 rhickey: and the libs are built on specific versions, since they are still changing the api

7:53 i.e. the things that parallel are built on are not going to be in Java 7

7:53 gerry_: i have one gui application writen by swing, drawString in swing is too slow, i want to test parallel lib

7:53 rhickey: thus the par branch based directly on ForkJoin

7:54 gerry_: ok, i'll check it out

7:57 i'm not sure whether swt is better for me

7:57 eevar2: gerry_: sure your performance issue isn't because of reflection?

7:58 gerry_: i'd stay with swing

7:58 gerry_: no, mainly due to drawString methon

7:58 eevar2: gerry_: http://www.javaworld.com/javaworld/jw-05-2009/jw-05-clojure.html?page=5

7:58 gerry_: this method maybe slowest in swing lib :)

7:59 eevar2: add some type hints if you haven't already

8:00 gerry_: more articles: http://www.google.no/search?hl=en&q=clojure%20type%20hints%20reflection%20-site:www.experts-exchange.com

8:00 gerry_: eevar2: i have done type hints

8:00 thx for your link

8:12 jsr166y.jar in google group works

8:12 eevar2: gerry_: what are you painting to?

8:13 more likely to improve performance doing that, than paralellizing calls to drawString

8:13 gerry_: gogame board

8:13 yes

8:13 eevar2: s/doing/switching to some other drawing surface

8:13 gerry_: i have to draw coords in board

8:14 i haven't found any alternative methods to do that

8:15 so i have to parallel them

8:31 eevar2: just like this: http://imagebin.ca/view/oIsKZUe6.html

8:33 eevar2: how many times do you call drawString?

8:34 gerry_: about 40times

8:35 eevar2: and that's a bottleneck, you think?

8:35 gerry_: and 360 time repaint

8:35 s/time/times

8:36 dont' much slow, really a bit slow, but i want perfect :)

8:39 enable drawSting, i got about 1 second stalling compare with disable drawsting

8:39 s/drawSting/drawString

8:42 i'm using agent to repaint

8:43 i don't know whether this is thread safe

8:50 (map f (par cloll)) just work?

8:50 or (pmap f (par coll))?

8:52 Chouser: I'm not sure, but I would guess 'par' is a linear (single-threaded) process

8:53 so it might be better to do (par coll) earlier and then keep the result around and reuse it.

8:55 gerry_: (par coll :map f)?

8:55 Chouser: I think that would also be a non-parallel process.

8:55 gerry_: Chouser: (let [pcoll (par coll)] (map f pcoll)) like this?

8:55 Chouser: pmap, but yes.

8:56 gerry_: ok

8:56 Chouser: well, assuming you do other things in that 'let' as well.

8:57 if all you do in the 'let' is run 'pmap' once, you might as well use your original statement.

8:57 gerry_: s/map/pmap will be better?

8:58 Chouser: wait, this is wrong. hand ong.

8:58 gerry_: oh?

8:58 Chouser: sorry, 'pmap' doesn't require the use of clojure.parallel at all

8:58 (doc pmap)

8:58 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

8:59 Chouser: pmap works on regular sequences, you don't need a "parallel array" first.

8:59 gerry_: but if i use it with par?

9:00 what will happen?

9:00 Chouser: I should probably stop talking about clojure.parallel, because I just don't know it that well.

9:00 anyone else have some advice?

9:01 gerry_: ok, let me try it

9:02 eevar2: gerry_: i'd say your rendering code/approach is broken somewhere. try running a profiler or something. or reading the swing docs

9:05 gerry_: eevar2: i have figured it out by disable drawString and enable it

9:05 problem is there,i'm sure

9:06 eevar2: okies. i have nothing further to contribute. good luck

9:07 gerry_: thx anyways

9:07 Chouser, map seems better than pmap in this case

9:08 Chouser: wait, you're running swing drawing methods in multiple threads? I don't think this is supported.

9:09 swing wants pretty much all drawing to happen from its event thread.

9:10 gerry_: Chouser, i just repaint in agent thread, and it works

9:10 but not in event thread

9:12 and sound play also in agent thread

9:15 oh,yes, repaint still call back to original thread

9:25 maybe problem due to videocard support in opensolaris? i'll try it on windows or linux

9:26 ati support in opensolaris sucks

9:31 ok, time to go

9:31 thx, bye

9:35 Jomyoot: Can Java.util.HashMap readily be converted into Clojure Hash?

9:35 like { :a 1 :b 2 :c 3 }

9:35 Chouser: (into {} my-hash-map)

9:35 Jomyoot: hmm

9:35 Chouser: ,(into {} (java.util.HashMap. {:a 1, :b 2, :c 3}))

9:35 clojurebot: {:a 1, :b 2, :c 3}

9:36 Jomyoot: so from Java :a is actually "a" right?

9:36 Chouser: That's a Clojure PersistentHashMap to java HashMap and back.

9:36 AWizzArd: no

9:36 Chouser: Java HashMap can store Clojure keywords

9:37 AWizzArd: they are ordinary objects, like you and me

9:37 Chousuke: ,({:a 1 "key" 2} "key")

9:37 clojurebot: 2

9:37 eevar2: ,(:a (java.util.HashMap. {:a 1 :b 2 :c 3}))

9:37 clojurebot: 1

9:37 Chouser: if you have a Java HashMap with string keys and you want a clojure PHM with keyword keys, I'd look at zipmap

9:38 Jomyoot: hmm

9:38 Chouser: ,(let [jhm (java.util.HashMap. {"a" 1, "b" 2, "c" 3})] (zipmap (map keyword (keys jhm)) (vals jhm)))

9:38 clojurebot: {:a 1, :c 3, :b 2}

9:40 Jomyoot: is that a natural way to do it?

9:40 or is that considered a hack?

9:40 If I like to pass Clojure hash back and forth with Java program

9:40 Chousuke: why would you change the keys at all?

9:40 just let them be as they are

9:40 Chouser: Jomyoot: any reason not to leave the keys as strings?

9:40 eevar2: just use string keys

9:41 Jomyoot: ok then

9:41 Chouser: :-)

9:41 AWizzArd: maybe you don't even need to convert it into a persistent map at all?

9:41 Chouser: slightly less pretty in the Clojure code, but less mucking around too.

9:41 AWizzArd: clojures function (get ...) works on j.u.Map's as well

9:44 avital: hi. is there any way to use for to collect more than one element on each iteration? something like (for [x [1 2 3]] x (+ x 10)) that would return '(1 11 2 12 3 13)

9:45 AWizzArd: you could collect [x (+ x 10)] and get ([1 11] [2 12] [3 14])

9:46 avital: yes i could also do (union (for [x [1 2 3]] [x (+ x 1)]))

9:46 but that seems weird

9:46 ,(union (for [x [1 2 3]] [x (+ x 1)]))

9:46 clojurebot: java.lang.Exception: Unable to resolve symbol: union in this context

9:46 avital: ,(set/union (for [x [1 2 3]] [x (+ x 1)]))

9:46 clojurebot: java.lang.Exception: No such namespace: set

9:46 avital: ,(clojure.set/union (for [x [1 2 3]] [x (+ x 1)]))

9:46 clojurebot: ([1 2] [2 3] [3 4])

9:46 avital: ,(clojure.set/union (for [x [1 2 3]] [x (+ x 10)]))

9:46 clojurebot: ([1 11] [2 12] [3 13])

9:47 AWizzArd: ,(apply concat (for [x [1 2 3]] [x (+ x 10)]))

9:47 clojurebot: (1 11 2 12 3 13)

9:47 AWizzArd: otherwise, there is always (loop ...)

9:47 avital: ok nice that works but it's too hacky, shouldn't for support multiple values added per iteration or something of the sort?

9:48 Chouser: ,(let [v [1 2 3]] (interleave v (map #(+ 10 %) v)))

9:48 clojurebot: (1 11 2 12 3 13)

9:48 AWizzArd: avital: could be useful. In functional programming it is a design pattern to write your own map/filter/etc functions that can do what you need in one go

9:48 if you want to traverse the list only once then loop is a good start to implement such a function

9:48 avital: Chouser chouser chouser chouser the apply suggestion also works and is much more readable. I am asking why this would not be part of for

9:49 AWizzArd: ok we'll implement our for that supports this

9:49 Chouser: avital: :-) beauty is in the eye of the beholder

9:50 AWizzArd: avital: the most typical use case is what for currently supports. I agree that it would not be bad to have something in place that works for inserting multiple values, but I guess it is a bit too special.

9:50 Chouser: avital: I've used (apply concat (for ...)) a few times. Many of those times I eventually found that there was a better way in the large.

9:50 avital: why do you want interleaved values like that? I mean, what consumes that seq?

9:50 avital: the specific example

9:50 we are writing a google wave robot

9:50 AWizzArd: oh good

9:50 avital: we need to send operations to be done on several waves

9:51 each operation is actually two operations in one - a delete and an append operation (instead of one replace operation)

9:51 so we collect all the wave ids that we need to act on in a list

9:51 and then create the json response containing the delete and append operations

9:51 each wave id needs to generate _two_ operations

9:51 in a nice interleaved way

9:51 Chouser: avital: it's important that they happen interleaved, and not all appends followed by all deletes?

9:52 AWizzArd: avital: which lib do you use to parse/compose json?

9:52 avital: Chouser: Maybe not but even so such a case might happen, it should be a solvable problem even if in this case it's not necessary

9:52 Chouser: ,(mapcat #(list % (+ 10 %)) [1 2 3 4])

9:52 clojurebot: (1 11 2 12 3 13 4 14)

9:53 avital: AWizzArd: clojure.contrib.json

9:53 AWizzArd: oki good, i also want to begin to use it right now

9:53 avital: AWizzArd: For wave?

9:54 Chouser: avital: of course it's solvable. The question is whether adding more complexity to 'for' is worth the benefit. If the use cases are largely theoretical, one may being to doubt the value.

9:54 avital: Chouser: What?! As far as I see the world, if you lose nothing and gain something it's always a good idea. No?

9:54 Chouser: adding complexity to 'for' is losing some simplicity

9:54 avital: Sorry for the What?! I meant What?

9:55 Chouser: not that there's much simplicity left in 'for' to lose! :-)

9:55 avital: Chouser: No loss of simplicity. If someone doesn't want to know about the posibility of putting several values they don't need to even know that exists

9:56 Chousuke: avital: what if someone wants a side-effect in for... for debugging? :)

9:57 avital: Chousuke: not sure what you mean...

9:57 Chousuke: (for [x someseq] (println "X: " x) x)

9:58 avital: Chousuke: So you're saying that you think what I'm suggesting is a good idea? again not sure...

9:58 Chousuke: with your multi-expression extension, you'd get a seq of (nil a nil b nil c...) :/

9:58 avital: No

9:58 If you want to do that you'd do

9:58 ,(for [x [1 2 3] (do (println "X: " x) x))

9:58 clojurebot: Unmatched delimiter: )

9:58 avital: ,(for [x [1 2 3] (do (println "X: " x) x)

9:58 clojurebot: EOF while reading

9:58 avital: ,(for [x [1 2 3]] (do (println "X: " x) x)

9:58 clojurebot: EOF while reading

9:58 avital: ,(for [x [1 2 3]] (do (println "X: " x) x))

9:58 Chouser: 'for' doesn't support more than one body expression now anyway. no implicit 'do'

9:58 clojurebot: (1 2 3)

9:59 Chousuke: oh, hmm :/

9:59 Chouser: ,(for [x [1 2 3]] x (+ x 10))

9:59 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$for

9:59 avital: Chousuke: I'm suggesting to allow for multiple values in the body expression in a for. If you want to do your thing, just use (do ...)

9:59 Chouser: not sure how chunking should work with multiple values.

10:00 just generate bigger chunks I suppose?

10:00 avital: what is chunking sorry?

10:00 Chousuke: avital: hm. that might be fine

10:00 avital: but I'll leave the implementation to you

10:00 ~def for

10:00 Chouser: avital: welcome to the complexity that is 'for'

10:00 Chousuke: good luck :P

10:00 avital: Sure, ayal is implementing for1 as we speak

10:00 forx

10:01 rhickey: if 'for' did that, wouldn't people want the same from map (somehow?), it's a general problem of expansive mapping

10:02 avital: I'm relatively new to Clojure and FP but in the meanwhile I've gotten to the point that I almost always prefer to use for than map/filter/etc unless I have a pre-existing function or predicate that just perfectly works.

10:02 Chouser: they would certainly want the same from 'doseq', but 'doseq' already provides the analogue

10:02 rhickey: certainly putting multiple values after one another like that is a mismatch with blocks elsewhere

10:02 Chousuke: I guess internally multi-value-for would have to be quite similar to (apply concat (for ...)) anyway :/

10:02 rhickey: forcat a la mapcat?

10:02 avital: rhickey: Sorry, not sure what you mean...

10:02 Chouser: for is already a bit like mapcat

10:02 AWizzArd: avital: not for wave, for some other server side app i want json

10:03 jdz: when do we have a lolcat?

10:03 AWizzArd: what was this again?

10:03 Chousuke: "applies a funny operation to the input. produces a list, if input is cheezburger"

10:04 avital: It's not easy to add this to map since map takes a function anyways

10:04 But it seems natural to add it to for

10:04 jdz: *produces a very lazy list :)

10:06 avital: As far as I understand, for is the generic wrapper for a bunch of stuff that could've been done with combinations of map filter and much more

10:06 but in general at some point of complexity (like where we are) the solutions with map/filter are too crazy and for renders a natural and simple implementation

10:07 so since for anyways is a huge machine that eases use of map/filter/etc why not give it as much functionality as possible?

10:07 AWizzArd: avital: well, reduce is the generalization of map/filter

10:07 Chouser: avital: because that way lies madness (a.k.a. Common Lisp's LOOP)

10:08 avital: AWizzArd: no, reduce map and filter work together and they are orthogonal in functionality

10:08 Chousuke: avital: except you can implement both map and filter with reduce :/

10:08 AWizzArd: what can map/filter do what reduce can't?

10:08 Chousuke: avital: albeit not lazily :)

10:08 manic12: does anybody else have a problem with swing crashing the netbeans repl?

10:09 avital: Chousuke: Ah, yes I see now; but I see that as a hack. In my view the most important aspect of code is its readability. map/filter are more readable than the equivalent weird reduce that would implement them

10:09 AWizzArd: yes

10:09 avital: It's all about keeping the code as similar as possible to a human language as possible

10:09 for looks like a human language

10:09 AWizzArd: sure

10:10 avital: And in a human language I'd like to be able to say "go over all these elements and for each one collect two elements"

10:10 AWizzArd: but for example a composition of filter and map may better be expressed with one reduce, which can do the work in one go

10:10 avital: instead of collecting lists and then apply concat'ing them

10:10 AWizzArd: avital: write a useful collect macro and open source it :p

10:11 jdz: what's the for incantation to go over a sequence with a counter?

10:11 avital: AWizzArd: My colleage Ayal is writing it as we speak.

10:12 Chousuke: I'm not really opposed to the idea itself but I think for supporting multiple expressions is somewhat... unexpected :/

10:14 jdz: i'd like to see CL's iterate in clojure, but...

10:14 not enough to go and start writing one, apparently

10:14 Chousuke: I think it would be conceptually simpler to have for be a "simple" list comprehension.

10:15 AWizzArd: jdz: want it for compatibility / code reuse?

10:15 clojurebot: for is not a loop

10:16 hiredman: ~suddenly

10:16 clojurebot: CLABANGO!

10:16 AWizzArd: cemerick: new record!

10:16 ~ max people

10:16 clojurebot: max people is 165

10:16 jdz: AWizzArd: not really. just for not writing complicated loop/recurs

10:17 AWizzArd: thesnowdog_: grats, you made the new record

10:17 cemerick: AWizzArd: man, no one even knows what you're talking about! ;-)

10:17 AWizzArd: cemerick: the max people thingy

10:17 it was set in February I guess

10:17 cemerick: oh, *I* know what you're talking about

10:17 AWizzArd: great :)

10:18 lisppaste8: Chouser pasted "support multiple values in 'for' body" at http://paste.lisp.org/display/87441

10:19 Chouser: not so hard to do, which concentrates us on the question: is it good to have?

10:19 hiredman: it's 7am, I don't need to see that

10:19 Chouser: note that doesn't do each value lazily, which could be desirable.

10:21 AWizzArd: hi ayal

10:22 lisppaste8: ayal pasted "forex macro" at http://paste.lisp.org/display/87442

10:22 ayal: AWizzArd: hi!

10:24 cgrand: stupid question: why for isn't implemented in terms of mapcat/map/filter? for perf reasons (easier on allocations)?

10:24 Chouser: hm. ayal's is simpler. :-)

10:24 ayal: Chouser: Thank you.

10:25 Chouser: cgrand: I actually looked into doing that at some point. I forget why I gave up...

10:25 maybe just that some features are very hard to implement that way too. Such as :while.

10:26 AWizzArd: ~seen kotarak

10:26 Chouser: though thinking about it again now, I don't know why a take-while with a special value wouldn't work.

10:26 clojurebot: no, I have not seen kotarak

10:26 cgrand: isn't :while a take-while?

10:27 Chouser: I looked at it when adding chunk support, because it would have been much nicer to just build on the chunk support already in map/filter

10:28 maybe it was just performance. should have made some notes. :-/

10:54 ben_m: Hi there :) This line: `javax.swing

10:54 gah.

10:54 Copy-paste fail.

10:55 (for [x (range 10)] (.add (. (new JLabel) (setPreferredSize 10 10))))

10:55 I get an error: "Wrong number of args passed to: core$for (grid.clj:5)

10:56 (I'm aware that the code might have more errors except the for one, I'm new to both Java and Clojure :)

10:56 Chouser: I get: No matching method found: setPreferredSize for class javax.swing.JLabel

10:57 note you're mixing method call style there.

10:57 ben_m: I'm in a (doto frame ...)

10:58 If that helps at all :)

10:58 Chouser: oh!!

10:58 yeah

10:58 that changes everything. :-)

10:58 ben_m: I'm tring to create 10 Labels inside the frame

10:58 Chouser: the doto will be inserting something after the first word of the list

10:58 ben_m: There's probably a better way instead of using for and range, but I don't know it :)

10:58 Chouser: (for <thing here> [x (range 10)] ...)

10:58 ben_m: Ah!

10:59 Chouser: you've outgrown that particular 'doto'. Time to put the object in a local (using 'let') and then try your loop again.

10:59 this time use 'doseq' instead of 'for' because you're looping for side effects.

11:00 hiredman: I think the reason I don't use for often (almost never) is it's lack of composability

11:01 lisppaste8: gluckspilz pasted "untitled" at http://paste.lisp.org/display/87445

11:01 hiredman: how do you use for inside a ->

11:01 Chousuke: you overuse -> anyway :P

11:02 Chouser: wait, how do you use 'map' inside a -> ?

11:02 hiredman: ((partial map fn))

11:03 Chousuke: that automatically looks ugly to me because of the double parens ;/

11:03 hiredman: you get used to it

11:04 Chousuke: more likely I will just write it some other way

11:17 tmountain: anybody know if clojure has a builtin to test if a number falls within a given range ?

11:17 Chouser: ,(< 2 5 10)

11:17 clojurebot: true

11:18 tmountain: whoa, wasn't aware of the three argument version

11:18 thanks

11:19 Chouser: sure. don't know of any that is like a <= b < c, which I've wanted once or twice.

11:20 ben_m: ,paste

11:20 clojurebot: java.lang.Exception: Unable to resolve symbol: paste in this context

11:20 ben_m: !paste

11:20 Hm.

11:20 Chouser: ~paste

11:20 clojurebot: lisppaste8, url

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

11:20 ben_m: Oh ;)

11:23 lisppaste8: ben_m pasted "Clojure & Swing problem" at http://paste.lisp.org/display/87447

11:23 ben_m: If anyone could take a look at that ... error etc. is at the bottom of the paste

11:23 ambient: btw, does clojure have clear distinction between mutation and immutable? http://blog.plt-scheme.org/2009/09/set-vs-set-box-and-unbox.html

11:24 i wonder how syntax highlighting would work for that

11:25 Chouser: ben_m: I get Unable to resolve symbol: x in this context, because the doseq is closed after the println

11:25 ambient: there's no perfectly reliable visual indicator, if that's what you mean.

11:26 ben_m: Chouser: Oh sorry. I added that println for debugging purposes, it's not usually.

11:26 Jomyoot: is there a way to concat results of doseq like mapcat?

11:26 Chouser: ambient: functions that mutate tend to end with !, access to mutable things use either . interop or @, generally.

11:26 ambient: Chouser only truly mutable thing in clojure i've found is arrays :p

11:26 Chouser: Jomyoot: doseq has not results

11:27 ambient: all the reference types are mutable: atom, ref, var, etc.

11:27 Jomyoot: i guess i use mapcat then

11:27 ambient: Chouser as far as i've understood them, they're all atomic

11:27 Chouser: well, protected yes, but still mutable

11:27 ambient: true

11:28 perhaps i should've formulated my question better

11:29 Chouser: ben_m: .. returns the final thing, in your case the return value of setPreferredSize. Adding that value to 'frame' is what's failing.

11:29 ben_m: I feared it was something like that

11:30 Chouser: ben_m: using 'doto' in there, or storing the fram in a local will clear that up.

11:31 ben_m: How would I use doto?

11:32 Chouser: (.add frame (doto (new JLabel (str x)) (.setPreferredSize (new Dimension 10 10))))

11:34 ben_m: Awesome :)

11:34 Thank you.

11:37 tmountain: is there an easy way to see if a sequence contains a given set of values?

11:38 Chouser: a set? like in order, or all of them in any order, or ?

11:38 tmountain: basically just want to see if a sequence contains all values provided

11:39 so if the sequence contained 1, 2, 3, 4, 5 and I provided 2 and 4, it would be true. 2 and 6 would be false

11:40 I could do it with some loop logic, but I'm guessing there's probably a better way

11:40 Chouser: tmountain: it's best to use a set instead of a seq if you're mainly going to be doing contains tests.

11:40 either way, you might like 'every?'

11:41 Chousuke: ,(every? boolean (map (set [1 2 3 4 5 6]) [2 4]))

11:41 clojurebot: true

11:41 Chouser: ,(every? #(.contains '(1 2 3 4 5) %) [2 6])

11:41 clojurebot: false

11:41 tmountain: oh, that's great

11:41 thanks for all the help this morning

11:41 playing around with a yahtzee implementation in clojure ;-)

12:04 Jomyoot: how would I iterate over a [vector] with index i and concat all results?

12:04 clojurebot: with style and grace

12:05 Jomyoot: well yeah

12:06 stuartsierra: ,(map (fn [x i] (prn x i)) [:a :b :c] (iterate inc 0))

12:06 clojurebot: (nil nil nil)

12:07 stuartsierra: ,(map (fn [x i] [x i]) [:a :b :c] (iterate inc 0))

12:07 clojurebot: ([:a 0] [:b 1] [:c 2])

12:08 Chouser: which is what seq-utils/indexed does, I believe

12:12 stuartsierra: yep

12:41 technomancy: I'm thinking of adding more elements to the warning-face in clojure-mode. seems like set! should be in there; any other suggestions?

12:42 io! is already there

12:44 hiredman: aset*

12:44 ?

12:45 technomancy: sounds good

12:58 cgrand: technomancy: symbols starting with &

12:58 technomancy: cgrand: I don't even know what those mean. =)

12:58 care to explain?

13:01 cgrand: I repeatedly saw newcomers to forget the space between & and the symbol in destructuring forms

13:01 hiredman: [a & b] vs [a &b]

13:02 technomancy: oh, to catch mistakes; I see

13:02 or people forgetting clojure is not CL. =)

13:03 hiredman: clojurebot: is this allegro?

13:03 clojurebot: this is not allegro

13:37 lisppaste8: ben_m pasted "Problem & Question of style" at http://paste.lisp.org/display/87454

13:38 ben_m: ^-- If anyone could tell me if some things are not idiomatic or some things are better done in another way

13:38 Also, at the commented two lines, some of the JLabels are supposed to have a blue background, but they don't :D

13:39 manic12: if I create a swing JFrame in clojure started from a command prompt, it works. if I create a JFrame in enclojure repl it gives a stack buffer overrun as it crashes

13:41 seeing as how I have to start and stop the enclojure repl just to recompile a gen-class, I think this may be a good reason to switch to something else besides netbeans

13:42 is emacs/slime/clojure the most supported setup?

13:45 * technomancy would claim so, but he's a bit biased

13:57 Licenser__: you will like to hear that but I hate threads and locking *grrrr*

13:58 ben_m: Are you using Clojure?

13:59 Chouser: re-compiling and then using a genclass always requires restarting a JVM.

13:59 samhughes: hey there. calling (def #^{:private true} myname "samuel") keeps the variable only accessible to its namespace, but that's not the for refs, e.g., (def #^{:private true} myname (ref "samuel")). is there a reason for that?

14:00 Licenser__: ben_m: no that is the problem :P

14:00 I just wanted to use my frustration to cheer you people up

14:01 ben_m: Licenser__: Thank you kindly.

14:01 * Licenser__ bows

14:01 Licenser__: you are welcome ben_m, at lest someone can have a gain from this $§*!&*! code

14:05 hiredman: I was just using some ruby xmpp bot library to monitor and control builds, that was a nightmare with regards to threading

14:06 I really should just throw it all out and do it in clojure

14:07 samhughes: speaking of nightmare, (def #^{:private true} myname (ref "samuel")) not actually making myname private is a nightmare.

14:08 hiredman: samhughes: does here

14:08 Licenser__: hiredman: I know ...

14:08 hiredman: samhughes: what version of clojure is this?

14:08 Licenser__: but I've a ruby library that does not exist in clojure

14:08 hiredman: do you have a test case?

14:09 ~paste

14:09 clojurebot: lisppaste8, url

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

14:09 samhughes: i think it's 1.0.0

14:11 sure, one sec (on the paste)

14:14 lisppaste8: samhughes pasted "private refs" at http://paste.lisp.org/display/87456

14:18 Chouser: both give an exception for me, in both 1.0.0 and latest master

14:19 hiredman: same here

14:19 I just grabbed the 1.0 zip and this works as expected

14:20 samhughes: you're right, with that test, it did. one sec. i'm going to retrace the sceneario and paste it.

14:21 hiredman: I would suspect some sort of pollution, i.e. repl that has been running for a while and you having imports and uses and requires all over the place

14:23 lisppaste8: samhughes pasted "second try at refs" at http://paste.lisp.org/display/87457

14:24 Chouser: heh. don't do that.

14:25 samhughes: which part? i wouldnt normally have both namespaces in one file if thats what you mean.

14:25 Chouser: no, don't call 'def' from somewhere other than top level.

14:26 hiredman: def is a global scope thing

14:26 and beyond that, def gets it's namespace stuff setup at compile time

14:26 so the namespace a thing is def'ed in is what namespace the form is in at compile time

14:27 samhughes: yeah. i just wanted a way to define it from another namespace but still keep it private. but i could use ref-set within the function, and define outside, i assume?

14:27 hiredman: in summary, don't do that

14:27 samhughes: referring to the last thing i just said?

14:27 Chousuke: you can do ref-set in the setup-ref function

14:27 hiredman: no

14:27 Chousuke: that's the proper way

14:28 hiredman: are you sure you need the ref?

14:29 samhughes: not necessarily. i'm creating api for memcached, and want to keep my sockets alive. but it doesn't necessarily need to be a ref.

14:29 hiredman: :(

14:29 Chouser: on the other hand, what the heck is actually happening there?

14:30 hiredman: it shouldn't be a ref

14:30 definitely

14:30 refs/atoms/agents are for holding immutable objects

14:30 Chouser: (meta #'my-ref) => {:ns #<Namespace names>, :name my-ref, :file "NO_SOURCE_PATH", :line 4, :private true}

14:30 hiredman: (that apear to change)

14:30 Chouser: that all looks right, so why is the privacy check failing?

14:31 samhughes: but my thinking was that additional sockets might be appended by multiple threads, so i'd want that happening in sync.

14:31 Chousuke: maybe because it's the same compilation unit? :/

14:31 samhughes: so you still want to have a global socket pool?

14:32 in that case, a ref is fine.

14:32 hiredman: Chousuke: it doesn't fail here

14:33 samhughes: Chousuke: yeah, i think so. i'm guessing that i'll have multiple servers handling the pool.

14:34 hiredman: samhughes: is there a reason to have the api keep track of the sockets, instead of having the user call an api method to create a socket, then pass it around, either via binding or explicitly

14:34 ugh

14:34 * technomancy just integrated the commons pool library with a clojure app last week; it was pretty painless

14:34 hiredman: Chouser: the privacy check doesn;t fail here

14:35 (use 'names) in the example does fail

14:35 Chouser: well, it really does here.

14:35 yeah, I used (refer 'names)

14:35 hiredman: hoho

14:35 interesting

14:35 Chouser: before calling setup-ref: (meta #'names/my-ref) => {:ns #<Namespace names>, :name my-ref}

14:36 hiredman: java.lang.Exception: Unable to resolve symbol: my-ref in this context

14:36 Chouser: the var is there with some metadata, but unbound.

14:36 hiredman: (after refer 'names)

14:36 Chouser: right

14:36 oh

14:36 hiredman: nice

14:36 Chouser: which is all what I would expect

14:37 then after calling setup-ref, names/my-ref has the private flag and is bound. This surprised me -- I expected it to create a var in the testcase namespace

14:37 samhughes: hiredman: i'm still debating on the best route. but you're right, it may be better to keep them on the client side, adn have them passed in.

14:39 yeah, because each server will have its own set of sockets.

15:36 drewr: is there a version of future with a timeout?

15:38 Chouser: drewr: it's been asked for

15:38 drewr: ah, ok

15:38 Chouser: drewr: actually, I have a unhappy implementation I'm using right now

15:39 you call the promise rather than deref'ing it, so you can provide the timeout as an arg. :-/

15:41 hiredman: time out on the deref, or time out on what the future is doing?

15:42 Chouser: oh, mine is promise/deliver, not future. sorry.

15:42 tomoj: I thought I remembered hearing something about how derefs automatically call functions.. seems they don't. is there something like that somewhere that I'm confusing this with?

15:42 Chouser: tomoj: calling a var calls its value

15:42 hiredman: .get on the future object takes a timeout unit

15:43 tomoj: Chouser: sure, like (@foo) ?

15:43 but I thought there was some special thing somewhere (maybe not with deref) where a function would automatically be called

15:43 sfuentes: so i'm new to clojure and i'm trying to learn the language by implementing a few data structures. i understand that clojure may already have sufficient data structures but this is again more of a learning exercise. anyway, i'm trying to implement a basic queue. the create-queue and dequeue functions are simple enough. however i'm stuck on writing an enqueue function.

15:44 Chouser: tomoj: well, (#'foo) is like (@#'foo) or (foo) -- maybe that's not what you were thinking of though.

15:44 sfuentes: now i don't want to traverse the whole queue to simply enqueue an item

15:44 tomoj: Chouser: exactly!

15:44 hiredman: sfuentes: see pop and peek

15:46 tomoj: (foo) == (@foo), that's what I was thinking of

15:47 sfuentes: hiredman: well i guess i'm trying to implement peek/last

15:47 but in O(1)

15:48 i think last is O(n)

15:48 tomoj: what's your underlying data structure?

15:48 a list?

15:48 Chouser: tomoj: that's not true for all reference types

15:48 sfuentes: yes

15:48 Chouser: tomoj: appears to work for vars and refs

15:48 tomoj: so.. just store the queue in reverse order, like peek/pop/conj

15:49 then enqueue/dequeue is O(1)

15:49 Chouser: you can't do O(1) queue and deque on a list

15:49 tomoj: sure you can..

15:50 Chouser: not a persistent list

15:50 tomoj: oh

15:50 I'm thinking cons cells I suppose

15:50 pop isn't linear, though, is it?

15:50 (nor conj?)

15:50 sfuentes: items in a list can be referenced by index, no?

15:51 Chouser: sfuentes: sure, O(n) though

15:51 sfuentes: what? indexing is O(n)?

15:51 Chouser: clojure.lang.PersistentQueue is built on a clever combination of a vector and a list.

15:52 sfuentes: yes! a list is essentially a linked list. traversal is O(n)

15:52 tomoj: is the reason pop isn't O(1) similar to the reason hash access isn't O(1)?

15:52 Chouser: sfuentes: vectors are indexed

15:52 tomoj: I haven't looked into the implementation of persistentlist

15:53 Chouser: list and vector both provide O(1) (or nearly) push and pop for stack-like access.

15:53 sfuentes: ok so i guess i should be implementing my queue using vectors

15:53 what's the downside of that i wonder

15:54 Chouser: if vectors or lists could provide effiecient queue-like behaviour, they would already.

15:55 tomoj: ooh, *slaps self*

15:55 I was thinking of a stack, not a queue

15:55 Chouser: ah. yes, both list and vector can do fast push (called conj) and pop.

15:56 for a list it's essentially the same as conj/rest. for a vector, pop is special.

15:58 finger trees provide fast consLeft/rest on the left and fast conjRight/pop on the rigth, so can be used as stack or queue going either direction.

15:59 sfuentes: I'm sorry, I was rudely disconnected so I might have missed a few things. Anyway, so if I want to implement a queue I should be using a vector, right? if so, are there any downsides?

15:59 Chouser: sfuentes: if vectors or lists could provide effiecient queue-like behaviour, they would already.

16:00 sfuentes: it seems like state would help here

16:00 but i'd hate to be accused of heresy.

16:00 hiredman: how would it help?

16:01 Chouser: you can conj onto the right end of a vector fast, and traverse from the left fast (using first/next), but 'next' would return a seq not a vector, so conj on the right would no longer be fast.

16:01 you could build a mutable queue out of a doubly-linked list of 3-element arrays or something. :-(

16:02 tomoj: PersistentQueue is not a finger tree, is it?

16:02 sfuentes: i retract my comment. is there such a thing as pointers or pointer-like things in clojure?

16:02 Chouser: tomoj: no, it's a clever combination of a vector and a seq

16:02 hiredman: I think the pqueue constructor takes a seq a vector and a map

16:03 Chouser: sfuentes: building fast persistent data structures is hard, with the exception of the singly-linked list.

16:04 tomoj: but worth it :)

16:05 Chouser: but PersistentQueue isn't *too* complicated, I guess. Might be interesting to try writing it in Clojure.

16:05 will have to be done eventually. :-)

16:07 hamza: hey guys, i am trying to create xml, been playing ith prxml, can i use to create a string instead of printing to out?

16:07 hiredman: ,(doc with-out-str)

16:07 clojurebot: "([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

16:08 sfuentes: Chouser: so implementing an efficient queue in clojure is more difficult/complex than in a language like C?

16:09 Chouser: no

16:09 hamza: thx is this the recommended way of doing this or is there a lib that i am not aware of?

16:09 Chouser: implementing an efficient persistent queue is more difficult/complex than a mutable queue

16:10 sfuentes: persistant is efficient in this context, correct?

16:11 Chouser: Yeah, I guess I should have said efficient immutable.

16:11 so pick a goal -- immutable queue or mutable queue.

16:11 vy: Is anybody able to succeed running (count (clojure.contrib.combinatorics/subsets (range 20))) without getting an OOM exception?

16:12 Chouser: if you want to try doing an immutable one, I'd recommend learning about an efficient data structure that someone else has already figured out -- Clojure's PersistentQueue, 2-3 finger trees, or something else.

16:14 actually, creating and using a persistent collection would be much more difficult in C because of no GC.

16:15 sfuentes: couple questions here

16:15 why would i want an immutable vs a mutable queue?

16:18 Chouser: immutable collections are much easier to use safely -- no iterator errors when they change while iterating, no chance some fn you call will delete data you need, no concurrency issues at all.

16:18 hiredman: equal immutable things are always equal

16:18 Chouser: they're very nice, and having good immutable collection and a standard API that supports using them comfortably is a huge part of what makes Clojure good.

16:20 sfuentes: i see. but mutable queues are more efficient, correct?

16:21 Chouser: they can probably be made slightly faster, yes, though the computational complexity can be essentially the same (O(1) push and pop)

16:23 sfuentes: ok so how can i have this O(1) for both push and pop in a queue?

16:23 vy: sfuentes: If you're sharing those queues among many other concurrent tasks, then you'll need to copy them for each thread instance, which will significantly decrease the performance. OTOH, if there will be a single thread fiddling with the queue it'll much more efficient to have a mutable queue implementation. To summarize, that all depends on the specific problem domain.

16:24 sfuentes: i know you mentioned PersistentQueue, but I'm trying to write this

16:24 implement this

16:24 Chouser: vy: even in single-threaded contexts, immutable collections are frequently worth while

16:24 vy: Chouser: +1

16:25 Chouser: sfuentes: you could look at what PersistentQueue does (it's written in Java) and do something similar in Clojure code.

16:25 sfuentes: Chouser: will do. thanks for the help

16:26 Chouser: sfuentes: sure, good luck!

16:47 manic12: I got clojure going with slime, and I realized something very important...

16:47 all my frustrations were because of netbeans.

16:48 maybe not all of them, but at least most of them

16:50 Chousuke: heh

16:50 now you can find new frustrations with emacs.

16:51 manic12: i have been using emacs for over ten years

16:51 Chousuke: hmm. I suppose you've found most of them then.

16:52 manic12: actually emacs is quite big, ten years isn't enough time to find all the frustrations

16:52 vy: Word.

16:53 Chousuke: well, yeah.

16:53 ten years isn't enough to find all the *features*

16:54 but that's okay. I have used emacs only for a couple months and I've found enough for a while

16:55 ben_m: My .emacs is so messy, I hate that :/

16:55 Chousuke: heh.

16:55 ben_m: My .vimrc is only 10 lines or something.

16:55 Chousuke: I have an emacs.d instead, based on emacs-starter-kit

16:56 hiredman: my vimrc is just over 200

16:56 Chousuke: it provides a good base for keeping things organised :)

16:56 ben_m: Chousuke: I should try that.

17:11 manic12: somebody should have warned me about netbeans

17:12 ben_m: What language do you come from? Before Clojure.

17:12 manic12: common lisp

17:12 ben_m: oh

17:12 They should've warned you then.

17:12 From my experience, only Java programmers actually like NetBeans.

17:19 sfuentes: i'm sorry, what's wrong with netbeans?

17:21 ben_m: I'm just not a fan of IDEs so I wouldn't know.

17:21 manic12: for clojure, it's like programming java with parens, but a little more frustrating

17:23 sfuentes: manic12: how so? i'm not a java programmer, but i'm learning clojure with netbeans.

17:24 manic12: when the repl doesn't stop by itself for a stack overflow or some other reason, you have to restart it yourself constantly

17:24 sfuentes: oh i see. so its a repl thing

17:24 is that all?

17:25 manic12: it's not a dynamic language without a fluid repl, as far as i am concerned

17:27 sfuentes: that's not all, I just don't want to revisit the pain

17:31 except of course to cut and paste the code I left there into an emacs buffer

17:34 ben_m: I still think it is the best IDE out there.

17:34 Just because of jVi

17:34 Chouser: ben_m: have you used jVi with enclojure?

17:34 ben_m: I don't even know what Enclojure is.

17:35 Chouser: it's the clojure plugin for netbeans

17:35 ben_m: Oh :)

17:35 I don't really use IDEs, but when I have to (school), then I use NetBeans.

17:37 jensli: Q: Im reading clojure.contrib.def.

17:37 In defnk theres a form: (-> arg name symbol)

17:37 Is because of a namespace thing, to make sure the sym gets interned in the right namespace?

17:39 hiredman: ,(doc defnk)

17:39 clojurebot: "clojure.contrib.def/defnk;[[fn-name & fn-tail]]; Define a function accepting keyword arguments. Symbols up to the first keyword in the parameter list are taken as positional arguments. Then an alternating sequence of keywords and defaults values is expected. The values of the keyword arguments are available in the function body by virtue of the symbol corresponding to the keyword (cf. :keys destructuring). defnk accepts

17:40 hiredman: jensli: that is to turn the keyword into a symbol

17:40 ,(-> :foo name)

17:40 clojurebot: "foo"

17:40 hiredman: ,(-> :foo name symbol)

17:40 clojurebot: foo

17:41 jensli: Right, so that they are avalible as syms in the func body. I see, cheers.

18:17 manic12: mystery solved: to call a native library, the function which loads the dlls must be AOT compiled

20:59 Chouser: rhickey: do you have any performance goals for finger trees?

21:00 rhickey: as fast as possible?

21:00 Chouser: yeah.

21:00 rhickey: I don't have any expectations really

21:01 clear + fast is ideal

21:01 what are the issues?

21:01 or tradeoffs

21:02 Chouser: just diminishing returns on time I spend on it vs. performance improvements

21:02 rhickey: are you unhappy with where it's at?

21:02 Chouser: a bit

21:03 rhickey: do you know where the bottlenecks are?

21:03 Chouser: I've removed several, finding the next bottleneck takes more time than removing in usually.

21:04 I haven't looked at it for several days, but I'm not relishing picking it up again.

21:04 rhickey: what kinds of things, and what kinds of speedups?

21:04 sproingie: is there any good introduction to finger trees that isn't in haskell?

21:05 Chouser: I was hopeful that when used as a queue (so no measurements involvements) that it would compete with PersistentQueues

21:05 but it's really not. Still 6 to 8 times slower.

21:07 I've removed most of the apply calls, which gave 15% to 30% improvement for many tasks.

21:08 I moved all measure calculations into delays, which also meant some are cached which weren't before, and that gave another 7-15% boost for split operations.

21:16 rhickey: I imagine that the split/concat functionality would dominate the decision to use a finger tree

21:16 for that there is no other game in town (at least in clojure)

21:20 Chouser: ok. well, there's probably some useful work I can still do there. measure still does more seq and map work than it probably has to.

21:36 rhickey: Chouser: yeah, one of the problems is that you have to avoid some of the high-level constructs when building low-level things

21:37 Chouser: sure, and I've removed those for a lot -- getting rid of (apply foo (concat ...)) constructs and similar has helped.

21:39 but I haven't done that for the measure/reducer stuff yet.

22:17 rhickey: http://www.artima.com/articles/hickey_on_time.html

23:32 arohner: is there a way to clear the repl history?

23:48 dnolen: arohner: in slime?

23:51 arbscht: if you're using jline, it will be in a jline history file, probably ~/.jline-clojure.*.history

Logging service provided by n01se.net