[R6RS] safe and unsafe; declarations

William D Clinger will at ccs.neu.edu
Sun Mar 5 23:05:27 EST 2006

Kent quoting me:
> > ....It
> > would be very easy to change Twobit so it pays attention
> > to the proposed declarations.  The way I would do
> > that is to have the macro expander ignore declarations
> > altogether, but pass them on to later phases of the
> > compiler.
> This would not lead to an acceptable implementation of identifier-priority
> as I have described it, since priorities reported by identifier-priority
> would not generally reflect accurately how the implementation itself
> treats identifiers in the scope of a declaration.

I think you're jumping to some conclusions.  Certainly
the paragraph you quoted is not sufficient by itself,
but I believe it is sufficient when combined with this
extremely simple bit of ad hackery:

The macro expander wraps all code that results from
expanding a local or library module within a
.larceny:internal:ignore-unsafe-declarations form.

Larceny's own macros will be written using a secret
handshake that tells the macro expander it doesn't
have to do that.  (I don't want to have a secret
handshake that lets my macros do things my users
can't do, but I'll do it if that's the best way I
can think of to implement your proposed semantics.)

> If an implementation is faithful to the lexical scoping model, this should
> expand to the equivalent of:
>   (lambda (ls)
>     ((let () (declare (safe 0)) +)
>      ((let () (declare (safe 1)) car)
>       ((let () (declare (safe 0)) cdr) ls))
>      7))
> Note that I said "equivalent of".  The actual expansion is implementation
> dependent.  But it should *behave* like this, i.e., with + and cdr being
> associated with safe priority 0 and car being associated with safe
> priority 1.

You are reading quite a bit more into your proposal than
you actually wrote.  I claim your proposal, as written,
allows an implementation to expand your example into the
equivalent of:

    (lambda (ls)
      (declare (safe 1))
      (let ()
        (declare (safe 0))
        (+ (.larceny:internal:ignore-unsafe-declarations
            (car (cdr ls)))

> Okay, but if declaration information is not available via
> identifier-priority, yet later passes of a compiler receive and act upon
> it, then I would consider the implementation to be broken, as I explained
> near the top of this note and in my response to your earlier question
> about identifier-priority returning 3 in all cases.

It sounds as though I could satisfy your demands by an
implementation in which identifier-priority always returns
a priority of 1, but has the side effect of causing the
form returned by the macro expander to be wrapped within
a .larceny:internal:ignore-unsafe-declarations form.

The .larceny:internal:ignore-unsafe-declarations form
would not prevent the compiler from paying attention to
the fast, small, and debug declarations, because they are
mere pragmas with no portable semantics anyway.

Do you now agree that my proposed implementation satisfies
the requirements you proposed?


More information about the R6RS mailing list