#clojure log - Feb 14 2009

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

0:02 durka42: ,(* 9.35 7)

0:02 clojurebot: 65.45

0:04 durka42: ,(/ 9.35 15)

0:04 clojurebot: 0.6233333333333333

0:05 durka42: ,(/ 9.35 0.5)

0:05 clojurebot: 18.7

0:06 Chouser: ?

0:06 * durka42 was too lazy to pull out a calculator

0:06 durka42: so i used a lazy language instead

0:30 blbrown: just an observation, if you have a proxy function... (proxy [Proxy] [] (func []) ...if

0:30 if Proxy is not defined, you get a nullpointerexception, is that normal

0:33 Chouser: what would you prefer it do?

0:36 ayrnieu: "Dear blbrown, your attempt to proxy an undefined Proxy on line 33 of yourprogram.clj has failed for this reason: Proxy does not exist. Maybe you meant Proxine? Would you like me to edit this change into yourprogram.clj and try what you were doing again?"

0:36 Chouser: hm, not bad.

0:37 blbrown: hehe

0:38 Im just saying

0:38 hiredman: ,(a 'b)

0:38 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

0:38 hiredman: hmmm

0:38 Chouser: even better "...Maybe you meant foo.bar.Proxy? I tried that instead and although it compiled, the formal names of some of the methods do not seem to fit well with superclass argument names, so you may wish to review this code."

0:38 ayrnieu: (declaim (speed 0) (safety 3) (clear-error-messages (fact 400)))

0:39 blbrown: ,(proxy [RunnableX][] (run [] (println foo))

0:39 clojurebot: Eval-in-box threw an exception:EOF while reading

0:39 blbrown: ,(proxy [RunnableX][] (run [] (println foo)))

0:39 clojurebot: java.lang.NullPointerException

0:39 blbrown: yea

0:39 ,(proxy [Runnable][] (run [] (println foo)))

0:39 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)

0:59 blbrown: Modius, you from Austin?

2:42 danlarkin: happy valentine's day, clojurecrats!

2:43 Raynes: Happy valentines day danlarkin.

2:44 * Raynes reads Programming Clojure.

2:44 blbrown: yea...random thought. I wonder why Yahoo didn't buy twitter, hmm

2:47 danlarkin: because they need cash flow, not another non-revenue producing acquisition :)

2:49 albino: cashflow for the twitter people though

3:01 blbrown: danlarkin, twitter will make cash, maybe not now, but guaranteed they will.

3:01 danlarkin: blbrown: easier forecast than done

3:59 zargon_: (map #([%]) [1 2 3])

3:59 java.lang.IllegalArgumentException: Wrong number of args passed to: LazilyPersistentVector

3:59 Why is that?

4:00 if I use a defn makevec instead of the anonymous function it works ...

4:03 (map (fn [x] [x]) [1 2 3]) works too

4:53 cgrand: zargon_: #([%]) expands to (fn [x] ([x])) not to (fn [x] [x])

4:53 ,(map vector [1 2 3])

4:53 clojurebot: ([1] [2] [3])

5:03 zargon_: cgrand: thx

6:20 turbo24prg: morning

6:20 is it possible to change pr's behaviour to print objects?

6:21 or is it necessary to create a new multimethod that dispatches on the type?

6:28 i'd like to hook up common lisp to a clojure script with a repl-server (on the clojure side)

6:29 but CL's reader won't understand brackets or braces

6:46 zakwilson: A couple of reader macros could make CL understand the brackets and braces.

6:49 turbo24prg: yeah, that's another way

6:50 i'd love to see some decent clojure/CL interaction possibility, but currently a repl-sockets seems the only possibility

9:23 kilp: , (+ 4 5 6)

9:23 clojurebot: 15

9:23 kilp: , (/ (+ 4 5 6) 2)

9:23 clojurebot: 15/2

9:24 kilp: , (/ (+ 4 5 6) (float 2))

9:24 clojurebot: 7.5

9:24 kilp: (import '(javax.swing JPane))

9:24 , (import '(javax.swing JPane))

9:24 clojurebot: java.lang.ClassNotFoundException: javax.swing.JPane

9:24 kilp: , (import '(javax.swing JFrane))

9:24 clojurebot: java.lang.ClassNotFoundException: javax.swing.JFrane

9:24 kilp: , (str "clojurebot" " sucks" " at" " importing")

9:24 clojurebot: "clojurebot sucks at importing"

9:25 kilp: (+ " hello" "there")

9:25 , (+ " hello" "there")

9:25 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

9:25 kilp: , (mod 5 2)

9:25 clojurebot: 1

9:25 kilp: , (rem 5 2)

9:25 clojurebot: 1

9:25 kilp: , (div 5 2)

9:25 clojurebot: java.lang.Exception: Unable to resolve symbol: div in this context

9:25 kilp: (/ 5 .0)

9:26 (/ 5 0)

9:26 (/ 5 1)

9:26 clojurebot: *suffusion of yellow*

9:26 kilp: , (/ 5 1)

9:26 clojurebot: 5

9:26 kilp: , (/ 5 1.0)

9:26 clojurebot: 5.0

9:26 kilp: why did he say that all the sudden?

9:40 lisppaste8: Chouser pasted "my first stream-creator" at http://paste.lisp.org/display/75472

9:40 Chouser: is an atom the best way to do that?

9:41 rhickey: Chouser: it's the best Clojure offers, but those cases could be more lightweight

9:42 I've thought about simpler reference type - 'box', but am holding off so far

9:43 Chouser: ok, but the explicit state is at least necessary.

9:43 rhickey: Chouser: I was wondering why for the if thing you didn;t just write a macro that defines if itself, removing any conditionality from if itself (other than the LazySeq test)

9:43 Chouser: yes, state needed - are you switching to streams now?

9:44 Chouser: not really, but dipping my toe in I guess.

9:49 as for the 'if' thing, I can take another run at it if you want. I didn't think the extra test at compile time was worth trying to avoid.

9:50 rhickey: Chouser: trying your patch now

9:50 Chouser: I want to make sure the value of the property at compile time is used also at runtime. my first patch didn't have that, and it makes it pretty easy to think you've got the assert on when in fact only some cases are being checked.

9:57 rhickey: Chouser: No matching field found: isEmpty for class java.lang.String

9:58 Chouser: 1.5?

9:59 there's a whole lot of clojure missing at that spot in core

9:59 rhickey: Chouser: yeah, it's hard working up there isn't it? :)

10:00 Chouser: it really is

10:00 rhickey: Util and RT have a lot though

10:00 Chouser: but it's feels weird to have, right, all of the methods of all of the classes.

10:00 rhickey: Util/equals

10:01 Chouser: gotta start somewhere

10:01 Chouser: .isEmpty was my 3rd or 4th attempt. :-)

10:01 rhickey: until we rewrite Clojure in Clojure

10:03 Chouser: you should be careful with such statements -- people will hold you to it.

10:05 rhickey: Chouser: at some point I'm likely to increase the generality of the underpinnings of fn to be a full class generator...

10:05 It's actually kind of arbitrary that it only generates IFn derivees

10:05 Chouser: lazy-seq was giving me a bit of that impression

10:05 rhickey: exactly

10:06 kilp: Android acepts paid applications now! wooooot! did anyoen got something significant running on android wrritten in clojure going?

10:07 rhickey: A few tweaks and it could gen almost anything, and with no indirection (and thus no dynamism) could compete for speed with the parts of Clojure now written in Java

10:10 Chouser: so what's your impression of lazy branch? hard port? more elegant lazy fns of your own?

10:15 Chouser: lazy branch is good.

10:16 I don't think I'll miss nil puns much for new code

10:17 even with the assert property, fixing existing puns is a bit of a pain

10:18 rhickey: Chouser: did you have a lot of them? was it more than just adding a seq call?

10:18 Chouser: I had one that I spotted visually, pondered for a while, decided it was ok, but was then caught by the assert.

10:18 no, not many

10:18 just a 'seq' call every time

10:18 clojurebot: svn rev 1281; [lazy] added (optional) detection of conditional test of LazySeq, build with: ant -Dclojure.assert-if-lazy-seq=true patch from Chouser

10:19 Chouser: in this one case, the assert stack trace confused me, and I spent a while hunting it down

10:19 the seq was created in one place, stored in a map elsewhere, and punned in a third spot. The assert of course didn't point out where the seq was created.

10:21 rhickey: Chouser: I think the assert will be a big help in the porting phase - thanks!

10:21 kilp: can anyone show an example of drawing some lines or shapes on a JFrame usign java graohics2D?

10:22 rhickey: Chouser: how about 'more'? I think keeping the semantics of rest was critical to making this idea work, but left with new more function

10:25 Chouser: rhickey: you're welcome. I enjoy participating in the language creation process without having to make any of the hard decisions. :-)

10:25 Chousuke: heh

10:26 pjb3: I'm trying to figure out how to use require from the REPL

10:26 I'd like to do the equivalent of

10:26 (ns foo (:require [clojure.xml :as xml]))

10:26 Chouser: rhickey: you're asking if I think (rest x) == (seq (more x)) is necessary?

10:27 pjb3: without the ns

10:27 (require [clojure.xml :as xml]) doesn't do it

10:28 (require '[clojure.xml :as xml])

10:28 that works

10:28 Chouser: kilp: It's a Frame instead of a JFrame, and there some other complexity in there, but... http://gist.github.com/40012

10:29 rhickey: uses of lazy-cons to lazy-seq were easy find and easy to fix (though i've not tested the actual laziness of any of them yet).

10:29 rhickey: Chouser: no, I'm wondering if you've thought of a brilliant name for 'more'

10:30 I'm pretty sure changing the semantics of rest (to mean what more does) would have been a disaster

10:32 Chouser: in lazy we have seq, sequence, and sequential to mean slightly different things, right?

10:32 'more' might accurately be called 'sequential-rest'?

10:32 lisppaste8: kilp pasted "listener" at http://paste.lisp.org/display/75474

10:33 kilp: ^^ how do I generate that in clojure?

10:33 leafw: kilp: with a proxy.

10:34 rhickey: Chouser: more currently guarantees Sequence, not Sequential

10:35 leafw: kilp: see example of proxy usage for an interface here: http://pacific.mpi-cbg.de/cgi-bin/gitweb.cgi?p=fiji.git;a=blob;f=plugins/Examples/Command_Launchers/Command_Launcher_Clojure.clj;hb=HEAD

10:36 rhickey: Chouser: best names would probably be: rest (now more), rest-seq (now rest)

10:37 Chouser: but of course 'rest-sequence' is too long and 'rest-seq' isn't right.

10:38 rhickey: are you considering those, or would that be too much of a breaking change for 'rest'?

10:40 rhickey: What I found was that there were plenty of acceptably eager uses of rest in terminal/consuming code, and far fewer calls to rest that needed to become more in lazy-sequence fns

10:40 Chouser: ok, that doesn't surprise me.

10:40 rhickey: so changing rest would be much needless grief

10:40 Chouser: sure

10:40 on the other hand while 'more' is not inaccurate, it's not a terribly helpful name.

10:40 rhickey: plus an incompatibility with other Lisps where rest/cdr is eager

10:40 blbrown: how would I send a class to a java method (E.g. String.class)

10:41 rhickey: so new functionality gets new name

10:41 kilp: are processor registers stacks?

10:41 what doe smore do?

10:41 rhickey: Chouser: agreed, more is not a great name

10:41 Chouser: I already have trouble remembering which is more and which is rest.

10:41 leafw: blbrown: just use String, without the .class

10:41 Chouser: but as you said, 'rest' isn't *terribly* common, so it could afford to be a bit long I'd think.

10:42 rhickey: Chouser: which 'rest'?

10:42 blbrown: leafw, that is what I thought, hmm

10:42 Chouser: but maybe not 'rest-sequence' longer

10:42 sorry!

10:42 I meant 'more' :-P

10:42 I meant 'more' isn't terribly common.

10:43 rhickey: rest-coll?

10:43 Chouser: let's call it that for the rest of this discussion, shall we?

10:44 rhickey: call it what?

10:44 whose on first? :)

10:44 who's

10:44 Chouser: (rest-coll myvec) seems to be the same as (rest myvec)?

10:45 rhickey: too similar?

10:45 Chouser: no, I was reaching the opposite conclusion.

10:46 this is a hard conversation.

10:46 rhickey: :)

10:46 what dod you mean by "rest-coll myvec) seems to be the same as (rest myvec)" ?

10:46 Chouser: I was thinking that if rest-coll does anything sensible on other kinds of collections (besides LazySeqs) that 'rest-coll' might indeed by a fine name.

10:47 rhickey: user=> (rest-coll [1 2 3])

10:47 (2 3

10:47 )

10:47 Chouser: right

10:47 rhickey: same as more

10:48 Chouser: oh

10:48 kilp: public class ExitListener extends WindowAdapter {

10:48 rhickey: user=> (more [1 2 3])

10:48 (2 3)

10:48 kilp: (proxy ExitListener (WindowAdapter

10:48 Chouser: wait... rest-coll *is* more, istn' it?

10:48 kilp: ?

10:48 rhickey: user=> (more [1])

10:48 ()

10:48 Chouser: oh, man.

10:48 rhickey: Chouser: yes, rest-coll as a new name for more

10:49 Chouser: ok, good. for a moment there I was very worried.

10:49 kilp: public class ExitListener extends WindowAdapter {

10:49 public void windowClosing(WindowEvent event) {

10:49 System.exit(0);

10:49 leafw: kilp: use http://paste.lisp.org/new/clojure

10:50 Chouser: right, so if some misguided soul calls 'rest-coll' on their vector because they know that vector is a coll and don't realize they can just use 'rest', no harm is done.

10:50 the '-coll' in the name isn't lying or misleading.

10:51 lisppaste8: kilp pasted "how to use proxy?" at http://paste.lisp.org/display/75475

10:51 Chouser: it's longer than 'rest' which helps suggest it's less commonly used, which I think is accurate.

10:52 leafw: kilp: did you see the TextListener example above?

10:52 rhickey: Chouser: well, if they wanted the nilling effects of rest, rest-coll wouldn't be the same

10:53 There's also lazy-rest, which implies a delay to me, but would match lazy-seq

10:53 Chouser: ah, I see you already demonstrated that to me. :-)

10:53 rhickey: user=> (rest [1])

10:53 nil

10:53 user=> (lazy-rest [1])

10:54 ()

10:54 does that seem weird?

10:54 Chouser: yes, I don't think lazy-rest is too good. lazy-seq-rest would be more accurate.

10:54 rhickey: etc?

10:55 Chouser: I think rest-coll is my favorite so far. It works on colls, returns a coll (not a ISeq/nil).

10:55 etc's not better than more

10:59 kilp: leafw: yes i look at it but dont quite get it

11:00 rhickey: more->rest, rest->next might be best possible names, compatibility aside

11:05 kilp: how do I write System.exit(0); from Clojure?

11:06 (.exit System 0) ?

11:06 Chousuke: (System/exit 0)

11:06 / for static fields

11:06 Chouser: kilp: good guess though, I think that used to work. :-)

11:06 Chousuke: yeah, but not any more :)

11:06 unless Class has a .exit field :/

11:07 Chouser: rhickey: sure, 'more->rest' is a fine name. :-) I gotta go, have fun making the hard decisions.

11:07 rhickey: nice

11:10 leafw: by the way: on the web page, the search field does not accept function names like "->"

11:10 kilp: very schemey with using ->

11:10 lisppaste8: kilp annotated #75475 with "untitled" at http://paste.lisp.org/display/75475#1

11:11 kilp: is that somehow correct?

11:14 leafw: kilp: that defn returns nil. IS that what you want?

11:22 pilk: leafw

11:22 no

11:22 iw ant to add an exitaction to the frame

11:25 when the user presses X I want to do some stuff

11:25 how?

11:26 lisppaste8: leafw annotated #75475 with "untitled" at http://paste.lisp.org/display/75475#2

11:28 pilk: thanks

11:28 public void windowClosing(WindowEvent event

11:28 and i never have to mention WindowEvent?

11:28 Chousuke: leafw: you don't need to call create-exit there? /:

11:29 leafw: yeah

11:29 too tired

11:29 the frame is not shown either.

11:30 lisppaste8: leafw annotated #75475 with "untitled" at http://paste.lisp.org/display/75475#3

12:33 shoover: rhickey: is the .net contrib you mentioned a few weeks ago public or private?

12:34 gnuvince_: Hey

12:34 Can anyone tell me how to "use" the hasclojure property in clojure-contrib's build.xml?

12:34 (so that the .clj are compiled to .class files)

12:35 rhickey: shoover: should be in contrib soon - watch the group for an announcement by the author

12:35 possibly this weekend

12:35 shoover: rhickey: thanks. my talk is Thursday, and I've love to have something to tell

12:38 danlarkin: gnuvince: -Dclojure.jar=/path/to/clojure.jar

12:39 gnuvince_: ah!

12:39 I was doing -Dhasclojure=/path/to/clojure.jar

12:56 Is it possible to have more than one Available task in an if with Ant?

12:56 Like, <target name="foo" if="predicate1,predicate2">...</target>

12:59 zargon_: how do I "map" a list to a map with key=list[i] and value=f(list[i]) ?

12:59 my solution would involve a loop ... but there must be a better more "idiomatic" way?

13:02 ayrnieu: ,(let [lst (range 10) f #(* % -1)] (apply hash-map (interleave lst (map f lst))))

13:02 clojurebot: {0 0, 1 -1, 2 -2, 3 -3, 4 -4, 5 -5, 6 -6, 7 -7, 8 -8, 9 -9}

13:03 kotarak: ,(let [lst (range 10)] (zipmap lst (map #(* % -1) lst)))

13:03 clojurebot: {0 0, 1 -1, 2 -2, 3 -3, 4 -4, 5 -5, 6 -6, 7 -7, 8 -8, 9 -9}

13:03 kotarak: Many ways to Rome... (and back again)

13:03 zargon_: zipmap!

13:03 thx guys

13:37 Lau_of_DK: Good evening everyone

13:41 danlarkin: oh hi lau :)

13:42 Lau_of_DK: Hi Dan, what did you decide?

13:42 * Lau_of_DK crosses fingers, hopes for Clabango

13:43 danlarkin: haha

13:43 neither!

13:43 Lau_of_DK: Cruel - Then what?

13:44 danlarkin: well, sorry to disappoint but I am still nameless. I really tried though, I swear! I talked it over with friends last night for as long as they could stand and the best we came up with was "copter"

13:45 Lau_of_DK: haha, man... you need more friends like me

13:45 How about "Mohito" ?

13:45 Or its prolly spelled 'Mojito'

13:46 danlarkin: I wish hansard were a better name

13:46 Lau_of_DK: So pick Hansard,

13:47 I mean, if thats the best you can come up with, then thats that :) We will suffer it

13:51 danlarkin: well you've got some time... right now it won't build, I'm in the middle of a circular dependency issue, so I won't be uploading until I work this out

13:52 Lau_of_DK: ok

14:08 clojurebot: svn rev 1282; [lazy] renamed rest to next, renamed more to rest

14:12 Lau_of_DK: rhickey_: Thats a little odd, why name rest => next?

14:13 cgrand: I tend to think of next as frest

14:13 Lau_of_DK: Are you thinking lazily ? :)

14:17 rhickey: cgrand: it's the next seq object, if any

14:18 I've updated this: http://clojure.org/lazier

14:18 cp2: hello ragnard

14:18 er, rhickey

14:20 rhickey: I'm not sure I'm going to do this, but I had to try it to see what it looks like and get feedback. It took me about 45 minutes to convert Clojure itself, so I think it is a manageable change (basically rename all rest calls to next, except those in lazy fns)

14:20 I like the resulting code - next means next seq/cursor, rest means rest of the collection

14:21 cp2: hi

14:25 cgrand: what I found in porting core was that most recur calls use next, and most lazy-seq conses use rest, which match the imperative/lazy semantics well

14:26 open to feedback, including OMG please don't!!

14:26 :)

14:27 Lau_of_DK: rhickey: Cant you just put some sample code in the pastebin ? :)

14:29 rhickey: http://code.google.com/p/clojure/source/diff?spec=svn1282&r=1282&format=side&path=/branches/lazy/src/clj/clojure/core.clj

14:29 Lau_of_DK: Clever :)

14:32 danlarkin: my only problem with next is it kinda sounds like it'd be frest

14:32 but I can get over that

14:32 rhickey: danlarkin: you mean second :)

14:33 danlarkin: but yes, I understand, cgrand thought so too

14:33 it could be next-seq or something else more explicit

14:34 danlarkin: mmhmm

14:35 Chouser: I don't know if I would have thought that, but I don't see how 'rest' doesn't mean the next lazy-seq obj.

14:35 rhickey: Chouser: note the next in your sentence

14:36 Chouser: yes, hense the confusiong over why 'next' means something else.

14:36 rhickey: it doesn't

14:36 Lau_of_DK: (def a [1 2 3]) (def b (next a)), is b then [2 3] ?

14:36 * Chouser sighs and looks at the patch again.

14:37 rhickey: (next aseq) == next seq object or nil there isn't one

14:37 (rest x) a collection of items other than the first

14:37 Chouser: 'next' now means "the next ISeq, or nil", and 'rest' now means "the next LazySeq", right?

14:38 Lau_of_DK: But you said that you just renamed rest? Which was why I thought it was weird

14:38 rhickey: Chouser: sorry, didn't catch the lazy- in your sentence

14:38 Chouser: ah

14:38 hard hard hard conversation. I'm sure it'd be bad in person in front of a white board, but not this bad.

14:38 ayrnieu: is clojurebot on lazy?

14:39 rhickey: rest doesn't promise lazy-seq, or have anything to do with lazy necessarily, better to think of as a collection of the rest of the items other than the first

14:39 ayrnieu: ,(more [1 2 3])

14:39 clojurebot: java.lang.Exception: Unable to resolve symbol: more in this context

14:40 rhickey: next -> next seq/cursor or nil , rest -> collection of rest of items, may be empty

14:40 Chouser: is it ever going to start returning sub-vectors or (disj (first mymap))?

14:40 Lau_of_DK: Got it

14:41 rhickey: Chouser: nope, because it promises that collection will be a Sequence

14:41 important because macros need to use sequence fns to create logical lists distinguishable from vectors/maps

14:42 and form-consuming code often needs to partition by list/not

14:42 jwinter: I also thought next would mean second, it feels a little strange that it returns a sequence and not an element. Naming things is hard.

14:42 rhickey: such code (e.g. the compiler) will use Sequence

14:44 jwinter: it's tru some iteration protocols use next to return the next item, but also have the side effect of moving cursor. In a functional iteration protocol (which is what seqs are), it can only do one or the other

14:44 hiredman: it might be easier for people to decide which one to use if they were called rest and lazy-rest

14:44 rhickey: hiredman: I think we put that to rest earlier

14:44 * rhickey ducks

14:45 hiredman: oh

14:46 * danlarkin golfclaps for rhickey

14:47 jwinter: What are the names for lazy-cdr in other languages?

14:47 Chouser: I think I still prefer rest+rest-coll over anything as ambiguous as 'more' or 'next'

14:48 rhickey: Chouser: what about rest and next-seq ?

14:48 * durka42 is also uneasy about near-synonyms rest, next, more having subtly different meanings

14:48 * rhickey thinks (next-seq aseq) is redundant

14:49 Chouser: it'd be worried about the -seq being misleading, as it doesn't mean the same kind of thing as the 'seq' function returns.

14:49 next-coll would be great.

14:49 rhickey: durka42: more would be gone, and rest/next are not synonyms in my book, a benefit

14:49 Chouser: it means exactly the same thing

14:50 returns seq or nil

14:50 durka42: true, those aren't really synonyms

14:50 rhickey: Chouser: ah, rest being current (more) and rest-seq being current (rest)

14:52 sorry, next-seq being current rest

14:52 Chouser: ah. oh. um...

14:52 rhickey: (rest x) -> a collection, (next-seq x) -> a seq or nil

14:52 Chouser: sheesh. yeah, I guess that'd be ok.

14:53 except that's the longer name for the more common case.

14:53 rhickey: right, thus next

14:53 Chouser: and 'rest' would still exist but mean something different.

14:53 eh.

14:53 gnuvince_: with ant, how can you view the available tasks?

14:54 rhickey: the core code looks good once you detach yourself from a preconception of next == second

14:54 gnuvince_: It doesn't appear to be documented in ant -h

14:55 rhickey: next is imperative, rest is lazy

14:55 Chouser: I think I still prefer rest == (seq (rest-coll x)) and rest-coll

14:55 Lau_of_DK: rhickey: when you say that next != second, is that because next is more like frest?

14:55 Chouser: or maybe next == (seq (rest-coll x)) and rest-coll. That'd be ok.

14:56 rhickey: Chouser: hmmm, I don't like rest-coll, begs what does -coll mean?

14:57 Chouser: it takes a coll and returns a coll

14:57 rhickey: Chouser: so do lots of things

14:58 seqs are colls too

14:58 Chouser: but nil is not

14:59 rhickey: I like rest and next because those are the words I'd use in sentences describing the behavior, independent of the implementation

15:00 Lau_of_DK: frest == second

15:01 Lau_of_DK: k

15:01 rhickey: many many people complain that the return value of rest can't be 'empty', but it's pretty easy to understand there might be no next thing

15:01 thus nil

15:02 Lau_of_DK: Thats true

15:02 I really liked the whole read-once concept, thats an intuitive way to consume a seq in my oppinion

15:04 jwinter: gnuvince: does ant -projecthelp do what you want?

15:04 Chouser: Experimental branches of Clojure -- http://blog.n01se.net/?p=39

15:07 Lau_of_DK: Chouser: Great blog you got

15:08 rhickey: Chouser: nice! and with an example that conveniently doesn't use more/rest-coll/next/whatever :)

15:09 Lau_of_DK: rhickey: You've got a definate meanstreak

15:09 gnuvince_: jwinter: yes, thanks!

15:09 rhickey: Lau_of_DK: no, I meant that as a compliment strictly

15:09 Chouser: rhickey: heh, yeah, I've been marvelling to myself that the discussion here wasn't invalidating my post.

15:09 Lau_of_DK: oh :)

15:10 rhickey: Chouser: exactly!

15:10 gnuvince_: I wrote a build.xml file for my project, but I've never used ant before

15:13 rhickey: I guess an alternative is to have only (rest x) -> collection, since (next x) is just (seq (rest x)), but that will just beg for next to be written (and named)

15:13 seq-rest?

15:14 Lau_of_DK: I dont really see the problem in just sticking with 'rest'

15:14 rhickey: Lau_of_DK: rest meaning what?

15:14 Lau_of_DK: Dont consider the names, but (seq (rest-coll x))

15:14 So just get a seq or nil, from whatever is left

15:15 rhickey: Lau_of_DK: that still leaves naming 'rest-coll'

15:15 which must be added for lazier, not derived behavior

15:16 Lau_of_DK: true

15:16 hiredman: rest-

15:16 rhickey: Lau_of_DK: that was my first take (a revert away from this point), leave rest alone and add 'more'

15:16 but the names are bad

15:17 Lau_of_DK: I never disliked 'more' actually, what dont you like about it?

15:17 Its as intuitive as next

15:18 rhickey: Lau_of_DK: it's more of a synonym for rest, and implies almost nothing about the difference

15:19 Lau_of_DK: So how about adopting your syntax-tweak for streams, having rest and rest*, making that a convention for clojure?

15:26 rhickey: Lau_of_DK: I'm not sure * conveys anything

15:27 Lau_of_DK: rhickey: It conveys nothing, thats why it should be a convention - but perhaps it was a dumb idea :)

15:27 rhickey: Lau_of_DK: which one is rest* ?

15:28 Lau_of_DK: You get to decide, you can make the convention, but I'd think rest == (seq (rest* x)) would make the most sense

15:29 Chouser: rhickey: without the assert patch, would you still be considering changing the meaning of 'rest'?

15:30 * Chouser wonders if there's any way to take it back. ;-)

15:31 rhickey: Chouser: I'm just going through core now, looking at what are now 'nexts', virtually all are nil puns, mostly like (if items ... (recur ... (next items))

15:32 The change of rest->next is easiest - search/replace, then it's the same job as more was, not using next in lazy fns

15:32 Chouser: ah, good point.

15:32 rhickey: Chouser: but like I said before, leaving rest alone is the easiest thing, but is it the best thing?

15:33 the vast majority of uses of next could be written (if (seq items) ... (recur ... (rest items)), and would thus match lazy code

15:34 the problem is they wouldn't be as fast as before, need the if/when-let for that

15:34 Chouser: I'm not so much in favor of leaving 'rest' alone as I am in not introducing a new subtly different meaning for it.

15:34 rhickey: agreed

15:34 and yet it is the presumed meaning of many

15:35 Chouser: every question posted here and on the group, every answer, every example is going to require a note clarifying which 'rest' this code is using.

15:36 rhickey: true, and not a small problem

15:37 so will the need to advise, moving forward, not to use rest

15:37 Chouser: less critical now, as most people who are using the lazy branch know they need to be careful, but after merge there will be old and new versions of clojure and new users may not be even aware which version they've got.

15:37 rhickey: OTOH, the only real difference is whether the pun works

15:38 (if items ... (recur ... (rest items)) changes in lazier to (if (seq items) ... (recur ... (rest items))

15:38 rest isn't broken, pun is

15:39 but yes, a breaking change to interface

15:40 Lau_of_DK: It'll get annoying real quick to prefix everything with (seq) though

15:40 rhickey: Chouser: so I take it you're in the "please don't!!" category?

15:40 Chouser: I still don't think nil punning will be much missed after some changeover pain.

15:41 my one converted file, 170 lines, 2 places needed seq calls added.

15:42 rhickey: Chouser: but rest still nil puns, and there were lots more of those in core, so it seems that one's harder to give up

15:43 Chouser: rhickey: yeah, I guess I'd slightly prefer rest/more over next/rest.

15:43 but I'd be fine with next/rest-coll or next/lazy-seq-rest

15:44 rhickey: next/rest* ?

15:44 Chouser: because then we'd get questions like "where did rest go" rather than "why is my program in an infinite loop"?

15:44 rhickey: right

15:45 Chouser: sure, next/rest* would be ok

15:45 rhickey: solves the 'which rest?' problem

15:45 Chouser: right

15:46 rhickey: next/more ?

15:46 if we're retiring rest

15:47 any of the synonyms become fair game

15:47 Chouser: and you like next for (seq (whatever x))

15:49 rhickey: Chouser: yes, wishes now I had chosen it in first place - I see in my note I thought the issue would be Java people presuming it returned the second item and had side effects of moving cursor, which they will :(

15:49 notes

15:50 Chouser: they'll get over it

15:51 rhickey: I agree, I'm most concerned with being internally consistent, and now, with legacy

15:51 next/dregs

15:51 Chouser: ha!

15:51 Lau_of_DK: with legacy ?

15:52 Chouser: I've been surprised at how easily confused I've been between rest and more, so I'm trying to guess how hard next/more or next/rest* would be.

15:52 or dregs, I suppose.

15:53 fanda: consistency is the most important

15:53 think about 2 years later... if something is broken, it will be even harder to fix

15:53 rhickey: Before I mapped to cons' first/rest, I had move/step etc as candidates for 'rest'

15:54 just working on persistent iterator, not the lazy issue then

15:54 Lau_of_DK: rhickey: I doesnt matter if 1.0 is completely backwards incompatible, as long as its optimal right?

15:55 rhickey: Lau_of_DK: I'm not sure, still smarting from the bashing that happened around AOT changeover...

15:55 thus hiding in branches

15:56 Lau_of_DK: Backwards compatability can/will get in the way of innovation, which is perfectly fine and understandable, but my feeling is that going into ver. 1.0 all bets are off, 1.1, 2.0 and so on should probably be launched with BC... But thats just my oppinion

15:56 Chouser: does such bashing come mostly from the CL folks who haven't seen their language change in a decade? Us scripty ruby/python kids don't mind so much, I'd guess.

15:57 rhickey: Chouser: there was a lot of influx to Clojure at the same time, people trying examples that didn't work, pulling a release that preceded the change, and getting the impression things were less stable than I think they have been generally

15:58 Chouser: hm, ok.

15:58 fanda: rhickey: just make as many people aware of the issue by posting on the mailing list or even on the website clojure.org

15:58 (when that happens)

15:59 i think it's understandable

16:11 rhickey: Here's another way to think about it - if (rest x) means a collection of the items other than the first (and this is the primary abstraction in fully lazy), what's a good nickname for the seq of that collection?

16:12 Lau_of_DK: rest? :)

16:13 rhickey: Lau_of_DK: did you miss the presumption? "if (rest x) means a collection of the items other than the first "

16:14 Lau_of_DK: No I didnt, and Im really not trying to be difficult, but it just seems like the right word for it, you have the first item, and then you have the rest - And I think that the rest call should default to a seq no matter what

16:14 rhickey: I'm thinking some seq variant, seq-> or something

16:15 Lau_of_DK: hmm.. seq-> is actually quite cool

16:15 rhickey: Lau_of_DK: then you can't have fully lazy

16:15 Chousuke: what's the -> supposed to signify? :/

16:15 Lau_of_DK: I have a fully lazy if the rest of my seq is always wrapped in a seq?

16:16 Chousuke: Advancing through the seq

16:16 (I assumed)

16:16 Chousuke: rhickey: so in this fully lazy world, would (rest [1 2 3]) return a vector?

16:17 rhickey: Chousuke: no, always a sequence

16:17 Chousuke: I see. so no way to have it keep the vector guarantees. :/

16:18 rhickey: sequence encompassing seqs and lazy sequential collections

16:19 Chousuke: use subvec

16:22 Chouser: or persistent queue, depending on what you're doing

16:25 cp2: is there a sort of "contains" function for sequences? (or something like member in common lisp)

16:26 Chouser: cp2: are you aware of sets? they usually work better than seqs when you're going to be testing for the existance of a particular value.

16:26 cp2: ah, i didnt think of that

16:26 yes, that would work better in this case

16:27 Chouser: excellent. and of course then you can just use the set itself as a function. so pretty. :-)

16:27 cp2: yeah, i do llike that :(

16:27 :) **

16:33 Lau_of_DK: Isnt there some serious documentation available on Compojure?

16:33 Chouser: Lau_of_DK: just what you're about to write.

16:34 Lau_of_DK: Thats not a whole lot

16:44 Compojure doesnt escape html by default I suppose? :)

16:50 java.lang.NoSuchMethodError: clojure.lang.Util.equal(Ljava/lang/Object;Ljava/lang/Object;)Z (iwish.clj:15)

16:50 [Thrown class clojure.lang.Compiler$CompilerException]

16:50

16:50 Can somebody enlighten me on what this means ?

16:55 Chouser: that doesn't look healthy.

16:56 but it's hard to guess without more stack or the code, or both.

17:01 gnuvince_: What's the general preference for GUIs, Swing or SWT?

17:01 Lau_of_DK: gnuvince_: Qt

17:01 gnuvince_: bleh

17:01 Lau_of_DK: bleh?

17:02 gnuvince_: I dislike Qt

17:02 Lau_of_DK: argh, I sense religious issues... nevermind, chooser whatever inferior standard your idol commands you to

17:05 gnuvince_: I'd rather use something that's actually used in the Java world

17:07 Lau_of_DK: You mean like QtJambi ?

17:08 gnuvince_: No, like the 120,000 tools you can download from Sourceforge

17:09 Lau_of_DK: Have fun with those :)

17:10 gnuvince_: It's not just a question of fun, it's a question of learning something that the majority of Java people actually use.

17:10 Lau_of_DK: Sure, youre free to do as you want

17:18 lisppaste8: shoover pasted "with-properties macro" at http://paste.lisp.org/display/75482

17:18 shoover: is there a better way to create the current# map in that paste?

17:19 well, I made a sequence of vector tuples there, but it's logically a map

17:19 I want a new map that has the same keys as the original but the values are the result of a function on the keys

17:20 durka42: zipmap might help

17:23 ,(let [orig {1 "one" 2 "two" 3 "three"}] [orig (zipmap (keys orig) (map #(* -1 %) (vals orig)))])

17:23 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

17:23 durka42: ,(let [orig {1 "one" 2 "two" 3 "three"}] [orig (zipmap (keys orig) (map #(* -1 %) (keys orig)))])

17:23 clojurebot: [{1 "one", 2 "two", 3 "three"} {3 -3, 2 -2, 1 -1}]

17:26 hiredman: ,(apply hash-map (mapcat (fn [[a b]] [a (+ b 1)]) {:a 1 :b 2 :c 3}))

17:26 clojurebot: {:b 3, :c 4, :a 2}

17:26 hiredman: ,(doc updatein)

17:26 clojurebot: java.lang.Exception: Unable to resolve var: updatein in this context

17:26 hiredman: ,(doc update-in)

17:26 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

17:27 hiredman: ,(doc update)

17:27 clojurebot: java.lang.Exception: Unable to resolve var: update in this context

17:27 hiredman: hmmm

17:29 shoover: hiredman: warmer

17:29 hiredman: ,(loop [h {:a 1 :b 2} k (keys h)] (if h (recur (update-in h [(first k)] inc) (rest k)) h))

17:29 clojurebot: java.lang.NullPointerException

17:29 hiredman: bah

17:30 ,(loop [h {:a 1 :b 2} k (keys h)] (if k (recur (update-in h [(first k)] inc) (rest k)) h))

17:30 clojurebot: {:a 2, :b 3}

17:32 hiredman: ugh

17:32 of course

17:32 you could just use recude

17:32 reduce

17:33 xoox: How do I use xml-zip to find a node "foo" that satisfies some properties and is also a child of "bar" that satisfies some other properties? I keep running out of heap when doing (xml-> (xml1->

17:33 hiredman: ,(reduce #(assoc % (first %2) (inc (second %2))) {} {:a 1 :b 2})

17:33 clojurebot: {:b 3, :a 2}

17:33 gnuvince_: I have a license question: if I modified and distribute a GPL3 library with my program, that means I need to be GPL3 too, right?

17:35 shoover: hiredman: durka42: thanks for the help. update-in was close, but I think the simple map will suffice

17:35 leafw: gnuvince_: yes

17:36 gnuvince_: leafw: thanks

17:37 Man, that license is practically a novel

17:38 leafw: it tries to patch all potential loopholes.

17:44 gnuvince_: This is sort of annoying...

17:45 Anyway

17:48 kilp: where is condp

17:50 hiredman: ~def condp

17:51 huh

17:51 weird

17:51 off by a few lines

17:52 ,(:line (meta #'condp))

17:52 clojurebot: 3793

17:53 hiredman: ~def update-in

17:54 kilp: condp is in a newer release?

17:54 , (doc condp)

17:54 clojurebot: "([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause matches, the result-expr is returned, if a ternary clause matches, its result-fn, which must

17:54 kilp: i have december release

17:55 hiredman: svn rev 1180

17:55 clojurebot: well?

17:55 clojurebot: Titim gan �ir� ort.

17:55 hiredman: gah

17:57 condp was added to core 2008-12-21 1

17:58 hiredman.clojurebot.svn=> @svn-rev-cache

17:58 java.lang.StackOverflowError

17:58 :(

17:59 svn rev 1180

17:59 clojurebot: svn rev 1180; added condp, with input from Stuart Sierra and Meikel Brandmeyer

18:03 gnuvince_: Nice; my old Python library takes 9:40 minutes to analyze 1000 Starcraft replay files. The Clojure implementation takes 3:50 minutes

18:06 ayrnieu: what other contrasts do you draw?

18:14 gnuvince_: ayrnieu: between Python and Clojure?

18:15 ayrnieu: between your Python and Clojure programs.

18:15 gnuvince_: I intend to blog about, but here are a few:

18:16 1. It was easier in Clojure to define the different actions of Starcraft in a declarative style. Python required meta classes and some thread unsafe things

18:17 2. The tools that Clojure has access to because of Java are nice. The profilers -Xprof and -Xrunhprof were particularily useful in tracking down performance issues

18:17 3. The community was extremely helpful whenever I had a problem.

18:18 ayrnieu: Thanks; I'll look for the blog-post.

18:34 lisppaste8: kilp pasted "windowlistener not working" at http://paste.lisp.org/display/75485

18:34 pilk: the first example works but in my bigger program(mp3 player it doesnt)

18:34 user=> java.lang.IllegalArgumentException: No matching method found: addWindowListener for class javax.swing.JFrame (mp3player.clj:0)

18:35 lisppaste8: kilp annotated #75485 with "untitled" at http://paste.lisp.org/display/75485#1

18:36 hiredman: pilk: no matching method found means you type signature does not match

18:36 your

18:37 pilk: wait doto

18:38 kilp: hmm system exit kills what, the whole jvm?

18:39 hiredman: yes

18:39 kilp: becuse i called system exit and then i didnt have to kill the player-thread

18:40 does System.exit(0); kill the whole JVM? all threads etc? do I ever need to expliicitly stop/close/kill a thread if calling System.exit? or shoulnt i call System.exit always?

18:40 hiredman: the jvm runs as a single process

20:53 blbrown: funny that I want to merge scala and clojure somehow. Scala library called from clojure

21:04 anyone working with javafx, wonder if it is possible to integrate with clojure

21:11 kilp: http://podularraludop.appspot.com/ <- what do you guys think of the idea? add some up/down-voting and then signup so personal taste can be tracked.

21:12 i will redesign it once i figured out the exact functionality and get a .com address. (it is a podcast aggregator/recommender site)

21:13 durka42: hmm, you could call it "poddit"

21:13 kilp: why?

21:15 durka42: because it seems loosely like a reddit for podcasts

21:15 kilp: thinking which is bette,r updown or 1-5 voting

21:18 te: reddit sucks

21:20 durka42: does it now

21:20 te: just being a jerk

21:20 kilp: digg was before reddit right?

21:20 and the idea is hardly original anyway

21:20 but all podcastsaggregators suck

21:20 te: nod

21:21 aggregation is equal to degradation

21:21 or something like that

21:21 kilp: i have to spend so much time funding the good oens it isnt worth it

21:21 maybe ill use yahoos searchapi and find podcasts and post them automatically to the site

21:21 something liek that

21:21 then have reviews

21:22 and have an app on android that you can buy

21:22 you think it could work?

21:25 te: are there apps for android?

21:25 like on iphone?

21:25 durka42: yes

21:25 te: i had no idea

21:26 durka42: "android market"

21:26 kilp: yes and now us and uk developers csn charge for them

21:26 and it will open for rest of the world too

21:39 gnuvince_: How accurate are the results of java -Xprof? It tells me that nearly 25% of my program is spent in calls to rest

21:57 eyeris: Could someone type out how they read this in english? "(defmacro cond-let [bindings & clauses] ..."

21:57 I am specifically confused by the & symbol

21:58 As far as I can tell it means "and bind the rest of the arguments to the clauses symbol"

21:58 However I don't know how I am supposed to use them

21:58 gnuvince_: ,(let [[x & xs] [1,2,3,4,5]] xs)

21:58 clojurebot: (2 3 4 5)

21:59 eyeris: So it is like deconstruting binding for lists?

21:59 gnuvince_: The rest of the arguments are put into a seq and bound to the clauses parameter

21:59 You can do whatever you want with them

21:59 eyeris: Okay, so what if I just want *all* of my paramters in a seq?

21:59 gnuvince_: [& xs]

22:00 eyeris: Oh wow, duh

22:00 gnuvince_: ,(let [[& xs] [1 2 3]] xs)

22:00 clojurebot: (1 2 3)

22:00 eyeris: I really should have tried that

22:00 :)

22:00 Thank you

22:02 gnuvince_: np

22:49 quiet tonight

22:49 Lots of guys on a tight leash I guess

22:51 blbrown: hmm, does xml/parse support parsing just a string, not a file

22:59 OK, inputstream

23:00 gnuvince_: ~seen technomancy

23:00 clojurebot: technomancy was last seen quiting IRC, 1596 minutes ago

23:01 ayrnieu: ,(/ 1596 60.0)

23:01 clojurebot: 26.6

23:01 gnuvince_: Kind of wanted his help with clojure-mode.

23:15 blbrown: ~seen blbrown

23:15 clojurebot: blbrown was last seen in #clojure, 0 minutes ago saying: ~seen blbrown

23:15 Chouser: nice

23:15 blbrown: ~seen ,blbrown

23:15 clojurebot: no, I have not seen ,blbrown

23:15 blbrown: ~seen ~seen blbrown

23:15 clojurebot: no, I have not seen ~seen blbrown

23:16 blbrown: Chouser, I have yet to trick this bot. then again, I haven't tricked any IRC bots. They are just that smart

23:20 gnuvince_: ~seen ""

23:20 clojurebot: no, I have not seen ""

23:21 Chouser: ~clojurebot

23:21 clojurebot: clojurebot is like life: you make trade-offs

23:21 Chouser: ~seen clojurebot

23:21 clojurebot: Of course I have seen myself.

23:24 gnuvince_: Does C-c C-c work for anyone else with Slime?

23:25 WizardofWestmarc: I just made sure, mine works fine. But I think my swank-clojure is a week or so old

23:26 gnuvince_: WizardofWestmarc: would you mind showing me your config?

23:26 Maybe you have something I don't

23:27 blbrown: I wonder if it is better to use slime/clojure over jline at the console

23:28 gnuvince_: blbrown: depends on what you prefer

23:28 If you're not into Emacs, jline, ledit, rlwrap are most likely better choices

23:28 blbrown: no, I am very into emacs

23:29 gnuvince_: I don't have jline

23:29 I don't see the point, all the command line editing functions are already there.

23:29 blbrown: I normally merge jline with the clojure repl. It is basically just rlwrap for java

23:29 really

23:30 interesting, hmm, I could have sworn this didn't work with cygwin

23:32 WizardofWestmarc: lemme dig it up, note mine's mostly clojurebox

23:33 gnuvince_: thanks

23:33 It's a .exe, so I can't download it myself.

23:33 WizardofWestmarc: nod

23:35 hiredman: jline has issues with unicode

23:35 WizardofWestmarc: hm, the one in my home dir is my old clisp one, odd

23:36 blbrown: hiredman, I could have sworn there was a reason I used jline, hmm

23:37 ayrnieu: blbrown - the wiki talks about jline before it talks about rlwrap :-) But use rlwrap. It's much nicer, and I had problems with wrapping with jline.

23:37 hiredman: I switched to rlwrap cuase I like my unicode, and I kept forgeting about jline messing up unicode and going "OH MY GOSH, CLOJURE BUG!!!"

23:37 blbrown: is rlwrap a java application. I would need something cross platform

23:38 gnuvince_: blbrown: it's C

23:38 But again, why do you need that if you got Emacs?

23:38 hiredman: cmd.exe seems to just give you some of the line editing stuff for free without jline or rlwrap

23:39 blbrown: hiredman, on XP?

23:39 hiredman: yeah

23:39 blbrown: is there a function to detect an objects type, I guess a better 'instanceof'

23:39 hiredman: ,(class '())

23:39 clojurebot: clojure.lang.PersistentList$EmptyList

23:40 blbrown: should I know the api by heart before asking these questions, thanks that you guys are nice

23:40 gnuvince_: According to many messages I've found, slime-interrupt doesn't work with Clojure apparently

23:40 lisppaste8: WizardofWestmarch pasted "from clojurebox .emacs file" at http://paste.lisp.org/display/75502

23:45 gnuvince_: Nope, doesn't work :-/

23:45 Thanks anyway

23:46 WizardofWestmarc: weird

23:46 do you get an error or the like?

23:48 and does C-c C-k work?

23:48 gnuvince_: No errors

23:48 It just doesn't do anything

23:48 WizardofWestmarc: wait

23:48 is the buffer named blah.clj?

23:48 it only works if it's a file with a clojure extension

23:48 gnuvince_: Usually, I try to stop something I've ran directly in the slime repl

23:49 * WizardofWestmarc found that out the hard way.

23:49 WizardofWestmarc: hm

23:49 yeah if the file you are editing and attempting to partial compile has the right extension, I'm at a los

23:49 *loss

23:50 gnuvince_: Yeah, nothing there.

23:50 And I don't have C-c C-k bound.

23:50 WizardofWestmarc: nod

23:50 I really like that one for when I'm doing continual work that I'm not full compiling into .class files

23:55 gnuvince_: What is it bound to?

23:56 WizardofWestmarc: C-c C-k? I'd need to look up the command, but it's compile-file

23:56 gnuvince_: ah

23:56 I usually just C-c C-c every defn I want

23:57 WizardofWestmarc: nod

23:57 gnuvince_: Hmmm

23:57 WizardofWestmarc: the second is just when I know I want eeeeverything and it's a lot of forms

23:57 gnuvince_: C-c C-k would be much faster ;)

23:57 thanks for the tip ;)

23:59 Next step: finding how to get my app to be faster

Logging service provided by n01se.net