#clojure log - Jun 29 2009

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

0:22 fullets: Can someone give me a clue as to how I would create two (proxy [AbstractAction] ...) forms that refer to each other?

0:23 i.e., something like http://clojure.pastebin.com/d1be1fd79 that will actually work

0:29 replaca: fullets: I can think of a bunch of cheats that use specials or refs, but I'm having a hard time coming up with anything straightforward that feels right

0:30 fullets: But that may just be too much time in the sun this weekend

0:58 JAS415: is there a proxy and gen-class for common lisp dummies available anywhere?

2:08 fffej: in Clojure Contrib it says I can rebind the tracer function - embarassingly I don't know how to do that without wrapping my entires set of code in a (binding) construct

2:08 is there an easier way?

2:08 hoeck: fffej: you can use alter-var-root to change the root binding of a var

2:09 fffej: thanks!

2:10 so something like (alter-var-root tracer (constantly (constantly nil)))?

2:13 hoeck: fffej: yes, then your var-value will be (constantly nil)

2:14 fffej: thanks again!

2:15 hoeck: you may want to try set! too: http://clojure.org/vars#set

2:15 you're welcome :)

2:15 fffej: I'd be looking at unalias in the namespaces - that didn't seem to help

2:24 hoeck: I got there in the end: (alter-var-root (var clojure.contrib.trace/tracer) (constantly (constantly nil))) seems to disable tracing, thanks for your help

2:30 hoeck: ah, yes, that disables the tracer function

2:31 the clojure head has got :pre and :post conditions to functions; maybe those are suitable for inserting traces too

2:33 fffej: and any other AOP type applications too I guess

2:55 Lau_of_DK: Morning gents

3:31 cgrand: hi all

4:01 AWizzArd: Hi cgrand

4:05 cgrand: AWizzArd: good morning

8:10 AWizzArd: Hello dear regexperts. I would like to know how a regexp would look (if it exists) and what function I need to call that splits a text for me into several strings, depending on some "groups". For example I have the groups: whitespace, numbers, special-chars and non-whitespace. Into the first group I want to put all chars that I want to treat as whitespace. I would like to call (regexp-foo regexp "Greetings to/t /t/nall Clojure fans12345in the world.") ==

8:12 Chouser: that got cut off at ==

8:14 AWizzArd: (regexp-foo regexp "Greetings to/t /t/nall Clojure fans12345in the world.") ==> ["Greetings", " ", "to", "/t /t/n", "all", " ", "Clojure", " ", "fans", "12345", "in", " ", "the", " ", "world", "."]

8:14 the ==> was your "=="

8:15 Chouser: (re-partition #"[\s\d]+" "Greetings to\t \t\nall Clojure fans12345in the world.")

8:15 AWizzArd: So, one whitespace group would contain space, \t, \r, \n but also for example the whitespace char that appears when one in Windows holds down the Alt key and types 255 on the number pad.

8:15 Chouser: re-partition is in clojure.contrib.str-utils

8:16 oh, you want . classified as whitespace

8:16 #"[\s\d.]+"

8:17 AWizzArd: Chouser: re-partition looks like what I want, or at least nearly as what I want. In your regexp [\s\d.] you list three of my groups: \s and \d and the .

8:18 It is just that I would like to have some few more chars in \s. Can I do something like [[\s xß]\d[.-+*/']] ?

8:19 Chouser: I think you don't want the inner [], but yes that should work

8:19 [-\s xß\d.-+*/']

8:19 [-\s xß\d.+*/']

8:20 or is it that you want each of those groups split differently

8:20 "123 456" ==> ["123" " " "456"] ?

8:20 cemerick: good morning!

8:20 AWizzArd: yes, if I have "hello x ßguys" I would like to get ["hello", " x ß", "guys"]

8:20 cemerick: Chouser: same to you :-)

8:21 for a second, I thought someone had set up a greeting bot in #clojure ;-)

8:21 Chouser: AWizzArd: hm, yes that's a bit trickier.

8:21 cemerick: :-)

8:22 AWizzArd: what is re-groups for?

8:22 Does that allow me to define several chars that I want to treat as one group, and get all strings consisting out of those?

8:23 And is there also such a splitting mechanism that keeps the positions (start, end) of the found groups?

8:23 Chouser: AWizzArd: no, it's just to help interact with the java regex api. You use it on a regex match object after the match has happened.

8:23 kinda internal.

8:24 There's an open question on what to do with things like that on non-JVM Clojures that implement regex's with a different api.

8:25 AWizzArd: very interesting puzzle. You want (.split "\b" string) but with your own definition of word-boundary.

8:27 cemerick: yeah, I saw no one replied to D. Miller's post about making the re-* cross-platform.

8:27 achim: AWizzArd: how about re-seq?

8:28 here's an example for 3 char classes: (re-seq #"[abc]+|[def]+|[jki]+" "adeadedfababacjki")

8:28 ,(re-seq #"[abc]+|[def]+|[jki]+" "adeadedfababacjki")

8:29 Chouser: cemerick: I nearly have a couple times, but with thoughts so vague I keep deciding it's not worth anybody's time.

8:29 achim: ah! I think you nailed it.

8:29 cemerick: Yeah, I don't see myself using clojureCLR much if at all, so I'm keeping my poorly-informed opinions out of that one.

8:30 AWizzArd: achim: I will try that

8:31 one sec

8:32 Chouser: I don't see how to avoid classifying "non-whitespace" using that method.

8:32 but maybe that's not a problem.

8:32 AWizzArd: well, maybe there is something that matches everything

8:33 re-seq looks at least very promising. It is basically doing 95% of what I want. It only does not report the positional info.

8:34 Chouser: oh, actually, maybe feed achim's regex into re-partition.

8:35 (re-partition #"[abc]+|[jki]+" "adeadedfababacjki") ==> ("" "a" "de" "a" "dedf" "ababac" "" "jki")

8:35 AWizzArd: positional info can be re-created from the match seq

8:36 AWizzArd: Chouser: yes, re-partition would help. I would specify my whitespace, number and special-char group and leave the non-whitespace group unspecified. re-partition would then split as I wish.

8:37 Yes, the result seq implicitly stores positional information. It looks as if nothing got thrown away.

8:37 Very good, thank you Chouser and achim :-)

8:38 btw, any one here knows the regexp for getting the numbers of the next lottery?

8:39 achim: hmm, i vaguely remember seeing a "reducing" fn somewhere, but don't remeber, where ...

8:39 Chouser: AWizzArd: I think so -- what's the format of the input?

8:39 achim: clojure.contrib.seq-utils/reductions

8:39 achim: Chouser: thanks!

8:41 (reductions + 0 (map count (re-partition #"[abc]+|[def]+|[jki]+" "adeadedfababacjki")))

8:41 AWizzArd: :-)

10:15 rhickey: Preferences? (partition n step pad coll) or (partition n step coll pad)

10:18 * mblinn votes for keeping coll at the end

10:18 danlei`: I like the first one better

10:21 Chousuke: a keyword argument would be nicer IMO, but I also prefer the former of the two.

10:21 danlei`: keyword would be nice, indeed

10:22 rhickey: then step and pad would be keys

10:22 Chouser: the coll is important, and it most fns it appears either first or last (interesting when it's one vs. the other)

10:24 rhickey: rationale here: http://groups.google.com/group/clojure/msg/a8866d34b601ff43

10:25 Chouser: I've always been in favor of at least optionally named args in general.

10:25 rhickey: optionally named?

10:25 Chouser: rhickey: ah, nice link. That would argue for coll last.

10:27 rhickey: Chouser: yes, that's what I originally argued, now just double checking this doesn't feel more like a 2 seq fn, a la concat, since it really is the partitioning of the concatenation

10:27 Chouser: yeah, allowing the caller to name some (or all) the args, but also providing a way to not name them in simple cases.

10:28 python has a solution for this (though it's not quite ideal).

10:28 rhickey: Chouser: sounds complicated and potentially slow

10:28 Chouser: if you "def foo(a, b, c)" you can call foo(1, 2, 3), foo(1, c=3), or whatever.

10:29 rhickey: early clojure had CL-style keyword and optional args

10:29 Chouser: you know how I feel about slow :-) but could something built on :inline help alleviate that in many cases?

10:29 danlei`: why did you drop the keyword args?

10:30 rhickey: danlei`: becasue they are not needed often enough, nor primitive

10:30 Chouser: actually, it was thoughts along these lines that prompted me to work on {:keys [...]} destructuring early on.

10:31 rhickey: and by you accepting that patch, I fear you've sealed your fate -- you'll never be rid of me now.

10:31 danlei`: rhickey: hm, but hand-rolled keyword args are not seldom ... wouldn't something like defnk from c.c. be nice in core?

10:32 rhickey: I have nothing against keyword args, there's just no need for primitive syntax in fn for them

10:32 Chouser: the fact that java is so much faster when dealing with positional args over keyword args does modulate my opinion.

10:33 stuartsierra: Can keyword args be handled at compile time?

10:34 rhickey: In a large codebase of CL (where it is very idiomatic), keyword usage was < 10% of functions

10:34 stuartsierra: some cases, sure

10:34 &optional less still

10:35 Chouser: 3 args is about the limit of what strikes me as comfortable without keywords. Putting keywords only on the end somewhat frustrates partial application. I could contradict myself all day...

10:35 rhickey: and both are somewhat covered by true variable arity

10:35 danlei`: hm ... to me something around 10% is not really sparse, but ok

10:35 stuartsierra: compile-time keyword args would certainly be more efficient than (apply hash-map args)

10:36 rhickey: danlei`: I bet you could nuke a ton of them just for :test, :start etc, which aren't really needed when you don't have so much variability in equality semantics and you have things like rseq

10:36 :from-end

10:36 etc

10:37 Clojure's own code is a testament to the fact that keyword args aren't needed often

10:37 So in the good fight against complexity, they lost

10:38 Chouser: I don't suppose 'partition' could be split up in such a way that no one function needs all 4 args?

10:38 stuartsierra: That's true for core fns, but they're more heavily used in contrib libs, where you need to configure some external object.

10:38 danlei`: I see, I'll think about it

10:39 rhickey: Chouser: I'm thinking now that overloading partition is wrong, as soon as I wrote "partitioning of the concatenation above"

10:39 Chouser: if partition always acted like it had a nil pad, then you could either filter on subseq length (original behavior) or pad to a given length (new behavior)

10:39 rhickey: really should have a different fn for partition with variable length trailing, rather than key it off of a pad

10:40 Chouser: not changing original behavior

10:41 just need a name for (partition+ n step coll) where it can yield partial partitions at end

10:42 Chouser: rhickey: clojure.contrib.seq-utils/partition-all

10:42 rhickey: right, but -all doesn't say much

10:42 to me

10:43 Chouser: there was a discussion...

10:43 stuartsierra: partition-remainder

10:45 Chousuke: or simply partition-with-pad, but it's a bit long

10:46 rhickey: Chousuke: but it's not with-pad, you don't need pads since you have concat

10:46 Chousuke: hmm.

10:47 rhickey: partition*

10:48 Chouser: http://groups.google.com/group/clojure/msg/e34f62e95d9de1c9

10:48 So I guess I'm to blame for -all

10:49 originally proposed as "chunk" -- guess that's out. :-)

10:49 stuartsierra: Maybe "partition" includes the ending and "strict-partition" doesn't.

10:49 Chouser: -all was meant to suggest that none of the original seq was left out.

10:50 rhickey: yeah, a completely different name, e.g. subseqs, wouldn't help people who first try partition and then want trailing partials

10:51 Chousuke: partition* might be good enough.

10:51 rhickey: chould also be considered a variant on take

10:51 or take-nth

10:52 take-seqs

10:53 (take n step coll)

10:55 for me, non-regular partition sizes isn't really partition

10:56 Chouser: a comment in the docstring would be sufficient to get from partition to something named differently

10:56 rhickey: I'm not arguing against the utility of taking subseqs every nth

10:57 would (take n step coll) be misleading>

10:57 ?

10:58 stuartsierra: what does the step mean there?

10:58 rhickey: the nice thing about it is that it doesn't promise exactly n, as take doesn't

10:59 Chouser: seems more surprising to me for take to return something starting past the beginning, than for partiton to return short seqs

10:59 rhickey: stuartsierra: step is the offset (take n n coll) == (partition-all n coll)

10:59 stuartsierra: hmm

10:59 Chouser: (map #(take n %) (nth-nexts step coll)) ?

11:00 except with a better name for nth-nexts

11:01 rhickey: (take-subs n coll) (take-subs n step coll)

11:02 Chouser: yes

11:04 rhickey: take-subs or take-seqs?

11:05 stuartsierra: "take-groups" ?

11:06 rhickey: stuartsierra: probably best not to consume another concept for this :)

11:06 Chousuke: take-subs makes me hungry :P

11:06 Chouser: I think "subs" because that more clearly indicates they're shortened

11:07 rhickey: Chouser: good point

11:07 ,(doc subs)

11:07 Chousuke: no clojurebot apparently :/

11:07 Chouser: clojurebot and hiredman are both MIA

11:07 rhickey: -------------------------

11:07 clojure.core/subs

11:07 ([s start] [s start end])

11:07 Returns the substring of s beginning at start inclusive, and ending

11:07 at end (defaults to length of string), exclusive.

11:08 Chousuke: I wonder if it's too abbreviated. I wouldn't mind take-subseqs

11:08 Chouser: why is that even in core?

11:08 Chousuke: subs definitely is too abbreviated :P

11:09 Chouser: I guess it lets you avoid hinting the String *shrug*

11:10 rhickey: Spot the difference:

11:10 http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#substring(int,%20int)

11:11 http://msdn.microsoft.com/en-us/library/system.string.substring.aspx

11:11 Chouser: bleh

11:11 stuartsierra: one off

11:11 Chouser: end vs len

11:11 rhickey: right

11:11 Chouser: I think javascript has both. :-)

11:12 rhickey: so we don't want .substring calls everywhere

11:12 stuartsierra: But I've been bugged that (subs "hi" 0 10) throws an exception.

11:12 * Chouser has .substring calls *everywhere*

11:13 stuartsierra: This is why I wrote c.c.str-utils2.

11:13 Chouser: JS substr is like .net, JS substring is like Java

11:13 rhickey: subs was added when I was trying to get Norvig's spell corrector out the door

11:14 vs Python which has something more concise for this

11:17 Chouser: ah, yeah -- array range syntax that works also on strings

11:18 rhickey: anyway, is take-subs confusing due to subs, hunger issues aside?

11:20 Chouser: any chance of renaming "subs" to "substring"?

11:20 but either way, I'd say "no".

11:21 rhickey: Chouser: possible, but the comparison vs Python will remain. For people doing a lot of that, typing out substring will seem quite tiresome

11:22 Chousuke: I think it's better to be a bit more verbose and have take-subseqs

11:22 Chouser: I'd be fine with take-subseqs

11:24 rhickey: but python can be concise there because it's leveraging the "namespace" of the object, just like any other OOP. Pushing object-specific methods up to the core namespace is a bit like cheating.

11:33 albino: and cheating is the right way to do it :)

11:39 cemerick: There has to be a fool in every room, so I'll take that on today: why not a reader macro for subsequencing in general? #[seq-or-string 0 10]?

11:40 stuartsierra: Or first class ranges, like Ruby (#[0 10] seq-or-string)

11:40 cemerick: I'm not sure I'd ever use it myself, but if some group of users is doing a lot of string-mangling, it might make sense.

11:41 stuartsierra: that's even better

11:42 Chouser: that would do substring, subvec, or drop/take as appropriate?

11:43 cemerick: yeah, that's the thought

11:44 having all of these siloed fns for strings, vectors, seqs, etc., doesn't make sense to me

11:44 rhickey_: IBM's X10 was doing some neat thing with first-class regions, encompassing ranges and multidimensional indexing

11:45 Chousuke: shouldn't be too difficult. The crappy thing is that IFn seems to be a painful interface to implement :P

11:45 Chouser: reader support for ranges is independent of a general sub-part fns though

11:45 rhickey_: ranges for non-indexed data structures are bad

11:45 so not for take/drop

11:45 Chouser: Chousuke: AFn and RestFn aren't bad though, are they?

11:45 Chousuke: is AFn enough?

11:46 cemerick: or, I should say, having all those siloed fns makes a lot of sense, but they shouldn't be the primary interface for 98% of all users. That other 2% might have some really good reason to explicitly choose one of them in a hot loop if something's known to be a particular type.

11:46 Chouser: select-keys for maps?

11:46 eh. hm.

11:46 nm.

11:46 Chousuke: Chouser: hm, but AFn is a class. Range already extends ASeq

11:47 Chouser: ah

11:47 * Chousuke wishes java had macros

11:47 Chousuke: most of implementing IFn is just cut & paste.

11:47 Chouser: Chousuke: why not write it in clojure, for goodness' sake!?

11:48 Chousuke: Range is in Java. :/

11:48 rhickey_: Chousuke: not in chunks branch

11:49 Chousuke: oh? neat.

11:49 rhickey_: but something that only did ranges and not multidimensional indexing is a waste, IMO

11:51 in X10 it's something like #[0:10] for a range and #[0:10 20:100] for a first-class md region

11:56 Chousuke: hm, that will be trickier

12:17 achim: how do languages with native range support handle range-minus, e.g. [0, 3] \ [1, 2] ?

12:18 stuartsierra: Hm, Ruby doesn't define minus on ranges.

12:20 achim: that's the easy way ;) - i tried implementing some range arithmetics stuff a while ago and ended up with by basic type being a set of vectors (ranges). that's probably not the way to go in terms of code readibility

12:25 cheddar: what's a good way of making a queue? If it's n-elements long, should I just do (let [new-queue (cons new-element (take n-1 queue))])?

12:26 performance-wise, would that be a reasonable approach?

12:26 achim: cheddar: (clojure.lang.PersistentQueue/EMPTY) - conj'es from the right, pops and peeks from the left

12:42 Chousuke: hm

12:42 well, implementing a simple splice was easy, but I'm not convinced it's good enough.

12:43 stepping and such will be the real problem anyway

12:46 Lau_of_DK: Good evening gentlemen

12:52 jackdempsey: evenin

12:52 anyone have video recommendations for clojure? been through the blip.tv vids a bit, looking for other stuff easy to ingest while workin out

12:53 Lau_of_DK: technomancy had some screencasts going that looked awesome

12:53 jackdempsey: oh nice

12:55 technomancy: yups: http://peepcode.com/products/functional-programming-with-clojure

12:55 not free though; sorry

12:56 jackdempsey: hehe

12:56 i love open source, however, the day you produce something amazing and have to say "its not free, sorry"

12:56 dunno :-)

12:56 happy to fork over the huge sum of $9 for some great content

12:57 was actually in the process of buying that when you linked to it

12:57 technomancy: cool. =)

12:57 jackdempsey: did you used to do some merb stuff as well? i recognize your nick from somewhere

12:57 technomancy: I used to write a lot of Ruby and have done a number of Elisp tools.

12:57 only dabbled in merb a small amount

12:58 jackdempsey: ah ok cool

12:58 maybe it was sequel, or dm, or who knows :-)

12:58 nice, cardio here i come

13:09 Lau_of_DK: technomancy: When will your screencast on ClojureQL be up ? And how much should I expect to get from that in terms of royalities ?

13:11 technomancy: hehe

13:11 Lau_of_DK: I'm actually thinking of doing a short intro to paredit

13:12 Lau_of_DK: Ok, thats actually not the same thing :)

13:12 technomancy: since it's easy to get confused by it, but it's super-helpful once you get the hang of it.

13:12 Lau_of_DK: I never use it - hitting shift+8 just didnt seem like a big investment

13:14 jackdempsey: clojureQL?

13:14 Lau_of_DK: Yep

13:15 Its hot

13:15 jackdempsey: ah

13:15 i see

13:15 Lau_of_DK: http://github.com/Lau-of-DK/clojureql/tree/master

13:15 jackdempsey: cool

13:15 yeah looking

13:16 Lau_of_DK: I'll make a post on the group later, but its v0.9 now, coming up on 1.0, so people are very welcome to fire away with bug-reports/feature-requests/love-letters etc. (last one should go to meikel)

18:40 Chousuke: I finally figured out how c.c.monads

18:56 danlei: see http://gist.github.com/137862 for a monadic version of ansi2html

18:56 now I need some sleep.

19:20 danlei: Chousuke: mee too, 1:19am over here ;) thanks for the effort, I'll have a look at it tomorrow (and a little talk I guess ;)

20:26 durka42: did anyone enter icfp in clojure?

20:29 jackdempsey: durka42: dont' think so, seen that asked here a couple times

20:29 actually one person did say they were doing something for it....but maybe that was you? :-)

20:29 durka42: did i?

20:29 i did, but i don't remember mentioning it

20:29 i didn't have time to really do it, but i solved the first challenge

20:30 ~logs

20:30 jackdempsey: ah cool

20:30 yeah i think it was someone else

20:30 can't recall their nick tho

20:34 Chouser: http://clojure-log.n01se.net/date/2009-06-27.html#12:02b

20:35 blbrown_win2: I think I am having classloader issues NoClassDefFoundError, etc. I am trying to invoke a java library from clojure I get an error where Log4J Logger is not found. I believe it has to do with the DynamicClassLoader. Is there more than one DynamicClassLoader can I use the Clojure classloader?

20:37 durka42: hiredman: where's your protegé? :p

21:53 samwisem: hey I was just wondering, 'clojure.lang.Script' and 'clojure.lang.Repl' seem deprecated, and the preferred way is to launch everything through 'clojure.main' now?

21:54 durka42: correct

21:55 samwisem: thanks

22:24 eyeris: What is the syntax for a function that returns a constant, literal value?

22:25 fullets[w]: (constantly 42) might do what you want

22:25 eyeris: Nice. Thanks.

22:29 Why is this false? (== ((constantly true)) true)

22:29 ,(== ((constantly true)) true)

22:29 In fact, (== true true) is false

22:30 fullets[w]: I believe == is for comparing numbers

22:30 (= ((constantly true)) true) is true

22:31 eyeris: Okay

22:31 Thanks

22:37 I read the documentation for each about 5 times.

22:37 Knowing that my first understanding is wrong, it totally makes sense.

22:38 But when I read it, the brevity of the definition of == made it seem as if it were just a modification of the definition of =, meaning that it returned a non-nil value, not garunteeing a boolean.

Logging service provided by n01se.net