Subject: Re: The LOOP macro (was Re: Be afraid of XML)
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 14 Mar 2004 09:09:07 -0600
Newsgroups: comp.lang.lisp
Message-ID: <wiCdnWFv05gO6Mnd3czS-w@speakeasy.net>
I just wrote:
+---------------
| Pascal Bourguignon  <spam@thalassa.informatimago.com> wrote:
| +---------------
| | Because the loop variables don't have to be available in the finally
| | clause! If they're available, their value is unspecified.
| +---------------
...
| The FINALLY clause is definitely "textually within the loop", so it must
| have access to all of the iteration control variables defined therein.
+---------------

Let me be a little more clear about what I'm suggesting/arguing. There are
actually two parts to this issue:

1. Whether the FINALLY clause is within the scope of the iteration variables.
   On this sub-point, I will continue to claim that it must be. And in
   fact your CLISP "counterexample" is no counterexample at all, since
   both *were* still visible!!

2. Whether the specific iteration variable which caused the loop to
   terminate (and any other variables in the *same* FOR...[AND...]*
   group) has been incremented past the termination condition or not
   when viewed by the FINALLY clause. On this sub-point I am less clear,
   and therefore will not argue particularly strongly one way or the
   other (though I confess a bias towards "stepping just before testing",
   see below). The reason for this uncertainty is an apparent conflict
   between the text in CLHS "6.1.2.1 Iteration Control" [emphasis added]:

	The for and as clauses iterate by using one or more local loop
	variables that are initialized to some value and that can be
	modified or STEPPED[1] AFTER EACH ITERATION. For these clauses,
	iteration terminates when a local variable reaches some supplied
	value or when some other loop clause terminates iteration. AT EACH
	ITERATION, VARIABLES CAN BE STEPPED[1] by an increment or a decrement
	or can be assigned a new value by the evaluation of a form).

   which implies that stepping occurs *after* each iteration [although
   the phrase "AT each iteration" raises some uncertainty], while CLHS
   "6.1.2.1.1 The for-as-arithmetic subclause" says:

	The variable var is BOUND to the value of form1 IN THE FIRST
	ITERATION AND IS STEPPED[1] by the value of form3 IN EACH SUCCEEDING
	ITERATION, or by 1 if form3 is not provided.

   That is, "in" could be anytime during an iteration outside of the body
   forms, which seems to leave open the possibility that stepping occurs
   before the *next* iteration if the termination condition is not met,
   and is not done if the termination condition is is met. Thus it is
   perhaps not totally unreasonable to allow the specific iteration
   variable which caused the loop to terminate (and its AND brethren)
   to *not* have been stepped when the loop terminates.

But whatever the case with the specific iteration variable which caused
the loop to terminate, the iteration variables which occur in *later* FORs
(sequential binding/stepping) must still contain the values they were last
stepped to (during the previous iteration) when the FINALLY is run. That is,
I concede that it is possible for the following form:

	(loop for i below 4
	      for j below 4
	  finally (return (list i j)))

to return either (4 3) or (3 3) [the latter only if the termination test
were smart enough to see that stepping "i" would take it to 4 or above], but
*not* (4 4)!! Therefore I would claim that CLISP is incorrect in this case.


-Rob

p.s. The form:

	(loop for i below 4
	      and j below 4
	  finally (return (list i j)))

could thus conceivably return either (3 3) or (4 4) [both CLISP & CMUCL
give the latter], but I believe that (4 3) and (3 4) should be forbidden
here. That is, in "parallel" steppings with AND, either all variables
in the FOR[AND]* set should be stepped before the final termination test
or none should. IMHO.

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607