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: Noah Lavine
Subject: Re: Non-stack-copying call-with-current-continuation?
Date: Thu, 1 Mar 2012 20:49:10 -0500

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.

> Sure, you can do
>
> (define (call-with-single-continuation proc)
>  (let ((tag (gensym)))
>    (catch tag
>           (proc (lambda x (throw tag x)))
>           (lambda (tag x) (apply values x)))))
>
> Oops.  (apply values ...)?  Does this even work?  Anyway, you get the
> drift.  But it is not pretty and it is not primitive.  And its failure
> mode when you disobey the "single" contract is an uncaught exception
> with a weird symbol.

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 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.

Noah



reply via email to

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