Subject: [clisp-list] assert goes into an endless loop

From: lin8080 <[email-masked]>
Date: Wed Apr 17 20:50:06 2002

Bruno Haible schrieb:

> With clisp-2.26,

> $ clisp -x '(assert (>= -1 0))'

With clisp-2.28 on win98:

[41]> (load "astest.lisp")
;; Loading file asit.lisp ...
** - Continuable Error
(>= -1 0) must evaluate to a non-NIL value.
If you continue (by typing 'continue'): Retry
1. Break [42]> abort

stefan

---

From: "Claudio Bley" <[email-masked]>
Date: Thu Apr 18 00:56:01 2002

>>>>> "lin8080" == lin8080  <[email-masked]> writes:

    lin8080> With clisp-2.28 on win98:

    lin8080> [41]> (load "astest.lisp") 

OK, but what about: clisp -x '(assert (>= -1 0))' ???

On Linux i686, GNU CLISP 2.28 it indeed creates an endless loop:

WARNING:
Retry
WARNING:
Retry
...

Claudio

---

From: lin8080 <[email-masked]>
Date: Fri Apr 19 08:53:19 2002

> (>= -1 0) must evaluate to a non-NIL value.

Would you type in 100x Retry? How should the Interpreter react? This
endloss loop is more from the user than from the system. The System says
what the analyse returned, it expects a non-nil value. Or should it make
0.99999... or something like that? All you can do is: after 3. retry the
Interpreter will close and diapear form the user-screen :)

1. Break [47]> :bl

Enter the limit for max. frames to print or ':all' for all: 15

EVAL frame for form (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1
0)))
EVAL frame for form (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1
0)))
EVAL frame for form (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>=
-1 0)))
)
EVAL frame for form
(RETURN-FROM #:G1754
 (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1 0)))))
EVAL frame for form
(LET*
 ((SYSTEM::*ACTIVE-RESTARTS*
   (LIST*
    (SYSTEM::MAKE-RESTART :NAME 'CONTINUE :INVOKE-FUNCTION
     #'(LAMBDA (&REST SYSTEM::ARGUMENTS) (SETQ #:G1755
SYSTEM::ARGUMENTS)
        (GO #:G1753))
     :REPORT #'SYSTEM::REPORT-NO-NEW-VALUE :INTERACTIVE
     #'(LAMBDA NIL (APPEND)))
    SYSTEM::*ACTIVE-RESTARTS*)))
 (RETURN-FROM #:G1754
   (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1 0))))))
 #:G1753 (RETURN-FROM #:G1754 (APPLY #'(LAMBDA NIL) #:G1755)))
EVAL frame for form
(LET (#:G1755)
 (TAGBODY
  (LET*
   ((SYSTEM::*ACTIVE-RESTARTS*
     (LIST*
      (SYSTEM::MAKE-RESTART :NAME 'CONTINUE :INVOKE-FUNCTION
       #'(LAMBDA (&REST SYSTEM::ARGUMENTS) (SETQ #:G1755
SYSTEM::ARGUMENTS)
          (GO #:G1753))
       :REPORT #'SYSTEM::REPORT-NO-NEW-VALUE :INTERACTIVE
       #'(LAMBDA NIL (APPEND)))
      SYSTEM::*ACTIVE-RESTARTS*)))
   (RETURN-FROM #:G1754
    (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1 0))))))
  #:G1753 (RETURN-FROM #:G1754 (APPLY #'(LAMBDA NIL) #:G1755))))
EVAL frame for form
(BLOCK #:G1754
 (LET (#:G1755)
  (TAGBODY
   (LET*
    ((SYSTEM::*ACTIVE-RESTARTS*
      (LIST*
       (SYSTEM::MAKE-RESTART :NAME 'CONTINUE :INVOKE-FUNCTION
        #'(LAMBDA (&REST SYSTEM::ARGUMENTS) (SETQ #:G1755
SYSTEM::ARGUMENTS)
           (GO #:G1753))
        :REPORT #'SYSTEM::REPORT-NO-NEW-VALUE :INTERACTIVE
        #'(LAMBDA NIL (APPEND)))
       SYSTEM::*ACTIVE-RESTARTS*)))
    (RETURN-FROM #:G1754
     (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1 0))))))
   #:G1753 (RETURN-FROM #:G1754 (APPLY #'(LAMBDA NIL) #:G1755)))))
EVAL frame for form
(RESTART-CASE (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1
0))))
 (CONTINUE :REPORT SYSTEM::REPORT-NO-NEW-VALUE :INTERACTIVE
  (LAMBDA NIL (APPEND)) NIL))
EVAL frame for form
(TAGBODY #:G1748 (WHEN (>= -1 0) (GO #:G1749))
 (RESTART-CASE (PROGN (ERROR "~A" (SYSTEM::ASSERT-ERROR-STRING '(>= -1
0))))
  (CONTINUE :REPORT SYSTEM::REPORT-NO-NEW-VALUE :INTERACTIVE
   (LAMBDA NIL (APPEND)) NIL))
 (GO #:G1748) #:G1749)
EVAL frame for form (ASSERT (>= -1 0))
EVAL frame for form (LOAD "asit~1.lis")
Printed 10 frames
1. Break [47]>

 (>=)  The value of >= is true if the numbers are in monotonically
nonincreasing order; otherwise it is false. 
 (assert) returns nil, the first arg is a predicate (requiered), if this
evaluates to nil, assert signals an error. (>= -1 0) is NIL. 

[60]> (assert)

*** - The macro ASSERT may not be called with 0 arguments: (ASSERT)

-HyperSpec--says-

 assert assures that test-form evaluates to true. If test-form evaluates
to false, assert signals a correctable error (denoted by datum and
arguments).
 Continuing from this error using the continue restart makes it possible
for the user to alter the values of the places before assert evaluates
test-form again. If the value of test-form is non-nil, assert returns
nil. 

 The places are generalized references to data upon which test-form
depends, whose values can be changed by the user in attempting to
correct the  error. Subforms of each place are only evaluated if an
error is signaled, and might be re-evaluated if the error is re-signaled
(after continuing without actually fixing the problem).
 The order of evaluation of the places is not specified; see Section
5.1.1.1 (Evaluation of Subforms to Places). If a place form is supplied
that produces more values than there are store variables, the extra
values are ignored. If the supplied form produces fewer values than
there are store variables, the missing values are set to nil. 

...

 The debugger need not include the test-form in the error message, and
the places should not be included in the message, but they should be
made available for the user's perusal. If the user gives the
``continue'' command, the values of any of the references can be
altered.
 The details of this depend on the implementation's style of user
interface.

see Hyperspec/../Issues/iss016-writeup.html

stefan

*The merciful LISP interpreter grants the programmer parole, not the
death penalty, from assertion failures. S.Slade

---

From: "Claudio Bley" <[email-masked]>
Date: Mon Apr 22 05:40:03 2002

>> WARNING: (>= -1 0) must evaluate to a non-NIL value.  Retry
    >> WARNING: (>= -1 0) must evaluate to a non-NIL value.  Retry ...

    lin8080> Would you type in 100x Retry? 

No, I wouldn't. I just wanted to point out that you did not do what
Bruno asked for and of course obtained a different behavior. I don't
know whether it is the same isssue Bruno was talking about as he said
"it creates an endless loop".

    lin8080> How should the Interpreter react? 

IMHO, if it is set in stone by the hyperspec that a "correctable"
error is signalled there should be a chance to actually correct the
error and the interpreter should wait for user input.

Otherwise if the interpreter is meant to be run in some sort of
non-interaction mode the interpreter should signal the error and just
exit without retrying to evaluate the test-form.

Claudio