#clojure log - May 31 2009

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

2:37 duck1123_: Are there any good libraries for working with namespaced xml? Most of the ones I've seen weren't ns-aware.

4:26 * cads_ gave a clojure mini-lecture today to an interested crowd of two today at his clojure group

6:54 cads_: is there a limited count function which won't bottom on infinite sequences?

7:01 ,(defn count-max [coll n] (count (take n coll)))

7:01 clojurebot: DENIED

7:02 cads_: ,((fn count-max [coll n] (count (take n coll))) (repeat :hat) 1000000)

7:02 clojurebot: 1000000

7:03 cads_: ,((fn count-max [coll n] (count (take n coll))) (repeat :hat 666) 1000000)

7:03 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number

7:03 cads_: ,((fn count-max [coll n] (count (take n coll))) (repeat 666 :hat) 1000000)

7:03 clojurebot: 666

7:05 cads_: ,((fn safe-count ([coll] safe-count 100000) ([coll n] (count (take n coll))) (repeat:hat)))

7:05 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

7:05 cads_: ,((fn safe-count ([coll] (safe-count 100000)) ([coll n] (count (take n coll))) (repeat:hat)))

7:05 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

7:05 cads_: aww man

7:05 ,((fn safe-count ([coll] (safe-count coll 100000)) ([coll n] (count (take n coll))) (repeat:hat)))

7:05 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

7:09 cads_: ,((fn safe-count ([coll] (safe-count coll 100000)) ([coll n] (count (take n coll)))) (repeat :hat))

7:09 clojurebot: 100000

7:55 Chouser: ,((fn safe-count [coll & [limit]] (if (counted? coll) (count coll) (count (take (or limit 100000) coll)))) (repeat :hat))

7:55 clojurebot: 100000

8:08 rhickey: where would Clojure be? - http://gmarceau.qc.ca/blog/2009/05/speed-size-and-dependability-of.html

8:13 Chouser: fascinating

8:21 * rhickey eyes the bottom left quadrant

8:33 rhickey: uh oh, new version of Arc on our tail: http://arclanguage.org/item?id=9383 :)

8:34 wlr: rhickey: wonder if this credible source has anything to offer the future of clojure (esp the bigraphical model): http://www.cl.cam.ac.uk/~rm135/

8:40 rhickey: wlr: I'll let you know after I read: http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=9780521738330

8:41 wlr: rhickey: You can preview portions there and also on Amazon

8:41 rhickey: wlr: ordered already

8:42 I'm skeptical

8:45 wlr: I wasn't convinced one way or the other. Just thought you might like to pass it through your gifted filter.

8:46 rhickey: Milner is awesome of course

8:46 bound to be interesting

8:46 Lomono: Robin Milner :3

8:49 rys: Speaking of books, is buying the pragprog Clojure book an indirect way to donate to the project?

8:51 rhickey: rys: does nothing for me, helps Clojure by rewarding pragprog for taking the risk with it and Stuart for his effort

8:52 rys: Ah, cool

8:53 I'll coerce paypal into life later on then

8:54 rhickey: rys: thanks!

8:54 rys: Ah, thank you for the language :)

8:54 Chouser: rhickey (theoretically) gets a percentage of revenue from http://www.zazzle.com/clojure

8:55 a small percentage. I'd tell you how much if I could find the number...

8:55 rys: A programmer can always do with some new threads ;)

8:56 Chouser: ah, 10% it looks like

8:56 rys: lol @ the slogans on the shirts

8:58 Lomono: any updates from the people trying to get Clojure into that shootout.alioth.debian.org?

8:58 rhickey: Lomono: are there people doing that?

8:59 Lomono: there're sporadic postings on the mailing list last I checked

9:01 I just read "The speed, size and dependability of programming languages", and I thought it was odd that Clojure was missing from the analysis

9:01 http://gmarceau.qc.ca/blog/2009/05/speed-size-and-dependability-of.html

9:25 durka42: well, we don't have any entries in the shootout

9:25 perhaps this should be changed

9:31 i wonder who you email to ask for them to include a new language

9:41 Lomono: durka42: you would need to register at their forum and create a new topic https://alioth.debian.org/forum/forum.php?forum_id=999

9:42 * durka42 grumbles about invalid security certificates

9:42 Lomono: (one of?) the caveat of participating in the alioth benchmark is [we ask that contributed programs not only give the correct result, but also use the same algorithm to calculate that result.]

9:43 I'd recommend that you give the FAQ a quick scan http://shootout.alioth.debian.org/u32q/faq.php

9:43 durka42: i did

9:43 i'll create a topic

9:47 ok, that would be the first time i've gotten an account verification email with instructions that don't work

9:47 Lomono: :[

11:29 rhickey_: whither github?

11:29 clojurebot: github is git://github.com/kevinoneill/clojure.git

11:32 Chouser: wfm

11:34 rys: Is that repo considered clojure's master as far as git goes? I've been using svn from googlecode, but I'm more comfortable with git

11:35 Chouser: rys: I use git-svn with the googlecode repo. That's where rhickey_ commits, so it's always going to be the most up to date.

11:36 rys: Ah, great

11:38 rhickey_: is there a notion of project members on github?

11:39 quidnunc: git svn is going to be much slower than pulling from git mirror.

11:39 rys: rhickey_: you can add contributors to a repo

11:39 So they have commit privileges

11:40 Chouser: "repository collaborators" in the Admin tab of the project

11:42 * rhickey_ doesn't see Admin tab

11:44 rys: Maybe only kevin can add new collaborators, since it's his repository?

11:45 Lomono: ^

11:45 http://github.com/guides/managing-collaborators

11:45 rhickey_: rys: I'm looking at my repo

11:45 quidnunc: There is also gitorious.org which is AGPLv3

11:48 rhickey_: ah, see it in Safari but not Camino - aargh

11:49 rys: heh

11:51 Chouser: if my window is too narrow, scrolling horizontally doesn't show any more tabs -- just blank area (firefox)

11:58 hm, same behavior in chromium.

12:01 alinp: hi

12:01 user=> (use clojure.contrib.server-socket)

12:01 java.lang.ClassNotFoundException: clojure.contrib.server-socket (NO_SOURCE_FILE:1)

12:01 828 s003 Ss+ 0:01.40 /usr/bin/java -cp /Users/alin/apps/clojure-1.0/clojure-1.0.0.jar:/Users/alin/apps/clojure-contrib/clojure-contrib.jar clojure.main

12:01 Chouser: alinp: you need to quote the arg

12:01 (use 'foo)

12:01 alinp: so, I started the repl also including the clojure-contrib

12:02 the :require doesn't work in repl ?

12:02 Chouser: note that's different from when used in the 'ns' macro, where you would say: (ns bar (:use foo))

12:02 'use' and 'require' are plain functions that take symbols as arguments, so you need to quote them.

12:02 alinp: I see

12:02 thanks

12:02 Chouser: the 'ns' macro does that quoting for you when used with :use and :require

12:06 alinp: (ns test)

12:06 (defn test [] ())

12:07 Exception in thread "main" java.lang.Exception: Name conflict, can't def test because namespace: test refers to:#'clojure.core/test (server.clj:3)

12:07 same result if I'm doing: (ns my.test)

12:07 what I'm missing here ?

12:07 Chouser: by default, the 'ns' macro brings into your new namespace all the names from clojure.core, which includes a function named "test"

12:08 so that you can say + or map instead of clojure.core/+ and clojure.core/map

12:08 but that also means you can't define your own functions (vars, really) with those same names.

12:09 alinp: can I exclude functions from being loaded ?

12:09 like haskell for instance

12:09 Chouser: so you can either exclude certain names from core when you do your 'ns' (see the :refer-clojure option), or name your function differently (which is what I would generally recommend) like (defn my-test [] ())

12:09 alinp: like you said, + or map ... to make them my own ... but to exclude from core

12:10 I see

12:10 thanks, I'll look into this

12:13 chrizel: I wonder what would be the easiest functional way to move an item in a vector to a different position inside the vector - can't find a function for this

12:18 Maybe lists will be better suited for this -- or some combination with subvec

12:40 Chouser: chrizel: vectors don't shrink or grow in the middle well. swap would be fast, but I suspect that's not what you want.

14:37 It would be nice if there were a difference between non-private vars and vars that are refer'ed by default.

14:38 mainly for functions that I want to call from public macros

16:05 rhickey_: Chouser: yes

16:06 Chouser: does xml-> require you create your own zipper?

16:30 Chouser: rhickey_: yes

16:30 rhickey_: I think zip-filter.xml may have been eclipsed by enlive

16:31 I haven't tried it yet, but cgrand looked at zip-filter, used it some, and then wrote something new. It's reasonable to assume what he created is better. :-)

16:31 rhickey_: yeah, does its select do everything zip-filter did?

16:32 * rhickey_ trying to get some chouser code into the contrib demo

16:34 Chouser: I don't know. The one feature that was most important for me with zip-filter was the ability to drop in straight clojure filters in the middle, to keep it open

16:35 I wasn't sure if enlive did that or not, but I saw in a blog recently that cgrand had that goal as well.

16:35 As soon as I try out some enlive stuff, I expect (hope?) to be able to deprecate zip-filter

16:36 I appreciate the effort, but I don't know if there's much I've done that looks that great.

16:36 I still like repl-utils. *shrug*

16:37 I'm doing fun stuff with JNA and libc. I nearly have inotify (linux filesystem change notification thing) working.

16:37 hm, but you can't demo that on a mac.

18:14 * rhickey_ practicing for script bowl - wow 4 minutes is incredibly short!!

18:25 durka42: script bowl?

18:31 rhickey_: durka42: at java one

18:32 durka42: ~script bowl is http://weblogs.java.net/blog/robc/archive/2009/04/javaone_2009_sc.html

18:32 clojurebot: Roger.

18:36 powr-toc: Is it possible to store a mutable java object in an agent? If the cost of refactoring it to be mutable was too high, what would be the best thing to do? Wrap it in a layer that ensures all mutations generate a new object; to enforce identity semantics?? Is there anything else I need do?

18:37 rhickey_: powr-toc: are you going to mutate it?

18:37 powr-toc: rhickey_: yeah

18:37 via the function to send

18:38 rhickey_: then people reading the agent will be messed up by that

18:38 basically a mess

18:38 mutable things need locks

18:38 powr-toc: rhickey_: is that because of identity equality?

18:39 rhickey_: it's just the normal dangers of inconsistency and race conditions

18:39 powr-toc: ok sorry... being stupid... I think I get it

18:40 yeah, it's all the classic visibility problems etc...

18:43 are there any clojure idioms for sane locking? Is it typically best to use the java5 java.util.concurrent.lock's or the synchronized key word?

18:43 hiredman: ,(doc locking)

18:44 clojurebot: "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."

18:44 hiredman: dunno how sane t hat is

18:44 powr-toc: ooo cool

18:44 though it assumes the monitor is the object right?

18:45 hiredman: eh?

18:45 rhickey_: http://www.amazon.com/gp/product/0321349601?ie=UTF8&tag=none0b69&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321349601

18:45 powr-toc: hiredman: In java monitor's are implemented in Object... so it's common to synchronize on the object itself... though that's not always what you want... particularly if you want finer grained locking

18:45 clojurebot: ?

18:46 stuhood: powr-toc: it is exactly like a synchronized block.

18:46 Chousuke: clojurebot has a caffeine addiction it seems.

18:46 stuhood: whatever object you choose to synchronize on provides the monitor

18:46 powr-toc: stuhood: ok... so it takes the monitor...

18:46 hiredman: yes

18:46 powr-toc: cool

18:48 I'm being very slow today... asking lots of stupid questions I'd know the answer to if I just engaged my brain...

19:51 ataggart: (#(+ %&) 123)

19:51 ,(#(+ %&) 123)

19:51 clojurebot: java.lang.ClassCastException

19:52 ataggart: ,(#(+ 5 %&) 1 2 3)

19:52 clojurebot: java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.Number

19:53 ataggart: ((partial + 5) 1 2 3)

19:53 Chousuke: need apply

19:53 ataggart: ah

19:53 thx

19:53 Chousuke: though with partial it ought to work

19:53 ataggart: ,((partial + 5) 1 2 3)

19:53 clojurebot: 11

19:53 ataggart: hmm

19:53 Chousuke: but partial isn't the same as #() with a %&

19:54 ataggart: partial returns a fn, and #() returns a fn, so why do they behave differently?

19:54 Chousuke: partial probably uses apply internaly.

19:54 +l

19:55 ataggart: ,(map #(+ 5 %&) 1 2 3)

19:55 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

19:55 ataggart: ,(map #(+ 5 %&) [1 2 3])

19:55 clojurebot: java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.Number

19:55 Chousuke: %& is a seq

19:55 ,(#(do %&) 1)

19:55 clojurebot: (1)

19:55 rhickey_: ,(+ 5 '(1 2 3))

19:55 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Number

19:56 ataggart: so then #() with &% really isn't a good substitute for patial

19:56 *partial

19:56 rhickey_: that's what you are saying with %&

19:56 Chousuke: partial is (fn [x] #(apply + x %&))

19:56 or something similar

19:56 (#(apply + 1 %&) 1 2 3 4)

19:56 rhickey_: partial knows the consumer of the args, with #() they could go anywhere - a consumer might want the seq, not applied

19:56 Chousuke: ,(#(apply + 1 %&) 1 2 3 4)

19:56 clojurebot: 11

19:57 ataggart: interesting

19:57 rhickey_: ,(#(count %&) 1 2 3)

19:57 clojurebot: 3

20:38 Chouser: oh, vars still have :line 0 in their metadata

20:43 slashus2: Chouser: When do they have :line 0 in their metadata?

20:43 Chouser: ,(:line ^#'map)

20:43 clojurebot: 1494

20:44 Chouser: hm.

20:44 slashus2: They seem to have the correct line when I tried it in some code.

20:45 Chouser: ah, I forgot my clojure working copy regressed.

20:45 svn 1382 is a-okay.

20:45 slashus2: Is that broken for 1.0?

20:45 Chouser: no

20:47 it was broken and fixed post-1.0

22:01 jomofo: In the API doc, add-watcher says that it's "Experimental". I think it is a good solution for a small problem I'm trying to solve. What are the risks of using an Experimental API in clojure?

22:07 durka42: watchers have been there for a while

22:07 i think they should be fine

22:07 not sure if their implementation has changed recently

22:07 on the other hand, you have to be prepared for bugs since it is experimental

22:12 Chouser: I think your greater risk is the api changing more than bugs.

22:12 jomofo: Ok, thanks. I can deal with bugs and API changes, just wanted to make sure it wasn't more like "don't use this at all right now"

22:21 Just curious, why does add-watcher require send-type?

22:22 durka42: i guess, so you can decide whether whoever calls the watcher needs to block

22:22 jomofo: Oh, wait... I think I get it

22:22 durka42: if you give :send for send-type, will the agent itself block?

22:24 unrelated question: can you recur through lazy-seq?

22:26 jomofo: durka42: Gotcha, when I first saw that I thought it referred to what triggered the state change on the 'observed' reference but I was clearly reading it wrong

22:26 durka42: oh dear, i seem to have crashed the JVM again

22:38 so is it true in general that if i have a bunch of functions that loop over a list doing something, and return a list, and then i convert them all to use lazy-seq and compose them all, then the list should be traversed only once?

22:47 cmvkk: in general, that sounds right. every time you grab a new element, all of the composed functions run for just that element.

22:49 durka42: cool

22:50 will do some benchmarks when i finish lazifying the functions

23:09 technomancy: how do you control the amount of whitespace in the output of clojure.xml/emit?

23:09 I've just been binding println to print, but that's lame. =)

23:10 durka42: ~def clojure.xml/exmit

23:10 whoops

23:10 ~def clojure.xml/emit

23:11 it doesn't look like there is any other way, with that implementation

23:12 technomancy: seems like quite an oversight.

Logging service provided by n01se.net