Unambiguous vScheme: Resolving names

This handout describes the disambiguated form of vScheme. If you haven’t read “Welcome to vScheme”, this might be a good time. If you have read it, this handout summarizes the key points.

Referents of names

The translation of a name depends on what the name stands for. In particular,

In ordinary Scheme code, as defined by module VScheme in file vscheme.sml, the names can’t be distinguished by looking at them—instead, each name’s meaning has to be looked up in an environment. But passing such an environment to every part of the UFT would be a pain. Instead, we’ll use an environment once to disambiguate the names, then record each name’s meaning using special abstract syntax. This plan not only eliminates the bothersome environment, but it leaves later compiler passes with abstract syntax that can easily be pattern matched.

Disambiguated Scheme

The target language of the disambiguation pass is UnambiguousVScheme, which is also defined in file vscheme.sml. UnambiguousVScheme compares with VScheme like this:

Disambiguation rules

The rules for disambiguating a function application are as follows:

The rules for disambiguating VAR and SET forms are simpler: determine the name’s referent and choose the appropriate LOCAL or GLOBAL form in the target language. There’s one exception: if the name of a primitive function is used outside of a function position, it must be eta-expanded. For example, in

(val plus (curry +))

the + is disambiguated to a lambda expression, as if it were

(val plus (curry (lambda (x y) (+ x y))))

which is equivalent but puts the + in function position. This part of the transformation is implemented by the etaExpand function in file disambiguate.sml.

The main handout for the module includes links to resources on eta-expansion.

That is all you need to know about unambiguous vScheme.