commit 938d2902475514dc5bc0017c7bc90d7c0ac69685
parent 0de939e5c66f49ddd57cfd2af92e6c7f39f73f3b
Author: Greg Hendershott <greghendershott@gmail.com>
Date: Fri, 2 Nov 2012 14:02:30 -0400
Update acknowledgments; other small edits.
Diffstat:
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/index.html b/index.html
@@ -1,6 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<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]--><meta name="keywords" content="Racket,macros,Scheme"><meta name="description" content="Practical Racket macros"><meta name="author" content="Greg Hendershott"><meta name="charset" content="utf-8"><link href='http://fonts.googleapis.com/css?family=Fenix' rel='stylesheet' type='text/css'><script type="text/javascript">var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-29709446-1']);_gaq.push(['_setDomainName', 'greghendershott.com']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();</script></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist" style="margin-bottom: 1em;"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"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._.Our_plan_of_attack)" class="tocviewlink" pltdoc="x">Our plan of attack</a></td></tr><tr><td align="right">3 </td><td><a href="#(part._.Transform_)" class="tocviewlink" pltdoc="x">Transform!</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._.What_s_the_point_of_splicing-let_)" class="tocviewlink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td align="right">7 </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">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._.Our_plan_of_attack)" class="tocsubseclink" pltdoc="x">Our plan of attack</a></td></tr><tr><td><span class="tocsublinknumber">3<tt> </tt></span><a href="#(part._.Transform_)" class="tocsubseclink" pltdoc="x">Transform!</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._.Pattern_variable_vs__template---fight_)" class="tocsubseclink" pltdoc="x">Pattern variable vs. template—<wbr></wbr>fight!</a></td></tr><tr><td><span class="tocsublinknumber">4.1.1<tt> </tt></span><a href="#(part._with-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">with-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.2<tt> </tt></span><a href="#(part._format-id)" class="tocsubseclink" pltdoc="x"><span class="RktSym">format-<wbr></wbr>id</span></a></td></tr><tr><td><span class="tocsublinknumber">4.2<tt> </tt></span><a href="#(part._.Making_our_own_struct)" class="tocsubseclink" pltdoc="x">Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.3<tt> </tt></span><a href="#(part._hash..refs)" class="tocsubseclink" pltdoc="x">Using dot notation for nested hash lookups</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._.What_s_the_point_of_splicing-let_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td><span class="tocsublinknumber">7<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.1<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_functions)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for functions</a></td></tr><tr><td><span class="tocsublinknumber">7.2<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_macros)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for macros</a></td></tr><tr><td><span class="tocsublinknumber">7.3<tt> </tt></span><a href="#(part._.Using_syntax_parse)" class="tocsubseclink" pltdoc="x">Using <span class="RktSym">syntax/<span class="mywbr"> </span>parse</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="http://www.greghendershott.com">Greg Hendershott</a></p></span></div><p><div class="SIntrapara"></div><div class="SIntrapara"><img src="fear-of-macros.jpg" alt="" />
-</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-11-02 11:51:39</span></div><div class="SIntrapara">Feedback and corrections are <a href="https://github.com/greghendershott/fear-of-macros/issues">welcome here</a>.</div></p><p>Contents:</p><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._.Our_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>Our 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._.Transform_)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transform!</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._.Pattern_variable_vs__template---fight_)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Pattern variable vs. template—<wbr></wbr>fight!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._with-syntax)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">with-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._format-id)" class="toclink" pltdoc="x">4.1.2<span class="hspace"> </span><span class="RktSym">format-id</span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Making_our_own_struct)" class="toclink" pltdoc="x">4.2<span class="hspace"> </span>Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._hash..refs)" class="toclink" pltdoc="x">4.3<span class="hspace"> </span>Using dot notation for nested hash lookups</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._.What_s_the_point_of_splicing-let_)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-let</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._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_functions)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>Error-handling strategies for functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_macros)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>Error-handling strategies for macros</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Using_syntax_parse)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>Using <span class="RktSym">syntax/parse</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><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">Copyright (c) 2012 by Greg Hendershott. All rights reserved.</span></div><div class="SIntrapara"><span class="Smaller">Last updated 2012-11-02 14:00:28</span></div><div class="SIntrapara">Feedback and corrections are <a href="https://github.com/greghendershott/fear-of-macros/issues">welcome here</a>.</div></p><p>Contents:</p><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._.Our_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>Our 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._.Transform_)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transform!</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._.Pattern_variable_vs__template---fight_)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Pattern variable vs. template—<wbr></wbr>fight!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._with-syntax)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">with-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._format-id)" class="toclink" pltdoc="x">4.1.2<span class="hspace"> </span><span class="RktSym">format-id</span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Making_our_own_struct)" class="toclink" pltdoc="x">4.2<span class="hspace"> </span>Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._hash..refs)" class="toclink" pltdoc="x">4.3<span class="hspace"> </span>Using dot notation for nested hash lookups</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._.What_s_the_point_of_splicing-let_)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-let</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._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_functions)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>Error-handling strategies for functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_macros)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>Error-handling strategies for macros</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Using_syntax_parse)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>Using <span class="RktSym">syntax/parse</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><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
@@ -288,7 +288,8 @@ over lambda". <span class="refelem"><span class="refcolumn"><span class="refcont
about closures and objects.</span></span></span> A closure hides <span class="RktSym">y</span>, which can
only be accessed via <span class="RktSym">get-y</span>.</p><p>So why would we care about the splicing forms? They can be more
concise, especially when there are multiple body forms:</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/require.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._require))" class="RktStxLink" pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktSym">racket/splicing</span><span class="RktPn">)</span></td></tr><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/splicing.html#(form._((lib._racket%2Fsplicing..rkt)._splicing-let))" class="RktStxLink" pltdoc="x">splicing-let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">0</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/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">inc</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/set_.html#(form._((quote._~23~25kernel)._set!))" class="RktStxLink" pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._%2B))" class="RktValLink" pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">1</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="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">dec</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/set_.html#(form._((quote._~23~25kernel)._set!))" class="RktStxLink" pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._-))" class="RktValLink" pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">1</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="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">get</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote><p>The splicing variation is more convenient than the usual way:</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._((quote._~23~25kernel)._define-values))" class="RktStxLink" pltdoc="x">define-values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">inc</span><span class="hspace"> </span><span class="RktSym">dec</span><span class="hspace"> </span><span class="RktSym">get</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">x</span><span class="hspace"> </span><span class="RktVal">0</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/values.html#(def._((quote._~23~25kernel)._values))" class="RktValLink" pltdoc="x">values</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><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">inc</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/set_.html#(form._((quote._~23~25kernel)._set!))" class="RktStxLink" pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._%2B))" class="RktValLink" pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">x</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="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><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">dec</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/set_.html#(form._((quote._~23~25kernel)._set!))" class="RktStxLink" pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._-))" class="RktValLink" pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">x</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="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><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">get</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote><p>When there are many body forms—<wbr></wbr>and we’re generating them in a
-macro—<wbr></wbr>the splicing variations can be much easier.</p><h3>7<tt> </tt><a name="(part._.Robust_macros__syntax-parse)"></a>Robust macros: syntax-parse</h3><p>Functions can be used in error. So can macros.</p><h4>7.1<tt> </tt><a name="(part._.Error-handling_strategies_for_functions)"></a>Error-handling strategies for functions</h4><p>With plain old functions, we have several choices.</p><p>1. Don’t check at all.</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))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktSym">s</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/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">string-append: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: string?</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: 0</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">argument position: 1st</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">other arguments...:</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">" snazzy suffix"</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I guess I goofed, but </span><span class="RktCmt">–</span><span class="RktCmt"> what is this "string-append" of which you</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">speak??</span></td></tr></table></blockquote><p>The problem is that the resulting error message will be confusing. Our
+macro—<wbr></wbr>the splicing variations can be much easier.</p><h3>7<tt> </tt><a name="(part._.Robust_macros__syntax-parse)"></a>Robust macros: syntax-parse</h3><p>Functions can be used in error. So can macros.</p><h4>7.1<tt> </tt><a name="(part._.Error-handling_strategies_for_functions)"></a>Error-handling strategies for functions</h4><p>With plain old functions, we have several choices how to handle
+misuse.</p><p>1. Don’t check at all.</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))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktSym">s</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/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">string-append: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: string?</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: 0</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">argument position: 1st</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">other arguments...:</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">" snazzy suffix"</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I guess I goofed, but </span><span class="RktCmt">–</span><span class="RktCmt"> what is this "string-append" of which you</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">speak??</span></td></tr></table></blockquote><p>The problem is that the resulting error message will be confusing. Our
user thinks they’re calling <span class="RktSym">misuse</span>, but is getting an error
message from <span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span>. In this simple example they
could probably guess what’s happening, but in most cases they won’t.</p><p>2. Write some error handling code.</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))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktSym">s</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/when_unless.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._unless))" class="RktStxLink" pltdoc="x">unless</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym">s</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/exns.html#(def._((quote._~23~25kernel)._error))" class="RktValLink" pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">misuse</span><span class="hspace"> </span><span class="RktVal">"expected a string, but got ~a"</span><span class="hspace"> </span><span class="RktSym">s</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/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">misuse: expected a string, but got 0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I goofed, and understand why! It</span><span class="RktCmt">'</span><span class="RktCmt">s a shame the writer of the</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">function had to work so hard to tell me.</span></td></tr></table></blockquote><p>Unfortunately the error code tends to overwhelm and/or obscure our
@@ -305,8 +306,9 @@ learning how to write macros, we especially don’t want more cognitive
load and obfuscation.</p><p>3. Use <span class="RktSym">syntax/parse</span>. For macros, this is the equivalent of
using contracts or types for functions. We can declare that input
pattern elements must be certain kinds of things, such as an
-identifier. Instead of "types", the things are referred to as "syntax
-classes". There are predefined syntax classes, plus we can define our own.</p><h4>7.3<tt> </tt><a name="(part._.Using_syntax_parse)"></a>Using <span class="RktSym">syntax/parse</span></h4><p>November 1, 2012: So here’s the deal. After writing everything up to
+identifier. Instead of "types", the kinds are referred to as "syntax
+classes". There are predefined syntax classes, plus we can define our
+own.</p><h4>7.3<tt> </tt><a name="(part._.Using_syntax_parse)"></a>Using <span class="RktSym">syntax/parse</span></h4><p>November 1, 2012: So here’s the deal. After writing everything up to
this point, I sat down to re-read the documentation for
<span class="RktSym">syntax/parse</span>. It was...very understandable. I didn’t feel
confused.</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktSym"><span</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">style=</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">accent:</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktVal">"Kenau-Reeves"</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"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._~3e))" class="RktValLink" pltdoc="x">></a></span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="RktSym">Whoa.</span><span class="RktMeta"></span></td></tr><tr><td><span class="RktMeta"></span><span class="RktSym"></span></span><span class="RktMeta"></span></td></tr></table></blockquote><p>Why? The documentation is written very well. Also, everything up to
@@ -339,7 +341,8 @@ conflating two different issues :), Shriram Krishnamurthi looked at an
early draft and encouraged me to keep going. Sam Tobin-Hochstadt and
Robby Findler also encouraged me. Matthew Flatt showed me how to make
a Scribble <span class="RktSym">interaction</span> print <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> as
-<span class="RktVal">"syntax"</span> rather than as <span class="RktVal">"#'"</span>.</p><p>Finally, I noticed something strange. After writing much of this, when
+<span class="RktVal">"syntax"</span> rather than as <span class="RktVal">"#'"</span>. Jay McCarthy helped me
+catch some mistakes and confusions.</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
diff --git a/main.rkt b/main.rkt
@@ -1385,7 +1385,8 @@ Functions can be used in error. So can macros.
@subsection{Error-handling strategies for functions}
-With plain old functions, we have several choices.
+With plain old functions, we have several choices how to handle
+misuse.
1. Don't check at all.
@@ -1451,10 +1452,7 @@ message. Plus, the message is in a standard, familiar format.
(: misuse (String -> String))
(define (misuse s)
(string-append s " snazzy suffix"))
-;; User of the function:
(misuse 0)
-;; I goofed, and understand why! I hear the writer of the function is
-;; a cheerful type.
]
With respect to error handling, Typed Racket has the same benefits as
@@ -1476,8 +1474,9 @@ load and obfuscation.
3. Use @racket[syntax/parse]. For macros, this is the equivalent of
using contracts or types for functions. We can declare that input
pattern elements must be certain kinds of things, such as an
-identifier. Instead of "types", the things are referred to as "syntax
-classes". There are predefined syntax classes, plus we can define our own.
+identifier. Instead of "types", the kinds are referred to as "syntax
+classes". There are predefined syntax classes, plus we can define our
+own.
@subsection{Using @racket[syntax/parse]}
@@ -1541,7 +1540,8 @@ conflating two different issues :), Shriram Krishnamurthi looked at an
early draft and encouraged me to keep going. Sam Tobin-Hochstadt and
Robby Findler also encouraged me. Matthew Flatt showed me how to make
a Scribble @racket[interaction] print @racket[syntax] as
-@racket["syntax"] rather than as @racket["#'"].
+@racket["syntax"] rather than as @racket["#'"]. Jay McCarthy helped me
+catch some mistakes and confusions.
Finally, I noticed something strange. After writing much of this, when
I returned to some parts of the Racket documentation, I noticed it had