guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Non-stack-copying call-with-current-continuation?


From: David Kastrup
Subject: Re: Non-stack-copying call-with-current-continuation?
Date: Fri, 02 Mar 2012 09:36:50 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Noah Lavine <address@hidden> writes:

> Hello,
>
>> Sure, but things like gensym and make-prompt-tag (and (list '()) for
>> creating an eq?-unique object) are artificial hygiene coming at a cost
>> in symbol table and symbol generation time rather than "lexical"
>> hygiene.  They need _extra_ work, whereas the
>> call-with-current-continuation approach needed _less_ work.  Basically I
>> want something like call-with-single-continuation that will only allow
>> one return (and any dynwind out counts and should work if it is the
>> first, so it is not exactly equivalent to using
>> with-continuation-barrier) and come without the stack-copying cost of
>> call-with-current-continuation.
>
> I agree that it's not pretty. We have hygienic macros so we don't have
> to use gensym, after all. But I don't know of a better way.

Well, to wrap this up: the manual (not current) states

    It is traditional in Scheme to implement exception systems using
    `call-with-current-continuation'.  Continuations (*note
    Continuations::) are such a powerful concept that any other control
    mechanism -- including `catch' and `throw' -- can be implemented in
    terms of them.

[...]

       The more targeted mechanism provided by `catch' and `throw' does not
    need to save and restore the C stack because the `throw' always jumps
    to a location higher up the stack of the code that executes the
    `throw'.  Therefore Guile implements the `catch' and `throw' primitives
    independently of `call-with-current-continuation', in a way that takes
    advantage of this _upwards only_ nature of exceptions.


I think that using something like "call-with-single-continuation" as the
underlying primitive would make Guile quite more similar to
"traditional" systems in the code base.  It would also provide a
minimally-invasive tool for tuning existing code based on
call-with-current-continuation in case that the stack copying semantics
are _not_ required.  Definitely more Schemeish than stuff like, uh,
prompts?

> Well, I can't fix all of that, but you could at least make it fail
> better like this:
>
> (define (call-with-single-continuation proc)
>   (let ((tag (gensym))
>         (thrown #f))
>     (catch tag
>       (proc (lambda x (if thrown (error "Single continuation called
> twice") (throw tag x)))
>       (lambda (tag . x) (apply values x)))))
>
> I think that will do what you want.

It would help to actually set "thrown" somewhere (which is sort of
tricky considering that you need to set it also on regular return).  You
wrap x into a list once too often (first with lambda x, then with lambda
(tag . x)).  But I get the drift.

> It doesn't look too bad to me, although I agree with your point in
> general - using symbols to denote names, like prompts, undoes the
> hygiene that Scheme is supposed to have. But the only solution I can
> think of is pretty messy.

Yup.  call-with-single-continuation would make best sense as a primitive
for building other stuff, not the other way round.

-- 
David Kastrup




reply via email to

[Prev in Thread] Current Thread [Next in Thread]