[R6RS] Safe/unsafe mode
William D Clinger
will at ccs.neu.edu
Wed Jul 12 12:18:44 EDT 2006
> Could we please get a bit more detail with remarks like this?
Sorry. The MLton compiler performs a whole-program
flow analysis to determine every lambda expression
whose value could possibly flow to a call site. It
then represents the closure by a record that contains
an integer identifying the lambda expression, together
with the values of its free variables. The caller
performs the call by executing a case dispatch on the
integer, executing the lambda expression's code inline
or via a jump to out-of-line code.
The relevance of this technique to our discussion is
that it divides the responsibility between caller and
callee in a way that Kent probably has not considered.
The importance of that relevance is much easier to see
by considering a simple example.
First, a digression on implementation techniques. I
have already described the semantics I prefer for safe
and unsafe code; we are still waiting for an equally
precise semantics from Kent, so I will have to guess
about some of his details.
In addition to a semantics, many programmers like to
have a mental model of how the semantics might be
implemented. For my semantics, a simple mental model
is that every procedure has two entry points, one for
when it is called from safe code, and another that may
be used (but does not have to be) when the procedure
is called from unsafe code. Even if the second entry
point is called from unsafe code, it may behave exactly
the same as the safe entry point.
I do not believe Kent's semantics, if and when we see
it, will have such a simple operational model. I think
Kent's preferred semantics has to do with names, not
values, and that his semantics will involve wholesale
implicit rebindings of vast numbers of identifiers at
declaration points, of the sort that we normally refer
to as non-hygienic.
Now for an example:
(let ((f -))
With my preferred semantics, and with the mental model
I sketched above, the unsafe call to f is allowed to
use the unsafe entry point when it calls the - procedure,
so all bets are off. My preferred semantics allows the
compiler optimization known as copy propagation, so the
example above is equivalent to
I believe that Kent's preferred semantics, if and when
we see it, will be sensitive to the name by which a
procedure is called. Calling a procedure by one of its
names (e.g. -) will probably not be equivalent to calling
the procedure by another of its names (e.g. f). Beyond
that speculation, I will just await Kent's semantics.
The relevance of this to the MLton compiler is that, if
the compiler's flow analysis can establish that, for a
call to f, - is the only procedure that can flow to f,
calling f will generate the same code as for a call to
-. This is true for some Scheme compilers also, even
(occasionally) for Twobit.
More information about the R6RS