LOOP macro initialization order is inconsistent.

Bug #1810229 reported by Jeremy Phelps on 2019-01-02
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
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://www.lispworks.com/documentation/lw70/CLHS/Body/06_aba.htm

   "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://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node239.html

   "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.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers