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