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 or
macro, called myor
:
;; (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
myor
macro has a base case---one
expression---and a recursive case, and it uses
syntax-rules
to determine which form a particular
use of the macro has. In the recursive case, it binds the
variable r
the the value of the first expression to
avoid evaluting it twice.
Copy the definition of myor
into DrScheme's
definitions window.
The following is a program that uses myor
:
(define (nonzero? r) (myor (negative? r) (positive? r)))It just tests whether a real number
r
is
nonzero. (A real number is nonzero if it is negative or if it is
positive.)
Copy the definition of nonzero?
into the
definitions window.
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 (define-syntax
and
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: