Xref: utzoo comp.object:520 comp.lang.c++:5696 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!shadooby!samsung!brutus.cs.uiuc.edu!apple!sun-barr!lll-winken!arisia!sgi!shinobu!odin!delrey!shap From: shap@delrey.sgi.com (Jonathan Shapiro) Newsgroups: comp.object,comp.lang.c++ Subject: Re: Continuations Message-ID: <1663@odin.SGI.COM> Date: 28 Nov 89 22:09:24 GMT References: <2664@bingvaxu.cc.binghamton.edu> <9624@pyr.gatech.EDU> <1623@odin.SGI.COM> Sender: news@odin.SGI.COM Organization: Silicon Graphics, Inc., Mountain View, CA Lines: 70 In article cimshop!davidm@uunet.UU.NET (David S. Masterson) writes: >In article <1623@odin.SGI.COM> shap@delrey.sgi.com (Jonathan Shapiro) writes: > > I do not believe that it is feasible to add continuations to C++ for > any number of reasons, but I would be interested to hear the reactions > in this community regarding their utility in object-oriented programming. > >Hmmm. Something in this caught my interest, but I'm not quite sure what. >Taking a purely object-oriented stab at it, might the idea of continuations be >implemented as merely messaging a static data area? Is there more to it? >-- >David Masterson Consilium, Inc. >uunet!cimshop!davidm Mt. View, CA 94043 I don't believe so. What is interesting about continuations is that they freeze an execution context into an object whose internals are not exposed to the programmer, but which can be invoked at a later time and passed a single value which is the value to return. Since the object can be saved outside of the scope in which it was defined, the continuation can be returned from multiple times. The reason messaging a static data area isn't enough is that you need to preserve the stack, and portions of the stack can be shared between the captured continuation and the main program thread. As an example: (if (call-with-current-continuation (lambda (cont) (set! *saved-continuation* cont) #f)) (do-something-interesting)) When first run, the continuation is passed to the lambda, which saves it and returns #f, causing the IF to fail. At any later time, the user can say: (*saved-continuation* non-#f-value) and the body of the if will be run, along with any code that ran following the execution of the if the first time. One could therefore package up an error routine in a top level loop as shown above and then implement (define (recover-from error-type cause-info) (call-with-current-continuation (lambda (cont) (function-that-handles-error-type cont cause-info)))) (define (catch-math-error where-happened cause-description) (if (try-to-recover cause) (cont #t) (*saved-continuation-for-unrecoverable-math-error where-happened))) And then say in the code encountering the error: (if (recover-from 'math-error 'overflow) (continue-happily) (die-horribly)) Note that the "cont" can be invoked by any handler in the chain to get back to the *original* context, and that if any of these pass #t to the continuation, execution will continue appropriately. If some handler gives up and invokes the continuation with #f, we call DIE-HORRIBLY, and presumably exit. I don't know if that makes things clearer or not... Jonathan Shapiro Silicon Graphics, Inc. Brought to you by Super Global Mega Corp .com