From: Hallvard B Furuseth
Subject: Order of events in (return) from unwind-protect
Date: 
Message-ID: <HBF.20001207y12g@bombur.uio.no>
As far as I can tell, the standard's secetion 5.2 (Transfer of Control
to an Exit Point) says this should print INNER:

  (defparameter *x* 'OUTER)
  (block foo
    (unwind-protect (let ((*x* 'INNER))
                      (return-from foo))
      (print *x*)))

Am I reading it right?  It seems strange, but I don't see how else to
interpret this section.  Relevant points:

2. The cleanup clauses of any intervening unwind-protect clauses are
   evaluated.

   -- (print *x*), while *x* is still bound to 'inner.

3. Intervening dynamic bindings of special variables ... are undone.

   -- abandon the x => 'inner binding.

HypeSpec URL:
http://www.xanalys.com/software_tools/reference/HyperSpec/Body/sec_5-2.html

-- 
Hallvard

From: Michael Hudson
Subject: Re: Order of events in (return) from unwind-protect
Date: 
Message-ID: <m3g0k04cav.fsf@atrus.jesus.cam.ac.uk>
Hallvard B Furuseth <············@usit.uio.no> writes:

> As far as I can tell, the standard's secetion 5.2 (Transfer of Control
> to an Exit Point) says this should print INNER:
> 
>   (defparameter *x* 'OUTER)
>   (block foo
>     (unwind-protect (let ((*x* 'INNER))
>                       (return-from foo))
>       (print *x*)))
> 
> Am I reading it right?  It seems strange, but I don't see how else to
> interpret this section.  Relevant points:
> 
> 2. The cleanup clauses of any intervening unwind-protect clauses are
>    evaluated.
> 
>    -- (print *x*), while *x* is still bound to 'inner.
> 
> 3. Intervening dynamic bindings of special variables ... are undone.
> 
>    -- abandon the x => 'inner binding.
> 
> HypeSpec URL:
> http://www.xanalys.com/software_tools/reference/HyperSpec/Body/sec_5-2.html

Read a bit further?

  Events 2 and 3 are actually performed interleaved, in the order
  corresponding to the reverse order in which they were
  established. The effect of this is that the cleanup clauses of an
  unwind-protect see the same dynamic bindings of variables and catch
  tags as were visible when the unwind-protect was entered.

Cheers,
M.

-- 
  Java sucks. [...] Java on TV set top boxes will suck so hard it
  might well inhale people from off  their sofa until their heads 
  get wedged in the card slots.              --- Jon Rabone, ucam.chat
From: Hallvard B Furuseth
Subject: Re: Order of events in (return) from unwind-protect
Date: 
Message-ID: <HBF.20001207xvj0@bombur.uio.no>
Response time is certainly quick in this group...
Thanks.

-- 
Hallvard
From: Kent M Pitman
Subject: Re: Order of events in (return) from unwind-protect
Date: 
Message-ID: <sfwitoww39b.fsf@world.std.com>
Michael Hudson <·····@cam.ac.uk> writes:

> 
> Hallvard B Furuseth <············@usit.uio.no> writes:
> 
> > As far as I can tell, the standard's secetion 5.2 (Transfer of Control
> > to an Exit Point) says this should print INNER:
> > 
> >   (defparameter *x* 'OUTER)
> >   (block foo
> >     (unwind-protect (let ((*x* 'INNER))
> >                       (return-from foo))
> >       (print *x*)))
> > 
> > Am I reading it right?  It seems strange, but I don't see how else to
> > interpret this section.  Relevant points:
> > 
> > 2. The cleanup clauses of any intervening unwind-protect clauses are
> >    evaluated.
> > 
> >    -- (print *x*), while *x* is still bound to 'inner.
> > 
> > 3. Intervening dynamic bindings of special variables ... are undone.
> > 
> >    -- abandon the x => 'inner binding.
> > 
> > HypeSpec URL:
> > http://www.xanalys.com/software_tools/reference/HyperSpec/Body/sec_5-2.html
> 
> Read a bit further?
> 
>   Events 2 and 3 are actually performed interleaved, in the order
>   corresponding to the reverse order in which they were
>   established. The effect of this is that the cleanup clauses of an
>   unwind-protect see the same dynamic bindings of variables and catch
>   tags as were visible when the unwind-protect was entered.
 
Right on variables.

Catch tags, if I recall, are different.  It's implementation-defined
what happens here.  There as a major war over this.  Some (myself included)
wanted a Scheme-style continuation model that said:

  (block foo
      (progn 
        (block bar
          (unwind-protect (return-from foo 3)
            (return-from bar)))
        4))

returns 4.  But there was a camp, which prevailed in the spec, that said
this might be a program error, and that it should be left undefined because
it can lead to programs that are hard to stop.

I BELIEVE the rule is, and someone else can track down the reference
if they care because I'm too lazy today, that the first thing that
happens when doing a non-local return is that all the intervening
control points (between the point of throw and the point to which the
throw is going) are either actually or potentially (can't remember
which) invalidated and *then* the unwind begins, so you can't throw or
return or go to any tag that was asserted in the going-away region.