Re: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-13 Thread Fluid Dynamics
Then all of them must be schizophrenic: forcing delay X while forcing delay 
X gives a stack overflow except if the delay happens to be the rest-part of 
a lazy seq, and then gives nil instead making the sequence seem to 
terminate early.

That's very odd. How does it "know" whether the delay it's forcing happens 
to be part of a lazy seq or is instead a freestanding delay? And why should 
it care? Or ... could the forcing of a lazy seq element be swallowing 
exceptions and converting them to nil? Yet:

=> (take 3 (cons 1 (lazy-seq (/ 3 0
ArithmeticException Divide by zero  clojure.lang.Numbers.divide 
(Numbers.java:156)

Exceptions thrown calculating the value aren't swallowed, at least not in 
1.5.1. If something is eating exceptions it's eating only 
StackOverflowError, or preserving and rethrowing exceptions generated by 
the body of the lazy-seq construct and only swallowing the ones produced by 
the surrounding machinery inside of the delay...

Curiouser and curiouser.

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-13 Thread Nicola Mometto
Clojure 1.6.0
user=> (def foo (delay (str @foo)))
#'user/foo
user=> @foo
StackOverflowError   clojure.lang.Delay.deref (Delay.java:37)
user=>

same with Clojure 1.7.0-master-SNAPSHOT, I don't see it returning nil
as you said.

On Fri, Feb 13, 2015 at 7:53 AM, Fluid Dynamics  wrote:
> On Friday, February 13, 2015 at 12:47:17 AM UTC-5, Justin Smith wrote:
>>
>> I don't want to sound too brusque in my defense of Clojure. I'm a huge
>> fan, so criticism of the language does get me a bit defensive.
>
>
> I am a fan as well. Constructive criticism is useful as it can lead to
> improvements.
>
>>
>> But preferring different behavior is actually reasonable here. There are
>> other Lisps (and languages in the ML family) that are more internally
>> consistent. I'll continue to prefer the better performance and easy access
>> to host interop, even if it does violate the occasional abstraction. But of
>> course there is no reason to begrudge someone else holding a different
>> opinion, and choosing a language that aligns with those expectations.
>>
>> But I do hope you give Clojure a chance, it's been very rewarding for me
>> and I expect you'd find the same if you take the time to get to know it and
>> get a feel for what's idiomatic
>
>
> Actually, I've been using it for years. And I've never encountered behavior
> like this, until now. It is definitely wrong for a lazy sequence to either
> a) appear to have the wrong length or b) appear at different times to have
> different lengths. As long as the var isn't rebound, "primes" indisputably
> should appear to have a fixed, immutable value, whether parts of that value
> are lazy via delay/force or otherwise.
>
> It appears that there is a buggy corner case with self-referencing delays,
> where if you (delay code) and "code" has a reference to the delay and tries
> to force it, it sees the delay's value as nil rather than, as it probably
> should, throwing an exception. (Recursively calling the delay's code leading
> to an eventual StackOverflowError seems like the only other *sensible*
> alternative, but if you can detect that case and return nil instead you can
> detect it and throw an exception directly. Something straightforward, like
> an IAE with a message of "Delay tried to force itself on evaluation" or
> something. This would be far preferable to exposing visible mutation in a
> thing that is supposed to be semantically immutable, such as (rest x)
> changing from nil to non-nil, and also exceptions are far preferable to
> returning a logically-incorrect result without complaint.)
>
> Incidentally, I don't see the same behavior using my somewhat old copy of
> Clojure 1.5.1:
>
> => (def foo (delay (str @foo)))
> #'user/foo
> => @foo
> StackOverflowError   clojure.core/deref (core.clj:2114)
>
> This is what I'd expect a naive implementation to do. So it looks like in
> 1.6 this must have changed to produce nil from the inner @foo, for lazy
> sequences to look like they terminate early from "inside themselves", and in
> 1.7 it *may* have changed again. I think clarification is needed here on
> what is going on. One thing already clear is the preference order of
> possible behaviors:
>
> nil < StackOverflowError < more specific exception such as "delay tried to
> force itself".
>
> Which suggests that 1.5.1 > 1.6, in this particular area...
>
> --
> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-13 Thread Nicola Mometto
Clojure 1.5.1
user=>  (def bar (cons 1 (map #(do (println %) (+ (nth bar %) %)) (range
#'user/bar
user=> (take 10 bar)
(0
1
IndexOutOfBoundsException   clojure.lang.RT.nthFrom (RT.java:795)


It is possible that it is lein/REPLy that's causing the output not to
be print, I've seen it done a number of times.


On Fri, Feb 13, 2015 at 8:02 AM, Fluid Dynamics  wrote:
> And here's some really crazy behavior from 1.5.1!
>
> => (def bar (cons 1 (map #(do (println %) (+ #_(nth bar %) %)) (range
> #'user/bar
> => (take 10 bar)
> (0
>
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
> 11
> 12
> 13
> 14
> 15
> 16
> 17
> 18
> 19
> 20
> 21
> 22
> 23
> 24
> 25
> 26
> 27
> 28
> 29
> 30
> 31
> 1 0 1 2 3 4 5 6 7 8)
> => (def bar (cons 1 (map #(do (println %) (+ (nth bar %) %)) (range
> #'user/bar
> => (take 10 bar)
> IndexOutOfBoundsException   clojure.lang.RT.nthFrom (RT.java:795)
>
> Erm, what? There should have been at least one number printed by the
> (println %) before the (nth bar %) could possibly have blown up.
> Furthermore, the *first* round of prints shows that % was never out of range
> for an infinite lazy sequence, i.e. was never negative. So 1.5.1 is actually
> behaving *schizophrenically* here: a bare delay that recursively forces
> itself overflows the stack, but the delay for the next-part of a ChunkedSeq
> is instead apparently being seen as holding nil when forced inside its own
> evaluation. But a delay is a delay is a delay and the same behavior should
> occur consistently, nil or an exception, no matter where the delay is
> "located"!
>
> --
> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Fluid Dynamics
And here's some really crazy behavior from 1.5.1!

=> (def bar (cons 1 (map #(do (println %) (+ #_(nth bar %) %)) (range
#'user/bar
=> (take 10 bar)
(0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1 0 1 2 3 4 5 6 7 8)
=> (def bar (cons 1 (map #(do (println %) (+ (nth bar %) %)) (range
#'user/bar
=> (take 10 bar)
IndexOutOfBoundsException   clojure.lang.RT.nthFrom (RT.java:795)

Erm, what? There should have been at least one number printed by the 
(println %) before the (nth bar %) could possibly have blown up. 
Furthermore, the *first* round of prints shows that % was never out of 
range for an infinite lazy sequence, i.e. was never negative. So 1.5.1 is 
actually behaving *schizophrenically* here: a bare delay that recursively 
forces itself overflows the stack, but the delay for the next-part of a 
ChunkedSeq is instead apparently being seen as holding nil when forced 
inside its own evaluation. But a delay is a delay is a delay and the same 
behavior should occur consistently, nil or an exception, no matter where 
the delay is "located"!

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Fluid Dynamics
On Friday, February 13, 2015 at 12:47:17 AM UTC-5, Justin Smith wrote:
>
> I don't want to sound too brusque in my defense of Clojure. I'm a huge 
> fan, so criticism of the language does get me a bit defensive.
>

I am a fan as well. Constructive criticism is useful as it can lead to 
improvements.
 

> But preferring different behavior is actually reasonable here. There are 
> other Lisps (and languages in the ML family) that are more internally 
> consistent. I'll continue to prefer the better performance and easy access 
> to host interop, even if it does violate the occasional abstraction. But of 
> course there is no reason to begrudge someone else holding a different 
> opinion, and choosing a language that aligns with those expectations.
>
> But I do hope you give Clojure a chance, it's been very rewarding for me 
> and I expect you'd find the same if you take the time to get to know it and 
> get a feel for what's idiomatic
>

Actually, I've been using it for years. And I've never encountered behavior 
like this, until now. It is definitely wrong for a lazy sequence to either 
a) appear to have the wrong length or b) appear at different times to have 
different lengths. As long as the var isn't rebound, "primes" indisputably 
should appear to have a fixed, immutable value, whether parts of that value 
are lazy via delay/force or otherwise.

It appears that there is a buggy corner case with self-referencing delays, 
where if you (delay code) and "code" has a reference to the delay and tries 
to force it, it sees the delay's value as nil rather than, as it probably 
should, throwing an exception. (Recursively calling the delay's code 
leading to an eventual StackOverflowError seems like the only other 
*sensible* alternative, but if you can detect that case and return nil 
instead you can detect it and throw an exception directly. Something 
straightforward, like an IAE with a message of "Delay tried to force itself 
on evaluation" or something. This would be far preferable to exposing 
visible mutation in a thing that is supposed to be semantically immutable, 
such as (rest x) changing from nil to non-nil, and also exceptions are far 
preferable to returning a logically-incorrect result without complaint.)

Incidentally, I don't see the same behavior using my somewhat old copy of 
Clojure 1.5.1:

=> (def foo (delay (str @foo)))
#'user/foo
=> @foo
StackOverflowError   clojure.core/deref (core.clj:2114)

This is what I'd expect a naive implementation to do. So it looks like in 
1.6 this must have changed to produce nil from the inner @foo, for lazy 
sequences to look like they terminate early from "inside themselves", and 
in 1.7 it *may* have changed again. I think clarification is needed here on 
what is going on. One thing already clear is the preference order of 
possible behaviors:

nil < StackOverflowError < more specific exception such as "delay tried to 
force itself".

Which suggests that 1.5.1 > 1.6, in this particular area...

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
To go into a bit more detail about what this code does:

Here's the code formatted idiomatically -

(defn divides? [x y] (zero? (mod x y)))

(defn prime-ub [x] (/ x (if (even? x) 2 3)))

(defn lower-primes [primes x]
  (let [ub (prime-ub x)]
(take-while #(<= % ub) primes)))

(defn prime? [primes x]
  (println "primes" primes "x" x)
  (not-any? #(divides? x %)
(lower-primes primes x)))

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))

When the definition of primes is evaluated, the var `primes` is created, 
and the value is a cons prepending 2 to a lazy-seq. I discovered via 
experiment that running the def again does not reuse the previous value of 
primes in the definition (which makes sense I guess due to the delayed 
evaluation inside the lazy-seq).

user=> (take 20 primes)
;; truncating the output a bit this time...
(primes (2) x 3
...
primes (2) x 31
2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 primes (2 3 5 7 9 11 13 15 17 19 21 
23 25 27 29 31) x 32
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 33
...
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 63
31 37 41 43 47)

So I made a couple of mistakes on my first glance of what this was doing. 
It is chunking via range, but the chunk boundary is not the first 32 
elements we get from range, it is the values we get *up to 32*. This is 
because we drop 3 elements from (range), but the chunk boundary is still 
coming from (range).

I added a print for the value of "primes" within the prime? function (I 
misplaced it before above, but due to the structure of the code this did 
not affect the correctness of the output). As we see, values up to 32 see a 
set of primes being (2), and verifying, the output gives us odd numbers 
from 3 up through 31. The next 32 items are filtered properly, because as 
you can expect, every non-prime below 64 has a factor below 32.

I take back my prior assertion that the alternative to the first N elements 
seeing (2) as their list of primes is a compilation error - another 
alternative would be whole-language lazy evaluation, under which the 
definition of primes would be perfectly cromulent. Also we could hide the 
problem by eliminating chunking (getting more intuitive behavior at the 
expense of performance). Of course (iterate inc 3) avoids the problem 
because its result is not chunked.

I don't want to sound too brusque in my defense of Clojure. I'm a huge fan, 
so criticism of the language does get me a bit defensive. But preferring 
different behavior is actually reasonable here. There are other Lisps (and 
languages in the ML family) that are more internally consistent. I'll 
continue to prefer the better performance and easy access to host interop, 
even if it does violate the occasional abstraction. But of course there is 
no reason to begrudge someone else holding a different opinion, and 
choosing a language that aligns with those expectations.

But I do hope you give Clojure a chance, it's been very rewarding for me 
and I expect you'd find the same if you take the time to get to know it and 
get a feel for what's idiomatic (part of that being learning to avoid 
unintuitively odd corners of the language, which is of course not something 
you can simply figure out from first principles, it takes a bit of 
exploration and a few mistakes along the way).

On Thursday, February 12, 2015 at 9:05:24 PM UTC-8, Justin Smith wrote:
>
> it's an infinite lazy sequence with itself as a dependency. The first n 
> elements see a value of the initial non-lazy prefix. The alternative would 
> be a compilation error.

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Fluid Dynamics
On Friday, February 13, 2015 at 12:05:24 AM UTC-5, Justin Smith wrote:
>
> it's an infinite lazy sequence with itself as a dependency. The first n 
> elements see a value of the initial non-lazy prefix. The alternative would 
> be a compilation error.


Nope. Every component of the sequence should be a cell with a first value 
and a delay of the rest, or in the chunked case a cell with 32 values and a 
delay of the rest. The delay may or may not have already been forced. But 
under no circumstances should it see a sequence endpoint that never 
actually exists.

And if something goes wrong it should be a runtime error, specifically, if 
computing element N requires going farther than element N-1 the computation 
of some delay should end up trying to force the same delay, which would 
hang ... at runtime. Similar to @(promise).

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
it's an infinite lazy sequence with itself as a dependency. The first n 
elements see a value of the initial non-lazy prefix. The alternative would be a 
compilation error.

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
it's an infinite lazy sequence with itself as a dependency. The first n 
elements see a value of the initial non-lazy prefix. The alternative would be a 
compilation error.

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Fluid Dynamics
On Thursday, February 12, 2015 at 11:24:03 PM UTC-5, Justin Smith wrote:
>
> Not unbound primes, primes as (cons 2 ...). If you look at my post above 
> where I added a print statement to prime? the first 32 inputs see (2) as 
> the value of primes. 32 is the chunking size of the range function.


That does seem broken. It certainly should not see an infinite lazy 
sequence as having only one element, regardless of the timing of when other 
elements are realized or not. 

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Timothy Baldridge
Oh, it's much worse than anyone has mentioned yet. The whole (def primes
...) bit is also a problem. What you are saying to the compiler is "create
a var named primes and assign it this lazy-seq...", and then while defining
that lazy seq you are creating closures that use "primes". That sort of
circular referencing is not only not recommended for code clarity reasons,
but also a problem because parts of the code are delayed.

What you are attempting to do is something akin to this:

(def foo (fn [] (foo)))

Which makes no sense at all. This is pretty much what Clojure lazy seqs
are, a list who's contents are delayed via a closure.

So yes, I would say most Clojure programmers are completely fine with this,
as no one writes Clojure code in a self-referential way like this. Not only
is it completely undefined, it's also quite hard to understand.

Timothy

On Thu, Feb 12, 2015 at 9:24 PM, Justin Smith  wrote:

> Not unbound primes, primes as (cons 2 ...). If you look at my post above
> where I added a print statement to prime? the first 32 inputs see (2) as
> the value of primes. 32 is the chunking size of the range function.
>
> --
> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
Not unbound primes, primes as (cons 2 ...). If you look at my post above where 
I added a print statement to prime? the first 32 inputs see (2) as the value of 
primes. 32 is the chunking size of the range function.

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni

I really fail to see how this can be related to chunking. So in:

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))

*prime?* would be being called with unbound *primes*? And no exception 
would be raised and again no 4 or even numbers left to testify?

Em sexta-feira, 13 de fevereiro de 2015 01:38:19 UTC-2, Justin Smith 
escreveu:
>
> Clojure is quite elegant, but it's not always unsurprising.
>
> Even if one surprising behavior around lazy-seq realization is changed, 
> others are likely to continue to occur.
>
> The solution to this is to not write code that implicitly relies on a 
> specific timing of lazy realization. If you need results to be calculated 
> in a certain scope, force them, and if you need results to be maximally 
> lazy in order to have correct code, then either force results not to chunk 
> (there are code examples for a "dechunk" function on the net) or refactor 
> to a form that doesn't rely on maximal laziness for correctness. As far as 
> I know, chunked sequences are not likely to leave the language any time 
> soon, and the behavior we see here will inevitably happen with chunked 
> inputs.
>
>
>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
Clojure is quite elegant, but it's not always unsurprising.

Even if one surprising behavior around lazy-seq realization is changed, 
others are likely to continue to occur.

The solution to this is to not write code that implicitly relies on a 
specific timing of lazy realization. If you need results to be calculated 
in a certain scope, force them, and if you need results to be maximally 
lazy in order to have correct code, then either force results not to chunk 
(there are code examples for a "dechunk" function on the net) or refactor 
to a form that doesn't rely on maximal laziness for correctness. As far as 
I know, chunked sequences are not likely to leave the language any time 
soon, and the behavior we see here will inevitably happen with chunked 
inputs.

On Thursday, February 12, 2015 at 7:28:13 PM UTC-8, Jorge Marques Pelizzoni 
wrote:
>
> Anyway, I would be in awe that being Closure such an expressive and 
> elegant language its user base is really ok with an state of affairs in 
> which:
>
> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
> (range))
>
> does not mean what it obviously should and above all means something 
> different from:
>
> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (iterate inc 
> 3)
>
> YES. I've just found out that it is (drop 3 (range)) that makes a 
> difference there.
>
> Even this will not work anymore:
>
> (def primes (cons 2 (for [n (drop 3 (range)) :when (prime? primes n)] n)))
>
> I really hope the actual developers of the language feel differently. At 
> least there's evidence to support that.
>
> Cheers,
>
> Jorge.
>
> Em sexta-feira, 13 de fevereiro de 2015 00:39:03 UTC-2, Justin Smith 
> escreveu:
>>
>> Considering for the sake of argument the possibility that it is a 
>> legitimate bug, and not a result of misusing the language features, it is a 
>> family of bug that will be more common than most, because it reflects a 
>> style of programming that is rare in real Clojure code.
>>
>> But it isn't a bug.
>>
>>


-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Even THIS works now:

(defn primes [] (let [primes' (atom nil)]
  (reset! primes' (cons 2 (filter #(prime? @primes' %) 
(iterate inc 3))



Em sexta-feira, 13 de fevereiro de 2015 01:28:13 UTC-2, Jorge Marques 
Pelizzoni escreveu:
>
> Anyway, I would be in awe that being Closure such an expressive and 
> elegant language its user base is really ok with an state of affairs in 
> which:
>
> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
> (range))
>
> does not mean what it obviously should and above all means something 
> different from:
>
> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (iterate inc 
> 3)
>
> YES. I've just found out that it is (drop 3 (range)) that makes a 
> difference there.
>
> Even this will not work anymore:
>
> (def primes (cons 2 (for [n (drop 3 (range)) :when (prime? primes n)] n)))
>
> I really hope the actual developers of the language feel differently. At 
> least there's evidence to support that.
>
> Cheers,
>
> Jorge.
>
> Em sexta-feira, 13 de fevereiro de 2015 00:39:03 UTC-2, Justin Smith 
> escreveu:
>>
>> Considering for the sake of argument the possibility that it is a 
>> legitimate bug, and not a result of misusing the language features, it is a 
>> family of bug that will be more common than most, because it reflects a 
>> style of programming that is rare in real Clojure code.
>>
>> But it isn't a bug.
>>
>>


-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Anyway, I would be in awe that being Closure such an expressive and 
elegant language its user base is really ok with an state of affairs in 
which:

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))

does not mean what it obviously should and above all means something 
different from:

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (iterate inc 3)

YES. I've just found out that it is (drop 3 (range)) that makes a 
difference there.

Even this will not work anymore:

(def primes (cons 2 (for [n (drop 3 (range)) :when (prime? primes n)] n)))

I really hope the actual developers of the language feel differently. At 
least there's evidence to support that.

Cheers,

Jorge.

Em sexta-feira, 13 de fevereiro de 2015 00:39:03 UTC-2, Justin Smith 
escreveu:
>
> Considering for the sake of argument the possibility that it is a 
> legitimate bug, and not a result of misusing the language features, it is a 
> family of bug that will be more common than most, because it reflects a 
> style of programming that is rare in real Clojure code.
>
> But it isn't a bug.
>
>
>>>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
no, we have not moved past this, and the error is absolutely because you 
take too much for granted about lazy behavior

(defn divides? [x y] (zero? (mod x y)))


(defn prime-ub [x] (/ x (if (even? x) 2 3)))


(defn lower-primes [primes x] (let [ub (prime-ub x)]
(println "primes" primes "x" x)
(take-while #(<= % ub) primes)))


(defn prime? [primes x] (not-any? #(divides? x %)(lower-primes primes x)))


user=> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))
#'user/primes
user=> (take 20 primes)
(primes (2) x 3
primes (2) x 4
primes (2) x 5
primes (2) x 6
primes (2) x 7
primes (2) x 8
primes (2) x 9
primes (2) x 10
primes (2) x 11
primes (2) x 12
primes (2) x 13
primes (2) x 14
primes (2) x 15
primes (2) x 16
primes (2) x 17
primes (2) x 18
primes (2) x 19
primes (2) x 20
primes (2) x 21
primes (2) x 22
primes (2) x 23
primes (2) x 24
primes (2) x 25
primes (2) x 26
primes (2) x 27
primes (2) x 28
primes (2) x 29
primes (2) x 30
primes (2) x 31
2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 primes (2 3 5 7 9 11 13 15 17 19 21 
23 25 27 29 31) x 32
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 33
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 34
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 35
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 36
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 37
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 38
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 39
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 40
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 41
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 42
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 43
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 44
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 45
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 46
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 47
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 48
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 49
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 50
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 51
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 52
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 53
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 54
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 55
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 56
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 57
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 58
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 59
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 60
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 61
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 62
primes (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31) x 63
31 37 41 43 47)


On Thursday, February 12, 2015 at 6:47:34 PM UTC-8, Jorge Marques Pelizzoni 
wrote:
>
>
> So why isn't 4 and any even numbers in the result list? Empty primes' 
> allows everything to pass. We are already beyond this. I've already posted 
> that even this does not work:
>
> (def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
> (range))
>
>
> Em sexta-feira, 13 de fevereiro de 2015 00:39:03 UTC-2, Justin Smith 
> escreveu:
>>
>> Considering for the sake of argument the possibility that it is a 
>> legitimate bug, and not a result of misusing the language features, it is a 
>> family of bug that will be more common than most, because it reflects a 
>> style of programming that is rare in real Clojure code.
>>
>> But it isn't a bug.
>>
>> Lazy-seqs don't promise to be "as lazy as possible", and when we step 
>> through the logic of the original code in Michael Blume's post, we can see 
>> why chunking breaks it. Taking for granted that something lazy is realized 
>> with a specific granularity is an error in Clojure (see also lazy-seqs used 
>> inside with-open blocks or db transactions - the opposite error is common, 
>> not being strict enough).
>>
>> defn primes [] (let [primes' (atom nil)]
>>  (reset! primes' (cons 2 (filter #(prime? @primes' %) 
>> (drop 3 (range)))
>>
>> The first time through the above code, primes' will be empty, so the 
>> first chunk of results will all be calculated with an empty list of 
>> candidate divisors.
>>
>>>

-- 
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...@googleg

Re: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni

So why isn't 4 and any even numbers in the result list? Empty primes' 
allows everything to pass. We are already beyond this. I've already posted 
that even this does not work:

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))


Em sexta-feira, 13 de fevereiro de 2015 00:39:03 UTC-2, Justin Smith 
escreveu:
>
> Considering for the sake of argument the possibility that it is a 
> legitimate bug, and not a result of misusing the language features, it is a 
> family of bug that will be more common than most, because it reflects a 
> style of programming that is rare in real Clojure code.
>
> But it isn't a bug.
>
> Lazy-seqs don't promise to be "as lazy as possible", and when we step 
> through the logic of the original code in Michael Blume's post, we can see 
> why chunking breaks it. Taking for granted that something lazy is realized 
> with a specific granularity is an error in Clojure (see also lazy-seqs used 
> inside with-open blocks or db transactions - the opposite error is common, 
> not being strict enough).
>
> defn primes [] (let [primes' (atom nil)]
>  (reset! primes' (cons 2 (filter #(prime? @primes' %) 
> (drop 3 (range)))
>
> The first time through the above code, primes' will be empty, so the first 
> chunk of results will all be calculated with an empty list of candidate 
> divisors.
>
>>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
Considering for the sake of argument the possibility that it is a 
legitimate bug, and not a result of misusing the language features, it is a 
family of bug that will be more common than most, because it reflects a 
style of programming that is rare in real Clojure code.

But it isn't a bug.

Lazy-seqs don't promise to be "as lazy as possible", and when we step 
through the logic of the original code in Michael Blume's post, we can see 
why chunking breaks it. Taking for granted that something lazy is realized 
with a specific granularity is an error in Clojure (see also lazy-seqs used 
inside with-open blocks or db transactions - the opposite error is common, 
not being strict enough).

defn primes [] (let [primes' (atom nil)]
 (reset! primes' (cons 2 (filter #(prime? @primes' %) (drop 
3 (range)))

The first time through the above code, primes' will be empty, so the first 
chunk of results will all be calculated with an empty list of candidate 
divisors.

On Thursday, February 12, 2015 at 5:26:52 PM UTC-8, Jorge Marques Pelizzoni 
wrote:
>
>
> Beautiful, Armando! Thanks for your the insight. Anyway, I really don't 
> buy the "that's the way it is" argument. Totally looks like a bug and I 
> don't find it a coincidence it is working differently in the development 
> branch. Thank you all for your time :)
>
> Em quinta-feira, 12 de fevereiro de 2015 22:30:02 UTC-2, Armando Blancas 
> escreveu:
>>
>> Jorge, I tried this on 1.6 and seemed to work:
>>
>> (def primes
>>   (cons 2 (for [n (iterate inc 3) :when (prime? primes n)] n)))
>>
>>
>>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Not even this works (in which I try to avoid state mutation):

(def primes (cons 2 (lazy-seq (filter #(prime? primes %) (drop 3 
(range))



Em quinta-feira, 12 de fevereiro de 2015 23:26:03 UTC-2, Fluid Dynamics 
escreveu:
>
> AFAICT the issue here is combining lazy evaluation with state mutation. 
> Don't do that. :)
>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Fluid Dynamics
AFAICT the issue here is combining lazy evaluation with state mutation. 
Don't do that. :)

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni

Beautiful, Armando! Thanks for your the insight. Anyway, I really don't buy 
the "that's the way it is" argument. Totally looks like a bug and I don't 
find it a coincidence it is working differently in the development branch. 
Thank you all for your time :)

Em quinta-feira, 12 de fevereiro de 2015 22:30:02 UTC-2, Armando Blancas 
escreveu:
>
> Jorge, I tried this on 1.6 and seemed to work:
>
> (def primes
>   (cons 2 (for [n (iterate inc 3) :when (prime? primes n)] n)))
>
>
>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Justin Smith
This is excellent, I was just working out something similar myself.

The version using an atom is not idiomatic Clojure, and isn't a translation 
of the Haskell version either.

On Thursday, February 12, 2015 at 4:30:02 PM UTC-8, Armando Blancas wrote:
>
> Jorge, I tried this on 1.6 and seemed to work:
>
> (def primes
>   (cons 2 (for [n (iterate inc 3) :when (prime? primes n)] n)))
>
> On Thursday, February 12, 2015 at 4:21:45 PM UTC-8, Jorge Marques 
> Pelizzoni wrote:
>>
>> Neither did delay help:
>>
>> (defn primes [] (let [primes' (atom nil)]
>>   (reset! primes' (delay (cons 2 (filter #(prime? (force 
>> (deref primes')) %) (drop 3 (range
>>
>>
>> Serious this is not a bug?
>>
>> Em quinta-feira, 12 de fevereiro de 2015 22:14:46 UTC-2, Jorge Marques 
>> Pelizzoni escreveu:
>>>
>>> Thanks, Michael, for your analysis and explanation. However not even 
>>> this worked:
>>>
>>> (defn primes [] (let [primes' (atom nil)]
>>>   (lazy-seq (reset! primes' (lazy-seq (cons 2 (lazy-seq 
>>> (filter #(prime? (deref primes') %) (drop 3 (range))
>>>
>>>
>  

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Armando Blancas
Jorge, I tried this on 1.6 and seemed to work:

(def primes
  (cons 2 (for [n (iterate inc 3) :when (prime? primes n)] n)))

On Thursday, February 12, 2015 at 4:21:45 PM UTC-8, Jorge Marques Pelizzoni 
wrote:
>
> Neither did delay help:
>
> (defn primes [] (let [primes' (atom nil)]
>   (reset! primes' (delay (cons 2 (filter #(prime? (force 
> (deref primes')) %) (drop 3 (range
>
>
> Serious this is not a bug?
>
> Em quinta-feira, 12 de fevereiro de 2015 22:14:46 UTC-2, Jorge Marques 
> Pelizzoni escreveu:
>>
>> Thanks, Michael, for your analysis and explanation. However not even this 
>> worked:
>>
>> (defn primes [] (let [primes' (atom nil)]
>>   (lazy-seq (reset! primes' (lazy-seq (cons 2 (lazy-seq 
>> (filter #(prime? (deref primes') %) (drop 3 (range))
>>
>>
  

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Andy Fingerhut
Laziness is pervasive in Haskell, for all computation (unless you force it
off with special constructs).

Laziness in Clojure is as pervasive as sequences, but it is not for all
computation like in Haskell, and sequences have the previously-mentioned
features of sometimes-more-eager-than-the-minimum required.

Self-referential lazy sequences are something I would recommend actively
avoiding in Clojure, unless you want to live with buggy code, or dig into
the implementation and convince yourself that you are within its behavior
(which can change from version to version).

Andy

On Thu, Feb 12, 2015 at 4:21 PM, Jorge Marques Pelizzoni <
jorge.pelizz...@gmail.com> wrote:

> Neither did delay help:
>
> (defn primes [] (let [primes' (atom nil)]
>   (reset! primes' (delay (cons 2 (filter #(prime? (force (
> deref primes')) %) (drop 3 (range
>
>
> Serious this is not a bug?
>
> Em quinta-feira, 12 de fevereiro de 2015 22:14:46 UTC-2, Jorge Marques
> Pelizzoni escreveu:
>>
>> Thanks, Michael, for your analysis and explanation. However not even this
>> worked:
>>
>> (defn primes [] (let [primes' (atom nil)]
>>   (lazy-seq (reset! primes' (lazy-seq (cons 2 (lazy-seq
>> (filter #(prime? (deref primes') %) (drop 3 (range))
>>
>>
   --
> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Neither did delay help:

(defn primes [] (let [primes' (atom nil)]
  (reset! primes' (delay (cons 2 (filter #(prime? (force 
(deref primes')) %) (drop 3 (range


Serious this is not a bug?

Em quinta-feira, 12 de fevereiro de 2015 22:14:46 UTC-2, Jorge Marques 
Pelizzoni escreveu:
>
> Thanks, Michael, for your analysis and explanation. However not even this 
> worked:
>
> (defn primes [] (let [primes' (atom nil)]
>   (lazy-seq (reset! primes' (lazy-seq (cons 2 (lazy-seq 
> (filter #(prime? (deref primes') %) (drop 3 (range))
>
>
>>>  

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Thanks, Michael, for your analysis and explanation. However not even this 
worked:

(defn primes [] (let [primes' (atom nil)]
  (lazy-seq (reset! primes' (lazy-seq (cons 2 (lazy-seq 
(filter #(prime? (deref primes') %) (drop 3 (range))


And one thing we klnow for sure is that (deref primes') is not nil, 
otherwise all numbers would be output as prime numbers...

Jorge.

Em quinta-feira, 12 de fevereiro de 2015 18:48:10 UTC-2, Michael Blume 
escreveu:
>
> Hmm, upon further investigation I think I would not call this a bug in 
> Clojure that got fixed, I think I'd call this an unspecified behavior in 
> Clojure that happened to break your function and now happens to allow it to 
> work.
>
> Your function depends heavily on Clojure's laziness, and laziness is an 
> area where Clojure actually does not make a lot of strong guarantees.
>
> Here's an example:
>
> user=> (def r (into [] (range 1000)))
> #'user/r
> user=> (defn print-and-inc [x] (println x) (inc x))
> #'user/print-and-inc
> user=> (def s (map print-and-inc r))
> #'user/s
> user=> (take 1 s)
> 0
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
> 11
> 12
> 13
> 14
> 15
> 16
> 17
> 18
> 19
> 20
> 21
> 22
> 23
> 24
> 25
> 26
> 27
> 28
> 29
> 30
> 31
> (1)
> user=>
>
> In this example we put a thousand numbers in a vector and call the vector 
> r, we map print-and-inc over r and then we take one element from the 
> resulting lazy sequence. You might expect this to mean we print one element 
> from r, but in fact we print 32. This is because of an optimization detail 
> in Clojure's map function. It's very easy to extract "chunks" from vectors, 
> so in Clojure, when we map over a vector, we quickly apply the mapping 
> function to the first chunk of the vector and return a sequence containing 
> the result chunk and a promise to map over the rest. In the long run, this 
> speeds up map quite a bit, but in the short run, it makes map much less 
> lazy than one might expect.
>
> The upshot is that when a Clojure function promises to consume your list 
> lazily, you should assume that it will not, say, consume 1000 elements of 
> your list for no reason, or try to force its way to the end of a lazy 
> sequence. You should *not* assume you can know exactly when it will force 
> the next element, as that is essentially considered an implementation 
> detail.
>
> Returning to your code, you have
>
> (defn primes [] (let [primes' (atom nil)]
>  (reset! primes' (cons 2 (filter #(prime? @primes' %) 
> (drop 3 (range)))
>
> When you dereference primes, you're essentially trusting that reset! has 
> already run and replaced nil with your empty sequence, but in fact you 
> cannot be certain of that. I can see two ways to ensure your function will 
> work. One is sort of gratuitous defensive programming -- make your initial 
> value of primes' something you *wouldn't mind getting*, say
>
> (defn primes [] (let [primes' (atom (drop 2 (range)))]
>  (reset! primes' (cons 2 (filter #(prime? @primes' %) 
> (drop 3 (range)))
>
> The other is to wrap your whole expression in lazy-seq -- then reset! will 
> definitely complete before any of the logic internal to your sequence runs:
>
> (defn primes [] (let [primes' (atom nil)]
>  (lazy-seq (reset! primes' (cons 2 (filter #(prime? 
> @primes' %) (drop 3 (range
>
> For anyone wondering, the change was Ghadi's reified range in CLJ-1515 
> which I seem to recall removed/modified the chunked seq implementation from 
> range.
>
> On Thu Feb 12 2015 at 12:06:28 PM Jorge Marques Pelizzoni <
> jorge.p...@gmail.com > wrote:
>
>> Well, that's a bug then :) And seems to have been fixed. Thanks!
>>
>> Em quinta-feira, 12 de fevereiro de 2015 17:51:13 UTC-2, Michael Blume 
>> escreveu:
>>
>>> Oh, well this is fun -- with bleeding edge clojure I get the right 
>>> answer, but with 1.6.0 I see the same results you did.
>>>
>>>
>>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@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+u...@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...

Re: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Michael Blume
Hmm, upon further investigation I think I would not call this a bug in
Clojure that got fixed, I think I'd call this an unspecified behavior in
Clojure that happened to break your function and now happens to allow it to
work.

Your function depends heavily on Clojure's laziness, and laziness is an
area where Clojure actually does not make a lot of strong guarantees.

Here's an example:

user=> (def r (into [] (range 1000)))
#'user/r
user=> (defn print-and-inc [x] (println x) (inc x))
#'user/print-and-inc
user=> (def s (map print-and-inc r))
#'user/s
user=> (take 1 s)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(1)
user=>

In this example we put a thousand numbers in a vector and call the vector
r, we map print-and-inc over r and then we take one element from the
resulting lazy sequence. You might expect this to mean we print one element
from r, but in fact we print 32. This is because of an optimization detail
in Clojure's map function. It's very easy to extract "chunks" from vectors,
so in Clojure, when we map over a vector, we quickly apply the mapping
function to the first chunk of the vector and return a sequence containing
the result chunk and a promise to map over the rest. In the long run, this
speeds up map quite a bit, but in the short run, it makes map much less
lazy than one might expect.

The upshot is that when a Clojure function promises to consume your list
lazily, you should assume that it will not, say, consume 1000 elements of
your list for no reason, or try to force its way to the end of a lazy
sequence. You should *not* assume you can know exactly when it will force
the next element, as that is essentially considered an implementation
detail.

Returning to your code, you have

(defn primes [] (let [primes' (atom nil)]
 (reset! primes' (cons 2 (filter #(prime? @primes' %) (drop
3 (range)))

When you dereference primes, you're essentially trusting that reset! has
already run and replaced nil with your empty sequence, but in fact you
cannot be certain of that. I can see two ways to ensure your function will
work. One is sort of gratuitous defensive programming -- make your initial
value of primes' something you *wouldn't mind getting*, say

(defn primes [] (let [primes' (atom (drop 2 (range)))]
 (reset! primes' (cons 2 (filter #(prime? @primes' %) (drop
3 (range)))

The other is to wrap your whole expression in lazy-seq -- then reset! will
definitely complete before any of the logic internal to your sequence runs:

(defn primes [] (let [primes' (atom nil)]
 (lazy-seq (reset! primes' (cons 2 (filter #(prime?
@primes' %) (drop 3 (range

For anyone wondering, the change was Ghadi's reified range in CLJ-1515
which I seem to recall removed/modified the chunked seq implementation from
range.

On Thu Feb 12 2015 at 12:06:28 PM Jorge Marques Pelizzoni <
jorge.pelizz...@gmail.com> wrote:

> Well, that's a bug then :) And seems to have been fixed. Thanks!
>
> Em quinta-feira, 12 de fevereiro de 2015 17:51:13 UTC-2, Michael Blume
> escreveu:
>
>> Oh, well this is fun -- with bleeding edge clojure I get the right
>> answer, but with 1.6.0 I see the same results you did.
>>
>>
>>  --
> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Andy Fingerhut
Or perhaps 1.7.0-alpha5 has a change vs. 1.6.0 that makes this code work by
accident.

Using lazy sequences to define later elements in terms of the prefix of the
sequence up to that point has come up multiple times, usually with the
example of generating primes (but different code each time).

I don't have time to dig for those examples and the explanation right now,
but I believe one potential issue is that lazy sequences are sometimes
'chunked' (the return value of range is) into groups of 32 consecutive
elements, and some functions operating on sequences preserve those chunks,
and operate on those batches of 32 elements all at once.  Also there are
some Clojure functions that are 'more eager than necessary', evaluating a
few elements of the lazy sequence past the minimum needed.

Andy

On Thu, Feb 12, 2015 at 12:06 PM, Jorge Marques Pelizzoni <
jorge.pelizz...@gmail.com> wrote:

> Well, that's a bug then :) And seems to have been fixed. Thanks!
>
> Em quinta-feira, 12 de fevereiro de 2015 17:51:13 UTC-2, Michael Blume
> escreveu:
>>
>> Oh, well this is fun -- with bleeding edge clojure I get the right
>> answer, but with 1.6.0 I see the same results you did.
>>
>>
>>  --
> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Jorge Marques Pelizzoni
Well, that's a bug then :) And seems to have been fixed. Thanks!

Em quinta-feira, 12 de fevereiro de 2015 17:51:13 UTC-2, Michael Blume 
escreveu:
>
> Oh, well this is fun -- with bleeding edge clojure I get the right answer, 
> but with 1.6.0 I see the same results you did.
>
>
>

-- 
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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Michael Blume
Oh, well this is fun -- with bleeding edge clojure I get the right answer,
but with 1.6.0 I see the same results you did.

On Thu Feb 12 2015 at 11:47:54 AM Michael Blume 
wrote:

> Strange, when I run your code I don't get 9 or 15
>
> On Thu Feb 12 2015 at 11:02:00 AM Jorge Marques Pelizzoni <
> jorge.pelizz...@gmail.com> wrote:
>
>> Hi, there! Please bear with me as I am very new to Closure (this is my
>> second program ever) but have a kind of solid Haskell background.
>>
>> I was trying to get a version of this Haskell code:
>>
>> divides x y = mod x y == 0
>> primeub x = div x (if even x then 2 else 3)
>> isprime primes x = all (not . divides x) (lowerprimes x)
>> where
>> lowerprimes x = takeWhile (<= primeub x) primes
>>
>> primes = 2 : filter (isprime primes) [3..]
>>
>>
>> which works fine. E.g.: take 10 primes == [2,3,5,7,11,13,17,19,23,29].
>> In Closure, I got this:
>>
>> (defn divides? [x y] (zero? (mod x y)))
>> (defn prime-ub [x] (/ x (if (even? x) 2 3)))
>> (defn lower-primes [primes x] (let [ub (prime-ub x)]
>>   (take-while #(<= % ub) primes)))
>> (defn prime? [primes x] (not-any? #(divides? x %)(lower-primes primes x
>> )))
>>
>> (defn primes [] (let [primes' (atom nil)]
>>  (reset! primes' (cons 2 (filter #(prime? @primes' %)
>> (drop 3 (range)))
>>
>> However, I am getting (take 10 (primes)) == (2 3 5 7 9 11 13 15 17 19)
>> (please notice the undesirable presence of 9 and 15 there...).
>>
>> Any ideas why this is happening? Thanks in advance.
>>
>>
>>  --
>> 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: [newbie] strange behaviour in self-referential primes lazy-seq attempt

2015-02-12 Thread Michael Blume
Strange, when I run your code I don't get 9 or 15

On Thu Feb 12 2015 at 11:02:00 AM Jorge Marques Pelizzoni <
jorge.pelizz...@gmail.com> wrote:

> Hi, there! Please bear with me as I am very new to Closure (this is my
> second program ever) but have a kind of solid Haskell background.
>
> I was trying to get a version of this Haskell code:
>
> divides x y = mod x y == 0
> primeub x = div x (if even x then 2 else 3)
> isprime primes x = all (not . divides x) (lowerprimes x)
> where
> lowerprimes x = takeWhile (<= primeub x) primes
>
> primes = 2 : filter (isprime primes) [3..]
>
>
> which works fine. E.g.: take 10 primes == [2,3,5,7,11,13,17,19,23,29]. In
> Closure, I got this:
>
> (defn divides? [x y] (zero? (mod x y)))
> (defn prime-ub [x] (/ x (if (even? x) 2 3)))
> (defn lower-primes [primes x] (let [ub (prime-ub x)]
>   (take-while #(<= % ub) primes)))
> (defn prime? [primes x] (not-any? #(divides? x %)(lower-primes primes x)))
>
> (defn primes [] (let [primes' (atom nil)]
>  (reset! primes' (cons 2 (filter #(prime? @primes' %)
> (drop 3 (range)))
>
> However, I am getting (take 10 (primes)) == (2 3 5 7 9 11 13 15 17 19)
> (please notice the undesirable presence of 9 and 15 there...).
>
> Any ideas why this is happening? Thanks in advance.
>
>
>  --
> 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.