so I try this code
(for [x (range 1 8) y (range 1 8) :while (and (< x y) (even? x))] [x y])
and get back ()
but I try this:
(for [x (range 1 8) y (range 1 8) :while (and (< y x) (even? x))] [x y])
and I get the desired result. What effect did changing the positions of x and y have? The first snippet shouldn't return an empty list.. after all there have to be some even x's smaller than y
In Clojure, (for [x (range 1 8) y (range 1 8)] [x y])
returns the cartesian product of x
and y
with y
running from 1
to 7
for each and every iteration of x
.
From the repl:
user=> (for [x (range 1 8) y (range 1 8)] [x y])
([1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [4 1] [4 2] [4 3] [4 4] [4 5] [4 6] [4 7] [5 1] [5 2] [5 3] [5 4] [5 5] [5 6] [5 7] [6 1] [6 2] [6 3] [6 4] [6 5] [6 6] [6 7] [7 1] [7 2] [7 3] [7 4] [7 5] [7 6] [7 7])
In your examples, :while
is associated with y
and not x
. So the :while
applies for every iteration of y
and then restarts after the next iteration of x
.
To make this clearer, note that you can also associate :while
with x
:
user=> (for [x (range 1 8) :while (odd? x) y (range 1 8)] [x y])
([1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7])
which runs the loop while x
is odd, then breaks.
So in your first example, :while
breaks on every single iteration on y
when y
equals 1
because there is no value of x
for which (and (< x 1) (even? x))
holds true
.
Your second example, on the other hand, works because even though :while
breaks on the first iteration of y
because (< 1 1)
yields false
, the second iteration of y
succeeds because x
starts from 2
, so if y
is 1
, and (and (< y x) (even? x))
is (and (< 1 2) (even? 2))
which evaluates to true
.
See http://clojuredocs.org/clojure_core/clojure.core/for for more details. Especially the part showing the difference between :when
and :while
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With