23.11.2014 Views

2006 Scheme and Functional Programming Papers, University of

2006 Scheme and Functional Programming Papers, University of

2006 Scheme and Functional Programming Papers, University of

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

The macro definition is a function that consumes a syntax tree,<br />

named stx. The syntax-case construct de-structures the tree<br />

<strong>and</strong> binds pattern variables to its components. The syntax<br />

constructor produces a new syntax tree by replacing the pattern<br />

variables in its template with their values.<br />

Using the macro, like thus:<br />

(def-false x y z)<br />

immediately exposes a problem. The macro exp<strong>and</strong>er fails with<br />

an error explaining that definitions can’t occur in an expression<br />

context. Of course, the problem is that the macro produces a list <strong>of</strong><br />

terms, which the macro exp<strong>and</strong>er interprets as an application <strong>and</strong><br />

which, in turn, may not contain any definitions.<br />

Our macro stepper shows the sequence <strong>of</strong> macro expansion<br />

steps, one at a time:<br />

Here we can see both the original macro form <strong>and</strong> the output <strong>of</strong> the<br />

macro application. The original appears at the top, the output <strong>of</strong> the<br />

first step at the bottom. The highlighted subterms on the top <strong>and</strong><br />

bottom are the redex <strong>and</strong> contractum, respectively. The separator<br />

explains that this is a macro expansion step. At this point, an<br />

experienced Lisp or <strong>Scheme</strong> programmer recognizes the problem.<br />

A novice may need to see another step:<br />

3.2 Syntax properties<br />

Nearly all hygienic macro papers use the or macro to illustrate the<br />

problem <strong>of</strong> inadvertent variable capture:<br />

(define-syntax (or stx)<br />

(syntax-case stx ()<br />

[(or e1 e2)<br />

(syntax (let ([tmp e1]) (if tmp tmp e2)))]))<br />

In <strong>Scheme</strong>, the purpose <strong>of</strong> (or a b) is to evaluate a <strong>and</strong> to produce<br />

its value, unless it is false; if it is false, the form evaluates b <strong>and</strong><br />

produces its value as the result.<br />

In order to keep or from evaluating its first argument more than<br />

once, the macro introduces a new variable for the first result. In<br />

Lisp-style macro exp<strong>and</strong>ers (or <strong>Scheme</strong> prior to 1986), the new tmp<br />

binding captures any free references to tmp in e2, thus interfering<br />

with the semantics <strong>of</strong> the macro <strong>and</strong> the program. Consequently,<br />

the macro breaks abstraction barriers. In <strong>Scheme</strong>, the new tmp<br />

identifier carries a mark or timestamp—introduced by the macro<br />

exp<strong>and</strong>er—that prevents it from binding anything but the two occurrences<br />

<strong>of</strong> tmp in the body <strong>of</strong> the macro-generated let [21]. This<br />

mark is vital to <strong>Scheme</strong>’s macro expansion process, but no interface<br />

exists for inspecting the marks <strong>and</strong> the marking process directly.<br />

Our macro debugger visually displays this scope information at<br />

every step. The display indicates with different text colors 3 from<br />

which macro expansion step every subterm originated. Furthermore,<br />

the programmer can select a particular subterm <strong>and</strong> see how<br />

the other subterms are related to it. Finally, the macro stepper can<br />

display a properties panel to show more detailed information such<br />

as identifier bindings <strong>and</strong> source locations.<br />

The following example shows a programmer’s attempt to create<br />

a macro called if-it, a variant <strong>of</strong> if that tries to bind the variable<br />

it to the result <strong>of</strong> the test expression for the two branches:<br />

(define-syntax (if-it1 stx) ;; WARNING: INCORRECT<br />

(syntax-case stx ()<br />

[(if-it1 test then else)<br />

(syntax<br />

(let ([it test]) (if it then else)))]))<br />

The same mechanism that prevents the inadvertent capture in the or<br />

example prevents the intentional capture here, too. With our macro<br />

debugger, the puzzled macro writer immediately recognizes why<br />

the macro doesn’t work:<br />

Here the macro exp<strong>and</strong>er has explicitly tagged the term as an<br />

application. The third step then shows the syntax error, highlighting<br />

the term <strong>and</strong> the context in which it occurred.<br />

The macro debugger actually exp<strong>and</strong>s the entire term before it<br />

displays the individual steps. This allows programmers to skip to<br />

the very end <strong>of</strong> a macro expansion <strong>and</strong> to work backwards. The<br />

stepper supports this approach with a graphical user interface that<br />

permits programmers to go back <strong>and</strong> forth in an expansion <strong>and</strong> also<br />

to skip to the very end <strong>and</strong> the very beginning. The ideas for this<br />

interface have been borrowed from Clements’s algebraic run-time<br />

stepper for PLT <strong>Scheme</strong> [3]; prior to that, similar ideas appeared in<br />

Lieberman’s stepper [22] <strong>and</strong> Tolmach’s SML debugger [29].<br />

When the programmer selects an identifier, that identifier <strong>and</strong> all<br />

others with compatible binding properties are highlighted in the<br />

same color. Thus, in the screenshot above, the occurrence <strong>of</strong> it<br />

from the original program is not highlighted while the two macrointroduced<br />

occurrences are.<br />

3 Or numeric suffixes when there are no more easily distinguishable colors.<br />

<strong>Scheme</strong> <strong>and</strong> <strong>Functional</strong> <strong>Programming</strong>, <strong>2006</strong> 17

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!