#clojure log - Jul 16 2010

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

0:43 Bahman: Hi all!

2:11 bortreb: How do I upload all the jars that I've hand-pick for my project to clojars, all under by group id?

2:27 what happens if you screw up uploading something to clojars? can you remove it?

2:28 chouser: I think you can send email to ask that it be removed. :-/

2:30 robtp: hey - does anyone care to critique this for style and idiomatic usage? http://gist.github.com/478019

2:31 that's the prisoner-lightbulb problem

2:31 and other than the fact that storing turned-off and turned-on is redundant

2:32 bortreb: I wouldn't put (main) in the file itself because that will trigger it when it is 'used'

2:32 robtp: and then, another question - is there a readymade function to count the number of elements of a collection passing some test?

2:33 count-passes(coll, #(> % 5)) ; for [5, 7, 2, 9, -1] => 2

2:34 bortreb: you could always combine count and filter

2:36 (defn count-passes [pred? coll] (count (filter pred? coll)))

2:48 cais2002: ,((fn count-passes [pred? coll] (reduce #(+ %1 (if (pred? %2) 1 0)) 0 coll)) #(> % 5) [5 7 2 9 -1])

2:48 clojurebot: 2

2:53 robtp: ahh, nice

2:54 chouser: ,((fn count-passes [pred? coll] (count (filter pred? coll))) #(> % 5) [5 7 2 9 -1])

2:54 clojurebot: 2

2:54 chouser: bortreb's is nice

2:55 cais2002: will filter create another copy of coll ?

2:57 chouser: it will lazily walk coll as count forces it to

2:57 so no, there will not be a full copy of coll alive in memory

3:00 cais2002: i mean a filtered copy of coll being created?

3:07 bortreb: Is it possible to delete stuff from clojars if you make a mistake?

3:21 robtp: in my test case, the reduce method works many times faster

3:21 ~5-6x

3:21 clojurebot: No entiendo

3:21 robtp: ~5-6x

3:24 cais2002: robtp: that's what i expect, as it avoids creating a filtered coll

3:41 bortreb: On my machine my version is about 20% faster

3:41 ,(time (dotimes [_ 30] (+))

3:41 clojurebot: EOF while reading

3:41 bortreb: ,(time (dotimes [_ 30] (+)))

3:41 clojurebot: "Elapsed time: 1.155 msecs"

3:45 bortreb: ,(time (dotimes [_ 50] ((fn count-passes-reduce [pred? coll] (reduce #(+ %1 (if (pred? %2) 1 0)) 0 coll)) even? (range 100))))

3:45 clojurebot: "Elapsed time: 26.85 msecs"

3:45 bortreb: ,(time (dotimes [_ 50] ((fn count-passes [pred? coll] (count (filter pred? coll))) even? (range 100))))

3:45 clojurebot: "Elapsed time: 7.049 msecs"

3:51 kuwabara: I can't seem to compile a class, not even the example from the doc. It says: "Could not locate clojure/examples/hello__init.class or clojure/examples/hello.clj on classpath", although the source is in clojure/examples/hello.clj.

3:51 How do I add "." into the classpath ?

3:56 bortreb: first off, you can literally type "." in the -cp argument to java

3:56 you also have to have the ./classes directory on the classpath to compile files

3:57 are you using emacs and connecting via slime?

4:01 kuwabara: bortreb: no, I'm simply at the repl.

4:02 I added "." in the cp when running clojure, but I get the same error.

4:03 echo "(compile 'clojure.examples.hello)" | java -cp /usr/share/java/clojure.jar:. clojure.main

4:05 Oops. I renamed clojure/examples/hello to clojure/examples/hello.clj and there is no more FileNotFoundException.

4:05 bortreb: that's great

4:05 kuwabara: but still java.io.IOException: No such file or directory (hello.clj:1)

4:06 Line 1 of hello.clj is: (ns clojure.examples.hello (:gen-class))

4:08 esj: Morning all.

4:08 bortreb: you may try a more complete (:gen-class)

4:08 kuwabara: Found it. -cp /usr/share/java/clojure.jar:./classes:. works.

4:08 bortreb: like

4:08 (:gen-class

4:08 :name rlm.push

4:08 :main true)

4:09 what did you change?

4:10 kuwabara: I added ./classes

4:10 which seems to be the hardcoded destination of compiled files, but it's not added to the cp by clojure

4:11 bortreb: yeah

4:11 you can change *compile-path* to get a different destination

5:27 cais2002: what's the best way to do this in clojure: opts=[]; if (condA) opts+=[valA]; if (condB) opts+=[valB]; if (condC) opts+=[valC]; return opts;

5:37 esj: cais2002: dunno if its the best, but a seq comprehension might help

5:38 something like

5:38 ,(apply + (for [c '([1 1] [0 2] [nil 3]) :while (first c)] (second c)))

5:38 clojurebot: 3

5:38 esj: where the first elementi in each pair is your condition, and the second the value

5:38 boojum: cals2002: (let [opts []] (cond condA (conj opts "valA") condB (conj opts "valV) ..)

5:39 esj: or leave out the apply + if you want it as a seq of the values

5:39 mjul: boojum: we need to reduce over the list - evaluation stops on the first true in cond

5:40 boojum: mjul: true

5:41 mjul: cals2002: are you trying to append to the list for each true condition or just get the sum of the vals for which the corresponding condition is true?

5:41 cais2002: esj: I end up using reduce again, but similar to ur approach

5:41 esj: cais2002: reduce is awesome

5:41 cais2002: mjul: append.. but I want to know the general way to do it

5:41 esj: cons ?

5:42 conj if you're using vectors, say.

5:42 cais2002: I mean the python way I mentioned above is intuitive to me.. but the clojure versions are not that obvious

5:43 esj: ,(into [] (for [c '([1 1] [0 2] [nil 3]) :while (first c)] (second c)))

5:43 clojurebot: [1 2]

5:46 mjul: ejs: sweet :-) using for is so much more readable than reduce

5:46 esj: mjul: especially for pythonistas

5:48 cais2002: esj: talking about this, could explain why the reduce version is not faster?

5:48 ,(time (dotimes [_ 50] ((fn count-passes-reduce [pred? coll] (reduce #(+ %1 (if (pred? %2) 1 0)) 0 coll)) even? (range 10000))))

5:48 clojurebot: "Elapsed time: 580.593 msecs"

5:48 cais2002: ,(time (dotimes [_ 50] ((fn count-passes [pred? coll] (count (filter pred? coll))) even? (range 10000))))

5:49 clojurebot: "Elapsed time: 529.725 msecs"

5:50 esj: cais2002: i'm afraid i can't, except to speculate that the provided higher order functions are likely to be better written than what you or I could do.

5:51 cais2002: I thought filter would create another list, while reduce does not..

5:51 bortreb: don't forget about derefrenceng

5:51 ,(into [] (for [[cond? value] [ [ true 1] [true 2] [false 3 ] [true 4]] :when cond?] value ))

5:51 clojurebot: [1 2 4]

5:53 Chousuke: cais2002: creating a new list isn't necessarily very expensive at all

5:54 cais2002: the clojure core functions make use of a whole bunch of tricks that improve performance, so doing things in a way that "seems" more efficient is not guaranteed to be so.

5:55 cais2002: Chousuke: if the elements are not simple structure, will that make a difference?

5:57 Chousuke: what do you mean by simple structure?

5:58 cais2002: rhickey just has put a lot of effort into making map/filter/for/into etc. really fast so that you don't need to write contrived code to get performance.

6:00 ~def reduce

6:00 reduce is fast too though

6:00 cais2002: Chousuke: I am just wondering whether it's only to create the pointers to point to the objects or it's replicating the objects/elements.. simple refers to (range 10000), it's all integers in the list

6:01 Chousuke: in java you only have pointers.

6:01 except if you have primitives

6:01 s/java/JVM/

6:02 and the integers created by range are objects too

6:03 since you can't have a list of primitives.

6:04 But then JVM optimisations will kick in and all those object allocations will suddenly be virtually free, in the best case :P

6:04 bortreb: heh the jVm makes stuff "virtually" free :)

6:05 Chousuke: heh, no pun intended :P

6:08 cais2002: ,(into [] (concat [1 2] [3 4]))

6:08 clojurebot: [1 2 3 4]

6:08 cais2002: ,(vec (concat [1 2] [3 4]))

6:08 clojurebot: [1 2 3 4]

6:09 cais2002: thanks, guys, my code looks a bit easier to understand now..

6:24 88 guys

6:37 mjul: LauJensen: hej! the Docjure lib for spreadsheet import/export is now open source: http://github.com/ative/docjure

6:46 zmila: mjul, it can read/write xlsx? so based on latest version of POI

6:46 our project uses old version, only for xls (2003) files

6:46 LauJensen: mjul: Great! Did you used a hacked version of Lein for that? :)

6:48 zmila: maybe the project was created before the -jure commit :)

6:52 mjul: it was created before the -jure commit :-) (it has been underway since 2009)

6:53 - and it reads/writes xlsx, too

7:30 powr-toc: Hey... is anyone using cljr http://github.com/liebke/cljr

7:31 It looks to be a pretty awesome complement for lein, for the times when you don't want a project, and just want a quick repl for experimenting with libs etc...

7:32 I was wondering though, if anyone knows whether you can get it to work with a .user.clj file

8:08 jowag: is it possible to dump the current environment?

8:13 zmila: right question is half of the answer. what is enviroment?

8:17 Kttmm: we found the solution of the problem of yesterday. There was some old code in the Library/Java/Extensions directory which was loaded and caused some troubles

8:17 thanks to all for the help

8:19 rhudson: jowag: if you mean system environment vars, (System/getenv)

8:21 jowag: I mean all the clojure Vars, all the stuff I've defined and loaded from .clj files

8:22 lets say I've been hacking in REPL and I want to save my stuff and later continue with it

8:22 rhudson: (ns-publics *ns*) maybe?

8:26 jowag: ok that will give me all the vars in the current ns, now what is left is how to dump a var

8:26 powr-toc: hmm I can't seem to get add-classpath to work properly with cljr... does it work ok in lein??

8:31 rhudson: jowag: any defn or macro is gonna be a problem

8:50 Bjering: I find time really neat for interactivly test runtime performance of what I do, is there an eqvivlant function for memory usage, something like (mem-usage [value] (...)) to give me how many bytes a particular value is occupying?

9:01 * defn picked a really poor nick a few years back and is paying for it dearly in #clojure

9:01 ragnard: How (if possible) can I write a function or a macro that, given a function as an argument returns a namespace qualified symbol (or a name/namespace pair) that can be used to resolve the given function?

9:02 neotyk: defn: lol, you must be getting notified quite a lot ;-)

9:02 defn: :)

9:02 ragnard: i can answer that but i need to pull up my editor

9:04 ragnard: defn: cool, excitedly waiting... :)

9:04 defn: ragnard: you could use (meta)

9:06 rhickey: chouser: whither finger trees?

9:06 defn: ragnard: (ns-name (:ns (meta #'doall)))

9:07 ,(ns-name (:ns (meta #'doall)))

9:07 clojurebot: clojure.core

9:07 defn: (:name (meta #'doall))

9:07 ,(:name (meta #'doall))

9:07 clojurebot: doall

9:07 defn: ragnard: would using that work for you?

9:08 chouser: rhickey: haven't touched them in ages. they work but the api and probably the performance should be improved.

9:08 rhickey: chouser: did you ever compare to the functional java ones?

9:09 chouser: no, that's at the top of my list for once the book is out of the way

9:09 defn: ,#^meta

9:09 clojurebot: EOF while reading

9:09 chouser: ...can see the light at the end of the tunnel now. And by tunnel I mean the process of adding index links

9:10 rhickey: if I can't match function java performance, I have officially failed. :-)

9:10 ragnard: defn: yes, thank you... I didn't realise I could use meta for this...

9:10 defn: #^ was deprecated, yeah?

9:11 ragnard: defn: so basically, all vars have metadata containing their name, and namespace (amongst other stuff)

9:12 defn: i believe the answer to that ragnard is yes

9:12 but i only have ever used this with core

9:13 it might not work on all vars

9:14 it looks like it does... (def foo 9) (meta #'foo)

9:14 rhudson: i believe the metadata is put there by def defn defmacro etc, so anything defined "the usual way" should be ok

9:14 raek: how often is the list on clojure.org/contributing updated?

9:14 defn: yeah rhudson

9:14 ragnard: defn: The docs says: http://clojure.org/special_forms#def

9:15 defn: rhudson: do you know if defmacro behaves similarly

9:15 rhudson: suspect so, but don't know

9:16 defn: and the answer is yes

9:16 chouser: rhickey: you have a finger tree use case or something?

9:17 defn: priority queue?

9:19 chouser: sorted set or map often works well for priority queue.

9:21 raek: rhickey: sorry for bugging you, but do you happen to know if my CA has arrived? (from Rasmus Svensson)

9:22 rhickey: chouser: it would be a nice addition to Clojure, I think. No specific use case here

9:22 raek: sorry, it's been a couple of weeks since I last checked the box. Will try to get there today

9:23 raek: ok, thanks!

9:23 acknowledged.

9:24 chouser: rhickey: ok. fwiw the possibility of getting finger trees included in Clojure has been and is a primary motivator for my work on it, so thanks for bringing it up again.

9:24 a few more weeks and I should be able to start making progress on it again.

9:25 rhickey: chouser: I periodically get asked about persistent data structures with efficient insertion, and reluctantly admit Clojure hasn't got one yet

9:26 chouser: sorted sets and maps :-) But I know what you mean.

9:28 testing the performance of my code vs. PersistentQueue and PersistentTreeMap was a bit discouraging.

9:37 LauJensen: chouser: How discouraging? :)

9:43 chouser: pretty discouraging. I forget the actual numbers, but conjing onto a vector is *fast*

9:50 AWizzArd: rhickey: The search box on the upper right side of http://clojure.org/ produces an error when being used.

9:50 chouser: was the PersistentTreeMap more efficient?

9:51 chouser: for anything that existing clojure collections can do, they're faster than my figer trees are right now.

9:59 rhickey: AWizzArd: it says "Search is temporarily unavailable." So, search is temporarily unavailable.

10:18 AWizzArd: Will read-lines be moved from clojure.contrib.io into clojure.java.io sooner or later?

10:22 pjstadig: rhickey: saw the keyword GC change

10:23 rhickey: pjstadig: work ok for you?

10:23 pjstadig: haven't tested it just yet, but i think it will

10:26 neotyk: AWizzArd: I've released ahc-clj 0.1.1 with your suggestion on NPE, thanks!

10:37 Bahman: Hi all!

10:45 yacin: does = not work for java arrays?

10:45 ,(= (into-array Byte/TYPE (map byte (range 10))) (into-array Byte/TYPE (map byte (range 10))))

10:45 clojurebot: false

10:49 AWizzArd: neotyk: oh cool!

10:50 * defn re-reads that

10:50 defn: ,(into-array Byte/TYPE (map byte (range 10)))

10:50 clojurebot: #<byte[] [B@53ff89>

10:50 defn: (into-array Byte/TYPE (map byte (range 10)))

10:50 ,(into-array Byte/TYPE (map byte (range 10)))

10:50 clojurebot: #<byte[] [B@184681f>

10:51 defn: yacin: they're not equal?

10:51 yacin: nope: http://osdir.com/ml/clojure/2010-03/msg01184.html

10:52 looks like it just compares the references

11:01 tomoj: did prim and friends make it into beta1, I wonder?

11:03 chouser: no

11:03 I think they've been officially pushed to post-1.2

11:10 tomoj: darn

11:26 defn: is there a way to print the full contents of a java array?

11:27 i mean the obvious answer is yes, but using aget and looping doesn't seem very elegant

11:29 jkkramer: ,(seq (into-array [1 2 3]))

11:29 clojurebot: (1 2 3)

11:31 AWizzArd: defn: for multidimensional arrays you will have to manually traverse them

11:55 tomoj: is there no way to test whether something is a java array?

11:59 AWizzArd: tomoj: yes

12:00 ,(let [x (byte-array 5)] (and (class? x) (.isArray x)))

12:00 clojurebot: false

12:01 AWizzArd: ,(let [x (byte-array 5)] (and x (.isArray x)))

12:01 clojurebot: java.lang.IllegalArgumentException: No matching field found: isArray for class [B

12:01 AWizzArd: ok, no, .isArray must be called on a class

12:01 so, it would be more like

12:02 ,(when-let [c (class (byte-array 5))] (.isArray c))

12:02 clojurebot: true

12:02 AWizzArd: ,(when-let [c (class 42)] (.isArray c))

12:02 clojurebot: false

12:04 tomoj: ah

12:05 I was surprised not to see (array? x)

12:06 AWizzArd: (def array? #(when-let [c (class %)] (.isArray c)))

12:06 (def array? #(boolean (when-let [c (class %)] (.isArray c))))

12:06 or if-let vs boolean

12:08 arohner: defn: pprint handles arrays, I believe

12:08 defn: or, it definitely handles 1-d arrays, not sure about 2-d

12:40 mefesto_: clojure couchdb driver "clutch" no longer on github?

12:42 bpsm: mefesto_: http://github.com/ashafa/clutch ?

12:42 mefesto_: bpsm: ah thanks, i guess i had a bad link

12:59 tomoj: username changed

13:42 savanni: Hi,all. I haven't been around in a while, but I ran into a question today.

13:43 defn: savanni: shoot

13:43 savanni: Is it idiomatic to, when a function encounters an error that it needs to report back up, raise an exception?

13:43 defn: i guess i don't see why not

13:43 savanni: and if so, how do I define new exceptions these days? The gen-and-load-class function that I see mentioned in a few places is not present in the clojure API documentation or in either version of clojure I have.

13:45 defn: that's a good question

13:45 savanni: Although I am considering just saying (throw (proxy [Exception] ["my error message"])), but I'd prefer to pattern match on the class of the exception.

13:45 ataggart: why bother with a proxy at all?

13:45 defn: ^^

13:45 ataggart: (throw (Exception. "my error message")) works fine

13:45 savanni: Oh, in that case, you're right.

13:46 But i'd still like to define my own exception classes.

13:46 ataggart: then, you'll need to gen-class iirc

13:46 but usually custom exceptions are a waste

13:46 savanni: Why is that?

13:46 err...

13:46 why are they a waste?

13:46 Hodapp: ugh

13:46 I got C++ all over me again

13:47 Raynes: Well, why would you need them?

13:47 Hodapp: how do I wash this off

13:47 defn: Hodapp: have a pressure washer?

13:47 Raynes: I've never needed DudeYouGaveMeTheWrongInformationException before.

13:47 Hodapp: defn: nah

13:47 defn: that's only good for Lispy languages... the water gets underneath all the parens

13:48 ataggart: in almost every case an exception indicates an unrecoverable condition anyway, just throw a RuntimeException

13:48 defn: Hodapp: as a service to the community ill hose you off, might sting a bit at 3000 PSI though

13:48 Hodapp: defn: wait till I get off work, I'm just gonna get covered in C++ again if I wash off

13:48 savanni: umm... no, I am working in cases where exceptions need to be handled. A runtime exception would not be nearly expressive enough. But I could possibly just match on the error string.

13:48 defn: good point.

13:48 ataggart: svanni: example of where the need to be handled, pls

13:48 defn: Hodapp: until then, enjoy the filth! :)

13:49 ataggart: I fail at typing today

13:49 savanni: can you give an example of where they need to be handled?

13:49 ffailla: hello, does anyone know if we can define our own constructor via defrecord

13:49 ataggart: ffailla: no

13:50 savanni: Okay... user gets an object from a database, makes some modifications, then submits the object back. In the meantime, another user modified that same object and my code notices that the save would destroy something I don't want to destroy. So, I throw an exception which a high-level handler catches and provides a proper recovery interface to teh user.

13:51 ffailla: ataggart: thanks

13:52 ataggart: There are other, possibly better, ways to handle such cases

13:53 savanni: perhaps. I'm thinking of returning results using something like Haskell's Either structure.

13:53 failing a sanity check isn't necessarily exceptional, at least not in the same way that total database failure or total disk failure would be exceptional.

13:54 ataggart: in the java world such exceptions would be checked (i.e., derived from Exception, not RuntimeException), and the caller would be forced to handle it. Clojure doesn't force such behavior, thus intervening levels between handler and thrower can break in unexpected ways

13:56 using typed, checked exceptions just isn't really a good fit

13:56 savanni: I'm much more experienced with Python than with Java, and we don't have checked exceptions there. But, again, the only way to return an expressive error is with an exception.

13:56 ataggart: yes, but "return[ing] an expressive error" is not your only option

13:57 at least not from the code that detects a mid-air collision

14:00 that said, you can also use error-kit

14:00 http://richhickey.github.com/clojure-contrib/error-kit-api.html

14:01 savanni: Okay, I'll study that for a while.

14:44 mefesto_: is there a way to simply download a jar from clojars instead of having to use leiningen/maven?

14:45 savanni: Yeah. Hit the "browse" link on clojars.org and just delve down into the hierarchy until you find the jar files.

14:45 mefesto_: savanni: ahh thank you :)

14:55 rsh: is there a function to set a var's root binding without supplying a function? I really just want to set it to a value

14:59 bulters: Gday all...

15:02 * raek just read "The lack of a simple dictionary type was the most significant hindrance." in http://prog21.dadgum.com/37.html

15:04 raek: thinking of it, we clojurians use maps pretty much everywhere

15:04 it's indeed a powerful data structure

15:04 technomancy: but, but--alists are functionally equivalent!</common-lisper>

15:04 programble: abloo

15:05 heh

15:05 lispy has no maps, uses alists

15:05 bulters: So I should consider myself lucky not having programmed in common lisp?

15:05 raek: I like how simple clojure makes usage of maps

15:06 technomancy: bulters: depends; are you often nostalgic for the 80s?

15:06 programble: =>72 / 24

15:06 ataggart: technomancy: what OS do you use?

15:06 programble: no?

15:06 bulters: technomancy: I'm from 1984

15:06 technomancy: ataggart: ubuntu

15:06 programble: ->72 / 24

15:06 sexpbot: => 72

15:06 programble: :\

15:06 lies

15:07 bulters: technomancy: So not too much to be nostalgic about...

15:07 programble: lololol

15:07 wtf is wrong with me

15:07 ->(/ 72 24)

15:07 sexpbot: => 3

15:07 qbg: CL pathnames are just so weird

15:07 bulters: Although, I still have a movie of a 3 year old bashing on a MSX2 ;-)

15:07 * programble pretends nothing happened

15:07 qbg: Clojure makes CL look ugly

15:08 programble: lots of things do that

15:12 ponzao____: I have a small noob question, which is not from a real problem I am suffering, just something I stumbled onto and didn't quite grasp why it does what it does. I have defined a struct (defstruct Foo :a), I am trying to map with :a over a list of Foos (map :a '((struct Foo 10))) -> (nil), if I use (map :a (list (struct Foo 3))) I get (3). If I use a map instead of a struct in both cases I get (3), just wondering what is the reason for this.

15:13 arohner: ponzao____: ((struct Foo 10)) tries to call the struct

15:13 try [(struct Foo 10)] instead

15:13 AWizzArd: well, not that, because it is quoted.. but, it is (list (list foo))

15:14 and (get '((100)) :a) ==> nil

15:14 programble: a quoted lists, nothing inside gets evaluated

15:14 ataggart: ^

15:14 programble: use vectors

15:14 arohner: oh right

15:14 (:a struct) (:a Foo) (:a 10)

15:14 no

15:15 programble: '((+ 1 2)) is literally ((+ 1 2)), not (3)

15:15 ataggart: I can't think of a case outside of macros where one needs to use literal lists in clojure

15:16 ponzao____: ataggart, I've seen them used in some examples, are they something that are not recommended?

15:16 arohner: ponzao____: quoting is annoying, so it's just more convenient to use vectors

15:16 ataggart: and is visually useful

15:17 AWizzArd: It may help some newcomers to litterally write out quote from time to time, as in (map :a (quote ((struct foo 10))))

15:18 bulters: *makes a mental note to quote lists*

15:18 programble: no, make a mental to note to always use vectors

15:18 ataggart: alternately, don't use lists.

15:18 damn my slow fingers

15:18 ponzao____: Why is the behavior different for maps and structs?

15:18 bulters: ataggart: You're telling me not to use lists in a lisp?

15:19 arohner: (list (struct Foo 10)) is also more convenient that quoting

15:19 programble: vectors are lists... just... different...

15:19 vector-ish

15:19 ponzao____: (map :a '({:a 10})) -> (10)

15:19 arohner: ponzao____: that map is a literal, while (struct Foo 10) is a function call (that needs to be evaluated) to produce a struct

15:20 the quote prevented evaluation

15:20 ponzao____: arohner, aaaah okay, well that explains it.

15:20 ataggart: bulters: yes, when simply constructing a literal datastructure.

15:21 ponzao____: arohner, That brings up another question I wondered at some point: How can I force the evaluation of quoted code?

15:21 ataggart: eval

15:21 arohner: ponzao____: eval, or backticks

15:21 bulters: ataggart: I almost thought you were serious ;-)

15:22 arohner: in this case `(~(struct Foo 10)) would work

15:22 that says, build a quoted list, but evaluate the things that start with squigglies

15:23 ponzao____: though 99% of the time, you don't need eval

15:23 ataggart: not enough 9s

15:24 I've used eval once in all the clojure I've written

15:25 ponzao____: arohner, Ok. As I said before my "problem" was not something I really ran into. Thanks for the help to you and everybody else. I think the biggest learning curve in Clojure (and other Lisps?) comes from understanding the evaluation and macros.

15:39 raek: basically, functions and macros are very similar:

15:39 functions: (apply f (map eval args))

15:39 macros: (eval (apply m args))

15:41 AWizzArd: ,(doc apply)

15:41 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

15:41 AWizzArd: if m is a macro then apply won't work on it

15:42 raek: yes, that was just a rough scetch demonstrating the differences in evaluation of functions and macros

15:42 I once made a lisp toy language

15:43 I thought it'd be a good idea to be able to apply macros

15:43 ...and special forms

15:43 (x true (do-foo) (do-bar))

15:44 that could do completely different things if x was a function, a macro, or a special form

15:45 e.g. if x evaluated to the special form object 'if'

15:45 somnium: Im guessing this was an interpreter?

15:46 raek: yes

15:46 compiling this would not be very easy

15:46 TimMc: It would certainly not be as optimizable.

15:47 (You could not compile it to bytecode.)

15:47 somnium: [if (= (%typeof x) if) ...]

15:48 maybe if it was lazy you could compile it

15:49 * programble made a toy lisp in python

15:50 KirinDave: programble: Sorry you had to endure python

15:50 raek: i once began on a lisp with only parentheses

15:50 () was 0

15:50 TimMc: Heh.

15:50 raek: (x) was (inc x)

15:50 ((())) = 2

15:51 all functions had numbers

15:51 programble: KirinDave: lol i use python all the time

15:51 raek: say, 3 is +

15:51 KirinDave: programble: My condolences.

15:51 programble: i like it, obv

15:51 raek: ((((())))()(())) -> (+ 0 1) => 1

15:51 TimMc: KirinDave: Hey now, someone has to like it.

15:51 programble: raek: im scared

15:52 * TimMc waits for raek to illustrate binding

15:52 raek: ok, 4 is let

15:53 (4 <binding> <body>)

15:53 hrm

15:53 programble: lol

15:53 raek: I think I solved naming with a special lookup functoin

15:54 (lets call it 5)

15:54 (5 3) is lookup variable 3

15:54 somnium: raek: I think the only legal identifiers should be sequences of [{}]...

15:55 KirinDave: TimMc: No. No one does.

15:55 programble: brainfuck is a great language

15:55 somnium: maybe ()<><>() for complex numbers

15:55 KirinDave: TimMc: Python is the first resort of the unimaginative. Knowing it is one thing. Liking it given the wealth of languages we have today that all do really well? Inexplicable.

15:55 raek: (let (var-6 (+ 1 2)) (+ 2 (lookup var-6)))

15:56 programble: i dont "like" it per se...

15:56 its more just... easy to use

15:56 raek: (4 (6 (3 1 2)) (3 2 (5 6)))

15:56 ponzao____: KirinDave, :D

15:56 raek: (((((()))))(((((((()))))))((((())))(())((()))))((((())))((()))((((((())))))((((((())))))))))

15:57 I should pick up this project again...

15:57 KirinDave: programble: Huh.

15:57 ponzao____: KirinDave, I think I'd like a t-shirt with that

15:57 programble: pythons works, and its not ugly...

15:57 good for scripts if you ask m

15:57 e

15:57 KirinDave: It's pretty ugly.

15:58 programble: well yeah

15:58 not as bad as some

15:58 KirinDave: It's not Erlang ugly.

15:58 programble: doesn't shove oop down your throat

15:58 its easy to do things

15:58 KirinDave: Hah. There Is Only One Way To Do It.

15:59 And It Is Not A Very Good Way But I Am Sure You Rubes Can Handle It. I'm GVR, I Don't Give A Fuck.

15:59 TimMc: raek: Ah, a lookup function.

15:59 KirinDave: Long acronyms in the python community.

15:59 TimMc: I almost buy that.

15:59 somnium: I am still amazed that GVR is actively opposed to adding TCO

16:00 apparently on the grounds that people would use it do recursion

16:00 TimMc: KirinDave: Unfortunately, PHP and Python can be run interpreted just about everywhere. :-(

16:00 KirinDave: So can PLT Scheme.

16:00 TimMc: KirinDave: Not on any web host I've seen.

16:00 programble: wait wait

16:01 we are talking about how bad python is

16:01 and someone mentions PHP?

16:01 TimMc: programble: As an example of something that is easy to use.

16:01 programble: lolololololol

16:01 TimMc: Not comparing ugliness.

16:01 programble: PHP is not easy to use

16:02 TimMc: PHP is easy to start using, sure. Great docs, great HTML integration, pretty good library of simple data manipulation functions.

16:02 It's only hard to use once you try to make your project bigger or scure.

16:02 *scure

16:02 programble: PHP is a preprocessor, not a language

16:02 * TimMc can't type the letter "" very well today

16:03 KirinDave: TimMc: PHP's inconsistent libraries are its biggest weakness last time I checked.

16:03 TimMc: KirinDave: Yes. But as a noob I had no trouble just looking up the syntax every few minutes.

16:03 somnium: KirinDave: have you seen Phuby?

16:04 KirinDave: No.

16:04 programble: ruby seems great and all

16:04 but the syntax makes me want to kill myself with a spoon

16:04 somnium: KirinDave: its on github, great stuff

16:04 KirinDave: Wait. Now I have.

16:04 zkim: Hey all

16:04 KirinDave: I wish I hadn't.

16:05 My last words will be, "My God, it's full of stars!"

16:05 somnium: KirinDave: theres a video where they run wordpress in rails

16:06 KirinDave: somnium: I'm going to have nightmares for weeks now.

16:06 somnium: :D

16:06 KirinDave: “When I open my eyes it is still there!”

16:06 programble: lol

16:28 zkim: Anybody doing swing development with clojure?

16:30 savanni: No, but i'm considering it, amongst other gui tools.

16:31 zkim: Ah, was wondering if there was a lib or people just roll their own wrappers

16:31 What other gui tools are you looking at?

16:48 dakrone: zkim: you could check out swing-utils in contrib: http://richhickey.github.com/clojure-contrib/swing-utils-api.html

16:51 zkim: dakrone: thanks, I'm starting to convert a java app of mine over to clojure, and was wondering if there was a consensus on swing dev

16:59 ragnard: zkim: have you read Stuart Sierras blog posts on clojure/Swing? can recommend them.

17:01 zkim: ragnard: yeah, the heating up clojure & swing post? Definitely helped.

17:02 ragnard: yup, I think it starts with "First Steps With Clojure & Swing"

17:03 zkim: I only saw the one, I'll have to take a look for the others

17:03 ragnard: zkim: first one is at http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing

17:03 zkim: it looks like the choices are c.c.swing-utils, Licenser's lib, and roll your own

17:04 * Licenser waves

17:04 Licenser: if you want clj-swing feel free to ask questions

17:04 zkim: Hey licenser

17:04 yeah definitely looking at your lib

17:05 Got two of your libs up on clojuredocs.org, having trouble with the other two

17:05 Licenser: :) yay

17:14 Raynes: zkim: Have you considered letting users add libraries themselves?

17:14 Seems kind of tedious to do all that yourself.

17:15 zkim: Yeah, definitely, there's some manual process around adding libs that I'm trying to get around

17:16 * Raynes will definitely add his own libs if/when libs can be added by users.

17:16 zkim: It's basically pull source -> lein / mvn install -> add to the cd-analyzer deps -> run

17:16 Raynes: :)

17:16 zkim: So I'm trying to automate the first 4 steps

17:17 That'd be great, it's second or third down on the list after categories

17:18 dakrone: zkim: coming to the meetup next wednesday?

17:18 ataggart: it'd be nice if the "namespaces" list omitted the common prefix

17:18 e.g. http://clojuredocs.org/Clojure%20Contrib

17:18 zkim: dakrone: yeah, I'm looking forward to it

17:19 dakrone: zkim: cool, will see you there then :)

17:19 zkim: ataggert: good idea, I'll add it to the list

17:19 dakrone: cool, hope there's a good turnout

17:19 dakrone: yea

17:33 robtp: any ideas, anyone - java.lang.ClassNotFoundException: incanter.Matrix - like this, maybe: http://www.mail-archive.com/clojure@googlegroups.com/msg14941.html

17:36 cschreiner: zkim: ataggert: and remove the center alignment

17:37 zkim: cschreiner: center alignment for on the ns sidebar?

17:37 (minus for)

17:38 cschreiner: on the namespaces column

17:38 zkim: It's left aligned for me, which browser / os you on?

17:38 cschreiner: mac/safari/ff

17:38 zkim: hrm

17:39 ataggart: left for me om mac chrome, but looks like its not left due to the elipses

17:40 cschreiner: ataggart: you're right :)

17:40 zkim: yeah, the ellipses were kind of a hack, prior to that the nss would wrap at odd places, or hang over the center

17:40 cschreiner: fooled myself

17:40 make them go away (the prefixes) and group them instead

17:41 no need to repeat clojure.contrib. 170 times on a page

17:41 zkim: agreed

17:41 cschreiner: really love your initiative

17:41 zkim

17:41 zkim: groupings a good idea, I'll play with it a bit

17:41 cschreiner: but, you're no designer ;)

17:41 zkim: thanks, labor of love and all

17:41 haha no kidding :)

17:42 cschreiner: but I'll look through that for now

17:42 zkim: know any designers that want to get their work out?

17:42 I'm trying to figure out where I would find somebody like that

17:43 cschreiner: I don't know

17:43 depends on what you want

17:43 would love to throw a css at it though

17:44 zkim: go for it and I'll test it out

17:44 cschreiner: okay

17:44 zkim: html's kind of ugly, but you should have all the hooks you need

17:45 cschreiner: you should try and clean up the html, like make it more 5'ish

17:46 zkim: havn't really looked at 5, they get rid of the div tag or something :)

17:48 * cschreiner is poking

19:29 lpetit: hi

19:29 does this macro already exist ? :

19:30 (let [x #"baz\(" y "bar"] (interpol-regex #"(?:a|`x`|`y`)") => #"(?:a|baz\(|bar)"

19:33 more useful (and real!) example: (let [symbol-head #"[a-z|A-Z]" symbol-rest (interpol-regex #"`symbol-head`|[0-9]")] (interpol-regex #"`symbol-head``symbol-rest`*")

19:45 nobody here ?

19:56 arohner: what's the type hint for an array of Objects?

19:59 defn: Wirth's law: Software is getting slower faster than hardware is getting faster

20:18 ataggart: arohner: ^objects

20:46 * slyrus uses M-h did the right thing in clojure mode like it does in lisp mode (CLHS lookup)

20:46 slyrus: s/uses/wishes/

20:48 dnolen: Clojure, Node.js and Concurrency Fail, http://dosync.posterous.com/clojure-nodejs-and-why-messaging-can-be-lame

20:49 bound to stir up some controversy

20:50 TeXnomancy: dnolen: "how Node.js might fair" should be fare

20:50 dnolen: TeXnomancy: thx

20:50 ataggart: "Node.js is not faster that Aleph" s/that/than

20:51 dnolen: attagart: thx

20:51 ataggart: on a less pedantic note, are there any good guide to getting code out on he Amazon Compute cluster?

20:52 dnolen: attagart: it's pretty simple, just use the CentOS image, install the latest JDK and yr pretty much good to go.

20:52 ataggart: cool

20:52 thx

20:58 dnolen: feel free to upvote on HN if you read that

21:15 robtp: logarithm?

21:15 i can't seem to find it

21:15 rhudson: Math/log

21:15 (from java.lang.Math)

21:15 robtp: oh

21:16 *slap*

21:31 slyrus: umm... how do I specify a default value for an optional arg for a function again?

21:32 i.e. the clojure equivalent of (defun foo (&optional (moose 32)) (1+ moose))

21:32 wishes google translate would do cl -> clojure

21:32 * slyrus that is

21:36 slyrus: wait, let me guess... you can't do that in clojure

21:39 raek: you can do it like this:: (defn foo ([] (foo 32)) ([moose] (inc moose)))

21:40 ericthorsen_: Iit appears that after a I AOT a defprotocol and attempt to use it in an extend-type expression I get an error "java.lang.IllegalArgumentException: interface org.model.db.MyProtocol is not a protocol"

21:40 slyrus: ah, so I don't need the &

21:40 thanks raek

21:40 oh, i see...

21:41 it's like i thought. ok.

21:41 * slyrus misread the punctuation soup the first time through

21:41 ericthorsen_: I also noticed that when AOTing defrecords the namespaces that get prepended are clojure style not java (so this-that does not turn into this_that) which surprised me

21:41 Anyone else playing with defprotocol and defrecord?

21:43 raek: or like this: (defn foo [a b & [moose]] (+ a b (or moose 32)))

21:44 not a very beautiful example, perhaps...

21:45 I haven't played with defrecords and AOT at the same time

21:45 slyrus: raek: the (or moose 32) is hardly a default value for the parameter :) yes, I can add another let around the function body and check the value of the parameter, but I guess the whole &optional thing is at odds with clojure's multi-arity thing

21:46 so the proper way to do this is as like what you had above

21:46 raek: that's probably the most common way of doing it

21:47 destructuring with maps has support for :or which can provide default values

21:47 this does not exist for sequence destructuring, though

21:48 (let [{a :a, b :b, :or {a 1, b 2}} some-map] (+ a b))

22:04 mudge: hello

22:05 i declared an atom in one namespace, and i required the namespace from another namespace, but how do I access the atom from the first namespace?

22:05 mikem: mudge: how did you require it?

22:06 hiredman: my guess would be with require

22:06 mudge: i used (:require in the ns declaration of the second namespace and said ":as pt-hook" so i could use pt-hook to reference the name space

22:07 mikem: mudge: then pt-hook/name-of-atom should do it

22:07 mudge: so would I then do: @pt-hook/my-atom ?

22:07 okay

22:09 hmm... my second namespace dosen't see pt-hook/my-atom, my first names space is actually using gen-class for AOT

22:10 i know that if you are going to use methods for a gen-class namespace you have to use :methods and declare your methods

22:10 but i'm not making a method, just an atom

22:11 so i guess the question is how do you expose definitions from within a gen-class namespace

22:13 i have this in one namespace: (def oh nil)

22:13 i want to refer to in another namespace, like so: pt-tools/oh

22:14 the first namespace is gen-classed

22:20 mikem: mudge: i'm not sure how gen-class complicates things, sorry

22:22 mudge: ok

22:27 can two namespaces require each other?

22:31 rhudson: no

22:35 mudge: no what?

22:36 how do you make a global variable at runtime in clojure?

22:37 rhudson: You can't have two namespaces require each other.

22:37 require is a dependency relationship

22:38 mudge: rhudson, great, great to know

22:38 rhudson: yea, it would be like mutually recursive requiring

22:39 or something

22:40 rhudson: Yeah, I learned this the first time I wrote a multi-ns program. I had to push some stuff into a different ns to break the loop.

22:42 slyrus: is there a good deftype example around?

22:42 oh, nvm the circuitbreaker example...

22:43 well, maybe not...

22:46 mudge: def works at compile time, is there something like that, that works at runtime, but has module scope like def does?

22:46 rhudson: ,(doc intern)

22:46 clojurebot: DENIED

22:47 rhudson: mudge, look at clojure.core/intern

22:50 slyrus: erm... how do I undef a type?

22:50 mudge: thanks rhudson

22:53 Raynes: mudge: http://clojuredocs.org/v/1779

23:03 slyrus: grumble grumble... the defprotocol/deftype example in the clojure.core API docs doesn't work

23:04 hugod: slyrus: it is missing an explicit "this" argument in the deftype

23:05 slyrus: yes

23:05 hugod: you might try ns-unmap for removing a definition

23:06 slyrus: yeah, that worked. thanks.

23:07 oh, no, sorry, I did remove-ns

23:07 and rebuilt the ns

23:07 i'll try ns-unmap next time

23:10 if i have (defrecord Foo [a b] ...) can I specify a default zero-arg constructor that will fill set a and b?

23:12 hugod: you have to write a factory function at the moment, but I believe it is planned

23:12 wooby: slyrus: fyi, reify also requires explicit 'this' for methods (contrary to examples)

23:12 ran into that myself

23:12 slyrus: factory... bah... what is this java? :)

23:13 hugod: just elide the word if it offends :)

23:14 slyrus: is used to (defclass ...) not DefaultAbstractFactoryGeneratorSingleton or whatever the java equivalent is :)

23:15 and (make-instance ...), of course

23:18 hugod: ode to a meta object protocol

23:18 slyrus: heh

23:19 hugod: the doc-string thing is bug #340, but seems to have been relegated to the backlog

23:20 it even has a patch from fogus

23:27 Bahman: Hi all!

23:40 defn: kisses

23:48 Tekk_: hey, my friend is too lazy to say why clojure is the best lisp and he sent me here >.>

23:49 rhudson: Tekk_: here's a good pitch: http://clojure.org/rationale

23:51 tautologico: is there any nice, built-in 2d matrix data structure available in clojure?

23:51 zkim: Tekk_: it sounds like you have a background in lisp, that correct?

23:54 Tekk_: zkim: learning scheme :P

23:54 zkim: Tekk_: background in any other languages?

23:55 Tekk_: zkim: also know python, some C, some C++, some perl, some ruby........

23:55 bit of everything :P

23:55 Raynes: We don't really deal in "this language is better than x". I'm sure you'll find plenty singing the praises of Clojure, but whether or not it's "the best Lisp" is for you to decide. :D

23:55 Tekk_: I like how simple scheme is, but I havent done clojure yet so not sure how I'll like it ;D

23:55 zkim: Tekk_: Video-wise http://blip.tv/file/982823 really helped when I was starting out

23:57 Trying to find that dzone video where rich talks about time, anybody got the link?

23:57 whoops, meant infoq

23:59 Tekk_: Prob my favorite: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

23:59 Raynes: zkim: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

23:59 I think it's that one.

23:59 zkim: Raynes: Yeah, loved that one

Logging service provided by n01se.net