Re: Re: How to import and use an enum enclosed in an java interface?

2011-08-03 Thread Ken Wesson
On Tue, Aug 2, 2011 at 10:42 AM, finbeu info_pe...@t-online.de wrote:
 Works! Ken, thx.

You're welcome.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: java.lang.StackOverflowError when calling function name instead of recur

2011-08-03 Thread Ken Wesson
On Tue, Aug 2, 2011 at 4:47 PM, David Nolen dnolen.li...@gmail.com wrote:
 On Tue, Aug 2, 2011 at 4:43 PM, Trastabuga lisper...@gmail.com wrote:

 I just came across the issue of getting the StackOverflowError in the
 function reading long file and recursively building a list of data.
 After I replaced function name with recur the problem went away.
 Hence a couple of questions. It's the programmer's responsibility to
 put recur instead of function names where tail-recursion is available?
 (Kind of obvious, but then why the compiler wouldn't detect it?)
 If tail-recursion is not available and function name has to be called,
 how do I deal with stack overflow in this case?

 Clojure does not have tail call optimization. You must use recur,
 trampoline, or redesign your code around lazy sequences.
 David

More specifically, you must use recur when your call chain is:

a - a - a ...

You'll need trampoline for more elaborate cases of mutually recursive
functions, like

a - b - c - a

or even

a - b - a - c - d - b - a

(where clearly a at least has conditional branches that can lead to
tail calls to at least either b or c depending).

Lazy sequences provide another way to do this. For example, suppose
you have a set of functions a, b, c ... and a state machine specified
with a map like {\a {\a b \b d \c q ...} \b {\a c \b a \c d ...} ...}
(as might be used if for some reason you wanted your own homegrown
regular expression implementation), you might implement this with
trampoline using

(defn a [in out]
  (if in
(let [new-state ((state-map (first in)) \a)]
  #(new-state (next in) (conj out whatever)))
   (list out)))

...

(defn process [in]
  (apply str (first (trampoline a (seq in) []

or something like that. You might also use lazy-seq:

(defn a [in]
  (lazy-seq
(if in
  (let [new-state ((state-map (first in)) \a)]
(cons whatever (new-state (next in)))

...

(defn process [in] (apply str (a in)))

though you might also use the higher-level reduce:

(def state-to-letter {a \a b \b ...})

(defn a [ch]
  whatever)

...

(defn process [in]
  (apply str
(second
  (reduce
(fn [[[current-state out] ch]
  (let [new-state ((state-map ch)
  (state-to-letter current-state))]
[new-state (conj out (current-state ch))]))
[a []]
in

or a low-level loop/recur:

(defn process [in]
  (loop [in (seq in) out [] current-state a]
(if in
  (let [ch (first in)
new-state ((state-map ch)
(state-to-letter current-state))]
(recur (next in) (conj out (current-state ch)) new-state))
  (apply str out

(Note: untested, and the whatevers are presumed to depend on the
state and the current input character, in such a way as to be hard to
replace with just a map lookup.)

Note that all of the above find some way to turn a calls b calls a
calls c calls ... into something sequentially calls a, then b on a's
return value, then a on that value, then c on that value ... and thus
avoids deeply nested stack frames.

In the case of trampoline, trampoline has the behavior that if the
function it's passed returns a new function, it calls that (with no
arguments), and repeats until a non-function return value is
generated. (In the state machine this has the awkward effect of
requiring the vector a returns if it's reached the end of in to be
wrapped in a list, since vectors are callable as functions and
trampoline might therefore call it instead of return it.) Since
functions can be selected programmatically in a functional language,
the state machine can be almost directly encoded in functions, or less
directly using a transition map as above.

Lazy-seq is good for cases like the above where each step is appending
to some growing output sequence. Then you just write each step almost
as you would with plain recursion, returning (cons this-steps-result
(next-step args)), but the whole thing is wrapped in (lazy-seq ...).
The seq is finite if and only if at some point one of the steps
returns nil instead of a cons. In this case that happens when the
input is exhausted. The seq generated is (step-1s-result
step-2s-result step-3s-result ...) and since it's lazy steps are only
performed as the consumer needs more items, and are called
sequentially, rather than nesting. (Technically, each step ends up
returning a delay rather than the cons, and the delay gets forced when
the step's output is needed by the consumer, which triggers the next
step, which produces another delay for the consumer to unwrap later;
so each step returns a delay instead of directly calling the next, and
the caller calls the next by forcing the delay, which turns the chain
of tail calls again into iteration.)

Reduce is generally useful for an iteration that accumulates a result,
in this case a vector. Direct use of loop/recur is also useful
sometimes for iteration.

Note that the trampoline, reduce, and loop/recur 

Re: Problem calling third-party library from ClojureScript code when advanced optimization used

2011-08-03 Thread Alen Ribic
Searching the CLJS bug reports, it turns out that the issue has been
reported. (http://dev.clojure.org/jira/browse/CLJS-10)
Additionally, I implemented a *quick-fix* for load-externs function in
clj/cljs/closure.clj and it resolved the problem as expected.

-Alen

--
Science is what you know, philosophy is what you don't know.
-- Bertrand Russell


On Aug 2, 4:18 pm, Alen Ribic alen.ri...@gmail.com wrote:
 I have the following function in my cljs that is bound to a click
 event. It makes a call to an external library via js* as seen in the
 last body form of the preview function.

 (defn preview []
   (let [body-el    (dom/getElement body_id)
         preview-el (dom/getElement preview_pane)
         b-txt      (.value body-el)
         safe       false]
     (dom/removeChildren preview-el)
     (dom/appendChild
      preview-el
      (dom/htmlToDocumentFragment
       (js* new Showdown.converter().makeHtml(~{b-txt},~{safe}))

 It works fine when the params has optimization set to
 {:optimizations :simple}.
 However, with when the :optimizations is set to :advanced, it fails
 with the following javascript error: Uncaught TypeError: undefined is
 not a function.
 I looked into this in a bit more detail and determined that the
 undefined part is the .converter in the Showdown namespace.

 In an attempt to find the reason behind this outcome, I read the
 Advanced Compilation and Externs Google Closure doc.
 To quote: Closure Compiler provides a mechanism for declaring that a
 name is defined in external code and so should not be renamed. This
 mechanism is called the extern. The compiler assumes that externs will
 exist in the environment in which the compiled JavaScript will be
 interpreted.http://code.google.com/closure/compiler/docs/api-tutorial3.html#comptoex

 Turning my attention to clj/cljs/closure.clj in ClojureScript, I
 located the load-externs function that is designed to
 support :externs, but unfortunately doesn't seem to be the case yet,
 judging by this function doc ... Any function in an extern file will
 not be renamed during optimization... TODO: Implement options
 described above. and judging by the function code itself.

 Firstly, I would like to clarify my understanding if the above is
 correct.
 If so, what is the current or suggested way to do this in the mean
 time?

 I thought about keeping the optimization level at
 {:optimizations :simple}, however the optimized, or lack thereof, js
 file weighs in at over 400K.

 -Alen

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: learning clojure library

2011-08-03 Thread Islon Scherer
You can use (ns-publics 'your.namespace) to see every public intern mapping 
in this namespace.

Islon

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: New to Clojure -- Errors Are Frustrating

2011-08-03 Thread MarisO
 (defn fac [n] (if (= n 1) 1 (* n fac (- n 1

your code tries to multiply n by function

this is correct:
 (defn fac [n] (if (= n 1) 1 (* n (fac (- n 1)



On Aug 2, 8:11 am, recurve7 dan.m...@gmail.com wrote:
 In browsing this group I see this topic has been brought up several
 times over the past 3 years, so I apologize for revisiting it.

 I just downloaded Clojure and was excited to try it, but so far trying
 to move beyond simple examples has often resulted in me making a
 mistake that yields a Java exception that presumably is helpful to the
 people who wrote Clojure, but doesn't provide me enough direction or
 sense of what I did wrong.

 Maybe improvement has been made in Clojure's so far, but it's very
 hard for me to think about working in a language that doesn't try to
 identify on what line and where on that line it encountered an error
 with my input.

 And when I get a Java-exception-style error from Clojure, it does me
 no good to copy it in to Google, because I get all these responses
 from Java programmers that have nothing to do with Clojure.

 I think it will be hard for Clojure to move beyond the fringe without
 its own, unique, Google-searchable error messages and without helpful
 positional error feedback for new people like me, who are maybe not
 used to its syntax.

 Here's one example where recursion and lack of positional error
 feedback make it hard for me, as someone coming from Java, to spot the
 error (and seeing ClassCastException threw me off and had me
 wondering where/how I had done something like that):

 user= (defn fac [n] (if (= n 1) 1 (* n fac (- n 1
 #'user/fac
 user= (fac 3)
 java.lang.ClassCastException: user$fac cannot be cast to
 java.lang.Number (NO_SOURCE_FILE:0)

 I will check back in on Clojure to see if it becomes more friendly for
 beginners and kids. Thanks for making it and working on it. =)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Clojure 1.3 Beta 1

2011-08-03 Thread Aaron Bedra
It does, thanks for the explanation.  Stuart Halloway and I took a look 
at this yesterday and have started on a solution. I will create a ticket 
in JIRA to track it. The basic idea is that BigInts that are small 
enough to store their value in the Long portion of the BigInt will not 
do the extra work if the end result doesn't spill over into BigInt 
territory. We tested some simple addition stuff last night and found it 
to be much faster.


Thanks for your help.

Cheers,

Aaron Bedra
--
Clojure/core
http://clojure.com

On 07/30/2011 09:10 PM, Mark Engelberg wrote:

On Fri, Jul 29, 2011 at 10:09 AM, abedraaaron.be...@gmail.com  wrote:

Can you provide a couple of concrete examples for this?  I will make
the ticket in JIRA and start working on it, but I am spread thin on
quite a few things at the moment and these examples will help a lot.

Cheers,

Aaron Bedra

Sure, let me elaborate on what I mean with a short but somewhat
contrived example.

Consider the following definition of factorial:
(defn fact [n]
   (loop [n n result 1]
 (if (zero? n) result
 (recur (dec n) (* result n)

factorial overflows as soon as you get to (fact 21).  Now, let's say
you don't know exactly at what point factorial overflows.  So to be on
the safe side, the recommended procedure is to pass a bigint to the
factorial function and rely on contagion to make this work, i.e.:
(fact 21N)

The problem is that (fact 21N) in 1.3 is slower than (fact 21) in 1.2.
  We're paying a big performance by relying on contagion.

Here's why:
In Clojure 1.2, the first 20 multiplications are done with longs, and
only when it overflows then the last multiplication is done with
bigints.
In Clojure 1.3, all the multiplications are done with bigints which are slow.

When this issue was first raised back when Rich floated the idea of
primitive ops with bigint contagion, he created the stub class saying
that eventually the plan would be to come up with a better version of
bigint than Java's BigInteger class in the sense that it would reduce
and compute with longs (and maybe ints) when in that range.

Now, factorial is contrived because overflow happens fairly early in
the process, yet the difference is still measurable.  For many of the
statistics I compute in my work project, a substantial number of the
computations happen within the long range, but sometimes they
overflow.  1.3 kills performance for me if I try to leverage
contagion; I must convert everything to the overflow ' operators.

I was thinking about this recently because I was rewriting my
clojure.contrib.math to support 1.3.  One of the things I had to think
about was how the expt function should behave.  It would be most
compatible with 1.3's outlook if
(expt primitive-long primitive-long) returned a primitive-long or
generated an overflow error.  But to implement expt in this way, I
also have to think about the fact that for many cases, exponentiation
will overflow.  So what should users do?  One option is I could also
provide a expt' function.  But I ruled this out because then I get
caught up in a proliferation of two versions (regular and ') of nearly
every math function.  It might be feasible to provide a single version
of expt that supports primitive math and then allow users to use
contagion (e.g., (expt 2N 100)), but this contagion will hurt
performance.  So the only viable option I see is to implement expt
with boxed numbers and the *' operator, maintaining the same
performance profile as 1.2, but missing out on the possibility of
making the primitive math people happy.

Does this explanation help?



--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


What information does (:key x) convey?

2011-08-03 Thread Brian Marick
It's very handy that :keywords act as functions and maps do too:

(:start voyage) = 5
(voyage :start) = 5

It's idiomatic Clojure, I think. I've been experimenting with a style of 
top-down TDD that puts off deciding about the shape of data as long as one 
can. [I hasten to add this is not a style for all problems: it's not what you'd 
use to come up with clojure.zip, for example.] Since Midje currently only lets 
you stub out vars, not keywords, using that particular style leaves you with 
code like this:

(def start :start)
(def end :end)

(def circular? [voyage)
   (= (start voyage) (end voyage)))

Stubbing out keywords can be done, which would give you the more (I think) 
idiomatic:

(def circular? [voyage)
   (= (:start voyage) (:end voyage)))

Question is: should I invest in doing it? Which depends on how much it's worth. 
Which leads to two questions:

* Is the `def start :start` alternative so offensive to your eye that it'd make 
you reluctant to try top-down TDD? (Note that the keyword-ey variant comes out 
just fine from bottom-up TDD.) That matters to me, because after a decade of 
not understanding top-down TDD, I finally did, so I have the zeal of the 
convert.

* What does it mean - to the reader - to see (:start voyage) in code as opposed 
to (start voyage)? What expectations does (start voyage) set up that (:start 
voyage) wouldn't? Midje is supposed to help with the whole 
principle-of-least-surprise thing.

** (:start voyage) could just mean  I didn't want to bother to write an 
accessor function.

** It could mean that voyage is a composite object with a distinct piece that 
is its start, as opposed to a calculation of some sort, and that the difference 
between the two is important. I'm wondering, though, if that distinction really 
makes sense. There is, first, the hoary old encapsulation argument: that you 
use explicit getters and setters on a Point so that the caller needn't care 
whether the underlying coordinates are cartesian or polar. And especially in a 
context of pure functions, where (f constant) will always have the same value, 
whether that's a stored, calculated, or calculated-and-memoized value seems 
irrelevant.

** It could mean there are no nasty surprises here. I vividly remember 
debugging a Smalltalk program and discovering what I'd been ignoring as a 
simple getter actually had hundreds of lines of code behind it. Using a keyword 
as a getter wouldn't have misled me so. (:start voyage) also makes it clear 
that the code is fast, whereas (start voyage) allows for anything - perhaps a 
leisurely calculation involving database queries.

++ It could mean: Picking good names is hard. Many words in English can be 
either a noun or a verb. Does (start voyage) mean 'commence traveling' or 'make 
a property of the voyage available'? (:start voyage) eliminates the possibility 
of that confusion, saving me some mental name-picking anguish.

I'm interested in what you think when you see a keyword, and what it would mean 
if you didn't.

(Sorry for the long note, but this way I get to use some of my B.A 1981, 
English Literature, background! 
http://en.wikipedia.org/wiki/Reader-response_criticism

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Occasional consulting on Agile
www.exampler.com, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: What information does (:key x) convey?

2011-08-03 Thread Sean Corfield
On Wed, Aug 3, 2011 at 10:03 AM, Brian Marick mar...@exampler.com wrote:

 ** It could mean there are no nasty surprises here. I vividly remember
 debugging a Smalltalk program and discovering what I'd been ignoring as a
 simple getter actually had hundreds of lines of code behind it. Using a
 keyword as a getter wouldn't have misled me so. (:start voyage) also makes
 it clear that the code is fast, whereas (start voyage) allows for anything -
 perhaps a leisurely calculation involving database queries.


FWIW, that's what I take it to mean. If I see (start voyage) I assume start
is a function that does something to voyage to return a value. If I see
(:start voyage) it conveys both the simple accessor and voyage is a
map-like structure which is potentially useful in understanding the code
(without that hint, voyage is some opaque data structure).
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: What information does (:key x) convey?

2011-08-03 Thread Colin Yates
+1 as well.  Surely (start-date voyage) would be more explicit than
(start voyage) though meaning there is no ambiguity for me; I would
(incorrectly) assume (start voyage) was a mutator :)

On 3 August 2011 18:22, Sean Corfield seancorfi...@gmail.com wrote:

 On Wed, Aug 3, 2011 at 10:03 AM, Brian Marick mar...@exampler.com wrote:

 ** It could mean there are no nasty surprises here. I vividly remember
 debugging a Smalltalk program and discovering what I'd been ignoring as a
 simple getter actually had hundreds of lines of code behind it. Using a
 keyword as a getter wouldn't have misled me so. (:start voyage) also makes
 it clear that the code is fast, whereas (start voyage) allows for anything -
 perhaps a leisurely calculation involving database queries.


 FWIW, that's what I take it to mean. If I see (start voyage) I assume start
 is a function that does something to voyage to return a value. If I see
 (:start voyage) it conveys both the simple accessor and voyage is a
 map-like structure which is potentially useful in understanding the code
 (without that hint, voyage is some opaque data structure).
 --
 Sean A Corfield -- (904) 302-SEAN
 An Architect's View -- http://corfield.org/
 World Singles, LLC. -- http://worldsingles.com/
 Railo Technologies, Inc. -- http://www.getrailo.com/

 Perfection is the enemy of the good.
 -- Gustave Flaubert, French realist novelist (1821-1880)

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: What information does (:key x) convey?

2011-08-03 Thread Laurent PETIT
2011/8/3 Sean Corfield seancorfi...@gmail.com

 On Wed, Aug 3, 2011 at 10:03 AM, Brian Marick mar...@exampler.com wrote:

 ** It could mean there are no nasty surprises here. I vividly remember
 debugging a Smalltalk program and discovering what I'd been ignoring as a
 simple getter actually had hundreds of lines of code behind it. Using a
 keyword as a getter wouldn't have misled me so. (:start voyage) also makes
 it clear that the code is fast, whereas (start voyage) allows for anything -
 perhaps a leisurely calculation involving database queries.


 FWIW, that's what I take it to mean. If I see (start voyage) I assume start
 is a function that does something to voyage to return a value. If I see
 (:start voyage) it conveys both the simple accessor and voyage is a
 map-like structure which is potentially useful in understanding the code
 (without that hint, voyage is some opaque data structure).


I would not rely too much on that : when associativity is done as a
protocol in a future version, voyage could then be of a type defined by
deftype which may involve database queries ...


 --
 Sean A Corfield -- (904) 302-SEAN
 An Architect's View -- http://corfield.org/
 World Singles, LLC. -- http://worldsingles.com/
 Railo Technologies, Inc. -- http://www.getrailo.com/

 Perfection is the enemy of the good.
 -- Gustave Flaubert, French realist novelist (1821-1880)

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: What information does (:key x) convey?

2011-08-03 Thread Kevin Downey
the clojure compiler also does some optimizations for keyword literal
calls on deftypes which you lose if you def it

On Wed, Aug 3, 2011 at 10:29 AM, Laurent PETIT laurent.pe...@gmail.com wrote:
 2011/8/3 Sean Corfield seancorfi...@gmail.com

 On Wed, Aug 3, 2011 at 10:03 AM, Brian Marick mar...@exampler.com wrote:

 ** It could mean there are no nasty surprises here. I vividly remember
 debugging a Smalltalk program and discovering what I'd been ignoring as a
 simple getter actually had hundreds of lines of code behind it. Using a
 keyword as a getter wouldn't have misled me so. (:start voyage) also makes
 it clear that the code is fast, whereas (start voyage) allows for anything -
 perhaps a leisurely calculation involving database queries.

 FWIW, that's what I take it to mean. If I see (start voyage) I assume
 start is a function that does something to voyage to return a value. If I
 see (:start voyage) it conveys both the simple accessor and voyage is a
 map-like structure which is potentially useful in understanding the code
 (without that hint, voyage is some opaque data structure).

 I would not rely too much on that : when associativity is done as a
 protocol in a future version, voyage could then be of a type defined by
 deftype which may involve database queries ...


 --
 Sean A Corfield -- (904) 302-SEAN
 An Architect's View -- http://corfield.org/
 World Singles, LLC. -- http://worldsingles.com/
 Railo Technologies, Inc. -- http://www.getrailo.com/

 Perfection is the enemy of the good.
 -- Gustave Flaubert, French realist novelist (1821-1880)

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en



-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: What information does (:key x) convey?

2011-08-03 Thread Stefan Kamphausen
inc

Functions in Lisps are (usually) verbs, to my eye the colon looks just like 
'get', doesn't it? :-)


Stefan 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Adding Change History To Clojure Modules

2011-08-03 Thread octopusgrabbus
Is there a preferred method for adding a Change History block to a
Clojure module? I'm doing this for now:

(ns addr-verify
  ^{:author Charles M. Norton,
:doc addr-verify is a small Clojure program that runs address
verification through ...

  Created on August 3, 2011
  Change History: }
  (:gen-class)
.
.
.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Adding Change History To Clojure Modules

2011-08-03 Thread Joop Kiefte
changelog.txt / VCS?

2011/8/3 octopusgrabbus octopusgrab...@gmail.com:
 Is there a preferred method for adding a Change History block to a
 Clojure module? I'm doing this for now:

 (ns addr-verify
  ^{:author Charles M. Norton,
    :doc addr-verify is a small Clojure program that runs address
 verification through ...

          Created on August 3, 2011
          Change History: }
  (:gen-class)
 .
 .
 .

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Adding Change History To Clojure Modules

2011-08-03 Thread octopusgrabbus
Thanks, and I'm searching as to how to get cvs commit to write this
into the module. If you know that, it would be so helpful.

On Aug 3, 3:31 pm, Joop Kiefte iko...@gmail.com wrote:
 changelog.txt / VCS?

 2011/8/3 octopusgrabbus octopusgrab...@gmail.com:







  Is there a preferred method for adding a Change History block to a
  Clojure module? I'm doing this for now:

  (ns addr-verify
   ^{:author Charles M. Norton,
     :doc addr-verify is a small Clojure program that runs address
  verification through ...

           Created on August 3, 2011
           Change History: }
   (:gen-class)
  .
  .
  .

  --
  You received this message because you are subscribed to the Google
  Groups Clojure group.
  To post to this group, send email to clojure@googlegroups.com
  Note that posts from new members are moderated - please be patient with 
  your first post.
  To unsubscribe from this group, send email to
  clojure+unsubscr...@googlegroups.com
  For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Adding Change History To Clojure Modules

2011-08-03 Thread Sean Corfield
I think Joop meant to use the change history in your version control system
directly, rather than try to put it into the source code.

I think the prevailing best practices these days are to _not_ duplicate
change history into source code, even thru VCS keyword substitution. The
change history is available in the VCS already and also in your IDE, so
anyone who needs to know how a given file has changed can go look that up.

Sean

On Wed, Aug 3, 2011 at 12:29 PM, octopusgrabbus octopusgrab...@gmail.comwrote:

 Is there a preferred method for adding a Change History block to a
 Clojure module? I'm doing this for now:

 (ns addr-verify
  ^{:author Charles M. Norton,
:doc addr-verify is a small Clojure program that runs address
 verification through ...

  Created on August 3, 2011
  Change History: }
  (:gen-class)



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Adding Change History To Clojure Modules

2011-08-03 Thread Ben Smith-Mannschott
This. 1000 times this.

Don't clutter your source code with this kind of stuff. It'll just
cause you pain down the road. (Say, when merging two branches.)

// ben

On Wed, Aug 3, 2011 at 23:36, Sean Corfield seancorfi...@gmail.com wrote:
 I think Joop meant to use the change history in your version control system
 directly, rather than try to put it into the source code.
 I think the prevailing best practices these days are to _not_ duplicate
 change history into source code, even thru VCS keyword substitution. The
 change history is available in the VCS already and also in your IDE, so
 anyone who needs to know how a given file has changed can go look that up.
 Sean
 On Wed, Aug 3, 2011 at 12:29 PM, octopusgrabbus octopusgrab...@gmail.com
 wrote:

 Is there a preferred method for adding a Change History block to a
 Clojure module? I'm doing this for now:

 (ns addr-verify
  ^{:author Charles M. Norton,
    :doc addr-verify is a small Clojure program that runs address
 verification through ...

          Created on August 3, 2011
          Change History: }
  (:gen-class)


 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: New to Clojure -- Errors Are Frustrating

2011-08-03 Thread Nicolas
On 3 août, 03:00, Mark markaddle...@gmail.com wrote:
 The compiler might not be able to do better but the runtime system certainly
 could.  In this case, both filtered and more information is what's needed.  
 Why couldn't the runtime generate a message like:
 Symbol fac of type clojure.lang.IFn is used where type java.lang.Number is
 expected in #2 operand to function *

 Of course, if this information were structured in some well-understood way,
 IDEs could consume the error and do an awfully good job of putting the
 cursor on exactly where the error is occurring.  When I code in clojure, IDE
 assistance for situations like this is probably the thing that I miss the
 most.

I agree that it would make us more effective. But honestly, before
that, I tend to find my clojure ide, to be very lacking. If I type
CTRL-SHIFT-T I can search for java type instantly but auto completion
in the editor for exampel take more than 10 seconds.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Adding Change History To Clojure Modules

2011-08-03 Thread Joop Kiefte
That was exactly what I meant. Sorry for not responding directly to
the second inquiry, I wanted to see if others thought the same about
this...

2011/8/3 Ben Smith-Mannschott bsmith.o...@gmail.com:
 This. 1000 times this.

 Don't clutter your source code with this kind of stuff. It'll just
 cause you pain down the road. (Say, when merging two branches.)

 // ben

 On Wed, Aug 3, 2011 at 23:36, Sean Corfield seancorfi...@gmail.com wrote:
 I think Joop meant to use the change history in your version control system
 directly, rather than try to put it into the source code.
 I think the prevailing best practices these days are to _not_ duplicate
 change history into source code, even thru VCS keyword substitution. The
 change history is available in the VCS already and also in your IDE, so
 anyone who needs to know how a given file has changed can go look that up.
 Sean
 On Wed, Aug 3, 2011 at 12:29 PM, octopusgrabbus octopusgrab...@gmail.com
 wrote:

 Is there a preferred method for adding a Change History block to a
 Clojure module? I'm doing this for now:

 (ns addr-verify
  ^{:author Charles M. Norton,
    :doc addr-verify is a small Clojure program that runs address
 verification through ...

          Created on August 3, 2011
          Change History: }
  (:gen-class)


 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: New to Clojure -- Errors Are Frustrating

2011-08-03 Thread Brian Goslinga
On Aug 2, 8:39 am, Ken Wesson kwess...@gmail.com wrote:
 It is true that the messages commonly encountered could stand to be
 better documented on a Clojure site. I'm wondering if we could go
 further, though, and make REPL exception printing more informative.
 The Java exception gets stored in *e, so someone can always type *e to
 retrieve it, or (.printStackTrace *e), etc., so printing an
 interpretation of the exception wouldn't render the raw exception
 inaccessible.
I've worked on a fork of Clojure that tries to do this: 
http://github.com/qbg/clojure

The solution I've implemented is to rewrite the exception as something
like:
java.lang.ClassCastException: A function (user/fac) cannot be used as
a number (java.lang.Number)

I've found for ClassCastExceptions, this is usually easy. For most
other types of exceptions, it is very difficult.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Are there potential licensing issues of doing a fully packaged ClojureScript zip for Windows ?

2011-08-03 Thread Laurent PETIT
Hello,

Do you know, given the licence of ClojureScript dependencies (which I don't
know in details), if doing the following would go against their licenses ? :

basically, a zip with pre-packaged fixed/tested versions of ClojureScript
and its dependencies, so that, e.g. on Windows, the manual steps can be
narrowed down to :

 * download zip
 * unzip
 * set environment variables
there you go

 ?

(a potential step could be to also embed such fixed versions into ccw to add
people start with it too)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Are there potential licensing issues of doing a fully packaged ClojureScript zip for Windows ?

2011-08-03 Thread Base
I hope not, because I would *love* that!

On Aug 3, 7:23 pm, Laurent PETIT laurent.pe...@gmail.com wrote:
 Hello,

 Do you know, given the licence of ClojureScript dependencies (which I don't
 know in details), if doing the following would go against their licenses ? :

 basically, a zip with pre-packaged fixed/tested versions of ClojureScript
 and its dependencies, so that, e.g. on Windows, the manual steps can be
 narrowed down to :

  * download zip
  * unzip
  * set environment variables
 there you go

  ?

 (a potential step could be to also embed such fixed versions into ccw to add
 people start with it too)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


deftypes that implement IPersistentCollection#equiv: argument order

2011-08-03 Thread Brian Marick
In Midje, I have reason to create a type Metaconstant whose instances are 
equal to a symbol with the same name. Here's the relevant bits of the 
definition:

(deftype Metaconstant [name storage]
  Object
  (equals [this that]
 (if (instance? (class this) that)
   (= (.name this) (.name that))
   (= (.name this) that)))
   
  clojure.lang.IPersistentCollection
  (equiv [this that]
 (println equiv is called with (type this) (type that))
 (.equals this that)))

That's fine when a Metaconstant is compared to a symbol, but I thought I'd have 
to engage in hackery when a symbol is compared to a Metaconstant. That is:

(println = symbol metaconstant?)
(println (= '...name... (Metaconstant. '...name... {}))) ; expect false
(println = metaconstant symbol?)
(println (= (Metaconstant. '...name... {}) '...name... )) ; expect true

Surprisingly, both directions produce true. That's because the order in which 
`.equiv` is called doesn't seem to depend on the order of arguments to `=`:

= symbol metaconstant?
equiv is called with midje.ideas.t-m.Metaconstant clojure.lang.Symbol
true
= metaconstant symbol?
equiv is called with midje.ideas.t-m.Metaconstant clojure.lang.Symbol
   true

Why is .equiv called with reordered arguments? And can I depend on that 
behavior going forward?

I see this behavior with 1.2.0, 1.2.1, and 1.3.0-beta1.


-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Occasional consulting on Agile
www.exampler.com, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: New to Clojure -- Errors Are Frustrating

2011-08-03 Thread Brian Marick

On Aug 2, 2011, at 7:23 PM, Armando Blancas wrote:
  Check out the work of Warren Teitelman on
 Conversational LISP and Do What I Mean, way back when most in this
 board weren't even born. 

Around 1985, I heard Teitelman's Do What I Mean (DWIM) referred to as DWWTWHM 
(Do What Warren Teitelman Would Have Meant). 

It is a hard problem. It's also an important problem. 

(In Midje, I've tried to be good about checking for user errors. It's 
surprising how often a misparenthesization can't be reported because there's a 
legitimate use with the same shape.)

-
Brian Marick, Artisanal Labrador
Contract programming in Ruby and Clojure
Occasional consulting on Agile
www.exampler.com, www.twitter.com/marick

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Trying to understand performance of two simple functions

2011-08-03 Thread Mark Feeney
As a test, I replaced the mapcat with a plain map in the slow version:

(defn collapse-slow [col pred rep]
  (let [f (fn [[x  more :as xs]] (if (pred x) [rep] xs))]
(map f (partition-by #(if (pred %) true) col

Is that the concat you were thinking of?

Ignoring that the functions aren't equivalent anymore, it's only a 10-20% 
boost.

(Let me know if I misinterpreted your suggestion.)


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: What information does (:key x) convey?

2011-08-03 Thread Ken Wesson
On Wed, Aug 3, 2011 at 1:26 PM, Colin Yates colin.ya...@gmail.com wrote:
 +1 as well.  Surely (start-date voyage) would be more explicit than
 (start voyage) though meaning there is no ambiguity for me;

I would have thought start-location. If it's start-date, then the
circular? in the OP can only return true for a nontrivial voyage in
case of time travel. :)

 I would (incorrectly) assume (start voyage) was a mutator :)

It does kind of sound like one, though I'd think (start! voyage) would
be preferable in such a case.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Are there potential licensing issues of doing a fully packaged ClojureScript zip for Windows ?

2011-08-03 Thread Devin Walters

On Aug 3, 2011, at 7:32 PM, Base wrote:

 I hope not, because I would *love* that!

+1 for the sake of the community.

AFAIK Google Closure operates under the Apache License 2.0. I am not personally 
aware of any conflicts that would arise from the dependencies ClojureScript 
requires, but I am not a lawyer or a license guru so I must defer to someone 
more familiar with the nuances of all the licenses involved.

With that said, I am happy to see your post Laurent. The work you've done with 
CCW is not only impressive, but great for the health of the Clojure community 
in general. I hope you will not be deterred in your effort to make working with 
ClojureScript on Windows as painless as possible.

Bon Chance,
Devin

 
 On Aug 3, 7:23 pm, Laurent PETIT laurent.pe...@gmail.com wrote:
 Hello,
 
 Do you know, given the licence of ClojureScript dependencies (which I don't
 know in details), if doing the following would go against their licenses ? :
 
 basically, a zip with pre-packaged fixed/tested versions of ClojureScript
 and its dependencies, so that, e.g. on Windows, the manual steps can be
 narrowed down to :
 
  * download zip
  * unzip
  * set environment variables
 there you go
 
  ?
 
 (a potential step could be to also embed such fixed versions into ccw to add
 people start with it too)
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en





-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: better community docs: getting started

2011-08-03 Thread Devin Walters

On Jul 29, 2011, at 7:30 PM, Stefan Kamphausen wrote:

 inc
 
 IMHO there are three types of people coming to Clojure
 
 Java Programmers
 Old-school lispers
 all the other, who just want to try (and possibly follow the examples in a 
 tutorial or book)
I humbly disagree. All of these groups branch in different ways. To me it's 
less of a question of where they came from and more of a question about where 
they want to go once they've made up their mind to try or use Clojure. I don't 
think it matters if they're comfortable with the tools provided so long as 
those tools provide a simple feedback loop from the word Go.

 For the first two groups the obstacles and interest can probably be sorted 
 out and the third groups just needs some basic setup, which may be presented 
 using Clooj (or lein repl or a virtual machine download or even just 
 clojure.main, or ...).

It would be nice to see a nice unified approach on this front. cake, lein, a 
pre-built vm, java -cp, etc. all bring along plenty of baggage which obscures 
the Getting Started story IMO. They all have their strengths and weaknesses. 
I believe the solution hangs in the balance between those differences.

 
 To me it seems important to get the common misunderstandings and problems out 
 of the way for groups 1 and 2.  The Java-programmers will need more help to 
 get going with REPL-oriented programming an to integrate Clojure in their 
 (existing) Java-programs, whereas the old-school lispers (OSPs? ;-) need a 
 hand getting around in the Java ecosystem (mvn, jar, war, classpath, etc).

The other category you mentioned needs just as much help with REPL-oriented 
programming. A solid editor-agnostic screencast on this style of development 
would do quite a bit of good, I think. The rhythm can be a bit fast for 
beginners when they don't see how you hit a hotkey to re-evaluate a form in 
your source in the REPL, for instance.

Cheers,
Devin

 
 Kind regards,
 Stefan
 
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Trying to understand performance of two simple functions

2011-08-03 Thread yair
No you didn't misinterpret it, I thought that would have been the
cause.  I ran a test and I think the de-structuring might have
something to do with it.  Here's the test:

(defn count-slow [[x  xs] acc]
  (if (empty? xs) (inc acc) (recur xs (inc acc

(defn count-fast [xs acc]
  (if (empty? (rest xs)) (inc acc) (recur (rest xs) (inc acc

(time (count-fast (range 1E8) 0))
Elapsed time: 48769.773688 msecs
1

(time (count-slow (range 1E8) 0))
Elapsed time: 88276.491181 msecs
1

(time (count (range 1E8)))
Elapsed time: 33762.022887 msecs
1

Still doesn't explain the 3-fold difference though.

I included count there out of curiosity, don't have time to look at
the code at work, but I am now intrigued by how it improves on my
version :)

Cheers

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en