[comp.lang.scheme] Ports & continuations & UNWIND-PROTECT & GC

gyro@cymbal.reasoning.COM (Scott Layson Burson) (05/01/91)

   Date: 29 Apr 91 19:25:16 GMT
   From: "Guillermo J. Rozas" <jinx@zurich.ai.mit.edu>

   In article <9104291751.AA10911@cymbal.reasoning.com.> gyro@cymbal.reasoning.COM (Scott Layson Burson) writes:

      Somebody on this list recently alluded to "the well-known difficulty of
      defining UNWIND-PROTECT in the presence of firstclass continuations".

      I have long thought that what UNWIND-PROTECT ought to mean is that the
      cleanup actions are performed when the continuation in which they were
      established becomes garbage.

   That is not clear at all.
   The standard example of UNWIND-PROTECT (from CLtLII) is

   (unwind-protect
    (progn (start-motor)
	   (drill-hole))
    (stop-motor))

   I don't think that waiting until the continuation is garbage to stop
   the motor is what the user intended.

   Sometimes you want it to happen on any exit from the protected action.
   Sometimes you want it to happen on "final" exit, whatever that means.

I don't think your conclusion about what the user intended is at all
obvious from the example.  Furthermore, except for implementing
shallow-bound dynamic variables, I can't think of a compelling example
of a case where one would want the exit action performed any time a
different continuation was invoked.  Another standard example -- a more
compelling one, to my mind -- is the implementation of WITH-OPEN-FILE,
for which the sensible behavior seems to be to close the file when the
continuation that "owns" it becomes garbage.

I point out also that Zetalisp, for which I believe UNWIND-PROTECT was
invented, distinguished special variable binding as different from a
SETQ with an UNWIND-PROTECT set up to undo it.  The latter was called
LET-GLOBALLY and in fact had the opposite behavior: bindings established
by LET-GLOBALLY, as the name would suggest, were visible across process
switches.  So I would argue that the original UNWIND-PROTECT had
behavior that was more like performing the exit action on "final" exit,
as you put it.

And finally, I think the name UNWIND-PROTECT itself -- although it
unfortunately shows its purely-stack-oriented heritage -- sounds like it
has more to do with final cleanup than with something like a process
switch.

      As Ken points out, this really isn't all that hard to implement.

   The issue is not implementation, but what the correct behavior should
   be.

Agreed -- I was merely pointing out that a perfectly reasonable
implementation exists for the behavior I was proposing (unimplementable
behavior, no matter how elegant, is not a good thing to have in a
language specification).

I would not consider it too awfully unreasonable to have distinct
constructs for these two cases.  But as I've argued, I think that the
one called UNWIND-PROTECT deserves, on the basis of the origin as well
as the sense of its name, to refer to the final cleanup (when the
continuation becomes garbage) only.

-- Scott
Gyro@Reasoning.COM