The syntax display

The macro stepper uses a special syntax display (or syntax browser) to show the intermediate terms of your program. The syntax display has many visual annotations and capabilities especially suited to inspecting syntax.

2.1  Mark colors

Macro expansion introduces marks on syntax produced by macros. The marks serve to distinguish identifiers for the purpose of binding: a marked identifier doesn’t bind an unmarked identifier, and vice versa. For more information, read up on hygiene and hygienic macro expansion.

The macro stepper shows marked syntax visually by changing the text color of marked subterms to a different color. The original program is always black; the syntax produced by the first macro expanded in the program is rendered in red, and subsequent macro transformations are assigned other colors. When the stepper runs out of colors, it adds numeric suffixes to the identifiers to indicate marks instead.

2.2  Selection

Clicking on any part of a term selects it. To select an identifier (or other atom), click any part of the identifier (or atom). To select a parenthesized term, click on either of the parentheses. The syntax display renders the selected syntax in bold.

Selecting a subterm allows you to inspect the properties of that syntax object, and when the subterm is an identifier, the syntax display highlights related identifiers. The next two sections discuss those capabilities.

2.3  Properties

The syntax browser has a properties panel that organizes and displays interesting properties of the selected syntax object. The properties panel has three tabbed pages:

2.4  Identifier relationships

Clicking on an identifier highlights all identifiers that are related to the selected identifier in some way, where the relationship is a parameter. You can change the identifier relationship through the “Syntax” menu or through the right-click popup menu.

The available identifier relationships are:

2.5  A word about “apparent bindings”

The binding information of a syntax object may not be the same as the binding structure of the program it represents. The binding structure of a program is only determined after macro expansion is complete.

Consider the following program:

(my-macro (lambda (x) (x x)))

Assuming that my-macro treats its single argument as an expression, the second and third occurrences of x are clearly bound by the first occurrence in the lambda formals list.

However, that relationship isn’t uncovered by the macro expander until it actually get to the lambda-term. Until then, x appears to be unbound. If you select x—any of them—in the syntax display and look at the binding properties, they will claim that x is unbound.

The syntax display shows the binding information available to the macro stepper at that point in the macro expansion process. Before it encounters a binding form for x, there is no apparent binding of the occurrences of x.

Always keep in mind the difference between the binding structure of the final (fully-expanded) program and the apparent binding structure of the intermediate terms. The macro stepper only shows the latter.