LOOP macro initialization order is inconsistent.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
SBCL version: 1.4.13.
Reproduction:
(loop for a = 1 then (1+ a)
for b from (if a 2 100)
while (< a 10)
collect b)
Result: (100 101 102 103 104 105 106 107 108)
This happens because A is initialized after B, so it's NIL when B is initialized.
The HyperSpec suggests that A should be initialized first:
http://
"If multiple iteration clauses are used to control iteration, variable initialization and stepping occur sequentially by default."
That's a little bit vague, because you can argue about whether B is being "used to control
iteration" since it isn't involved in any termination tests. CLtL is more clear on this matter:
https:/
"All variables are initialized first, regardless of where the establishing clauses
appear in the source. The order of initialization follows the order of these clauses."
If I iterate B with a =..THEN clause, I get a result that
shows that initialization is happening in the correct order:
(loop for a = 1 then (1+ a)
for b = (if a 2 100) then (1+ b)
while (< a 10)
collect b)
Result: (2 3 4 5 6 7 8 9 10)
The difference happens because = uses the LET form to do its initialization,
while FROM does its initialization at the beginning of the loop TAGBODY, using
DESETQ.