commit 5b517ae4b9393db592f6779c3126ad8583097e75
parent 8ab1d7d8b357526d98ad19c1a1fdcea9e52ce383
Author: Greg Hendershott <greghendershott@gmail.com>
Date: Thu, 1 Nov 2012 12:12:36 -0400
Regen html
Diffstat:
| M | index.html | | | 54 | +++++++++++++++++++++++++++++++++++++----------------- |
1 file changed, 37 insertions(+), 17 deletions(-)
diff --git a/index.html b/index.html
@@ -1,8 +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._.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-31 11:46:36</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
+<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._.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._.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">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.__.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">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._.Using_dot_notation_for_nested_hash_lookups)" 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._.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._.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">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-01 12:11:35</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._.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.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)" class="toclink" pltdoc="x">4.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><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._.Using_dot_notation_for_nested_hash_lookups)" 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._.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._.What_s_the_point_of_splicing-let_)" class="toptoclink" pltdoc="x">7<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._.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
@@ -171,9 +169,11 @@ territory. Hopefully, because we started with a basic syntax
transformer, and worked up from that, we won’t have that problem. We
can appreciate <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> as a convenient shorthand,
but not be scared of, or confused about, that for which it’s
-shorthand.</p><h4>4.1<tt> </tt><a name="(part._.Patterns_and_templates)"></a>Patterns and templates</h4><p>Most of the materials I found for learning macros, including the
+shorthand.</p><p>Most of the materials I found for learning macros, including the
Racket <span style="font-style: italic">Guide</span>, do a very good job explaining how patterns
-work. I’m not going to regurgitate that here.</p><p>Instead, let’s look at some ways we’re likely to get tripped up.</p><h5>4.1.1<tt> </tt><a name="(part.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)"></a>"A pattern variable can’t be used outside of a template"</h5><p>Let’s say we want to define a function with a hyphenated name, a-b,
+and templates work. I’m not going to regurgitate that here.</p><p>Sometimes, we need to go a step beyond the pattern and template. Let’s
+look at some examples, how we can get confused, and how to get it
+working.</p><h4>4.1<tt> </tt><a name="(part.__.A_pattern_variable_can_t_be_used_outside_of_a_template_)"></a>"A pattern variable can’t be used outside of a template"</h4><p>Let’s say we want to define a function with a hyphenated name, a-b,
but we supply the a and b parts separately. The Racket <span class="RktSym"><a href="http://docs.racket-lang.org/reference/define-struct.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._struct))" class="RktStxLink" pltdoc="x">struct</a></span>
macro does something like this: <span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define-struct.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._struct))" class="RktStxLink" pltdoc="x">struct</a></span><span class="stt"> </span><span class="RktSym">foo</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">field1</span><span class="stt"> </span><span class="RktSym">field2</span><span class="RktPn">)</span><span class="RktPn">)</span>
automatically defines a number of functions whose names are variations
@@ -208,7 +208,30 @@ 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="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
+names.</p></li></ul><h4>4.2<tt> </tt><a name="(part._.Making_our_own_struct)"></a>Making our own <span class="RktSym"><a href="http://docs.racket-lang.org/reference/define-struct.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._struct))" class="RktStxLink" pltdoc="x">struct</a></span></h4><p>In this example we’ll pretend that Racket doesn’t already have a
+<span class="RktSym"><a href="http://docs.racket-lang.org/reference/define-struct.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._struct))" class="RktStxLink" pltdoc="x">struct</a></span> capability. Fortunately, we can define a macro to
+provide this feature. To keep things simple, our structure will be
+immutable (read-only) and it won’t support inheritance.</p><p>Given a structure declaration like:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">our-struct</span><span class="hspace"> </span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">field1</span><span class="hspace"> </span><span class="RktSym">field2</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>We need to define some procedures.</p><ul><li><p>A constructor procedure whose name is the struct name. We’ll
+represent structures as a <span class="RktSym"><a href="http://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector))" class="RktValLink" pltdoc="x">vector</a></span>. The structure name will be
+element zero. The fields will be elements one onward.</p></li><li><p>A predicate, whose name is the struct name with <span class="stt">?</span>
+appended.</p></li><li><p>For each field, an accessor procedure to get its value. These
+will be named struct-field (the name of the struct, a hyphen, and the
+field name).</p></li></ul><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="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/syntax</span><span class="RktPn">)</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/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-struct</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 href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fields</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></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">pred-id</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">format-id</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">"~a?"</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></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/begin.html#(form._((quote._~23~25kernel)._begin))" class="RktStxLink" pltdoc="x">begin</a></span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define a constructor.</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"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktSym">fields</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/procedures.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._apply))" class="RktValLink" pltdoc="x">apply</a></span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector))" class="RktValLink" pltdoc="x">vector</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cons))" class="RktValLink" pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</span><span class="hspace"> </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">fields</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></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define a predicate.</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">pred-id</span><span class="hspace"> </span><span class="RktSym">v</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)._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/vectors.html#(def._((quote._~23~25kernel)._vector~3f))" class="RktValLink" pltdoc="x">vector?</a></span><span class="hspace"> </span><span class="RktSym">v</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/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector-ref))" class="RktValLink" pltdoc="x">vector-ref</a></span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define an accessor for each field.</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/for.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._for%2Flist))" class="RktStxLink" pltdoc="x">for/list</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="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="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym">fields</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></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._in-naturals))" class="RktValLink" pltdoc="x">in-naturals</a></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/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">acc-id</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">format-id</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktSym">x</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">ix</span><span class="hspace"> </span><span class="RktSym">n</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">acc-id</span><span class="hspace"> </span><span class="RktSym">v</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">pred-id</span><span class="hspace"> </span><span class="RktSym">v</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">acc-id</span><span class="hspace"> </span><span class="RktVal">"~a is not a ~a struct"</span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</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/vectors.html#(def._((quote._~23~25kernel)._vector-ref))" class="RktValLink" pltdoc="x">vector-ref</a></span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktSym">ix</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="RktPn">]</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">Test it out</span></td></tr><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">rackunit</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">our-struct</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</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/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">check-true</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo?</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">check-false</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo?</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">check-equal?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo-a</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">check-equal?</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo-b</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</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">check-exn</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/exns.html#(def._((quote._~23~25kernel)._exn~3afail~3f))" class="RktValLink" pltdoc="x">exn:fail?</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/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="RktPn">(</span><span class="RktSym">foo-a</span><span class="hspace"> </span><span class="RktVal">"furble"</span><span class="RktPn">)</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">The tests passed.</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Next, what if someone tries to declare:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">our-struct</span><span class="hspace"> </span><span class="RktVal">"blah"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVal">"blah"</span><span class="hspace"> </span><span class="RktVal">"blah"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">format-id: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: (or/c string? symbol? identifier? keyword? char?</span></p></td></tr><tr><td><p><span class="RktErr">number?)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">given: #<syntax:71:0 "blah"></span></p></td></tr></table></blockquote><p>The error message is not very helpful. It’s coming from
+<span class="RktSym">format-id</span>, which is a private implementation detail of our macro.</p><p>You may know that a <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> clause can take an
+optional "guard" or "fender" expression. Instead of</p><blockquote class="SCodeFlow"><p><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/stxparse-specifying.html#(form._((lib._syntax%2Fparse..rkt)._pattern))" class="RktStxLink" pltdoc="x">pattern</a></span><span class="hspace"> </span><span class="RktSym">template</span><span class="RktPn">]</span></p></blockquote><p>It can be:</p><blockquote class="SCodeFlow"><p><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/stxparse-specifying.html#(form._((lib._syntax%2Fparse..rkt)._pattern))" class="RktStxLink" pltdoc="x">pattern</a></span><span class="hspace"> </span><span class="RktSym">guard</span><span class="hspace"> </span><span class="RktSym">template</span><span class="RktPn">]</span></p></blockquote><p>Let’s add a guard expression to our clause:</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="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/syntax</span><span class="RktPn">)</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/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-struct</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 href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fields</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></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Guard or "fender" expression:</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/pairs.html#(def._((lib._racket%2Fprivate%2Fmap..rkt)._for-each))" class="RktValLink" pltdoc="x">for-each</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="RktSym">x</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/stxops.html#(def._((lib._racket%2Fprivate%2Fstx..rkt)._identifier~3f))" class="RktValLink" pltdoc="x">identifier?</a></span><span class="hspace"> </span><span class="RktSym">x</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)._raise-syntax-error))" class="RktValLink" pltdoc="x">raise-syntax-error</a></span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">"not an identifier"</span><span class="hspace"> </span><span class="RktSym">stx</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/pairs.html#(def._((quote._~23~25kernel)._cons))" class="RktValLink" pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</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="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym">fields</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></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">pred-id</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">format-id</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">"~a?"</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></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/begin.html#(form._((quote._~23~25kernel)._begin))" class="RktStxLink" pltdoc="x">begin</a></span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define a constructor.</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"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktSym">fields</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/procedures.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._apply))" class="RktValLink" pltdoc="x">apply</a></span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector))" class="RktValLink" pltdoc="x">vector</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cons))" class="RktValLink" pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</span><span class="hspace"> </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">fields</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></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define a predicate.</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">pred-id</span><span class="hspace"> </span><span class="RktSym">v</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)._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/vectors.html#(def._((quote._~23~25kernel)._vector~3f))" class="RktValLink" pltdoc="x">vector?</a></span><span class="hspace"> </span><span class="RktSym">v</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/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/vectors.html#(def._((quote._~23~25kernel)._vector-ref))" class="RktValLink" pltdoc="x">vector-ref</a></span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Define an accessor for each field.</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/for.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._for%2Flist))" class="RktStxLink" pltdoc="x">for/list</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="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="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym">fields</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></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">n</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._in-naturals))" class="RktValLink" pltdoc="x">in-naturals</a></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/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">acc-id</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">format-id</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Library_Syntax_Classes_and_Literal_Sets.html#(form._((lib._syntax%2Fparse..rkt)._id))" class="RktStxLink" pltdoc="x">id</a></span><span class="hspace"> </span><span class="RktSym">x</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">ix</span><span class="hspace"> </span><span class="RktSym">n</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">acc-id</span><span class="hspace"> </span><span class="RktSym">v</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">pred-id</span><span class="hspace"> </span><span class="RktSym">v</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">acc-id</span><span class="hspace"> </span><span class="RktVal">"~a is not a ~a struct"</span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">id</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/vectors.html#(def._((quote._~23~25kernel)._vector-ref))" class="RktValLink" pltdoc="x">vector-ref</a></span><span class="hspace"> </span><span class="RktSym">v</span><span class="hspace"> </span><span class="RktSym">ix</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="RktPn">]</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">Now the same misuse gives a better error message:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">our-struct</span><span class="hspace"> </span><span class="RktVal">"blah"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktVal">"blah"</span><span class="hspace"> </span><span class="RktVal">"blah"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:74:0: our-struct: not an identifier</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: "blah"</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (our-struct "blah" ("blah" "blah"))</span></p></td></tr></table></blockquote><p>Later, we’ll see how <span class="RktSym"><a href="http://docs.racket-lang.org/syntax/Parsing_Syntax.html#(form._((lib._syntax%2Fparse..rkt)._syntax-parse))" class="RktStxLink" pltdoc="x">syntax-parse</a></span> makes it even easier to
+check usage and provide helpful messages about mistakes.</p><h4>4.3<tt> </tt><a name="(part._.Using_dot_notation_for_nested_hash_lookups)"></a>Using dot notation for nested hash lookups</h4><p>The previous two examples used a macro to define functions whose names
+were made by joining identifiers provided to the macro. This example
+does the opposite: The identifier given to the macro is split into
+pieces.</p><p>If you write programs for web services you deal with JSON, which is
+represented in Racket by a <span class="RktSym">jsexpr?</span>. JSON often has
+dictionaries that contain other dictionaries. In a <span class="RktSym">jsexpr?</span>
+these are represented by nested <span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hasheq))" class="RktValLink" pltdoc="x">hasheq</a></span> tables.</p><p>JavaScript you can use dot notation:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktSym">foo</span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/generic-numbers.html#(def._((quote._~23~25kernel)._~3d))" class="RktValLink" pltdoc="x">=</a></span><span class="RktMeta"></span><span class="hspace"> </span><span class="RktMeta"></span><span class="RktSym">js.a.b.c</span><span class="RktCmt">;</span><span class="RktMeta"></span></td></tr></table></blockquote><p>In Racket it’s not so convenient:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Nested hasheqs typical of a jsexpr:</span></td></tr><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">js</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hasheq))" class="RktValLink" pltdoc="x">hasheq</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hasheq))" class="RktValLink" pltdoc="x">hasheq</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hasheq))" class="RktValLink" pltdoc="x">hasheq</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">c</span><span class="hspace"> </span><span class="RktVal">"value"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Typical annoying code to get something:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="RktValLink" pltdoc="x">hash-ref</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="RktValLink" pltdoc="x">hash-ref</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="RktValLink" pltdoc="x">hash-ref</a></span><span class="hspace"> </span><span class="RktSym">js</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">b</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">c</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"value"</span></p></td></tr></table></blockquote><p>We can write a helper function to make this a bit cleaner:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">This helper function:</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/attaching-contracts-to-values.html#(form._((lib._racket%2Fcontract%2Fregion..rkt)._define%2Fcontract))" class="RktStxLink" pltdoc="x">define/contract</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hash-refs</span><span class="hspace"> </span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktSym">ks</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">def</span><span class="hspace"> </span><span class="RktVal">#f</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/hashtables.html#(def._((quote._~23~25kernel)._hash~3f))" class="RktValLink" pltdoc="x">hash?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/data-structure-contracts.html#(def._((lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt)._listof))" class="RktValLink" pltdoc="x">listof</a></span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/data-structure-contracts.html#(def._((lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt)._any%2Fc))" class="RktValLink" pltdoc="x">any/c</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/data-structure-contracts.html#(def._((lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt)._any%2Fc))" class="RktValLink" pltdoc="x">any/c</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/function-contracts.html#(form._((lib._racket%2Fcontract%2Fbase..rkt)._-~3e*))" class="RktStxLink" pltdoc="x"><span class="nobreak">-></span>*</a></span><span class="RktPn"> .</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/data-structure-contracts.html#(form._((lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt)._any))" class="RktStxLink" pltdoc="x">any</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/exns.html#(form._((lib._racket%2Fprivate%2Fmore-scheme..rkt)._with-handlers))" class="RktStxLink" pltdoc="x">with-handlers</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/exns.html#(def._((quote._~23~25kernel)._exn~3afail~3f))" class="RktValLink" pltdoc="x">exn:fail?</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/procedures.html#(def._((lib._racket%2Ffunction..rkt)._const))" class="RktValLink" pltdoc="x">const</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)._cond))" class="RktStxLink" pltdoc="x">cond</a></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/procedures.html#(def._((quote._~23~25kernel)._procedure~3f))" class="RktValLink" pltdoc="x">procedure?</a></span><span class="hspace"> </span><span class="RktSym">def</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">def</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._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._else))" class="RktStxLink" pltdoc="x">else</a></span><span class="hspace"> </span><span class="RktSym">def</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="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/for.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._for%2Ffold))" class="RktStxLink" pltdoc="x">for/fold</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktSym">h</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">k</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._in-list))" class="RktValLink" pltdoc="x">in-list</a></span><span class="hspace"> </span><span class="RktSym">ks</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/hashtables.html#(def._((quote._~23~25kernel)._hash-ref))" class="RktValLink" pltdoc="x">hash-ref</a></span><span class="hspace"> </span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktSym">k</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Lets us say:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash-refs</span><span class="hspace"> </span><span class="RktSym">js</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace"> </span><span class="RktVal">b</span><span class="hspace"> </span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"value"</span></p></td></tr></table></blockquote><p>That’s not bad. Can we go even further and use a dot notation somewhat
+like JavaScript?</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">This macro:</span></td></tr><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="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/syntax</span><span class="RktPn">)</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/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">hash.refs</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="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)._raise-syntax-error))" class="RktValLink" pltdoc="x">raise-syntax-error</a></span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">"Expected (hash.key0[.key1 ...] [default])"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">chain</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">chain</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">hash.refs</span><span class="hspace"> </span><span class="RktSym">chain</span><span class="hspace"> </span><span class="RktVal">#f</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">chain</span><span class="hspace"> </span><span class="RktSym">default</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/symbols.html#(def._((quote._~23~25kernel)._symbol~3f))" class="RktValLink" pltdoc="x">symbol?</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-e))" class="RktValLink" pltdoc="x">syntax-e</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">chain</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/exns.html#(def._((quote._~23~25kernel)._raise-syntax-error))" class="RktValLink" pltdoc="x">raise-syntax-error</a></span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">"Expected (hash.key0[.key1 ...] [default])"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">chain</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/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">xs</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket%2Fprivate%2Fmap..rkt)._map))" class="RktValLink" pltdoc="x">map</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="RktSym">x</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)._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="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="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/regexp.html#(def._((lib._racket%2Fprivate%2Fbase..rkt)._regexp-split))" class="RktValLink" pltdoc="x">regexp-split</a></span><span class="hspace"> </span><span class="RktVal">#rx"\\."</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)._symbol-~3estring))" class="RktValLink" pltdoc="x">symbol->string</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-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">chain</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="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/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/generic-numbers.html#(def._((quote._~23~25kernel)._~3e~3d))" class="RktValLink" pltdoc="x">>=</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._length))" class="RktValLink" pltdoc="x">length</a></span><span class="hspace"> </span><span class="RktSym">xs</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">2</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/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/booleans.html#(def._((quote._~23~25kernel)._eq~3f))" class="RktValLink" pltdoc="x">eq?</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-e))" class="RktValLink" pltdoc="x">syntax-e</a></span><span class="hspace"> </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="RktPn">)</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">||</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/exns.html#(def._((quote._~23~25kernel)._raise-syntax-error))" class="RktValLink" pltdoc="x">raise-syntax-error</a></span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">"Expected hash.key"</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">chain</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/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">h</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._car))" class="RktValLink" pltdoc="x">car</a></span><span class="hspace"> </span><span class="RktSym">xs</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">ks</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/pairs.html#(def._((quote._~23~25kernel)._cdr))" class="RktValLink" pltdoc="x">cdr</a></span><span class="hspace"> </span><span class="RktSym">xs</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">hash-refs</span><span class="hspace"> </span><span class="RktSym">h</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">ks</span><span class="hspace"> </span><span class="RktSym">default</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></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Gives us "sugar" to say this:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="hspace"> </span><span class="RktSym">js.a.b.c</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">"value"</span></p></td></tr></table></blockquote><p>It works!</p><p>We’ve started to appreciate that our macros should give helpful
+messages when used in error. We tried to do that here. Let’s
+deliberately elicit various errors. Are the messages helpful?</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:80:0: hash.refs: Expected (hash.key0[.key1 ...]</span></p></td></tr><tr><td><p><span class="RktErr">[default])</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: chain</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (hash.refs)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:83:0: hash.refs: Expected (hash.key0[.key1 ...]</span></p></td></tr><tr><td><p><span class="RktErr">[default])</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: 0</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (hash.refs 0 #f)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="hspace"> </span><span class="RktSym">js</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:84:0: hash.refs: Expected hash.key</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: js</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (hash.refs js #f)</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="hspace"> </span><span class="RktSym">js.</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:85:0: hash.refs: Expected hash.key</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: js.</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (hash.refs js. #f)</span></p></td></tr></table></blockquote><p>Not too bad.</p><p>Maybe we’re not convinced that writing <span class="RktPn">(</span><span class="RktSym">hash.refs</span><span class="stt"> </span><span class="RktSym">js.a.b.c</span><span class="RktPn">)</span>
+is really clearer than <span class="RktPn">(</span><span class="RktSym">hash-refs</span><span class="stt"> </span><span class="RktSym">js</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktVal">b</span><span class="stt"> </span><span class="RktVal">c</span><span class="RktVal">)</span><span class="RktPn">)</span>. Maybe we
+won’t actually use this approach. But the Racket macro system makes it
+a possible choice.</p><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
@@ -230,18 +253,15 @@ default. Only inside of our <span class="RktSym">aif</span> will it have a meani
value:</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/stxparam</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/stxparam.html#(form._((lib._racket%2Fstxparam..rkt)._define-syntax-parameter))" class="RktStxLink" pltdoc="x">define-syntax-parameter</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="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">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/exns.html#(def._((quote._~23~25kernel)._raise-syntax-error))" class="RktValLink" pltdoc="x">raise-syntax-error</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-e))" class="RktValLink" pltdoc="x">syntax-e</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"can only be used inside aif"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </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">tmp</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">tmp</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/stxparam.html#(form._((lib._racket%2Fstxparam..rkt)._syntax-parameterize))" class="RktStxLink" pltdoc="x">syntax-parameterize</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="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxtrans.html#(def._((quote._~23~25kernel)._make-rename-transformer))" class="RktValLink" pltdoc="x">make-rename-transformer</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">tmp</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></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="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">10</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="RktOut">10</span></p></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">aif</span><span class="hspace"> </span><span class="RktVal">#f</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></table></blockquote><p>Inside the <span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxparam.html#(form._((lib._racket%2Fstxparam..rkt)._syntax-parameterize))" class="RktStxLink" pltdoc="x">syntax-parameterize</a></span>, <span class="RktSym">it</span> acts as an alias
for <span class="RktSym">tmp</span>. The alias behavior is created by
<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxtrans.html#(def._((quote._~23~25kernel)._make-rename-transformer))" class="RktValLink" pltdoc="x">make-rename-transformer</a></span>.</p><p>If we try to use <span class="RktSym">it</span> outside of an <span class="RktSym">aif</span> form, and
-<span class="RktSym">it</span> isn’t otherwise defined, we get an error like we want:</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/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></td></tr><tr><td><p><span class="RktErr">it: can only be used inside aif</span></p></td></tr></table></blockquote><p>But we can still define <span class="RktSym">it</span> as a normal variable:</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">it</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">it</span></td></tr><tr><td><p><span class="RktRes">10</span></p></td></tr></table></blockquote><h3>6<tt> </tt><a name="(part._.Robust_macros__syntax-parse)"></a>Robust macros: syntax-parse</h3><p>TO-DO.
-TO-DO.
-TO-DO.</p><h3>7<tt> </tt><a name="(part._.Other_questions)"></a>Other questions</h3><p>Hopefully I will answer these in the course of writing the other
-sections. But just in case, here’s a running list:</p><h4>7.1<tt> </tt><a name="(part._.What_s_the_point_of_with-syntax_)"></a>What’s the point of <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>?</h4><p>Done.</p><h4>7.2<tt> </tt><a name="(part._.What_s_the_point_of_begin-for-syntax_)"></a>What’s the point of <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>?</h4><p>Done.</p><h4>7.3<tt> </tt><a name="(part._.What_s_the_point_of_racket_splicing_)"></a>What’s the point of <span class="RktSym">racket/splicing</span>?</h4><p>I stared at <span class="RktSym">racket/splicing</span> for the longest time, not
-understanding exactly how it works, or why I’d want to use it. As with
-other aspects of Racket macros, step number one was to de-mythologize
-it. This:</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">splicing-let</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">get-x</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><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">get-x is visible out here:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">get-x</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">but x is not:</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">x</span></td></tr><tr><td><p><span class="RktErr">x: 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>is shorthand for this:</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="RktSym">get-y</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">y</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/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="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</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">get-y is visible out here:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">get-y</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">but y is not:</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">y</span></td></tr><tr><td><p><span class="RktErr">y: 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>This is the classic Lisp/Scheme/Racket idiom sometimes called "let
+<span class="RktSym">it</span> isn’t otherwise defined, we get an error like we want:</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/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></td></tr><tr><td><p><span class="RktErr">it: can only be used inside aif</span></p></td></tr></table></blockquote><p>But we can still define <span class="RktSym">it</span> as a normal variable:</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">it</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">it</span></td></tr><tr><td><p><span class="RktRes">10</span></p></td></tr></table></blockquote><h3>6<tt> </tt><a name="(part._.Robust_macros__syntax-parse)"></a>Robust macros: syntax-parse</h3><p>TO-DO.</p><p>TO-DO.</p><p>TO-DO.</p><h3>7<tt> </tt><a name="(part._.What_s_the_point_of_splicing-let_)"></a>What’s the point of <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>?</h3><p>I stared at <span class="RktSym">racket/splicing</span> for the longest time. What does
+it do? Why would I use it? Why is it in the Macros section of the
+reference?</p><p>Step one, <span class="strike">cut a hole in the box</span>
+de-mythologize it. For example, using <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> like this:</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">get-x</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><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">get-x is visible out here:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">get-x</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">but x is not:</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">x</span></td></tr><tr><td><p><span class="RktErr">x: 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>is equivalent to:</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="RktSym">get-y</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">y</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/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="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">y</span><span class="RktPn">)</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">get-y is visible out here:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">get-y</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">but y is not:</span></td></tr><tr><td><span class="stt">> </span><span class="RktSym">y</span></td></tr><tr><td><p><span class="RktErr">y: 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>This is the classic Lisp/Scheme/Racket idiom sometimes called "let
over lambda". <span class="refelem"><span class="refcolumn"><span class="refcontent">A
<a href="http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html">koan</a>
-about closures and objects.</span></span></span> A closure hides <span class="RktSym">y</span>, which can’t
-be accessed directly, only 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">splicing-let</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 you are generating them in a
+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 you are generating them in a
macro—<wbr></wbr>the splicing variations can be much easier.</p><h3>8<tt> </tt><a name="(part._.References_and_.Acknowledgments)"></a>References and Acknowledgments</h3><p>Eli Barzliay’s blog post,
<a href="http://blog.racket-lang.org/2011/04/writing-syntax-case-macros.html">Writing
‘syntax-case’ Macros</a>, helped me understand many key details and