From: Pascal Bourguignon
Subject: loop never + thereis
Date: 
Message-ID: <87vfcyu3gc.fsf@thalassa.informatimago.com>
I find this while trying to compile ThinLisp in clisp 2.33.2:

*** - LOOP: ambiguous result of loop 
(LOOP FOR SUBFORM = (CAR SUBFORM-CONS) WHILE SUBFORM-CONS NEVER (ATOM SUBFORM)
 THEREIS (EQUAL SUBFORM '(TL:GO TL::NEXT-LOOP)) DO
 (SETF SUBFORM-CONS (CONS-CDR SUBFORM-CONS)))
�Break 1 TLI[7]> 


The formal syntax of LOOP does not impose any exclusion between always
or never and thereis. 

Here is what CLHS says about the default return value for always,
never  and thereis:

always:   Otherwise, it provides a default return value of t. 

never:    Unless some other clause contributes a return value, the
          default value returned is t.

thereis:  Unless some other clause contributes a return value, the
          default value returned is nil.


So, the result specified by never and thereis seem to be in
contradiction, but these clauses are not evaluated in parallel!

    6.1.1.6 Order of Execution

    With the exceptions listed below, clauses are executed in the loop
    body in the order in which they appear in the source. Execution is
    repeated until a clause terminates the loop or until a return, go, or
    throw form is encountered which transfers control to a point outside
    of the loop.

Obviously, one of the never or thereis clause will determine it's
time to return before the other, and then the "unless someother clause
contributes a return value" condition will activate in the other
clause and it won't provide a default value.

IMO, there's absolutely no ambiguity in there.

   (loop never condition-1 
         thereis condition-2 
         while condition-3 
         do body
         finally something)

should mean:

   (loop :loop
         with default-return-value
         do (if condition-1
                (return-from :loop nil)
                (setf default-return-value t))
            (if condition-2
                (setf default-return-value nil)
                (return-from :loop t))
            (if condition-3
                (progn body)
                (loop-finish))
          finally something
                  (return default-return-value))


Or for another example:

    (loop for i from 1 to 10 thereis nil never nil)

should return the default value of the last clause seen: T




My reading of CLHS          -           T

ThinLisp source expects:    -           T

clisp   2.33.2              error       -

gcl     2.6.3               warning     NIL

ecl     0.9                 warning     T

cmucl   18e                 warning     T

sbcl    0.8.14.9            -           T       (issues a deleting 
                                                 unreachable code note
                                                 as expected).


So, the question is: what does the standard specify in the case where
we mix ALWAYS or NEVER with THEREIS in a LOOP?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Voting Democrat or Republican is like choosing a cabin in the Titanic.

From: Yuji Minejima
Subject: Re: loop never + thereis
Date: 
Message-ID: <5c5533cb.0410251751.573f06cc@posting.google.com>
Pascal Bourguignon <····@mouse-potato.com> wrote in message news:<··············@thalassa.informatimago.com>...

> Obviously, one of the never or thereis clause will determine it's
> time to return before the other, and then the "unless someother clause
> contributes a return value" condition will activate in the other
> clause and it won't provide a default value.
> 
> IMO, there's absolutely no ambiguity in there.
> 
>    (loop never condition-1 
>          thereis condition-2 
>          while condition-3 
>          do body
>          finally something)
> 
> should mean:
> 
>    (loop :loop
>          with default-return-value
>          do (if condition-1
>                 (return-from :loop nil)
>                 (setf default-return-value t))
>             (if condition-2
>                 (setf default-return-value nil)
>                 (return-from :loop t))
>             (if condition-3
>                 (progn body)
>                 (loop-finish))
>           finally something
>                   (return default-return-value))

I think the following expansion which returns the opposite value to
yours seems equally plausible.

(loop :loop
      with default-return-value
      do (when condition-1
           (return-from :loop nil))
         (when condition-2
           (return-from :loop t))
         (if condition-3
             (progn body)
             (loop-finish))
      finally something
              (return t)   ;; never condition-1 origin.
              (return nil) ;; thereis condition-2 origin.
              )

Yuji.
From: Pascal Bourguignon
Subject: Re: loop never + thereis
Date: 
Message-ID: <87d5z6tc9a.fsf@thalassa.informatimago.com>
········@nifty.ne.jp (Yuji Minejima) writes:

> Pascal Bourguignon <····@mouse-potato.com> wrote in message news:<··············@thalassa.informatimago.com>...
> 
> > Obviously, one of the never or thereis clause will determine it's
> > time to return before the other, and then the "unless someother clause
> > contributes a return value" condition will activate in the other
> > clause and it won't provide a default value.
> > 
> > IMO, there's absolutely no ambiguity in there.
> > 
> >    (loop never condition-1 
> >          thereis condition-2 
> >          while condition-3 
> >          do body
> >          finally something)
> > 
> > should mean:
> > 
> >    (loop :loop
> >          with default-return-value
> >          do (if condition-1
> >                 (return-from :loop nil)
> >                 (setf default-return-value t))
> >             (if condition-2
> >                 (setf default-return-value nil)
> >                 (return-from :loop t))
> >             (if condition-3
> >                 (progn body)
> >                 (loop-finish))
> >           finally something
> >                   (return default-return-value))
> 
> I think the following expansion which returns the opposite value to
> yours seems equally plausible.
> 
> (loop :loop
>       with default-return-value
>       do (when condition-1
>            (return-from :loop nil))
>          (when condition-2
>            (return-from :loop t))
>          (if condition-3
>              (progn body)
>              (loop-finish))
>       finally something
>               (return t)   ;; never condition-1 origin.
>               (return nil) ;; thereis condition-2 origin.
>               )
> 
> Yuji.

In fact, most of the free implementations I tested returns a result
agreeing with my interpretation (one gives an error, the other returns
a result agreeing with yours).

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Vladimir Sedach
Subject: Re: loop never + thereis
Date: 
Message-ID: <87pt36g3la.fsf@shawnews.cg.shawcable.net>
Interesting issue (and pretty good ammunition for those who advocate
language design by reference implementation). I usually don't trust
CLISP's implementation of loop.

I tried to get Thinlisp working on CLISP, but gave up because of some
bug or other (I don't think this was it, though). You can download
something I hacked up (with a few improvements) that works ok on CMUCL
and SBCL here: http://voodoohut.homeunix.net/thinlisp-1.1.tar.gz

(I talked the gracious folks who released Thinlisp into allowing me to
post this on their SourceForge site, but then got into a confused mess
with SF's user registration (apparently I'd forgotten I registered
before under the same name, or something stupid), so it never got
done).

Fun fact: Thinlisp has the 2nd most hirsute loop s I've seen, behind
Multi-Garnet (which doesn't work on CLISP either).

Vladimir
From: Pascal Bourguignon
Subject: Re: loop never + thereis
Date: 
Message-ID: <87hdoitg3x.fsf@thalassa.informatimago.com>
Vladimir Sedach <(string-downcase (concatenate 'string last-name (subseq first-name 0 1)))@cpsc.ucalgary.ca> writes:

> Interesting issue (and pretty good ammunition for those who advocate
> language design by reference implementation). I usually don't trust
> CLISP's implementation of loop.

I'd advocate true specification, not informal description of a common
denominator of existing implementations...  But let's say I'm not
refering to Common-Lisp, I don't want to sound to harsh on it.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Voting Democrat or Republican is like choosing a cabin in the Titanic.