Re: s/valid? vs. s/explain

2016-11-16 Thread James Gatannah
Thank you, Alex.

Both for the feedback about what I'm doing wrong and for a fix that looks 
simple and obvious.

Regards,
James

On Sunday, November 13, 2016 at 9:57:55 AM UTC-6, James Gatannah wrote:
>
> One of my system boundary data structures is particularly ugly.  It 
> involves things like JNI classes wrapping native socket libraries, go 
> loops, and higher-order functions that I can use to plug in message 
> dispatchers.
>
> I'm in the process of translating it from schema to spec. So far, the 
> process has been very educational.
>
> I've reached a point where calling (s/valid? ::foo x) returns false, but 
> (s/explain ::foo x) returns nil.
>
> Is this a bug in spec? Or am I misinterpreting the docstrings?
>
> (Narrowing it down enough to identify/fix my actual problem is one thing. 
> Getting something that's easily/obviously reproducible is going to be more 
> difficult, just because the problem spans at least 3-4 different github 
> repos).
>
> Thanks,
> James
>  
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [ANN] Clojure Programming Cookbook

2016-11-16 Thread James Gatannah
Congrats!

On Monday, November 14, 2016 at 9:09:01 PM UTC-6, Nicolas Modrzyk wrote:
>
> Hi Clojure people,
>
> So after one year and 23 days, (that would be 388 days) the IT book I was 
> working on with Makoto (merci!) finally got published!
>
> It has been a long battle with many late nights to get it out, tough 
> deadlines and never-ending reviews, but thanks to some skilled people at 
> Packt, thank you Sachin, Pranav (and not forgetting Nikhil, you got it all 
> started!) (http://packtpub.com/ 
> )
>  
> it is finally there in all its 635 pages glory ;)
>
> (PACK) 
> https://www.packtpub.com/application-development/clojure-programming-cookbook
>
> (AMAZON) http://a.co/3c9ckbp 
>
> The book while also presenting Clojure language centric topics, wants to 
> be slightly more focused around using Clojure at work and is bringing tons 
> and tons of working examples for every day usage. Along its (long!) 10 
> chapters, the book goes through many various topics but tries to keep each 
> topic easy to follow, with fun and useful recipes for great projects and 
> various creative ideas.
>
> The book may sometimes be too simple to many of the members of this 
> mailing list, but we hope the book contribute to grow the Clojure community 
> by sharing useful (and battled) Clojure code and stories.
>
> This is out now ! Enjoy!
> Nicolas & Makoto, all the way from Japan
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Help me understand what part of this code is slow, and how to make it faster?

2016-11-16 Thread Michael Gardner
Below is the fastest version I tested, using ideas from the various responses 
in this thread. It runs in ~4s on my machine, compared with ~27s for the 
original version.

The biggest win by far was from James Reeves' suggestion of switching to Java's 
mutable HashSet. I'm not sure why; I'd thought that using transients and 
transducers with Clojure's native sets would provide comparable performance, 
but this was not true in my testing.

I also couldn't figure out how to avoid the reflection warning when invoking 
HashSet's constructor that takes a generic Collection, which is why that ugly 
doto is there in nth-neighbors. How would I avoid that?

(ns hash-set-bench
  (import
[java.util HashSet]
[java.awt Point]))
  
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)

(defn neighbors [^Point p]
  (let [x (.-x p), y (.-y p)]
[(Point. x (inc y))
 (Point. x (dec y)) 
 (Point. (inc x) y)
 (Point. (dec x) y)]))

(defn nth-neighbors [^long n ^Point p]
  (loop [n n, s1 (doto (HashSet.) (.add p)), s2 (HashSet.)]
(if (zero? n) s1
  (let [s0 (HashSet.)]
(doseq [_ s1, p (neighbors _)]
  (when-not (or (.contains s1 p) (.contains s2 p))
(.add s0 p)))
(recur (dec n) s0 s1)

> On Nov 15, 2016, at 19:39, Didier  wrote:
> 
> Hey all,
> 
> I came upon a benchmark of F#, Rust and OCaml, where F# performs much faster 
> then the other two. I decided for fun to try and port it to Clojure to see 
> how Clojure does. Benchmark link: https://github.com/c-cube/hashset_benchs
> 
> This is my code for it: 
> https://gist.github.com/didibus/1fd4c00b69d927745fbce3dcd7ca461a
> 
> (ns hash-set-bench
>   "A Benchmark I modified to Clojure from:
>https://github.com/c-cube/hashset_benchs;)
> 
> (defn iterNeighbors [f [i j]]
>   (f [(dec i) j])
>   (f [(inc i) j])
>   (f [i (dec j)])
>   (f [i (inc j)]))
> 
> (defn nth* [n p]
>   (loop [n n s1 #{p} s2 #{}]
> (if (= n 0)
>   s1
>   (let [s0 (atom #{})]
> (letfn [(add [p]
>  (when (not (or (contains? s1 p) (contains? s2 p)))
>(reset! s0 (conj @s0 p]
>(doseq [p s1] (iterNeighbors add p))
>(recur (dec n) @s0 s1))
> 
> #_(printf "result is %d" (count (time (nth* 2000 [0 0]
> 
> And here's the F# code: 
> https://github.com/c-cube/hashset_benchs/blob/master/neighbors2.fsx
> 
> Currently, this takes about 30s in Clojure, while it only takes around 3s for 
> OCaml, Rust and F#.
> 
> From what I see, the differences between my code and theirs are:
>   • Lack of a Point struct, I'm just using a vector.
>   • They use a mutable set, I don't.
>   • They overrode Hashing for their point struct, as well as equality. I 
> rely on Clojure's default hashing, and vector equality.
> I'm not sure if any of these things should really impact performance that 
> much though. And what I could do in Clojure if I wanted to improve it.
> 
> 
> 
> Any Help?
> 
> 
> 
> Thanks.
> 
> 
> -- 
> 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 unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How to check type of generic parameter with spec?

2016-11-16 Thread Eunmin Kim
Thanks for the reply. :)

On Wednesday, November 16, 2016 at 11:44:50 PM UTC+9, Alex Miller wrote:
>
>
>
> On Tuesday, November 15, 2016 at 10:11:34 PM UTC-6, Eunmin Kim wrote:
>>
>> Hi! I had a question while reading Functional Programming in Scala book.
>>
>> The following code is Exercise 2:
>>
>> // Exercise 2: Implement a polymorphic function to check whether
>> // an `Array[A]` is sorted
>>
>> def isSorted[A](as: Array[A], gt: (A,A) => Boolean): Boolean = {
>>   @annotation.tailrec
>>   def go(n: Int): Boolean =
>> if (n >= as.length-1) true
>> else if (gt(as(n), as(n+1))) false
>> else go(n+1)
>>
>>   go(0)
>> }
>>
>> In the above code, Generic typ parameter(A) is displayed. How should I 
>> express it in clojure spec?
>>
>
> Because Clojure doesn't have generics, there is no direct representation 
> of A in the Clojure version. If you want to ensure that all elements of the 
> collection are of the same type, then say that.
>
> (defn same-type? [coll]
>   (or (empty? coll)
>  (let [t (class (first coll))]
>(every? #(= t (class %)) coll
>
> (s/fdef sorted-coll?
>   :args (s/cat :as (s/and (s/coll-of any?) same-type?)
>  :ordered-fn? ifn?) ;; cheating for brevity
>   :ret boolean?)
>
>  
>
>> (defn sorted-coll? [as ordered-fn?]
>>   (loop [coll (seq as)]
>> (cond 
>>   (= 1 (count coll)) true
>>
>
> just by inspection, this is broken for empty collections - should be <= 1 
> here
>  
>
>>   (not (ordered-fn? (first coll) (second coll))) false
>>   :else (recur (rest coll)
>>
>>
> And I would be remiss not to mention that 
> a) there is an existing sorted? predicate that I would use for this purpose
> b) the sorted set and map implementations in Clojure already require that 
> elements are all of the same type for the comparator to work
>  
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How to check type of generic parameter with spec?

2016-11-16 Thread Alex Miller


On Tuesday, November 15, 2016 at 10:11:34 PM UTC-6, Eunmin Kim wrote:
>
> Hi! I had a question while reading Functional Programming in Scala book.
>
> The following code is Exercise 2:
>
> // Exercise 2: Implement a polymorphic function to check whether
> // an `Array[A]` is sorted
>
> def isSorted[A](as: Array[A], gt: (A,A) => Boolean): Boolean = {
>   @annotation.tailrec
>   def go(n: Int): Boolean =
> if (n >= as.length-1) true
> else if (gt(as(n), as(n+1))) false
> else go(n+1)
>
>   go(0)
> }
>
> In the above code, Generic typ parameter(A) is displayed. How should I 
> express it in clojure spec?
>

Because Clojure doesn't have generics, there is no direct representation of 
A in the Clojure version. If you want to ensure that all elements of the 
collection are of the same type, then say that.

(defn same-type? [coll]
  (or (empty? coll)
 (let [t (class (first coll))]
   (every? #(= t (class %)) coll

(s/fdef sorted-coll?
  :args (s/cat :as (s/and (s/coll-of any?) same-type?)
 :ordered-fn? ifn?) ;; cheating for brevity
  :ret boolean?)

 

> (defn sorted-coll? [as ordered-fn?]
>   (loop [coll (seq as)]
> (cond 
>   (= 1 (count coll)) true
>

just by inspection, this is broken for empty collections - should be <= 1 
here
 

>   (not (ordered-fn? (first coll) (second coll))) false
>   :else (recur (rest coll)
>
>
And I would be remiss not to mention that 
a) there is an existing sorted? predicate that I would use for this purpose
b) the sorted set and map implementations in Clojure already require that 
elements are all of the same type for the comparator to work
 

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Help me understand what part of this code is slow, and how to make it faster?

2016-11-16 Thread Alex Miller
In general, any benchmark code using math should be aware of boxing (old 
post here: http://insideclojure.org/2014/12/15/warn-on-boxed/).

I would recommend doing the work to leverage primitive longs and unchecked 
math. Generally this makes numeric code like this about 2 orders of 
magnitude faster.

Removing the stateful atom and converting to a purely functional form would 
probably be a win too, but it's hard to say.

Make sure to run it multiple times before looking at timings so that the 
JVM compiles and optimizes the code.


On Tuesday, November 15, 2016 at 9:39:43 PM UTC-6, Didier wrote:
>
> Hey all,
>
> I came upon a benchmark of F#, Rust and OCaml, where F# performs much 
> faster then the other two. I decided for fun to try and port it to Clojure 
> to see how Clojure does. Benchmark link: 
> https://github.com/c-cube/hashset_benchs
>
> This is my code for it: 
> https://gist.github.com/didibus/1fd4c00b69d927745fbce3dcd7ca461a
>
> (ns hash-set-bench
>   "A Benchmark I modified to Clojure from:
>https://github.com/c-cube/hashset_benchs;)
>
> (defn iterNeighbors [f [i j]]
>   (f [(dec i) j])
>   (f [(inc i) j])
>   (f [i (dec j)])
>   (f [i (inc j)]))
>
> (defn nth* [n p]
>   (loop [n n s1 #{p} s2 #{}]
> (if (= n 0)
>   s1
>   (let [s0 (atom #{})]
> (letfn [(add [p]
>  (when (not (or (contains? s1 p) (contains? s2 p)))
>(reset! s0 (conj @s0 p]
>(doseq [p s1] (iterNeighbors add p))
>(recur (dec n) @s0 s1))
>
> #_(printf "result is %d" (count (time (nth* 2000 [0 0]
>
> And here's the F# code: 
> https://github.com/c-cube/hashset_benchs/blob/master/neighbors2.fsx
>
> Currently, this takes about 30s in Clojure, while it only takes around 3s 
> for OCaml, Rust and F#.
>
> From what I see, the differences between my code and theirs are:
>
>- Lack of a Point struct, I'm just using a vector.
>- They use a mutable set, I don't.
>- They overrode Hashing for their point struct, as well as equality. I 
>rely on Clojure's default hashing, and vector equality.
>
> I'm not sure if any of these things should really impact performance that 
> much though. And what I could do in Clojure if I wanted to improve it.
>
>
> Any Help?
>
>
> Thanks.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Spec validation cache?

2016-11-16 Thread Alex Miller
Maybe you don't need to instrument *all* functions in development? 

Alternatively, you could instrument and provide simpler replacement specs 
to improve speed. For example, an fspec arg could be replaced with ifn?. 

On Tuesday, November 15, 2016 at 10:29:34 PM UTC-6, Gal Dolber wrote:
>
> I'm having an issue with clojure.spec, its been great in more ways than I 
> expected but it's slowing down everything too much for development. On one 
> side when running the app on development with all fspecs instrumented and 
> on the other when running the tests.
>
> For the first case, most of the fdef functions take the app state as the 
> first argument, and the app state, being a really big data structure, gets 
> constantly validated and re-validated, while only few parts change. So I've 
> been wondering if there's a way to memoize spec/valid? to speed everything 
> up (while sacrificing memory).
>
> For the tests the case is different, because the app state gets generated 
> every time, so I don't see how this could speed them up.
>
> I tried doing it with `with-redefs without any luck. 
> Any ideas? (I'm running on clojurescript)
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Help me understand what part of this code is slow, and how to make it faster?

2016-11-16 Thread Alex Miller


On Wednesday, November 16, 2016 at 8:10:27 AM UTC-6, Jason Felice wrote:
>
> I'll bet the atom accesses dominate the computation.  They are a part of 
> Clojures software transactional memory (STM) and have a cost.
>

Atoms don't use the STM and if used in a single-threaded context like this, 
they will be uncontended, so the fastest case. That said, if you want 
something stateful, a volatile is faster in a single-threaded context.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Help me understand what part of this code is slow, and how to make it faster?

2016-11-16 Thread Jason Felice
I'll bet the atom accesses dominate the computation.  They are a part of
Clojures software transactional memory (STM) and have a cost.

Something like this (untested) should be faster:

(->> (iterate  neighbors #{p}) (drop 1999) first)

neighbors could be:

(into #{} (for [[id jd] [[-1 0] [+1 0] [0 +1] [0 -1]]
[(+ i id) (+ j jd)]))

This creates some negligible lazy lists.

If you want to test actual time for hash inserts, though, you'll probably
need to use transients or some such, and the code would become less
idiomatic.


On Tue, Nov 15, 2016 at 10:39 PM, Didier  wrote:

> Hey all,
>
> I came upon a benchmark of F#, Rust and OCaml, where F# performs much
> faster then the other two. I decided for fun to try and port it to Clojure
> to see how Clojure does. Benchmark link: https://github.com/c-cube/
> hashset_benchs
>
> This is my code for it: https://gist.github.com/didibus/
> 1fd4c00b69d927745fbce3dcd7ca461a
>
> (ns hash-set-bench
>   "A Benchmark I modified to Clojure from:
>https://github.com/c-cube/hashset_benchs;)
>
> (defn iterNeighbors [f [i j]]
>   (f [(dec i) j])
>   (f [(inc i) j])
>   (f [i (dec j)])
>   (f [i (inc j)]))
>
> (defn nth* [n p]
>   (loop [n n s1 #{p} s2 #{}]
> (if (= n 0)
>   s1
>   (let [s0 (atom #{})]
> (letfn [(add [p]
>  (when (not (or (contains? s1 p) (contains? s2 p)))
>(reset! s0 (conj @s0 p]
>(doseq [p s1] (iterNeighbors add p))
>(recur (dec n) @s0 s1))
>
> #_(printf "result is %d" (count (time (nth* 2000 [0 0]
>
> And here's the F# code: https://github.com/c-cube/
> hashset_benchs/blob/master/neighbors2.fsx
>
> Currently, this takes about 30s in Clojure, while it only takes around 3s
> for OCaml, Rust and F#.
>
> From what I see, the differences between my code and theirs are:
>
>- Lack of a Point struct, I'm just using a vector.
>- They use a mutable set, I don't.
>- They overrode Hashing for their point struct, as well as equality. I
>rely on Clojure's default hashing, and vector equality.
>
> I'm not sure if any of these things should really impact performance that
> much though. And what I could do in Clojure if I wanted to improve it.
>
>
> Any Help?
>
>
> Thanks.
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Help me understand what part of this code is slow, and how to make it faster?

2016-11-16 Thread James Reeves
On 16 November 2016 at 03:39, Didier  wrote:
>
> Currently, this takes about 30s in Clojure, while it only takes around 3s
> for OCaml, Rust and F#.
>
> From what I see, the differences between my code and theirs are:
>
>- Lack of a Point struct, I'm just using a vector.
>- They use a mutable set, I don't.
>- They overrode Hashing for their point struct, as well as equality. I
>rely on Clojure's default hashing, and vector equality.
>
> I'm not sure if any of these things should really impact performance that
> much though. And what I could do in Clojure if I wanted to improve it.
>
It's the mutability of the set that's causing the greatest performance
impact. You can't substitute in an immutable data structure into an
algorithm that makes heavy use of a mutable structure, and expect it to
have the same performance.

Something like this is more faithful to the original F# benchmark you
posted:

(defn nth* [n p]
  (loop [n n, s1 (java.util.HashSet. [p]), s2 (java.util.HashSet.)]
(if (= n 0)
  s1
  (let [s0 (java.util.HashSet.)]
(letfn [(add [p]
  (when-not (or (.contains s1 p) (.contains s2 p))
(.add s0 p)))]
  (doseq [p s1] (iter-neighbors add p))
  (recur (dec n) s0 s1))

- James



>
> Any Help?
>
>
> Thanks.
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.