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

Re: a (revised) draft of R5RS




Hi all!

Not too surprisingly to many of you (I think), I mostly disagree with
Kent's request for a different call/cc.

There are several reasons, which I will try to explain here:

The first reason is a purely aesthetic one: I just like to think of
continuations as what they are in denotational semantics: functions
from values to anwers.  Explaining anything ranging from dynamic-wind
to extraneous optimization hints in denotational semantics seems to
require the introduction of another, hidden layer of low-level
continuations.  I find this mixing of terminology confusing.

The second reason is that I don't agree with the purpose of such
efficiency hacks.  We were through this before for the case of
multiple value returns, so I perhaps shouldn't hope that people will
give too much about my resentiments.  I would like to see multiple
values disappear again, because they don't add expressive power to the
language (in fact, they take away from it because of loss of
orthogonality), and their potential benefits in terms of efficiency
can also be obtained from better compile-time analyses.

Perhaps the latter is not true for continuations and dynamic-wind (I
honestly don't know), but here I also see things in a slightly
different light.  The main use of continuations in Scheme seems to be
non-local returns, i.e., exceptions.  Perhaps exceptions should be
made part of the language proper -- without reference to a possible
implementation in terms of (low-level) continuations.

Dynamic-wind _really_ bothers me, because I see no use for it at all.
The only example people always come up with is about opening and
closing files, i.e. managing a limited system resource.  Ideally this
should be entirely transparent.  The programmer should never have to
write (close-port ...) at all.  In fact, there shouldn't have to be a
procedure to close ports.

If one thinks of the dynamic context of a computation (current input
port, current output port, current exception handler) as implicit
arguments to _every_ procedure, then call/cc would automatically, by
_definition_, save and restore that context correctly.  And if
reclaiming unused resources (memory, file descriptors, channels, ...)
is left to the runtime system, then there won't be a need for
dynamic-wind at all.  Olin Shivers has done some interesting work on
how to maintain operating system resources in a (mostly) transparent
fashion -- even handling the oddities of contemporary systems in an
interesting, clever way.

Summary:

All operating resources that show up as language abstractions should
be managed in such a way that the illusion of an unlimited supply is
maintained.  We've been doing this with memory for a long time now,
but the ideas are obviously not limited to memory.  This eliminates
the most urgent need for something like dynamic-wind, which in turn
eliminates any nasty interaction between dynamic-wind and
continuations.  The most common use for continuations (exceptions)
should probably be factored out and turned into a feature of the core
language.  Exceptions deserve to be standardized anyway.  Efficiency
hacks should be banned from the language -- they always seem to create
more problems than they solve.

-Matthias