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.
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.
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.
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:
If the selection is an identifier, shows the identifier’s apparent binding in different phases.
For more information, see
identifier-template-binding in the Help Desk.
Displays source location information about the syntax object.
Displays arbitrary symbol-keyed properties (see
syntax-property in the Help Desk) of the syntax
object. It only displays properties that have keys that are
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:
Two identifiers are
bound-identifier=? if they have the
same apparent binding and if they have the same marks.
Two identifiers are
module-identifier=? if they have the
same apparent binding.
Two identifiers are
module-or-top-identifier=? if they have
the same apparent binding, or if they have the same symbolic name
but one of them is unbound.
Two identifiers are symbolic-identifier=? if discarding all lexical context information yields the same symbol.
same source module
The bindings of the two identifiers come from definitions in the same module.
same nominal module
The bindings of the two identifiers were imported into the current context by requiring the same module.
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)))
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
x appears to be unbound. If you select
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
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.