Re: The LOOP macro (was Re: Be afraid of XML)

From: Rob Warnock (rpw3_at_rpw3.org)
Date: 03/14/04


Date: Sun, 14 Mar 2004 09:09:07 -0600

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



Relevant Pages

  • Re: LOOP blows!
    ... The order of initialization follows the ... There are two `initializations' in execution of LOOP, ... before staring the first iteration. ... |> The first for clause will never terminate. ...
    (comp.lang.lisp)
  • Re: LOOP blows!
    ...     clauses appear in the source. ... This clause is not combined with the ... Right, and ``People'' includes the ones implementing LOOP, apparently, ... You must use your hidden list iteration variable to set up the ...
    (comp.lang.lisp)
  • Re: Structure of the multitasking server
    ... Which is a bad pattern because it propagates task termination requests to ... task Server is ... Workers: array of Worker; ... for Times in 1..7 loop ...
    (comp.lang.ada)
  • Re: The mystery of the missing (compound) variables.
    ... separated text string line which can be PARSEd. ... limit of 50 passes through the loop. ... to the second last END clause. ... other than READY the THEN LEAVE clause passes control to the second ...
    (comp.lang.rexx)
  • RE: Oracle cursor help
    ... rids dbms_utility.uncl_array; ... where <your where clause> ... Subject: Re: Oracle cursor help ... exit the loop: */ ...
    (perl.dbi.users)