David Powell <[email protected]> writes:
>> No, it's perfectly possible to have a comprehension with a :while that
>> generates more elements after :while evaluated to false. :while skips
>> some bindings, but it doesn't need to skip all of them. See my original
>> reply to Nicolas.
>
> Wow - I never knew that. That isn't at all obvious from the sparse
> doc string.
Yes, that's really not really easy to get right.
> (Is that actually a bug, I wonder? - it seems like a pretty useless
> behaviour?)
I think it's useful. Check my second example with the :while as last
form. Although these two result in the same value
(for [x [1 2 3] y [1 2 3] z [1 2 3] :while (<= x y)] [x y z])
(for [x [1 2 3] y [1 2 3] z [1 2 3] :when (<= x y)] [x y z])
the former performs a bit better because the version with :when needs to
test the :when form for any binding while the :while version doesn't
evaluates the test less frequently.
Another example counting the number of test evaluations:
--8<---------------cut here---------------start------------->8---
user> (def a (atom 0))
#'user/a
user> (time (dorun (for [x (range 1000)
y (range 100)
z [1 2 3]
:when (do (swap! a inc) (<= x y))]
[x y z])))
"Elapsed time: 205.593919 msecs"
nil
user> @a
300000
user> (def a (atom 0))
#'user/a
user> (time (dorun (for [x (range 1000)
y (range 100)
z [1 2 3]
:while (do (swap! a inc) (<= x y))]
[x y z])))
"Elapsed time: 146.163655 msecs"
nil
user> @a
110100
--8<---------------cut here---------------end--------------->8---
So if your :while/:when test is expensive, that might make a difference
performance-wise.
Bye,
Tassilo
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en