commit 3ac5c1cc40d6548a3dd24d52dc8deadb62bf42fe
parent 43883f4fc77bd17bc007000208bb33e9abdf2c27
Author: Greg Hendershott <greghendershott@gmail.com>
Date: Sat, 27 Oct 2012 09:47:38 -0400
Regen html
Diffstat:
| M | index.html | | | 40 | +++++++++++++++++++++------------------- |
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/index.html b/index.html
@@ -2,7 +2,7 @@
<html><head><meta http-equiv="content-type" content="text-html; charset=utf-8" /><title>Fear of Macros</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]--><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,"tocview_0");">►</a></td><td></td><td><a href="" class="tocviewselflink" pltdoc="x">Fear of Macros</a></td></tr></table></div><div class="tocviewsublistonly" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="#(part._.Preface)" class="tocviewlink" pltdoc="x">Preface</a></td></tr><tr><td align="right">2 </td><td><a href="#(part._.The_plan_of_attack)" class="tocviewlink" pltdoc="x">The plan of attack</a></td></tr><tr><td align="right">3 </td><td><a href="#(part._.Transformers)" class="tocviewlink" pltdoc="x">Transformers</a></td></tr><tr><td align="right">4 </td><td><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocviewlink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td align="right">5 </td><td><a href="#(part._.Syntax_parameters)" class="tocviewlink" pltdoc="x">Syntax parameters</a></td></tr><tr><td align="right">6 </td><td><a href="#(part._.Robust_macros__syntax-parse)" class="tocviewlink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td align="right">7 </td><td><a href="#(part._.Other_questions)" class="tocviewlink" pltdoc="x">Other questions</a></td></tr><tr><td align="right">8 </td><td><a href="#(part._.References_and_.Acknowledgments)" class="tocviewlink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td align="right">9 </td><td><a href="#(part._.Epilogue)" class="tocviewlink" pltdoc="x">Epilogue</a></td></tr></table></div></div></div><div class="tocsub"><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">1<tt> </tt></span><a href="#(part._.Preface)" class="tocsubseclink" pltdoc="x">Preface</a></td></tr><tr><td><span class="tocsublinknumber">2<tt> </tt></span><a href="#(part._.The_plan_of_attack)" class="tocsubseclink" pltdoc="x">The plan of attack</a></td></tr><tr><td><span class="tocsublinknumber">3<tt> </tt></span><a href="#(part._.Transformers)" class="tocsubseclink" pltdoc="x">Transformers</a></td></tr><tr><td><span class="tocsublinknumber">3.1<tt> </tt></span><a href="#(part._.What_is_a_syntax_transformer_)" class="tocsubseclink" pltdoc="x">What is a syntax transformer?</a></td></tr><tr><td><span class="tocsublinknumber">3.2<tt> </tt></span><a href="#(part._.What_s_the_input_)" class="tocsubseclink" pltdoc="x">What’s the input?</a></td></tr><tr><td><span class="tocsublinknumber">3.3<tt> </tt></span><a href="#(part._.Actually_transforming_the_input)" class="tocsubseclink" pltdoc="x">Actually transforming the input</a></td></tr><tr><td><span class="tocsublinknumber">3.4<tt> </tt></span><a href="#(part._.Compile_time_vs__run_time)" class="tocsubseclink" pltdoc="x">Compile time vs. run time</a></td></tr><tr><td><span class="tocsublinknumber">3.5<tt> </tt></span><a href="#(part._begin-for-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">begin-<wbr></wbr>for-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4<tt> </tt></span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocsubseclink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td><span class="tocsublinknumber">4.1<tt> </tt></span><a href="#(part._.Patterns_and_templates)" class="tocsubseclink" pltdoc="x">Patterns and templates</a></td></tr><tr><td><span class="tocsublinknumber">4.1.1<tt> </tt></span><a href="#(part.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)" class="tocsubseclink" pltdoc="x">"A pattern variable can’t be used outside of a template"</a></td></tr><tr><td><span class="tocsublinknumber">5<tt> </tt></span><a href="#(part._.Syntax_parameters)" class="tocsubseclink" pltdoc="x">Syntax parameters</a></td></tr><tr><td><span class="tocsublinknumber">6<tt> </tt></span><a href="#(part._.Robust_macros__syntax-parse)" class="tocsubseclink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td><span class="tocsublinknumber">7<tt> </tt></span><a href="#(part._.Other_questions)" class="tocsubseclink" pltdoc="x">Other questions</a></td></tr><tr><td><span class="tocsublinknumber">7.1<tt> </tt></span><a href="#(part._.What_s_the_point_of_with-syntax_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">with-<wbr></wbr>syntax</span></span>?</a></td></tr><tr><td><span class="tocsublinknumber">7.2<tt> </tt></span><a href="#(part._.What_s_the_point_of_begin-for-syntax_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">begin-<wbr></wbr>for-<wbr></wbr>syntax</span></span>?</a></td></tr><tr><td><span class="tocsublinknumber">7.3<tt> </tt></span><a href="#(part._.What_s_the_point_of_racket_splicing_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym">racket/<span class="mywbr"> </span>splicing</span>?</a></td></tr><tr><td><span class="tocsublinknumber">8<tt> </tt></span><a href="#(part._.References_and_.Acknowledgments)" class="tocsubseclink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td><span class="tocsublinknumber">9<tt> </tt></span><a href="#(part._.Epilogue)" class="tocsubseclink" pltdoc="x">Epilogue</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><h2><a name="(part._.Fear_of_.Macros)"></a>Fear of Macros</h2><div class="SAuthorListBox"><span class="SAuthorList"><p class="author"><a href="https://github.com/greghendershott/fear-of-macros/issues">Greg Hendershott</a></p></span></div><p><div class="SIntrapara"><img src="fear-of-macros.jpg" alt="" />
</div><div class="SIntrapara"></div><div class="SIntrapara"><span class="Smaller">Copyright (c) 2012 by Greg Hendershott. All rights reserved.</span>
-</div><div class="SIntrapara"><span class="Smaller">Last updated 2012-10-26 17:10:25</span></div><div class="SIntrapara"><table cellspacing="0"><tr><td><p><span class="hspace"> </span><a href="#(part._.Preface)" class="toptoclink" pltdoc="x">1<span class="hspace"> </span>Preface</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.The_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>The plan of attack</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Transformers)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transformers</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_is_a_syntax_transformer_)" class="toclink" pltdoc="x">3.1<span class="hspace"> </span>What is a syntax transformer?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_input_)" class="toclink" pltdoc="x">3.2<span class="hspace"> </span>What’s the input?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Actually_transforming_the_input)" class="toclink" pltdoc="x">3.3<span class="hspace"> </span>Actually transforming the input</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Compile_time_vs__run_time)" class="toclink" pltdoc="x">3.4<span class="hspace"> </span>Compile time vs. run time</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._begin-for-syntax)" class="toclink" pltdoc="x">3.5<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="toptoclink" pltdoc="x">4<span class="hspace"> </span>Pattern matching: syntax-case and syntax-rules</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Patterns_and_templates)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Patterns and templates</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span>"A pattern variable can’t be used outside of a template"</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Syntax_parameters)" class="toptoclink" pltdoc="x">5<span class="hspace"> </span>Syntax parameters</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Other_questions)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Other questions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_with-syntax_)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">with-syntax</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_begin-for-syntax_)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_racket_splicing_)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>What’s the point of <span class="RktSym">racket/splicing</span>?</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.References_and_.Acknowledgments)" class="toptoclink" pltdoc="x">8<span class="hspace"> </span>References and Acknowledgments</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Epilogue)" class="toptoclink" pltdoc="x">9<span class="hspace"> </span>Epilogue</a></p></td></tr></table></div></p><h3>1<tt> </tt><a name="(part._.Preface)"></a>Preface</h3><p>I learned Racket after 25 years of mostly using C and C++.</p><p>Some psychic whiplash resulted.</p><p>"All the parentheses" was actually not a big deal. Instead, the first
+</div><div class="SIntrapara"><span class="Smaller">Last updated 2012-10-27 09:45:22</span></div><div class="SIntrapara"><table cellspacing="0"><tr><td><p><span class="hspace"> </span><a href="#(part._.Preface)" class="toptoclink" pltdoc="x">1<span class="hspace"> </span>Preface</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.The_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>The plan of attack</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Transformers)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transformers</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_is_a_syntax_transformer_)" class="toclink" pltdoc="x">3.1<span class="hspace"> </span>What is a syntax transformer?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_input_)" class="toclink" pltdoc="x">3.2<span class="hspace"> </span>What’s the input?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Actually_transforming_the_input)" class="toclink" pltdoc="x">3.3<span class="hspace"> </span>Actually transforming the input</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Compile_time_vs__run_time)" class="toclink" pltdoc="x">3.4<span class="hspace"> </span>Compile time vs. run time</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._begin-for-syntax)" class="toclink" pltdoc="x">3.5<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="toptoclink" pltdoc="x">4<span class="hspace"> </span>Pattern matching: syntax-case and syntax-rules</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Patterns_and_templates)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Patterns and templates</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span>"A pattern variable can’t be used outside of a template"</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Syntax_parameters)" class="toptoclink" pltdoc="x">5<span class="hspace"> </span>Syntax parameters</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Other_questions)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Other questions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_with-syntax_)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">with-syntax</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_begin-for-syntax_)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_racket_splicing_)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>What’s the point of <span class="RktSym">racket/splicing</span>?</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.References_and_.Acknowledgments)" class="toptoclink" pltdoc="x">8<span class="hspace"> </span>References and Acknowledgments</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Epilogue)" class="toptoclink" pltdoc="x">9<span class="hspace"> </span>Epilogue</a></p></td></tr></table></div></p><h3>1<tt> </tt><a name="(part._.Preface)"></a>Preface</h3><p>I learned Racket after 25 years of mostly using C and C++.</p><p>Some psychic whiplash resulted.</p><p>"All the parentheses" was actually not a big deal. Instead, the first
mind warp was functional programming. Before long I wrapped my brain
around it, and went on to become comfortable and effective with many
other aspects and features of Racket.</p><p>But two final frontiers remained: Macros and continuations.</p><p>I found that simple macros were easy and understandable, plus there
@@ -30,15 +30,15 @@ that soon.</p><p>But if we start there, you’re likely to feel overwhelmed
and terminology, and get very confused. I did.</p><p>1. Instead let’s start with the basics: A syntax object and a function
to change it (a "transformer"). We’ll work at that level for awhile to
get comfortable and to de-mythologize this whole macro business.</p><p>2. Next, we’ll realize that some pattern-matching would make life
-easier. We’ll learn about <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span>, and its shorthand
+easier. We’ll learn about <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span> and its shorthand
cousin, <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fmisc..rkt)._define-syntax-rule))" class="RktStxLink" pltdoc="x">define-syntax-rule</a></span>. We’ll discover we can get
confused if we want to munge pattern variables before sticking them
back in the template, and learn how to do that.</p><p>3. At this point we’ll be able to write many useful macros. But, what
if we want to write the ever-popular anaphoric if, with a "magic
variable"? It turns out we’ve been protected from making certain kind
of mistakes. When we want to do this kind of thing on purpose, we use
-a <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax))" class="RktStxLink" pltdoc="x">syntax</a></span><span class="stt"> </span><span class="RktSym">parameter</span>. [There are other, older ways to do
-this. We won’t look at them. We also won’t spend a lot of time
+a syntax parameter. [There are other, older ways to do this. We won’t
+look at them. We also won’t spend a lot of time
advocating "hygiene"—<wbr></wbr>we’ll just stipulate that it’s good.]</p><p>4. Finally, we’ll realize that our macros could be smarter when
they’re used in error. Normal Racket functions optionally can have
contracts and types. These catch usage mistakes and provide clear,
@@ -52,7 +52,7 @@ always outputs syntax for a string literal:</p><blockquote class="SCodeFlow"><ta
encounter a chunk of syntax starting with <span class="RktSym">foo</span>, please give it
to my transformer function, and replace it with the syntax I give back
to you." So Racket will give anything that looks like <span class="RktPn">(</span><span class="RktSym">foo</span><span class="stt"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span> to our function, and we can return new syntax to use
-instead. Much like a search-and-replace.</p><p>Maybe you know that the usual way to define a function in Racket:</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">f</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>is shorthand for:</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">f</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>That shorthand lets you avoid typing <span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span> and some parentheses.</p><p>Well there is a similar shorthand for <span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">also-foo</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktVal">"I am also foo"</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">also-foo</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"I am also foo"</span></p></td></tr></table></blockquote><p>What we want to remember is that this is simply shorthand. We are
+instead. Much like a search-and-replace.</p><p>Maybe you know that the usual way to define a function in Racket:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></p></blockquote><p>is shorthand for:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote><p>That shorthand lets you avoid typing <span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span> and some parentheses.</p><p>Well there is a similar shorthand for <span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">also-foo</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktVal">"I am also foo"</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">also-foo</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"I am also foo"</span></p></td></tr></table></blockquote><p>What we want to remember is that this is simply shorthand. We are
still defining a transformer function, which takes syntax and returns
syntax. Everything we do with macros, will be built on top of this
basic idea. It’s not magic.</p><p>Speaking of shorthand, there is also a shorthand for <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax))" class="RktStxLink" pltdoc="x">syntax</a></span>,
@@ -110,7 +110,7 @@ input syntax:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="Rkt
change it into a plain Racket <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" class="RktValLink" pltdoc="x">list</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((lib._racket%2Fprivate%2Fmisc..rkt)._displayln))" class="RktValLink" pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktOut">(our-if-v2 #t true false)</span></p></td></tr></table></blockquote><p>2. To change this into a Racket <span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span> form, we need to take
the three interesting pieces—<wbr></wbr>the condition, true-expression, and
false-expression—<wbr></wbr>from the list using <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadr))" class="RktValLink" pltdoc="x">cadr</a></span>, <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._caddr))" class="RktValLink" pltdoc="x">caddr</a></span>,
-and <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span> and arrange them into a <span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span> form:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._quasiquote))" class="RktStxLink" pltdoc="x">`</a></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadr))" class="RktValLink" pltdoc="x">cadr</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._caddr))" class="RktValLink" pltdoc="x">caddr</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._else))" class="RktStxLink" pltdoc="x">else</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>3. Finally, we change that into <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax))" class="RktStxLink" pltdoc="x">syntax</a></span> using
+and <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span> and arrange them into a <span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span> form:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">cond</span><span class="hspace"> </span><span class="RktVal">[</span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadr))" class="RktValLink" pltdoc="x">cadr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._caddr))" class="RktValLink" pltdoc="x">caddr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktVal">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">[</span><span class="RktVal">else</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr></table></blockquote><p>3. Finally, we change that into <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax))" class="RktStxLink" pltdoc="x">syntax</a></span> using
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">cond</span><span class="hspace"> </span><span class="RktVal">[</span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadr))" class="RktValLink" pltdoc="x">cadr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._caddr))" class="RktValLink" pltdoc="x">caddr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktVal">]</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktVal">[</span><span class="RktVal">else</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">#<syntax (cond (#t "true") (else "fals...></span></p></td></tr></table></blockquote><p>So that works, but using <span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cadddr))" class="RktValLink" pltdoc="x">cadddr</a></span> etc. to destructure a list is
painful and error-prone. Maybe you know Racket’s <span class="RktSym"><a href="http://docs.racket-lang.org/reference/match.html#(form._((lib._racket%2Fmatch..rkt)._match))" class="RktStxLink" pltdoc="x">match</a></span>?
Using that would let us do pattern-matching.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Notice that we don’t care about the first item in the
@@ -134,7 +134,7 @@ macro? One way to do that is put it in another module, and
the <span class="RktSym">racket/match</span> module.</p><p>If instead we want to put the helper in the same module, we can’t
simply <span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span> it and use it—<wbr></wbr>the definition would exist at
run time, but we need it at compile time. The answer is to put the
-definition of the helper function(s) inside <span class="RktSym"><a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin-for-syntax))" class="RktStxLink" pltdoc="x">begin-for-syntax</a></span>:</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/begin.html#(form._((quote._~23~25kernel)._begin-for-syntax))" class="RktStxLink" pltdoc="x">begin-for-syntax</a></span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">my-helper-function</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">macro-using-my-helper-function</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">my-helper-function</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>To review:</p><ul><li><p>Syntax transformers work at compile time, not run time. The good
+definition of the helper function(s) inside <span class="RktSym"><a href="http://docs.racket-lang.org/reference/begin.html#(form._((quote._~23~25kernel)._begin-for-syntax))" class="RktStxLink" pltdoc="x">begin-for-syntax</a></span>:</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/begin.html#(form._((quote._~23~25kernel)._begin-for-syntax))" class="RktStxLink" pltdoc="x">begin-for-syntax</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">my-helper-function</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">macro-using-my-helper-function</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">my-helper-function</span><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>To review:</p><ul><li><p>Syntax transformers work at compile time, not run time. The good
news is this means we can do things like rearrange the pieces of
syntax without evaluating them. We can implement forms like
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" class="RktStxLink" pltdoc="x">if</a></span> that simply couldn’t work properly as run time functions.</p></li><li><p>More good news is that there isn’t some special, weird language
@@ -155,7 +155,7 @@ possible but tedious using list accessors such as
added to Racket later.</p></blockquote></blockquote></blockquote><p>It turns out that pattern-matching was one of the first improvements
to be added to the Racket macro system. It’s called
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span>, and has a shorthand for simple situations called
-<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fmisc..rkt)._define-syntax-rule))" class="RktStxLink" pltdoc="x">define-syntax-rule</a></span>.</p><p>Recall our previous example:</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/require.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._require))" class="RktStxLink" pltdoc="x">require</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._for-syntax))" class="RktStxLink" pltdoc="x">for-syntax</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">racket/match</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">our-if-using-match-v2</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/match.html#(form._((lib._racket%2Fmatch..rkt)._match))" class="RktStxLink" pltdoc="x">match</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3elist))" class="RktValLink" pltdoc="x">syntax->list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" class="RktValLink" pltdoc="x">list</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">condition</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">true-expr</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">false-expr</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">stx</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._quasiquote))" class="RktStxLink" pltdoc="x">`</a></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktSym">condition</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktSym">true-expr</span><span class="RktPn">]</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._else))" class="RktStxLink" pltdoc="x">else</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quasiquote.html#(form._((quote._~23~25kernel)._unquote))" class="RktStxLink" pltdoc="x">,</a></span><span class="RktSym">false-expr</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>Here’s what it looks like using <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-if-using-syntax-case</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="RktPn">]</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._else))" class="RktStxLink" pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">our-if-using-syntax-case</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="hspace"> </span><span class="RktVal">"true"</span><span class="hspace"> </span><span class="RktVal">"false"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"true"</span></p></td></tr></table></blockquote><p>Pretty similar, huh? The pattern matching part looks almost exactly
+<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fmisc..rkt)._define-syntax-rule))" class="RktStxLink" pltdoc="x">define-syntax-rule</a></span>.</p><p>Recall our previous example:</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/require.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._require))" class="RktStxLink" pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/require.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._for-syntax))" class="RktStxLink" pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktSym">racket/match</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-if-using-match-v2</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/match.html#(form._((lib._racket%2Fmatch..rkt)._match))" class="RktStxLink" pltdoc="x">match</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3elist))" class="RktValLink" pltdoc="x">syntax->list</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._list))" class="RktValLink" pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">cond</span><span class="hspace"> </span><span class="RktVal">[</span><span class="RktRdr">,</span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">true-expr</span><span class="RktVal">]</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">[</span><span class="RktVal">else</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">false-expr</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Here’s what it looks like using <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">our-if-using-syntax-case</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._cond))" class="RktStxLink" pltdoc="x">cond</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="RktPn">]</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._else))" class="RktStxLink" pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">our-if-using-syntax-case</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="hspace"> </span><span class="RktVal">"true"</span><span class="hspace"> </span><span class="RktVal">"false"</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"true"</span></p></td></tr></table></blockquote><p>Pretty similar, huh? The pattern matching part looks almost exactly
the same. The way we specify the new syntax is simpler. We don’t need
to do quasi-quoting and unquoting. We don’t need to use
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span>. Instead, we supply a "template", which uses
@@ -192,11 +192,11 @@ size" template. Let’s try that:</p><blockquote class="SCodeFlow"><table ce
But when we tried to use it, no luck. It seems that a function named
<span class="RktSym">foo-bar</span> wasn’t defined.</p><p>This is where the Macro Stepper in DrRacket is invaluable. Even if you
prefer to work mostly in Emacs (like I do), this is a situation where
-it’s worth using DrRacket temporarily for its Macro Stepper.</p><p><img src="macro-stepper.png" alt="" width="598" height="564" /></p><p>The Macro Stepper says that the use of our macro:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">hyphen-define/wrong1.1</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">foo</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">bar</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#t</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>expanded to:</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">name</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#t</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>Well that explains it. Instead, we wanted to expand to:</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#t</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>Our template is using the symbol <span class="RktSym">name</span> but we wanted its
+it’s worth using DrRacket temporarily for its Macro Stepper.</p><p><img src="macro-stepper.png" alt="" width="598" height="564" /></p><p>The Macro Stepper says that the use of our macro:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">hyphen-define/wrong1.1</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></p></blockquote><p>expanded to:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></p></blockquote><p>Well that explains it. Instead, we wanted to expand to:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></p></blockquote><p>Our template is using the symbol <span class="RktSym">name</span> but we wanted its
value, such as <span class="RktSym">foo-bar</span> in this use of our macro.</p><p>A solution here is <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span>, which lets us say that
<span class="RktSym">name</span> is something whose value can be used in our output
template:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/wrong1.3</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/wrong1.3</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">foo-bar: undefined;</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </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"> </span><span class="RktErr">in module: 'program</span></p></td></tr></table></blockquote><p>Hmm. <span class="RktSym">foo-bar</span> is <span style="font-style: italic">still</span> not defined. Back to the Macro
-Stepper. It says now we’re expanding to:</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">|#<syntax:11:24foo>-#<syntax:11:28 bar>|</span><span class="RktPn">)</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#t</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>Oh right: <span class="RktRdr">#'</span><span class="RktSym">a</span> and <span class="RktRdr">#'</span><span class="RktSym">b</span> are syntax objects, and
+Stepper. It says now we’re expanding to:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">|#<syntax:11:24foo>-#<syntax:11:28 bar>|</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></p></blockquote><p>Oh right: <span class="RktRdr">#'</span><span class="RktSym">a</span> and <span class="RktRdr">#'</span><span class="RktSym">b</span> are syntax objects, and
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span> is printing them as such. Instead we want the datum
inside the syntax object, the symbol <span class="RktSym">foo</span> and
<span class="RktSym">bar</span>. To get that, we use <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>And now it works!</p><p>By the way, there is a utility function in <span class="RktSym">racket/syntax</span>
@@ -207,7 +207,7 @@ converting from syntax to datum and back again.</p><p>To review:</p><ul><li><p>I
template, <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span> is your friend.</p></li><li><p>You will need to use <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax))" class="RktStxLink" pltdoc="x">syntax</a></span> or <span class="stt">#</span><span class="stt">’</span><span class="stt"></span> on the pattern
variables to turn them into "fun size" templates.</p></li><li><p>Usually you’ll also need to use <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span> to get
the interesting value inside.</p></li><li><p><span class="RktSym">format-id</span> is convenient for formatting identifier
-names.</p></li></ul><h3>5<tt> </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#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._let))" class="RktStxLink" pltdoc="x">let</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">tmp</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">big-long-calculation</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" class="RktStxLink" pltdoc="x">if</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">tmp</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">tmp</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></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="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">big-long-calculation</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">it</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">#f</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote><p>In other words, when the condition is true, an <span class="RktSym">it</span> identifier
+names.</p></li></ul><h3>5<tt> </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#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._let))" class="RktStxLink" pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">tmp</span><span class="hspace"> </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"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" class="RktStxLink" pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktSym">tmp</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">tmp</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </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"> </span><span class="RktPn">(</span><span class="RktSym">big-long-calculation</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">it</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </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">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fmisc..rkt)._define-syntax-rule))" class="RktStxLink" pltdoc="x">define-syntax-rule</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace"> </span><span class="RktSym">condition</span><span class="hspace"> </span><span class="RktSym">true-expr</span><span class="hspace"> </span><span class="RktSym">false-expr</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/let.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._let))" class="RktStxLink" pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">it</span><span class="hspace"> </span><span class="RktSym">condition</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((quote._~23~25kernel)._if))" class="RktStxLink" pltdoc="x">if</a></span><span class="hspace"> </span><span class="RktSym">it</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">true-expr</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </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">> </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((lib._racket%2Fprivate%2Fmisc..rkt)._displayln))" class="RktValLink" pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">it</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/void.html#(def._((quote._~23~25kernel)._void))" class="RktValLink" 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"> </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"> </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
@@ -244,16 +244,18 @@ Looking Hygiene</a>, which explains syntax-parameterize. I relied
heavily on that, mostly just updating it since his post was written
before PLT Scheme was renamed to Racket.</p><p>After initially wondering if I was asking the wrong question and
conflating two different issues :), Shriram Krishnamurthi looked at an
-early draft and encouraged me to keep going. Sam Tobin-Hochstadt also
-encouraged me.</p><p>After writing much of this, I noticed that Racket’s documentation had
-improved since I last read it. Actually it was the same, and very
-good—<wbr></wbr>I’d changed. It’s interesting how much of what we already know
-is projected between the lines. That’s what makes it so hard to write
-documentation. The only advantage I had was knowing so much less.</p><h3>9<tt> </tt><a name="(part._.Epilogue)"></a>Epilogue</h3><blockquote class="SCentered"><p>"Before I had studied Chan (Zen) for thirty years, I saw mountains as
+early draft and encouraged me to keep going. Sam Tobin-Hochstadt and
+Robby Findler also encouraged me.</p><p>Finally, I noticed something strange. After writing much of this, when
+I returned to some parts of the Racket documentation, I noticed it had
+improved since I last read it. Of course, it was the same. I’d
+changed. It’s interesting how much of what we already know is
+projected between the lines. My point is, the Racket documentation is
+very good. The <span style="font-style: italic">Guide</span> provides helpful examples and
+tutorials. The <span style="font-style: italic">Reference</span> is very clear and precise.</p><h3>9<tt> </tt><a name="(part._.Epilogue)"></a>Epilogue</h3><blockquote class="SCentered"><p>"Before I had studied Chan (Zen) for thirty years, I saw mountains as
mountains, and rivers as rivers. When I arrived at a more intimate
knowledge, I came to the point where I saw that mountains are not
mountains, and rivers are not rivers. But now that I have got its very
substance I am at rest. For it’s just that I see mountains once again
as mountains, and rivers once again as rivers"</p><p><span class="Smaller">–Buddhist saying originally formulated by Qingyuan Weixin,
later translated by D.T. Suzuki in his <span style="font-style: italic">Essays in Zen
-Buddhism</span>.</span></p></blockquote><p>Translated into Racket:</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/cont.html#(def._((quote._~23~25kernel)._dynamic-wind))" class="RktValLink" pltdoc="x">dynamic-wind</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._not))" class="RktValLink" pltdoc="x">not</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">mountains</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/quote.html#(form._((quote._~23~25kernel)._quote))" class="RktStxLink" pltdoc="x">'</a></span><span class="RktSym">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktMeta"></span></td></tr></table></blockquote></div></div><div id="contextindicator"> </div></body></html>
-\ No newline at end of file
+Buddhism</span>.</span></p></blockquote><p>Translated into Racket:</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/cont.html#(def._((quote._~23~25kernel)._dynamic-wind))" class="RktValLink" pltdoc="x">dynamic-wind</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._not))" class="RktValLink" pltdoc="x">not</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/lambda.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._lambda))" class="RktStxLink" pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/if.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._and))" class="RktStxLink" pltdoc="x">and</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">mountains</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">rivers</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></div><div id="contextindicator"> </div></body></html>
+\ No newline at end of file