This tutorial introduces the features of the macro stepper by way of a few small examples. For more discussion on the macro stepper's features, see the manual.
Follow along by performing the instructions written in emphasized text. Start by opening a new DrScheme window and setting the language level to Textual (MzScheme).
Consider this reimplementation of Scheme's
;; (myor e1 ... eN) means: evaluate each eI in order until ;; one of them returns a true value, then return that value. (define-syntax myor (syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))The
myormacro has a base case---one expression---and a recursive case, and it uses
syntax-rulesto determine which form a particular use of the macro has. In the recursive case, it binds the variable
rthe the value of the first expression to avoid evaluting it twice.
Copy the definition of
myor into DrScheme's
The following is a program that uses
(define (nonzero? r) (myor (negative? r) (positive? r)))It just tests whether a real number
ris nonzero. (A real number is nonzero if it is negative or if it is positive.)
Copy the definition of
nonzero? into the
Now click the macro stepper button:
When you run the macro stepper on a program, it opens a frame for the program's expansion. The frame has a navigation bar that steps backwards and forwards in the macro expansion of the current term, as well as two buttons that go up and down between the terms of the program. Beneath the navigation bar is the syntax display area: it shows all the terms of the program. Our program, for instance, has two terms: the macro definition and the function definition.
Here is the initial macro stepper frame for our program:
The first term is a macro definition. It doesn't contain any macros that we want to see (
syntax-rules are part of the
Let's move to the second term by clicking the Next term button.
The next term has a macro occurrence. The macro stepper highlights the macro use in pink, draws an arrow, and shows the term that it produces, highlighted in light blue. It colors the syntax produced by the macro red to distinguish it from the program's original syntax. The macro stepper uses a new color for each macro expansion step; eventually, when it runs out of colors, it uses numeric suffixes instead.
The colors correspond to marks or timestamps that
the macro expander puts on syntax introduced by a
macro. Generally, the binding of a colored identifier only
affects other identifiers of the same color. So the red
r does not bind the black
r from the
original function definition.
The macro transformation step produces another use of
myor, and if we step forward, we see its expansion:
If we step forward once more, we find ourselves at the end of this term's expansion:
That's the end of our program. If we click once more on Next
term we can see the macro expansion of the entire program: