#clojure log - Oct 18 2008

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

0:02 AWizzArd: Btw, are there any mechanisms in Clojure to control for weighting the importance of parallelism for specific functions? Or does the jvm mostly care about this automatically?

0:05 rottcodd: is it considered bad style to compare numbers with = ?

0:05 Chouser: rottcodd: nope, that's good.

0:05 rottcodd: so when would I use == ?

0:06 Chouser: AWizzArd: I don't think Clojure has anything like that, but I wouldn't be shocked if there was something in the Java libs for that.

0:06 rottcodd: oh. well, perhaps I don't know what I'm talking about.

0:09 AWizzArd: although (= 1 1.0)

0:09 pjb3: = means are the things equal, equivalent, in the Java sense, a.equals(b)

0:09 == means are the references to the same exact object in memory

0:10 so Java ==

0:10 (== "foo" "foo") is false

0:10 Chouser: if you're working with primitives, you can get unboxed compares with == and not with =

0:10 pjb3: (= "foo" "foo") is true

0:10 AWizzArd: I think == will only work for number objects

0:11 Chouser: if you really want object identity comparison, you should use (identical?)

0:11 AWizzArd: (== true true) ==> false

0:11 Chouser: heh

0:11 AWizzArd: and the documentating explicitly talks about numbers

0:12 it just doesn't produce an error

0:12 although in principle it's a type error

0:12 Chouser: so back to the original question of = being bad style for numbers, I'd like to revise my answer to: I don't know. :-)

0:13 AWizzArd: I think = is not bad style, but it is not good style.. maybe an "well, okay"-style

0:13 (== a b) tells your reader that a and b are numbers

0:14 pjb3: I don't know what == is, I assumed it was identical?, but it's not

0:15 AWizzArd: pjb3: == checks for mathematical identity for any number of number arguments

0:15 pjb3: java .equals is clojure =, java == is clojure identical?

0:15 Chouser: == is Numbers.equiv

0:15 AWizzArd: so CLJs == is CLs = it seems

0:16 while CLJs = seems to be CLs equal

0:16 while CLJs identical? is CLs eq

0:16 Chouser: yes, identical? is Java ==

0:16 AWizzArd: genau

0:17 Chouser: clojure == uses Java ==, but it appears to do other work as well.

0:17 (identical? 5 5.0) -> false but (== 5 5.0) -> true

0:19 AWizzArd: yes

0:20 like eq in Lisp

0:20 Chouser: from what language do you come from?

0:22 Chouser: hm... a few. pascal C++ python ruby javascript and such. nothing exotic.

0:22 no haskell. I've dabbled with CL, Ocaml, Scala, but none of them stuck.

0:23 AWizzArd: ic

0:25 btw, can a function defined via #(...) refer to itself?

0:25 Chouser: nope

0:26 It could recur though, I suppose.

0:28 yeah, recur works, but there's no name it can use for itself

0:28 I'm off to bed. See you folks later.

0:28 AWizzArd: I also

0:28 6:25 here in Germany

0:28 n8 n8

0:31 crathman: question from an absolute newbie... before I post it, is there a preferred place to put code snippets around here?

0:31 asbjxrn: paste.lisp.org

0:32 AWizzArd: yes: http://paste.lisp.org/new/clojure

0:32 lisppaste8: Chris Rathman pasted "cond in clojure" at http://paste.lisp.org/display/68729

0:33 crathman: ok. so what am I missing in trying to use cond? I get a cast error in trying to run the code

0:34 (probably to scheme-ish since it comes from sicp)

0:35 dudleyf: crathman: Too many parens

0:35 rottcodd: remove parens around each clause

0:35 AWizzArd: crathman: look at the example here: http://blog.thinkrelevance.com/2008/8/26/java-next-3-dispatch-2

0:35 headline "Clojure's cond function"

0:36 lisppaste8: dudleyf annotated #68729 with "corrected" at http://paste.lisp.org/display/68729#1

0:36 AWizzArd: crathman: coming from CL?

0:37 crathman: not CL. I know just enuf scheme to be dangerous.

0:37 AWizzArd: ;-)

0:37 crathman: hobby project to translate sicp to other languages. been wanting to learn a little more about clojure. so I've combined the two.

0:38 AWizzArd: the price you have to pay for saving these parens is that you need to embed a body of code into a (do ...) if you want some side effects in a cond

0:39 crathman: thanks for the help all

4:24 nullstyle: hi all, I've got a super noob question...

4:24 Given a vector (or any sequence, ideally), can I get clojure to use the values in that sequence as arguments to a function?

4:24 For example, how would I get the minimum value in a vector? (min [3 1 2]) return [3 1 2]

4:26 tWip: well you could use apply

4:27 nullstyle: sweet, that worked. thanks

4:27 * nullstyle is a fish out of water

6:35 meredydd: Is there a straightforward way of testing whether a value is an array?

6:36 or is this the best I can do? (defn array? [x] (.. x (getClass) (isArray)))

6:37 tWip: looks pretty straightforward to me

6:38 just out of curiosity. why do you need to test for that?

6:39 meredydd: I'm just worried about the performance hit - there's a general acknowledgement that Reflection Is Slow - dunno how much slower that was than an 'instanceof' check.

6:39 (the penalty won't be as nasty as for method calls, that's for sure

6:39 trebor_home: what does it mean clojure makes them jvm dynamic? jvm = java virtual machine?

6:39 tWip: yes, but if you call Java, you should know by signatures if something returns an array

6:40 meredydd: I'm getting a result from an XML-RPC library. XMLRPC arrays come in as arrays, structs as HashMaps, and primitives as their appropriate types.

6:40 XML-RPC is dynamically typed - there's no way of telling what you're getting.

6:41 tWip: but if you are doing remote calls, a simple array check isn't going to be your bottlenek

6:42 meredydd: You're right, of course. I just didn't want to do it the ugly way if there were a better way.

6:44 trebor_home: oh, i was confusing clojure with another lisp, sorry. shoul have been googling before asking.

6:44 tWip: trebor_home: really? which one? :)

6:49 trebor_home: i thought of an macos-lisp ;)

7:12 tWip: btw if anyone is using webjure, the latest svn version works with the latest clojure

7:25 meredydd: Hmm. New question: What's the best way to do a rounded/truncated division in Clojure?

7:26 There appears not to be a (floor) or (ceil), and I can't use the Math.xxx() functions because they don't support Clojure rationals.

7:29 Lau_of_DK: Can you give an example of your calculation that needs flooring

7:33 meredydd: Lau_of_DK: I want to get from (/ 15 4) to 3.

7:34 Lau_of_DK: And why isnt this good enough?

7:34 user=> (Math/floor (/ 15 4))

7:34 3.0

7:34 meredydd: 1. That gives me a float, not an integer

7:34 2. If I understand correctly, that loses the Clojure nice-friendly-bignum support

7:35 Lau_of_DK: 1. So wrap it in (int ) ? 2. Not sure about it. I've only just Int/Double so far :)

7:35 meredydd: (which isn't a showstopper in this particular instance - for now, I've been using (.intVal (/ 15 4)) - but gives me a feeling there should be A Better Way)

7:36 Lau_of_DK: I'll stand back and let some of the olders guys here answer :)

7:40 arbscht: Math/floor is not necessary if you're going to wrap in int, surely? (int 15/4) => 3

7:42 rhickey: what's the question? 15/4

7:42 re: 15/4

7:44 arbscht: achieving floor and ceil behaviour on rationals and returning integers, I think

7:45 rhickey: (quot 15 4)

7:46 (quot (.numerator x) (.denominator x))

7:48 Lau_of_DK: Is there something similar to (pop list) for sets ?

7:49 rhickey: Lau_of_DK: pop is a sequential notion, which item would you 'pop' from a set?

7:49 Chouser: Lau_of_DK: you want to remove a specific one, or just iterate through the set?

7:49 Lau_of_DK: Right... :) I actually need to drop the last-one inserted

7:49 But I just remembered that theyre sorted

7:49 rhickey: Lau_of_DK: only if it is a sorted set

7:50 Lau_of_DK: Basically, I need to check if there are 2 hits of a number, so tht (contains? myset 5) only gives me half the story

7:51 But this is actually to patch a flaw in my loop that I think I can fix now, so nevermind

7:51 Dumb question :P

8:17 dmiles: the sorted set exists so i can pop items off the set knowing i am am going to pop in a sorted order?

8:17 this way i can know if my last item was greater then any of my current members.. i can stop pooping since the search is done?

8:18 oops.. popping

8:18 Lau_of_DK: lol :)

8:18 Im glad Im not the only one who can make a "mess" of things, haha! :)

8:19 dmiles: an unsorted set retains order in which the items are pushed?.. is a hash set any faster then a set that is sorted and se4arch in 1/2ing manner?

8:20 i guess what i believe a hashset is useless when you already have sorted sets

8:21 since a sorted set is always faster than a hashset i think

8:21 rhickey: dmiles: you don't usually search a set linearly, since the point of sets is to support better-than-linear search

8:21 sorted sets have a defined iteration order, hashed sets do not

8:22 dmiles: the divide by two search of a sorted set is fast as a hashed set right?

8:22 Chouser: but if you wanted all the items in a group that are less than x, a sorted-set would do quite nicely.

8:22 rhickey: see subseq and rsubseq as well

8:23 Chouser: hm, I guess filter would do even better in many cases.

8:23 dmiles: i guess what i am wodering what the use of an unsorted set

8:23 rhickey: Chouser: no, if sorted subseq is better than filter

8:24 dmiles: unsorted (hash) set should be faster, also doesn't require comparable elements

8:24 dmiles: rhickey, ah right the type of elements that really cant be sorted

8:25 rhickey: that's why the hashed variants are the defaults

8:28 Lau_of_DK: I optimised my decimal expansion routine to use sets instead of a list that concattet results on with a helper function fdigit. This improved performance by 430%

8:29 Chouser: (.bar x) does different things depending on whether (class x) has a function bar or a field bar, right?

8:29 rhickey: Chouser: yes

8:30 dmiles: prefering the method ? (C# would have inspired the callling of a getter method)

8:31 Chouser: and that is resolved at compile or runtime, just like other host-calling resolution (based on type hints)?

8:33 cljs has been assuming they're always fields unless parameters are given. Incorrect.

8:35 lisppaste8: Lau_of_DK pasted "Decimal expansion (faster)" at http://paste.lisp.org/display/68737

8:35 dmiles: ((.bar x-the-class) x-the-instance) ?

8:35 Lau_of_DK: I know that result would probably be better suited as a vector. But besides from this, if somebody has a fantastic insigt in how to could be refactored I'd love to hear it

8:36 AWizzArd: 'lo

8:36 rhickey: dmiles: yes, favors method

8:37 lisppaste8: Lau_of_DK pasted "Decimal expansion (faster)" at http://paste.lisp.org/display/68739

8:41 rhickey: Chouser: It's resolved to a method at compile time if I can find one, if I can't but can find field. resolves to that (note this may miss a method of the runtime type), else reflection preferring method

8:42 dmiles: getMethods()/getFields()/getDeclaredMethods()/getDeclaredFields() order?

8:45 AWizzArd: rhickey: does the use of apply make a function call less efficient? So (apply foo arg1 arg2 10 20 more) vs (foo arg1 arg2 10 20 arg3 ... argn)? This could matter if we map over gigabytes of data and need to call apply millions of times vs calling the function with its fixey number of args directly.

8:52 I just see that "more" needs to be unpacked... the other (- n 4) args

8:55 rhickey: dmiles: it's not that simple, as Clojure doesn't know the actual type of the target

8:57 AWizzArd: there's some overhead to apply, but your calls above are not right, it's (foo x y z) or (apply foo some-collection-of-args)

8:58 in the apply case, it might be more efficient to use apply if your args are already in seqs, for instance, rather than have to unpack the collection in order to make a fixed-arg call (it's likely you code to do so will be similar to what apply does already)

8:58 AWizzArd: ah okay, I thought of apply as CLs apply where the arguments don't have to be sequences and can be atoms instead

9:00 nevermind, it works like CLs

9:40 rhickey_: Rich, do you already have plans for "recur" when tail call optimization hits the vm? When it does recur is in principle not longer needed, is it? But removing it would break existing code...

9:41 Lau_of_DK: Its really amazing how slow lists are in Clojure. 500 fractions expanded took 75 secs with 2 lists, took 17 secs with 1 set and 1 list, and took 2 secs with 1 set and 1 vector, I get that to be 3500% improvement

9:41 rhickey_: Lau_of_DK: lists aren't slow, it's how you use them

9:41 Lau_of_DK: thanks :)

9:42 rhickey_: linear lookups are slow

9:42 Lau_of_DK: I had 1 really bad lookup, but other than that I was just using concat

9:42 and yea, I removed a linear lookup

9:42 But lists are supposed to perform like sets and vectors ?

9:42 rhickey_: same thing - its about picking the right tool for the job

9:43 Lau_of_DK: okay, good to know :) Thanks

9:44 rhickey_: lists and sets and vectors all have very different performance characteristics for different operations

9:46 lisppaste8: Lau_of_DK annotated #68739 with "anyone faster?" at http://paste.lisp.org/display/68739#1

9:52 Lau_of_DK: rhickey_, have you written some material on these differences?

9:54 AWizzArd: a faq on this could be nice, but in general wikipedia offers some basic insight

9:55 rhickey_: Lau_of_DK: it's not specific to Clojure - see any CS book on data structures, or: http://en.wikipedia.org/wiki/Data_structure

9:55 Lau_of_DK: Okay, thanks to both of you, I'll have a look

9:56 AWizzArd: maybe one day the jvm will host an AI system which will substitute your used datatype with something that is most appropriate :-)

10:00 rhickey_: Rich, do you already have plans for "recur" when tail call optimization hits the vm? When it does recur is in principle not longer needed, is it? But removing it would break existing code...

10:01 rhickey_: recur will remain, and has utility. It can be simpler and clearer than a nested fn, and will have tail-position checks where ordinary recursive calls cannot. Many people actually like it for those reasons.

10:02 lisppaste8: hoeck annotated #68739 with "lazy decimal expansion" at http://paste.lisp.org/display/68739#2

10:04 Lau_of_DK: uuuuh thats trixy Hoeck - Thanks alot!

10:04 AWizzArd: what I like about recur is that it allows me to recurse over anon functions (without having the y-combinator at my hands)

10:05 Chouser: where "many people" == "Chouser" ?

10:05 hoeck: Lau_of_DK: you know, i guessed your problem wrong the first time, and then stepped in some kind of turingtarpit and couldn't resist

10:05 Lau_of_DK: haha

10:05 Dont I know that feeling :)

10:05 hoeck: : )

10:06 Lau_of_DK: Have you benchmarked it in comparison with my func ?

10:08 hoeck: yes, yours was about 8s, mine about 2s

10:08 Chouser: about 4 times the speed here.

10:08 ooh, consistant. :-)

10:08 hoeck: haha

10:08 Lau_of_DK: nice... I'll return later with questions as soon as the jealousy dies down

10:08 (kidding)

10:15 AWizzArd: length of a sequence: (reduce (fn [x y] (+ x 1)) 0 [10 20 30 40]) ==> 4. Good, works. Why does (reduce #(+ %1 1) 0 [10 20 30 40]) produce an error: Wrong number of args passed to: eval--2465$fn

10:17 Chouser: reduce passes in two args, but the highest number of % in your #() is 1, so that little function only takes one arg

10:17 AWizzArd: right

10:23 nvteighen: Hi

10:23 Chouser: hi

10:24 nvteighen: I'm a Scheme guy, but got interested on Clojure

10:24 AWizzArd: excellent choice nvteighen

10:24 nvteighen: Which one?

10:24 Chouser: Funny, you'll probably find lots of people who like Clojure in the #clojure channel. :-)

10:24 AWizzArd: to be interested in Clojure

10:25 Chouser: and several who've come from scheme, for what it's worth.

10:25 nvteighen: Well, that was what I wanted to ask here...

10:25 AWizzArd: would it make sense to make reduce lazy? (take 5 (reduce + (cycle [1 2 3 4 5]))) currently doesn't terminate

10:26 nvteighen: I got the impression Clojure shares a bit the Scheme philosophy... The Lisp-1 idea is very attractive

10:26 Chouser: AWizzArd: reduce is going to return a single value. take doesn't make sense there.

10:27 AWizzArd: right

10:28 Chouser: so no, it wouldn't make sense for reduce to be lazy.

10:29 AWizzArd: stupid me, I got a Haskell guy tricking me into thinking that foldr is lazy and works on infinit sets

10:30 rhickey_: AWizzArd: laziness in Haskell is completely different

10:30 AWizzArd: without further thinking I expected this to be true, but now I wonder what (reduce + natural-numbers) should yield

10:32 rhickey_: AWizzArd: a very warm computer

10:32 AWizzArd: *g*

10:33 nvteighen: Does Clojure support something like Scheme streams? That would ease it...

10:33 rhickey_: but folds over infinite lists yielding infinite lists can be done easily with the lazy seq functions

10:34 nvteighen: that is the normal way Clojure seq functions work - no separate streams lib needed

10:34 AWizzArd: rhickey_ do you have a small example?

10:34 nvteighen: Oh, great!

10:34 rhickey_: user=> (take 15 (cycle [1 2 3 4]))

10:34 (1 2 3 4 1 2 3 4 1 2 3 4 1 2 3)

10:34 AWizzArd: yes ok

10:43 Chouser: maybe an example like this, for adding the 30 first numbers of an infinite sequence: (reduce (fn [x y] (if (> x 30) 0 (+ x y))) (cycle [1 2 3 4 5]))

10:43 I know that one can express it in a way that makes much more sense

10:44 (apply + (take 30 (natural-numbers)))

10:47 well, it doesn't matter too much

10:53 Chouser: AWizzArd: sorry, what are you asking?

10:56 AWizzArd: what I gave was an artificial example on how lazyness could work... but that would be more the Haskell way, and there lazyness is different, as Rich already said

11:36 Where in the source (path) is the reader macro #(...) implemented

11:36 ?

11:38 Chouser: LispReader.java line 531

11:39 AWizzArd: thx

12:11 rhickey_: yay - cgrand is back blogging about Clojure!: http://clj-me.blogspot.com/2008/10/clojure-golf-combinations.html

12:20 Chouser: *sigh* he cut my "combinations" in half. I spent an hour on mine.

12:21 rhickey_: so is genclass going away soon enough that you don't want minor patches to it?

12:22 rhickey_: Chouser: it's pretty, isn't it?

12:23 Chouser: I'm still pondering it. Lisp is amazing in its density.

12:23 rhickey_: Chouser: I'd rather everyone interested in genclass think about this - every ns is going to become a class def - with metadata we can annotate the .clj in plac eto designate fns as methods etc - what should those annotations be to cover the genclass use cases?

12:25 Chouser: I'm not very deep into genclass, but I did have a (load) use case I was curious about -- will that ability be going away?

12:31 rhickey_: gotta run

12:33 Chouser: yeah, wow. I simply couldn't have come up with cgrand's "combinations".

12:33 rhickey_: ok, see ya

12:38 AWizzArd: What are genclasses in short?

12:44 Chouser: cgrand: your "combinations" humbles me.

12:44 AWizzArd: I am also playing with it right now :-)

12:45 Chouser: AWizzArd: genclass creates a new named Java class with constructors and methods implemented to call Clojure fns.

12:46 AWizzArd: so genclass is only interesting to people who plan to switch the language or make their lib available to non-Clojure hackers, yes?

13:01 Chouser: primarily the latter, though there are some other places where you need a .class file or need to implement a method that's not defined in any interface.

13:02 to make a servlet, for example, you need an actual .class file.

13:02 AWizzArd: i see

14:02 Lau_of_DK: could somebody bring me up to speed on this parallel computing that people are talking about, and how it ties into clojure?

14:02 AWizzArd: What do you mean?

14:03 Lau_of_DK: I mean, cgrande talked about parallelizing primes, and clojure has a parallel.clj if I remember correctly, and I dont really know what either of them is

14:11 AWizzArd: In Clojure there are no side effects. That means in principle it can run most functions calls on any available cpu/core.

14:15 So it means: if you write your programs in Clojure it is likely that a lot of your code will run in parallel on several cpus. This comes in handy, especially because intel said that in a few years 100 cores per cpu will be typical.

14:17 Lau_of_DK: so paralellism is the tool to make sure that everything starts and finishes like it should?

14:18 AWizzArd: If functions run in parallel they run at the same time. Just think about people.. they all can think independently and do things at the same time. While I am breathing you can do the same.

14:19 arbscht: is it really reasonable to say, "clojure has no side effects"? I prefer to say, "clojure has immutable state"

14:22 AWizzArd: yes, I like this also more

14:25 Lau_of_DK: and the advantage of all that is that your programs will run faster in many situations. Of course it depends on what you are doing

14:25 Lau_of_DK: yea, I mean, its basically multi-threading isnt it ?

14:26 AWizzArd: yup

14:26 concurrency, parallelism, multi-threading, etc

14:26 if you are writing data to a file it makes no sense if 50 threads want to write at the same time, because you usually want to keep it in order (the stuff you write to the file). So, when you are doing side effects often you will not win from multi-threading.

14:27 Lau_of_DK: Thats true

14:27 AWizzArd: But if you are doing Genetic Programming and have thousands of programs for which you want to find out their fitness it makes totally sense

14:27 for some tasks doubling the number of cpus will double the efficiency of your Clojure program

14:28 Lau_of_DK: Maybe I should be a new computer and experiment :)

14:28 AWizzArd: now the really fine thing is: you don't need to work very hard to get Clojure running your code on all these cpus

14:28 don't worry Lau.. you will soon enough have access to tens of cores. A 70$ processor will have tons of them

14:29 Lau_of_DK: You mean because the dollar is dropping so hard? :)

14:30 AWizzArd: since about 100 years the number of calculations per timeunit in a cpu grows hyperexponentially

14:31 at the moment you can give the conservative estimation that the calculation power that you can buy for 1000$ doubles every 12 months (says Ray Kurzweil)

14:31 Lau_of_DK: The rule used to be every 18 months right?

14:31 AWizzArd: no, that is moores law

14:31 Lau_of_DK: oh ok

14:32 AWizzArd: that talks about the amount of transistors

14:32 while Kurzweil discusses the price performance

14:32 but this is really very conservative

14:32 he says: every 10 years you have 1000x as much computational power

14:33 Lau_of_DK: Its beyond my imagination what all that horsepower will be used for

14:33 I know that the UN has had a supercomputer for years now, that sinked in liquid coolant (hydrogen I think), and I cant imagine what they might need that type of processingpower for

14:33 AWizzArd: but just take a look at http://en.wikipedia.org/wiki/FLOPS and see: 1997 one gigaflops cost 30.000$. In October 2007 the price was less than 50 cents per gigaflops. That means the priceperformance changed by a factor of 60.000, not 1000

14:34 around 2012 the fastest super computer will reach +/- the calculation power of a human brain. In 2023 a desktop cpu for 1000$ could do the same.

14:35 Lau_of_DK: Crazy - Thanks alot for all the info - Now we better get back to the topic: Clojure! :)

14:36 AWizzArd: Kurzweil continues calculating with his conservative interpolation and finds: in 2037 one can buy human brain capability for around one cent. In 2049 we have human race capability for around 1000$ and in 2059 a cpu which calculates as fast as all brains of all humans on this planet would cost around 1 cent.

14:51 Lau_of_DK: I've seen an example of firing up a Jetty webserver with dynamic content. Not knowing anything about Jetty, how difficult would it be to enable such a server to run PHP ?

14:51 AWizzArd: Depends on how good you are.

14:52 PHP is turing complete... Someone like Data could probably write something like Linux in it within a few seconds ;-)

14:53 Lau_of_DK: Sure, but he'd get all pale in the process

14:53 Is it a huge task, or is it a matter of stuffing Jetty with modules ?

14:55 walters_: there is an implementation of PHP for the JVM, but really it's an awful language. Something like Groovy or JRuby is going to be a lot nicer. Or even Clojure

14:57 Lau_of_DK: ok :)

14:57 AWizzArd: Why Groovy or Ruby when you can have Clojure? :-)

14:57 Lau_of_DK: I never really developed even half an appreciation of either Groovy or Ruby

14:57 mmcgrana: clojure has the advantage of being designed from the start to interoperate cleanly with the jvm, whereas e.g. in jruby java interop is still a big pain

14:58 AWizzArd: even if they were made with the jvm in mind (okay, this is true for Groovy), you still have the problem of finding out how to do multi-threading

14:59 mmcgrana: you mean how to get good concurrency semantics or how to just implement threading?

15:00 AWizzArd: 1st

15:00 getting threading itself should be cheap when the jvm already offers it

15:01 mmcgrana: right ruby's pervasive statefullness is brutal, even the class/module model gets mutated all over the place so you can't reason about that

15:01 AWizzArd: maybe with Groovy it is better, but Groovy is still an imperative language in the first place

15:02 in Clojure parallelization is trivial and mostly automatic

15:02 I mean, in principle whenever we see a function call that guy could run on its own core.

15:03 Lau_of_DK: Are there any larger project under development atm, in clojure ?

15:03 AWizzArd: The biggest is probably Clojure itself

15:04 As soon I have time I will implement my Genetic Programming system in Clojure. Currently I have it in Lisp, so most of my code already is nearly there. But that is nothing really big.

15:04 mmcgrana: all clojure programmers need to read boot.clj - pretty awsome; otherwise there is alt-law which is pretty big (http://github.com/lawcommons/altlaw-backend/tree/master)

15:05 i also suspect that there are several super-stealth startups that don't even wan't people to know that they are using clojure. I do wish that there were more open source clojure projects.

15:05 That first bit I didn't pull out of a hat, Rich at one point mentioned clojure users that he couldn't talk about.

15:06 AWizzArd: mmcgrana: yes, it is very good, and today I started reading it (only found Clojure on Thursday night)

15:06 Lau_of_DK: Thanks mmcgrana

15:06 walters_: interesting, a combination java/ruby/clojure project

15:06 mmcgrana: yeah very polygot

15:09 Lau_of_DK: Does anybody have some Clojure thoughts on this: http://projecteuler.net/index.php?section=problems&id=28

15:12 mmcgrana: haven't done it, though you might try generating a lazy seq of the x,y cords of the successive number locations, the use range for the sequence of numbers, then reduce pairs of these against an initial empty vector of vecotrs for the board

15:12 i haven't considered the posibility of a non-computational solution, though i tend not to when using these problems as programming practice

15:16 Lau_of_DK: I try to keep both in mind, though Im not quite sure I follow your approach

15:17 mmcgrana: well you actually just need to keep track of the values that fall on the diagonals. the idea is to generate the sequence of x,y coordinates on the board, then associating each successive one with a correspondingly incremented integer. when such an x,y is on a diagonal, record it and continue. you could use loop instead of reduce prop. i'll try it myself too...

15:18 Lau_of_DK: k, cool, Eulers are fun

15:18 achim_p_: Lau_of_DK: if you don't want to brute force, you might consider asking sloane

15:18 Lau_of_DK: and as an added bonus in Clojure, theyre both fun and frustrating :)

15:19 achim_p_, sloanes our strategist ?

15:19 achim_p_: http://www.research.att.com/~njas/sequences

15:19 http://www.research.att.com/~njas/sequences/?q=1%2C3%2C13%2C31&language=english&go=Search

15:20 AWizzArd: Has Rich said anything about the general efficiency hit that Clojure takes, compared to pure Java programs?

15:20 mmcgrana: lol nice

15:20 Lau_of_DK: achim_p_, thats a pretty sick site

15:23 achim_p_: exactly what you need for project euler - did i mention that i hate number theory? ;)

15:24 Lau_of_DK: no you didnt

15:24 I think its fun

15:24 That page qualifies as cheating though, 80% of the fun is finding the right approach :)

15:25 AWizzArd: would it make sense if (seq 'abc) ==> "abc" or (\a \b \c) ?

15:27 arbscht: what's your justification for either of those?

15:27 Lau_of_DK: (\a \b \c) would make the most sense

15:27 AWizzArd: one could see that a symbol is a sequence of characters

15:28 as a string is also not atomic, but a container

15:29 arbscht: I'd say a symbol's name is a sequence of characters

15:29 Chouser: A symbol suggests more meaning than just its list of chars, though you can (str 'abc)

15:29 arbscht: what would (seq 'my/foo) return?

15:29 Chouser: arbscht: right! (name 'abc) -> "abc"

15:30 (seq (name 'abc)) -> (\a \b \c)

15:30 AWizzArd: it could be either the same as (seq (name 'my/foo)) or (seq "my/foo")

15:31 Chouser: I can't say I've ever wanted the sequence of chars that make up the name of a symbol.

15:34 arbscht: AWizzArd: for the latter case, there is (str 'my/foo). for the former, there is exactly what you wrote, seq of the name

15:34 for the latter, seq of (str ..), I mean

15:36 I think it would be confusing to have seq prefer one of the two

15:41 Lau_of_DK: Where did Rich hide (pow x n) ?

15:41 arbscht: Math/pow

15:41 Lau_of_DK: eww

15:41 thanks

15:43 mmcgrana: math.clj: http://groups.google.com/group/clojure/browse_frm/thread/d07b93e26b2f0f06

15:43 Lau_of_DK: What is the syntax if I want to do something like (mapcat #(Math/pow % %) (range 5) (range 5)) ?

15:44 mmcgrana: why 2 ranges if they are the same?

15:44 Lau_of_DK: because they wont be the same in the actual program

15:44 mmcgrana: note 2-arg fns need e.g. %1 and %2

15:45 Lau_of_DK: this works: (take-while #(<= (* % %) n) primes)

15:45 AWizzArd: Lau_of_DK: maybe you want (map #(Math/pow %1 %2) (range 5) (range 5)) ?

15:46 Lau_of_DK: AWizzArd, works, thanks. I thought map and mapcat operated more along the same lines

15:46 AWizzArd: nearly

15:47 try (map #(list %) (range 0 5)) and then mapcat

15:48 you can think of mapcat having a "flattening effect". Look at the boot.clj to see how mapcat is implemented

15:49 mapcat runs map and then runs concat on maps result

15:50 Lau_of_DK: I guess I really should reat that boot.clj

15:56 meredydd: Heya - Compojure question

15:57 There's what looks like a tiny bit of glue code between Jetty's cometd and Compojure

15:57 but I'm having trouble figuring out how it all works.

15:57 Does anyone have any pointers and/or examples?

16:02 AWizzArd: Anyone here running emacs and http://clojure.codestuffs.com/ ?

16:04 Lau_of_DK: Yes sir

16:06 For those of you who have solved Euler 29, compare the 1.st C solution in the forum, to this

16:06 (defn euler-29

16:06 [min max]

16:06 (count

16:06 (apply sorted-set

16:06 (for [x (range min (inc max)) y (range min (inc max))]

16:06 (Math/pow x y)))))

16:11 ...and eh... then be impressed

16:12 mmcgrana: heh nice

16:19 arbscht: is it necessary to sort it? would distinct not suffice?

16:19 Lau_of_DK: it sure would

16:27 Has anyone found some clever uses for (partition )

16:31 duck1123: is let what I should be using for local variables inside a fn?

16:31 Lau_of_DK: yes, probably

16:31 duck1123: or is there a better choice?

16:31 Hun: that depends

16:31 duck1123: def just does globals, right?

16:32 Hun: in most lisps you usually want let

16:32 otherwise you'll know

16:33 Lau_of_DK: let wont let you down

16:33 Hun: oh noes. here comes the let-roll

16:33 duck1123: thanks. I'm prompting the user for values, and I was a little worried about how many lets I might need

16:34 Lau_of_DK: cant you just pass them directly?

16:34 like

16:34 (defn prompt-for-cd []

16:34 (struct

16:34 cd

16:34 (prompt-read "Title")

16:34 (prompt-read "Artist")

16:34 (parse-integer (prompt-read "Rating"))

16:34 (y-or-n-p "Ripped [y/n]")))

16:35 duck1123: hmm... good idea

16:36 I'm just today really getting started using clojure for more than (+ 1 1)

16:36 Lau_of_DK: coming from what ?

16:36 duck1123: Java, but more recently Ruby

16:36 Hun: coming from CL it feels a bit weird, but i kind of like it

16:37 Lau_of_DK: Ah sweet, well enjoy the ride, to me Clojure felt extremely up-hill in the beginning, I couldnt wrap my skull around functional programming, but you reach a point where the learning curve is pretty satisfying

16:37 duck1123: my lisp experience is from configuring emacs and stumpwm

16:38 Lau_of_DK: and to be frank, nowadays I cant really sit down with anyother language than clojure anymore

16:38 Hun: Lau_of_DK: i have the complete opposite problem. i still don't know how to use the java documentation properly...

16:39 Lau_of_DK: oh.. well that shouldnt take you very long to dive into

16:40 duck1123: can a slurped file be used as an InputStream?

16:40 Hun: coming from CL, i definitely miss apropos. you can do a (apropos "something") and it gives you anything containing something

16:41 Lau_of_DK: Yea we dont quite have that feature yet I think

16:41 duck1123: Hun: what about (find-doc)

16:41 Lau_of_DK: But my main complaint (except the debugger) is actually documentation

16:41 Like with C# you can basically sit a complete beginner down in Visual Studio and between the help and Intellisense, he'll pick up all he needs while working

16:41 In clojure however, I come to a complete stop everytime Im lacking some detail

16:42 Hun: i don't have clojure handy right now (i'm on my big pc), so i can't answer now. i'll look at it on monday

16:43 duck1123: as much as I hate them sometimes, I wish the clojure api page used frames like (ruby|java)doc

16:43 Hun: Lau_of_DK: i get turned into a complete moron sitting on (VS, eclipse, xcode, ...). i try that about once a year, but i always get baffled by the UI and crawl back to my good old emacs

16:44 Lau_of_DK: Youre the 2.nd person Ive heard say that. Its very weird because VS is made intuitively easy I think

16:44 Hun: i kind of integrated javadoc-mode, so i at least have an apropos for classpath

16:44 duck1123: javadoc-mode you say?

16:44 where can I find that?

16:45 Hun: that's an emacs-mode for searching through javadoc

16:45 hmm... must have memorized the wrong name

16:45 one moment

16:48 http://sourceforge.net/project/showfiles.php?group_id=219831&package_id=265324

16:48 i think this was it. not sure though

16:53 Lau_of_DK: maybe that's caused by me having used emacs a few years before my first contact with `proper' IDEs (with qbasic and comal in the 90s)

16:54 Lau_of_DK: It could be that, sure :) I'm also thinking genetics maybe

16:54 Hun: i also like the lispy/smalltalky way of doing things on live programs. just about all of the mainstream langs and IDEs force you in the hack/compile/test/debug-circle

16:56 especially trying to find out why a crashed program has crashed is evil there. in image-based systems you'll get thrown in the debugger right where it crashed and can examine everything. everywhere else your world dies and you got to reconstruct it

16:56 duck1123: I used VS and Eclipse forever until I "discovered" emacs

16:56 haven't looked back since

16:57 Hun: does the mode you use open a browser, or does it display it in a buffer?

16:57 Hun: both

16:57 it opens in a browser which (in my config) runs inside a buffer

16:57 hail w3m

17:01 duck1123: ok, this is pretty nice, thanks

17:13 Lau_of_DK: was (prompt-read) something you just made up, or is that a function somewhere? (not in core api)

17:13 Lau_of_DK: duck1123, http://blog.thinkrelevance.com/2008/9/16/pcl-clojure-chapter-3

17:14 reading this, http://projecteuler.net/index.php?section=problems&id=31, Im thinking there must be some features in clojure to solve this, any clues?

17:15 mmcgrana: DK did you get 28 already?

17:15 Lau_of_DK: No I skipped it, I think 31 is more interesting

17:16 mmcgrana: i'm thinking "dynamic programming" but i could just be imagining things - does that make sense?

17:17 Lau_of_DK: no not really :)

17:17 I was thinking rotations, permutations and combinations

17:17 does that make sense?

17:17 mmcgrana: maybe, i'm not sure about either one

17:20 Lau_of_DK: mmcgrana, we should start by making a collaboratory clojure/euler tool

17:21 mmcgrana: Lau_of_DK: nice. I should probably do my actual math homework first though...

17:21 duck1123: did you notice that each diagonal increases by 2 each time?

17:21 I wonder if that pattern holds

17:22 mmcgrana: yeah sort of its like +2 +2 +2 +2 +4 +4 +4 +4 +6 +6 +6 +6 + ... i think

17:22 Lau_of_DK: duck1123, the diagonal is a little too easy, check out achim_p's link from before, it has a fomulae to compute all the numbers in the diagonal

17:23 duck1123: must've been before i entered the room

17:24 Lau_of_DK: <achim_p_> http://www.research.att.com/~njas/sequences

17:24 <achim_p_> http://www.research.att.com/~njas/sequences/?q=1%2C3%2C13%2C31&language=english&go=Search

17:45 rhickey, isnt this taking rounding a little too far? :)

17:45 user=> (/ 49 98)

17:45 1/2

17:48 arbscht: Lau_of_DK: what would you expect instead?

17:48 Lau_of_DK: im not that strong in non-trivial fractions

17:48 I just saw this

17:49 "The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8"

17:49 http://projecteuler.net/index.php?section=problems&id=33

17:51 bitbckt: ", which is correct, is obtained by cancelling the 9s."

17:51 that part is really quite important

17:51 arbscht: that 49/98 = 4/8 is not an incorrect belief. that it is obtained by cancelling digits is incorrect

17:51 yes

17:51 Lau_of_DK: oh that way round

17:51 yea I get it, thanks

17:53 blackdog: meredydd: i have some jetty/comet clojure code if you're interested?

17:54 meredydd: blackdog: I'm all ears

17:54 achim_p_: http://clojure-euler.wikispaces.com/ - from my very early clojure days. i quickly lost interest, but the wiki is open, so if anybody would like to contribute some (alternative) solutions, please do.

17:55 blackdog: ok, hang on

17:55 Lau_of_DK: achim_p_, and you said you hated number theory :P

17:56 achim_p_: yeah, i just did some easy ones

17:57 lisppaste8: blackdog pasted "cometd" at http://paste.lisp.org/display/68775

17:58 blackdog: meredydd: there's some bit's and pieces in there too from the jetty example in java, like echo

18:37 Lau_of_DK: There's a good chance that I've hit the point where I should just go to bed, but can you give think of a simpler/quicker way to do this

18:37 (defn pandigital?

18:37 [n]

18:37 (= (apply sorted-set (map #(Integer. (str %)) (str n)))

18:37 (apply sorted-set (map #(Integer. %) (range 1 (inc (count (str n))))))))

19:12 rottcodd: is there any convention to indicate that a map is intended to be an abstract type?

19:21 AWizzArd: Anyone here uses Clojure under Windows (Vista) in Emacs? I am having some problems there as it seems, no syntax highlightning in clojure-mode and some java exceptions after M-x run-clojure.

19:23 If you think you know emacs and slime quite good please have a look at my .emacs and the output that I get:

19:23 lisppaste8: AWizzArd pasted "Problems with getting Clojure running in clojure-mode in Emacs" at http://paste.lisp.org/display/68784

20:41 achim_p: AWizzArd: swank-clojure targets the svn version, not the latest release. *1, *2, *3, *e (which are causing your error) were added afterwards

20:42 AWizzArd: I see.. but to use the svn version of Clojure I would need something like this Maven thing yes?

20:43 achim_p: no, just ant

20:43 AWizzArd: I just found Clojure two days ago and had no time to work on my unix box and need to do all that stuff here under Windows

20:43 how can I use ant? Sorry, never worked with Java :-)

20:44 i have three directories from the svn: branches, tags, trunk

20:44 achim_p: have you got ant? then typing "ant" will do in the trunk dir

20:44 AWizzArd: do I need to cd into one of them?

20:44 achim_p: yes, trunk

20:44 AWizzArd: ah okay, let me see if ant is available for Vista

20:44 klingt gut :-)

20:47 achim_p: :)

21:41 _emjay: Starting from scratch, which books would you guys recommend as a path to Clojure enlightenment?

21:43 duck1123: do you know lisp?

21:44 _emjay: duck1123: A little. This is for someone else that only knows Java. I'm having a hard time trying to figure out a track for him.

21:44 duck1123: I would start with the video series

21:45 _emjay: I'd recommend PCL, but there's a lot of non-relevant stuff in there. The decisions to remove or rename things from Common Lisp make it hard to recommend lisp material.

21:45 AWizzArd: the book about Clojure will be out in March 2009 I think

21:45 duck1123: I was going to say PCL, there's a collection of posts that have translated the code into clojure

21:46 AWizzArd: PCL might be the best choice until then...

21:46 _emjay: Yeah, that's like 5 internet years! I'm hoping for a quick beta release.

21:46 duck1123: I think I'm going to have to buy that book

21:46 AWizzArd: duck1123: which one? PCL or the Clojure book?

21:47 the CLJ book would be this one: http://www.pragprog.com/titles/shcloj/programming-clojure

21:47 _emjay: PCL is available for free online.

21:48 duck1123: I was just at the book store today. I almost bought PCL in hardcopy, but my wife would kill me if I spent $50 right now

21:48 _emjay: From the author of Programming Clojure: "We'll go beta with five chapters before the end of the year."

21:50 AWizzArd: it's 50$ well spent

21:50 Why are it always our wifes who are the real bosses of our lifes? ;-)

21:51 _emjay: AWizzArd: Order from Amazon and have it shipped to your work. :)

21:51 AWizzArd: _emjay: I already have it.. so duck1123 should be doing exactly this *g*

21:52 duck1123: open up a secret banking account... for computer books

21:52 AWizzArd: r0ckz

21:53 _emjay: I usually hate buying programming books because they date so quickly, but CL is pretty old now and doesn't look to be changing any time soon, so PCL seems like a good investment.

21:55 AWizzArd: All in all Lisp is Lisp, so the dialect does not matter too much. The language itself is not overly important, but to understand the concepts. Going from C to Pascal is not too hard. Form C++ to Java or C# dito.

21:56 duck1123: I was reading it online, but it would be nice to have a real copy to read away from the computer

21:56 AWizzArd: Clojure is more similar to CL than it is different, so, PCL is not the worst choice to learn CLJ.

21:56 duck1123: Be a man, buy that book. For centuries didn't tell their husbands what books to buy or not.

21:58 For centuries wifes didn't ...

22:02 achim_p: thanks for your tip, indeed emacs+slime+clojure do now work, with the svn version of CLJ

22:04 duck1123: you might also want to get the git versions of slime, clojure-mode, and swank-clojure

22:04 cutting edge all the way

22:05 has anyone written a good primality test in clojure? I want to compare it with my attempt

22:05 AWizzArd: duck1123: I got this clojure-mode and swank-clojure stuff from http://clojure.codestuffs.com/ .. do you mean that?

22:06 duck1123: yeah, it looks like they point to the github versions

22:07 AWizzArd: duck1123: have you written a prime-tester in Java itself? Can you compare how much slower Clojure runs?

22:08 duck1123: i found one online

22:08 i can tell you that it is running pretty fast

22:08 know of a good big prime I can test?

22:09 AWizzArd: 6561557

22:12 duck1123: "Elapsed time: 22.494683 msecs"

22:12 AWizzArd: and is it a prime?

22:12 duck1123: yes

22:13 AWizzArd: how fast is 43054017141137?

22:14 lisppaste8: duck1123 pasted "My first attempt at a primality tester" at http://paste.lisp.org/display/68789

22:14 duck1123: false "Elapsed time: 37.01863 msecs"

22:14 you sure that's prime?

22:16 AWizzArd: I am not sure

22:19 duck1123: devisible by 101

22:19 divisible even

22:21 user=> (time (prime? 9997954969))

22:22 "Elapsed time: 1219.362989 msecs"

22:22 true

22:22 AWizzArd: not too bad I guess

22:22 duck1123: There's a better algorithm on wikipedia

22:23 I'm just trying to solve problem 10 on project euler

22:26 rpdillon: That's funny, I'm working on problem 4...

22:28 duck1123: it would be cool to gather all the code from the wiki and put it into a lib

22:30 ok, anyone know how to get a lazy infinite series of positive integers

22:30 I could've swarn there was a function

22:31 AWizzArd: duck1123: wouldn't (range 1 9999999999999999999999999999999999999999) be good enough for now?

22:31 arbscht: (iterate inc 1)?

22:31 AWizzArd: arbscht: thx

22:34 arbscht: duck1123: which wiki are you referring to?

22:35 duck1123: http://clojure-euler.wikispaces.com/

22:38 arbscht: I don't think most of that code is lib-worthy. more general functions become useful in the later euler questions

22:39 duck1123: I would never load it, but i would read it, eval stuff and steal good code from it

22:40 assuming we got most/all of the questions

22:41 arbscht: yes, I'm keen to see solutions in the 100-200 range

22:59 duck1123: If I need to sum a list, is apply what I need to be looking at?

22:59 I can't seem to get it to work

23:00 bitbckt: reduce

23:00 (reduce + [])

23:00 like so

23:01 duck1123: thanks

23:02 bitbckt: yup

23:02 AWizzArd: in the clojure-mode in emacs I can autocomplete functions via tab.. so (red<tab> ==> (reduce

23:03 but how can I autocomplete in a buffer where I edit my code.clj?

23:11 rottcodd_: AWizzArd: M-x where-is RET slime-complete-symbol RET

23:14 AWizzArd: oki, I will bind that then, thx

23:14 asbjxrn: Next up on that clojure-euler page should be how to sort numerically :)

23:15 rottcodd_: AWizzArd: there is also slime-indent-and-complete-symbol

23:16 AWizzArd: what about slime-fuzzy-complete-symbol?

23:19 duck1123: filter is lazy, right?

23:19 rottcodd_: that's one of the add-ons I don't use, if it doesn't depend on CL it might work, try it

23:20 duck1123: yes

23:21 duck1123: I'm trying to take an infinite series, filter for primes, then filter for those less than 10, and it's taking forever

23:22 bitbckt: filtering an infinite series on primes sounds like it would take forever

23:22 filter for less than 10, then filter for primes sounds more reasonable, to me

23:23 duck1123: I'm sorry, after that, I took 3

23:23 so I would think it should only have to calculate the 1st 3 primes

23:23 am i wrong?

23:24 switching the filters gives the same result

23:26 bitbckt: this is using the prime? function you were describing, above?

23:26 duck1123: yeah

23:29 lisppaste8: duck1123 annotated #68789 with "taking forever" at http://paste.lisp.org/display/68789#1

23:29 bitbckt: this works quickly: (take 3 (filter prime? (iterate inc 1)))

23:30 with the reduce: "Elapsed time: 0.196 msecs"

23:31 duck1123: .277958 for me

23:34 bitbckt: and, I suppose, you could get the "less than 10" portion with a simple range:

23:34 (time (reduce + (take 3 (filter prime? (range 1 11)))))

23:34 .217, for me

23:36 does that do what you intended?

23:36 duck1123: mental note: don't try to take the first 3 even prime numbers

23:36 bitbckt: lol

23:39 duck1123: range works, but i still feel like the filter option should work

23:39 #10 solved in 14+ sec

23:40 bitbckt: the filter option runs out of heap space, for me

23:40 duck1123: i never gave it that much time

23:40 bitbckt: ... in about 2 secs.

23:40 I have my java at 64M

23:41 duck1123: does my paste look right to you at least?

23:41 bitbckt: it seems logical

23:43 trimming to: (filter #(< %1 10) (iterate inc 1))

23:43 I get a heap error after 9

23:43 that's... amazing, to me

23:44 duck1123: that's an inf seq

23:44 bitbckt: at 9?

23:44 duck1123: it has no way of knowing a 4 won't show up

23:44 9 sec, or 9 number

23:44 bitbckt: 9, the integer

23:45 9 interations

23:45 -n

23:45 duck1123: that's odd

23:45 bitbckt: quite

23:45 asbjxrn: filter keeps taking numbers because it can't know that the numbers keeps increasing.

23:46 It has to go through all numbers to filter them?

23:46 You only see up to 9 because the rest get filtered out.

23:47 Chouser: you could use (take-while)

23:47 bitbckt: the memory usage is what is interesting, to me...

23:47 good idea, Chouser

23:48 Chouser: much better

23:48 Chouser: you can also use % instead of %1 when you only have one arg

23:49 duck1123: but if filter is lazy, wouldn't it only filter as needed?

23:50 bitbckt: that usage of filter generates quite the leak, for me. so noted.

23:50 Chouser: yes, but the repl tries to print the everything, which means filter will try to produce everything -- continuing until the end

23:51 duck1123: but if you wrap it in a take 3....

23:51 which is what I've been doing

23:51 Chouser: exactly.

23:52 bitbckt: duck1123: the prime? check, then the take 3...

23:52 I like the take-while idiom better, anyhow. I hadn't thought of using that. >_<

23:52 duck1123: I've been leaving the prime check out for now

23:53 (take 9 (filter #(< % 10) (iterate inc 1)))

23:53 wait

23:53 I see now

23:54 wait, no, 9 is still less than 10, that one should still work

23:56 bitbckt: yup, the REPL is running away on anything greater than 8

23:57 duck1123: take-while is the much clearer option in this situation, but that's still odd

23:57 asbjxrn: Maybe the filter/take is calculating one "ahead" in the sequence?

23:58 bitbckt: asbjxrn: it should execute to 10, fail, and return

23:58 asbjxrn: what should?

23:58 bitbckt: so, in that sense, it should be one "ahead"

23:59 duck1123: asbjxrn: you might be right, changing it to #(< % 11) works

23:59 asbjxrn: filter doesn't fail.

Logging service provided by n01se.net