[R6RS] safe and unsafe; declarations

dyb at cs.indiana.edu dyb at cs.indiana.edu
Tue Mar 7 12:42:03 EST 2006

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

Well, why didn't you say so?  :-)

(I assume you mean "local or library *macro*".)

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

I think we should decide if the semantics is what we want to adopt, then
each implementor can decide how to implement it.  It's always acceptable
to ``cheat'' on the semantics if you can arrange not to get caught.  If
the documentation for your implementation makes no promises, like
"safe-priority 0 cdr never raises an exception", then I see no reason why
you can't get away with this.

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

I read nothing more into my proposal than what is there.  I explicitly
stated that the expansion just has to behave like the expansion I gave. 
Your expansion does behave like the expansion I gave, given that safety
level 0 procedures aren't required to be unsafe and again assuming you
haven't made too many promises.

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

If I didn't misinterpret what you said above, the 
.larceny:internal:ignore-unsafe-declarations form will always be
wrapped around (user) macro output, so there's no need for the
side effect.

I'm not sure whether this is a valid implementation if we include
identifier-priority, but I don't want to debate identifier-priority or
even think it through at this point.  As I said, it's not part of the
model, just something we might or might not want to add later if we adopt
the model.

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

Agreed.  But if you promise too much about fast, small, and debug
declarations in your documentation, you might get caught violating the
semantics.  For example, you probably shouldn't promise that all calls to
debug-priority 3 primitives are logged in a backtrace log.

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

Yes, with the caveats above.


More information about the R6RS mailing list