while-short-circuit.png is hard to understand
I find this explanation hard to follow. I would like to suggest showing first the form without the :while modifier, and its resulting sequence of the Cartesian product.
user=> (pprint (for [x [1 2 3] y [1 2 3] z [:a :b]] [x y z]))
([1 1 :a]
[1 1 :b]
[1 2 :a]
[1 2 :b]
[1 3 :a]
[1 3 :b]
[2 1 :a]
[2 1 :b]
[2 2 :a]
[2 2 :b]
[2 3 :a]
[2 3 :b]
[3 1 :a]
[3 1 :b]
[3 2 :a]
[3 2 :b]
[3 3 :a]
[3 3 :b])
nil
Then, when discussing the :while following the y sequence, it seems to me that upon meeting the line with element [1 1 :a], the REPL should say, "hey, x and y are equal, I have to skip this line and all next lines where (= x 1), i.e. I have to reset y to 1 and increment x to 2, thus continue at the line containing [2 1 :a]". Upon meeting [2 2 :a] the REPL says to itself, "hey, x and y are equal, I need to skip this line and all the next lines where (= x 2), i.e. I have to reset y to 1 and increment x to 3, thus continue at the line containing [3 1 :a]". Finally, the REPL will meet element [3 3 :a], skip that one, and all the next lines where (= x 3). But no more incrementing x, as its sequence has run out. The resulting seq being:
([2 1 :a] [2 1 :b] [3 1 :a] [3 1 :b] [3 2 :a] [3 2 :b])
When discussing the :while following the z sequence, it seems to me that upon meeting element [1 1 :a], the REPL should say, "hey, x and y are equal, I have to skip this line and all next lines where (= y 1), i.e. I have to reset z to :a and increment y to 2, thus continue at the line containing [1 2 :a]". Upon meeting [2 2 :a] the REPL says to itself, "hey, x and y are equal, I need to skip this line and all the next lines where (= y 2), i.e. I have to reset z to :a and increment y to 3, thus continue at the line containing [2 3 :a]". Finally, the REPL will meet element [3 3 :a], skip that one, and all the next lines where (= y 3). But no more incrementing y, as its sequence has run out of elements. The resulting seq can be shown to contain more elements than the one above:
user=> (pprint (for [x [1 2 3] y [1 2 3] z [:a :b] :while (not= x y)] [x y z]))
([1 2 :a]
[1 2 :b]
[1 3 :a]
[1 3 :b]
[2 1 :a]
[2 1 :b]
[2 3 :a]
[2 3 :b]
[3 1 :a]
[3 1 :b]
[3 2 :a]
[3 2 :b])
nil
I hope you can see the way my brain worked on this and where it deviated from yours :-)
Agreed. IMO the skipped values should not be shown, e.g.,
change
[1 1 :a] - skipping all where (= y 1)
to
skipping all where (= y 1)