fear-of-macros/Syntax_parameters.html
2013-08-15 13:38:13 -04:00

25 lines
28 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>5&nbsp;Syntax parameters</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default" /><link rel="stylesheet" type="text/css" href="racket.css" title="default" /><link rel="stylesheet" type="text/css" href="scribble-style.css" title="default" /><link rel="stylesheet" type="text/css" href="gh.css" title="default" /><script type="text/javascript" src="scribble-common.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--><meta name="keywords" content="Racket,macros,Scheme"><meta name="description" content="Practical Racket macros"><meta name="author" content="Greg Hendershott"><meta name="charset" content="utf-8"><link href='http://fonts.googleapis.com/css?family=Fenix' rel='stylesheet' type='text/css'><script type="text/javascript">var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-29709446-1']);_gaq.push(['_setDomainName', 'greghendershott.com']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();</script></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist" style="margin-bottom: 1em;"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9660;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">Fear of Macros</a></td></tr></table></div><div class="tocviewsublistonly" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="Preface.html" class="tocviewlink" data-pltdoc="x">Preface</a></td></tr><tr><td align="right">2&nbsp;</td><td><a href="Our_plan_of_attack.html" class="tocviewlink" data-pltdoc="x">Our plan of attack</a></td></tr><tr><td align="right">3&nbsp;</td><td><a href="Transform_.html" class="tocviewlink" data-pltdoc="x">Transform!</a></td></tr><tr><td align="right">4&nbsp;</td><td><a href="pattern-matching.html" class="tocviewlink" data-pltdoc="x">Pattern matching:<span class="mywbr"> &nbsp;</span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td align="right">5&nbsp;</td><td><a href="" class="tocviewselflink" data-pltdoc="x">Syntax parameters</a></td></tr><tr><td align="right">6&nbsp;</td><td><a href="What_s_the_point_of_splicing-let_.html" class="tocviewlink" data-pltdoc="x">What&rsquo;s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td align="right">7&nbsp;</td><td><a href="Robust_macros__syntax-parse.html" class="tocviewlink" data-pltdoc="x">Robust macros:<span class="mywbr"> &nbsp;</span> syntax-<wbr></wbr>parse</a></td></tr><tr><td align="right">8&nbsp;</td><td><a href="References_and_Acknowledgments.html" class="tocviewlink" data-pltdoc="x">References and Acknowledgments</a></td></tr><tr><td align="right">9&nbsp;</td><td><a href="Epilogue.html" class="tocviewlink" data-pltdoc="x">Epilogue</a></td></tr></table></div></div></div></div><div class="maincolumn"><div class="main"><div class="navsettop"><span class="navleft">&nbsp;&nbsp;</span><span class="navright">&nbsp;&nbsp;<a href="pattern-matching.html" title="backward to &quot;4 Pattern matching: syntax-case and syntax-rules&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Fear of Macros&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="What_s_the_point_of_splicing-let_.html" title="forward to &quot;6 What's the point of splicing-let?&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div><h3>5<tt>&nbsp;</tt><a name="(part._.Syntax_parameters)"></a>Syntax parameters</h3><p>"Anaphoric if" or "aif" is a popular macro example. Instead of writing:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">tmp</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">big-long-calculation</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktSym">tmp</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace">&nbsp;</span><span class="RktSym">tmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>You could write:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">big-long-calculation</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">#f</span><span class="RktPn">)</span></td></tr></table></blockquote><p>In other words, when the condition is true, an <span class="RktSym">it</span> identifier
is automatically created and set to the value of the condition. This
should be easy:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#%28form._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._define-syntax-rule%29%29" class="RktStxLink" data-pltdoc="x">define-syntax-rule</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktSym">condition</span><span class="hspace">&nbsp;</span><span class="RktSym">true-expr</span><span class="hspace">&nbsp;</span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">it</span><span class="hspace">&nbsp;</span><span class="RktSym">condition</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">true-expr</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">false-expr</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktVal">#t</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/void.html#%28def._%28%28quote._~23~25kernel%29._void%29%29" class="RktValLink" data-pltdoc="x">void</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">it: undefined;</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace">&nbsp;</span><span class="RktErr">cannot reference an identifier before its definition</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktErr">in module: 'program</span></p></td></tr></table></blockquote><p>Wait, what? <span class="RktSym">it</span> is undefined?</p><p>It turns out that all along we have been protected from making a
certain kind of mistake in our macros. The mistake is if our new
syntax introduces a variable that accidentally conflicts with one in
the code surrounding our macro.</p><p>The Racket <span style="font-style: italic">Reference</span> section,
<a href="http://docs.racket-lang.org/reference/syntax-model.html#(part._transformer-model)">Transformer
Bindings</a>, has a good explanation and example. Basically, syntax
has "marks" to preserve lexical scope. This makes your macro behave
like a normal function, for lexical scoping.</p><p>If a normal function defines a variable named <span class="RktSym">x</span>, it won&rsquo;t
conflict with a variable named <span class="RktSym">x</span> in an outer scope:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktVal">"outer"</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktVal">"inner"</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28quote._~23~25kernel%29._printf%29%29" class="RktValLink" data-pltdoc="x">printf</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"The inner `x' is ~s\n"</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28quote._~23~25kernel%29._printf%29%29" class="RktValLink" data-pltdoc="x">printf</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"The outer `x' is ~s\n"</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0"><tr><td><p><span class="RktOut">The inner `x' is "inner"</span></p></td></tr><tr><td><p><span class="RktOut">The outer `x' is "outer"</span></p></td></tr></table></td></tr></table></blockquote><p>When our macros also respect lexical scoping, it&rsquo;s easier to write
reliable macros that behave predictably.</p><p>So that&rsquo;s wonderful default behavior. But <span style="font-style: italic">sometimes</span> we want
to introduce a magic variable on purpose&#8212;<wbr></wbr>such as <span class="RktSym">it</span> for
<span class="RktSym">aif</span>.</p><p>The way to do this is with a "syntax parameter", using
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#%28form._%28%28lib._racket%2Fstxparam..rkt%29._define-syntax-parameter%29%29" class="RktStxLink" data-pltdoc="x">define-syntax-parameter</a></span> and
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#%28form._%28%28lib._racket%2Fstxparam..rkt%29._syntax-parameterize%29%29" class="RktStxLink" data-pltdoc="x">syntax-parameterize</a></span>. You&rsquo;re probably familiar with regular
parameters in Racket:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">current-foo</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/parameters.html#%28def._%28%28quote._~23~25kernel%29._make-parameter%29%29" class="RktValLink" data-pltdoc="x">make-parameter</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"some default value"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">current-foo</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"some default value"</span></p></td></tr><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/parameters.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._parameterize%29%29" class="RktStxLink" data-pltdoc="x">parameterize</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">current-foo</span><span class="hspace">&nbsp;</span><span class="RktVal">"I have a new value, for now"</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">current-foo</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">"I have a new value, for now"</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">current-foo</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"some default value"</span></p></td></tr></table></blockquote><p>That&rsquo;s a normal parameter. The syntax variation works similarly. The
idea is that we&rsquo;ll define <span class="RktSym">it</span> to mean an error by
default. Only inside of our <span class="RktSym">aif</span> will it have a meaningful
value:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="hspace">&nbsp;</span><span class="RktSym">racket/stxparam</span><span class="RktPn">)</span></td></tr><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#%28form._%28%28lib._racket%2Fstxparam..rkt%29._define-syntax-parameter%29%29" class="RktStxLink" data-pltdoc="x">define-syntax-parameter</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/exns.html#%28def._%28%28quote._~23~25kernel%29._raise-syntax-error%29%29" class="RktValLink" data-pltdoc="x">raise-syntax-error</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#%28def._%28%28quote._~23~25kernel%29._syntax-e%29%29" class="RktValLink" data-pltdoc="x">syntax-e</a></span><span class="hspace">&nbsp;</span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">"can only be used inside aif"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#%28form._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._define-syntax-rule%29%29" class="RktStxLink" data-pltdoc="x">define-syntax-rule</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktSym">condition</span><span class="hspace">&nbsp;</span><span class="RktSym">true-expr</span><span class="hspace">&nbsp;</span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">tmp</span><span class="hspace">&nbsp;</span><span class="RktSym">condition</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktSym">tmp</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#%28form._%28%28lib._racket%2Fstxparam..rkt%29._syntax-parameterize%29%29" class="RktStxLink" data-pltdoc="x">syntax-parameterize</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">it</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._make-rename-transformer%29%29" class="RktValLink" data-pltdoc="x">make-rename-transformer</a></span><span class="hspace">&nbsp;</span><span class="RktRdr">#'</span><span class="RktSym">tmp</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">true-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">false-expr</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/void.html#%28def._%28%28quote._~23~25kernel%29._void%29%29" class="RktValLink" data-pltdoc="x">void</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">10</span></p></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace">&nbsp;</span><span class="RktVal">#f</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/void.html#%28def._%28%28quote._~23~25kernel%29._void%29%29" class="RktValLink" data-pltdoc="x">void</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Inside the <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#%28form._%28%28lib._racket%2Fstxparam..rkt%29._syntax-parameterize%29%29" class="RktStxLink" data-pltdoc="x">syntax-parameterize</a></span>, <span class="RktSym">it</span> acts as an alias
for <span class="RktSym">tmp</span>. The alias behavior is created by
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._make-rename-transformer%29%29" class="RktValLink" data-pltdoc="x">make-rename-transformer</a></span>.</p><p>If we try to use <span class="RktSym">it</span> outside of an <span class="RktSym">aif</span> form, and
<span class="RktSym">it</span> isn&rsquo;t otherwise defined, we get an error like we want:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">it: can only be used inside aif</span></p></td></tr></table></blockquote><p>But we can still define <span class="RktSym">it</span> as a normal variable in local
definition contexts like:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">it</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">10</span></p></td></tr></table></blockquote><p>or:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">it</span><span class="hspace">&nbsp;</span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace">&nbsp;&nbsp;</span></span><span class="hspace">&nbsp;&nbsp;</span><span class="RktSym">it</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">10</span></p></td></tr></table></blockquote><p>For a deeper look, see <a href="http://www.schemeworkshop.org/2011/papers/Barzilay2011.pdf">Keeping it Clean with Syntax Parameters</a>.</p><div class="navsetbottom"><span class="navleft">&nbsp;&nbsp;</span><span class="navright">&nbsp;&nbsp;<a href="pattern-matching.html" title="backward to &quot;4 Pattern matching: syntax-case and syntax-rules&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;Fear of Macros&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="What_s_the_point_of_splicing-let_.html" title="forward to &quot;6 What's the point of splicing-let?&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>