[plt-scheme] r6rs eval + phases + exceptions

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Wed May 21 03:04:33 EDT 2008

Stephen Wrobleski wrote:
> Hi,
> I have a a bit of a problem with values getting passed between phases. I'm
> calling r6rs:eval on an expression that may throw arbitrary exceptions in a
> syntax expander. As such, a value from phase 1 (of the eval) has now escaped
> into phase 0 of the running program. I would like to programmatically test
> for these exceptions, but of course none of my phase 0 predicates work
> because they're from a different instantiation. (Actually the r6rs condition
> library predicates don't work either, so r6rs:simple-conditions ends up
> mangling the exception)

I don't have any pragmatic advice, but I've answered some of the 
questions about how things work and why they work that way.

> I can still test for exn:fail. It seems that exn:fail must have the same
> identity across phases, since it's part of the core implementation.

That's right. Primitive structs like exn are shared across phases, but 
things defined in libraries (like R6RS conditions) are not. Prefab 
structs are, but you can't make prefab exception subtypes.

> Reading the documentation about such things, I came across the following bit
> doc/reference/syntax-model.html:
>> When the expander encounters require and require-for-syntax within a
>> module context, the resulting visits and instantiations are specific to
>> the expansion of the enclosing module, and are kept separate from visits
>> and instantiations triggered from a top-level context or from the
>> expansion of a different module.
> I don't see how the above can be anything but completely false. I notice
> that the modules do get instantiated multiple times, but every use of the
> module uses the same instantiation (as it has to be for values retrieved by
> syntax-local-value to work). (Also, why _are_ modules instantiated so many
> times when required for-syntax (looking at their side effects) ?)

There are two reasons to visit or instantiate a module A: "for 
execution" and "for expansion of module B", where B depends on A. Let's 
call those "instantiation contexts". So if there are 12 modules in your 
program, there are 13 instantiation contexts: 12  during the compilation 
of your program, and one more when you run it.

No two different ICs share module instantiations.

But within an IC, a module is instantiated exactly once per phase that 
it's required for. If, during the compilation of B, module A is 
reachable by chasing requires in ten different ways, there's still a 
single instantiation of B (at phase 0). If it's reachable by chains of 
requires and just one require-for-syntax, it's instantiated again at 
phase 1, a separate instantiation from phase 0, but shared for all phase 
1 references. And so on.

The design rationale is explained in Matthew Flatt's "Composable and 
Compilable Macros: You Want It When?", ICFP '02. The system ensures that 
all compilation dependencies are explicitly accounted for, and that 
things don't accidentally work interactively and later fail in batch 

> The only workaround I've come up with is to pass the phase 1 exception back
> into eval and have a syntax expander pick it out and somehow turn it into
> the phase 0 representation of the same exception. This seems needlessly
> complex, and not generalized for the case of an exception thrown from phase
> 2 or higher.
> Is there a better solution? It seems there's a lot of flexibility in
> mzscheme's underlying namespaces. Could r6rs:environment be changed to
> eliminate this problem? Given that eval expands and then immediately
> executes code (with no possibility for independent compilation steps), it
> would make sense to me if any for-syntax includes just referenced
> already-existing phase 0 instantiations.

Perhaps the R6RS exn/condition system should be implemented with 
phase-crossing machinery. I'm not sure what the best way to do that 
would be, though.


> Steve
> ------------------------------------------------------------------------
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.