From: jimka
Subject: don't understand unwind protect
Date: 
Message-ID: <534430e2-8978-452b-867b-888a995dfd80@y5g2000hsf.googlegroups.com>
Can someone please help me understand unwind-protect?  Why do 2, 3,
and 4 get
printed in the following, an no divide by zero error?

(unwind-protect (progn (print 1)
		       (error "first"))
  (print 2)
  (print 3)
  (/ 2 0)
  (print 4))

From: Ken Tilton
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <478e5dd7$0$9155$607ed4bc@cv.net>
jimka wrote:
> Can someone please help me understand unwind-protect?

I got the divde by zero error interpreting this in ACL 8.1 on windows.

kt


   Why do 2, 3,
> and 4 get
> printed in the following, an no divide by zero error?
> 
> (unwind-protect (progn (print 1)
> 		       (error "first"))
>   (print 2)
>   (print 3)
>   (/ 2 0)
>   (print 4))

-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: jimka
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <8d5448fe-4697-41af-9f9b-33147fecbd27@l1g2000hsa.googlegroups.com>
thanks for the reply.  My main reason for the question was
of course not because i wanted to divide something by zero,
but rather to see what happens if one of the cleanup-forms
of unwind protect throws an error.  I read the hyperspec
page of unwind protect but could not see any specification
for what should happen in this case.

Which lisp am i using?   SBCL 0.9.4,


-jim

On Jan 17, 1:41 am, Ken Tilton <···········@optonline.net> wrote:
> jimka wrote:
> > Can someone please help me understand unwind-protect?
>
> I got the divde by zero error interpreting this in ACL 8.1 on windows.
>
> kt
>
> > Why do 2, 3, and 4 get
> > printed in the following, an no divide by zero error?
>
> > (unwind-protect (progn (print 1)
> >                   (error "first"))
> >   (print 2)
> >   (print 3)
> >   (/ 2 0)
> >   (print 4))
>
From: Kaz Kylheku
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <dce13c20-07ae-4a85-8481-2c47993fb36c@k39g2000hsf.googlegroups.com>
On Jan 17, 1:48 pm, jimka <·····@rdrop.com> wrote:
> thanks for the reply.  My main reason for the question was
> of course not because i wanted to divide something by zero,
> but rather to see what happens if one of the cleanup-forms
> of unwind protect throws an error.

UNWIND-PROTECT specifies code to be executed if control leaves an
expression normally, or by means of some dynamic non-local exit. It's
not specific to condition handling. For example, a RETURN-FROM a named
block is an example of a non-local exit. In error handling, a non-
local exit takes place implicitly within the HANDLER-CASE or RESTART-
CASE constructs.  Note that the UNWIND-PROTECT description in the CLHS
doesn't mention errors anywhere! The only connection to error handling
is that error handling makes use of non-local exits (though strictly
speaking not necessarily).

The CLHS description of UNWIND-PROTECT clearly specifies what happens
if a dynamic if a non-local exit takes place during the evaluation of
the cleanup forms.

``If a non-local exit occurs during execution of cleanup-forms, no
special action is taken. The cleanup-forms of unwind-protect are not
protected by that unwind-protect.''

An error being signaled within one of these forms in such a way that
control escapes via a non-local exit (to a handler or restart set up
in an enclosing dynamic contour) would an example of a non-local exit,
as would be a THROW or RETURN-FROM, etc so the above text covers the
case you are concerned about.

What the above text says is that in that situation, the evaluation of
these forms simply bails. For instance if there are three cleanup
forms: (UNWIND-PROTECT PROTECTED A B C) and B performs a non-local
exit, then C is not evaluated. The behavior of the cleanup forms is
much like (PROGN A B C).

To arrange for C to be evaluated if B bails you have to add an
additional nested UNWIND-PROTECT, like this (UNWIND-PROTECT PROTECTED
A (UNWIND-PROTECT B C)). But of course, if A bails, there is no
protection. To have total protection, you need (U-P PROTECTED (U-P A
(U-P B C))). Now PROTECTED can bail, then A can bail and then B can
bail, and C is still run.
From: jimka
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <b06159f1-5de0-4359-bf4e-14fb754dac56@j78g2000hsd.googlegroups.com>
On Jan 18, 9:39 am, Kaz Kylheku <········@gmail.com> wrote:
> On Jan 17, 1:48 pm, jimka <·····@rdrop.com> wrote:
>
>
> The CLHS description of UNWIND-PROTECT clearly specifies what happens
> if a dynamic if a non-local exit takes place during the evaluation of
> the cleanup forms.
>
> ``If a non-local exit occurs during execution of cleanup-forms, no
> special action is taken. The cleanup-forms of unwind-protect are not
> protected by that unwind-protect.''
>
>
> To arrange for C to be evaluated if B bails you have to add an
> additional nested UNWIND-PROTECT, like this (UNWIND-PROTECT PROTECTED
> A (UNWIND-PROTECT B C)). But of course, if A bails, there is no
> protection. To have total protection, you need (U-P PROTECTED (U-P A
> (U-P B C))). Now PROTECTED can bail, then A can bail and then B can
> bail, and C is still run.


I did not catch that in the HS but it was pretty much what I
guessed SHOULD happen.  However the behaviour I was seeing was not
what you described.  The behavior i was seeing is that all the
cleanup forms were getting evaluated, and that exceptions were
ignored.

I believe SBCL was doing the right thing, i just did not understany
way cleanup forms after (/1 0) were being evaluated.
I still don't.  It may have something to do with slime's
error handlers...  sigh.

-jim
From: Rainer Joswig
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <joswig-8BBF92.01182017012008@news-europe.giganews.com>
In article 
<····································@y5g2000hsf.googlegroups.com>,
 jimka <·····@rdrop.com> wrote:

> Can someone please help me understand unwind-protect?  Why do 2, 3,
> and 4 get
> printed in the following, an no divide by zero error?
> 
> (unwind-protect (progn (print 1)
> 		       (error "first"))
>   (print 2)
>   (print 3)
>   (/ 2 0)
>   (print 4))

You always need to tell us which Lisp implementation (name and
version) you are using.

One reason can be that the compiler optimized the form
(/ 2 0) away. It has no side effects (other than triggering
an error) and the result is not used anywhere.
From: Steven M. Haflich
Subject: Re: don't understand unwind protect
Date: 
Message-ID: <h3zjj.36359$JD.19100@newssvr21.news.prodigy.net>
Rainer Joswig wrote:

> One reason can be that the compiler optimized the form
> (/ 2 0) away. It has no side effects (other than triggering
> an error) and the result is not used anywhere.

It is worth explaining that the "triggering an error" is not
specified (required) behavior by /, so your compiler is
_allowed_ to eliminate this constant division.

In a tighter language it might have been reasonable for an
ANS to require zero divide to be detected and signalled, but
at the time and culture of X3J13 it was more important to
allow _efficient_ implementations on indeterminate and
possibly-bizarre platforms that might nor efficiently
implement zero-divide detection.