## Tuesday, September 27, 2011

### definitions vs enclosing binding forms

There are two kinds of binding forms in Racket: definitions and enclosing binding forms. The scope of a binding introduced by an enclosing binding form is entirely evident: it’s one (or more) of the form’s sub-terms. For example, in

(lambda (var ...) body)

the scope of the var bindings is body. In contrast, the scope of a definition is determined by its context: the enclosing lambda body, for example, or the enclosing module—except that scope is too simple a term for how bindings work in such contexts. Enclosing binding forms are simpler and cleaner but weaker; definition forms are more powerful, but have a more complicated binding structure. Definitions also have the pleasant property of reducing rightward code drift.

## Friday, September 09, 2011

### syntax-parse and literals

In my last post, I talked about macros and referential auxiliary identifiers—what we usually call a macro’s “literals.” Scheme macro systems only get it half right, though, because while they compare identifiers using referential equality (i.e., using the free-identifier=? predicate), they allow literals to refer to nonexistent bindings. While the comparison is well-defined via the definition of free-identifier=?, at a higher level the idea is nonsensical.

In contrast, syntax-parse requires that every literal refer to some binding. (I’ll sometimes refer to this requirement as the is-bound property for short.) This requirement is problematic in a different way. Specifically, this property cannot be checked statically (that is, when the syntax-parse expression containing the literal is compiled).

That might strike you as bizarre or unlikely. After all, you can easily imagine checking that a syntax-rules macro, say, satisfies the is-bound property. But in Racket, not every macro uses syntax-rules, and—more importantly—not every bit of syntax-analyzing code is a macro. And both of these facts have to do with phases.

## Wednesday, September 07, 2011

### macros and literals

Macros often have associated auxiliary identifiers (sometimes called keywords or reserved words, although both terms are problematic in Racket). For example, cond has else; class has public, private, etc; unit has import and export.

The fundamental question is what constitutes a use of an auxiliary identifier, and there are two reasonable answers: symbolic equality and referential equality. By symbolic equality I mean, for example, that any identifier written with exactly the letters else is accepted as an else auxiliary form. By referential equality I mean any identifier that refers to (using the standard notions of binding, environments, etc) the binding identified as the else binding.