commit f5a1fd6d381d04e8e786a9b70b76c0aae790d503
parent 5289907fd901e7164054555e538f10e5e5640a95
Author: Greg Hendershott <greghendershott@gmail.com>
Date: Mon, 12 Nov 2012 23:15:08 -0500
Regen html
Diffstat:
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/index.html b/index.html
@@ -1,6 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html><head><meta http-equiv="content-type" content="text-html; charset=utf-8" /><title>Fear of Macros</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default" /><link rel="stylesheet" type="text/css" href="racket.css" title="default" /><link rel="stylesheet" type="text/css" href="scribble-style.css" title="default" /><link rel="stylesheet" type="text/css" href="gh.css" title="default" /><script type="text/javascript" src="scribble-common.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--><meta name="keywords" content="Racket,macros,Scheme"><meta name="description" content="Practical Racket macros"><meta name="author" content="Greg Hendershott"><meta name="charset" content="utf-8"><link href='http://fonts.googleapis.com/css?family=Fenix' rel='stylesheet' type='text/css'><script type="text/javascript">var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-29709446-1']);_gaq.push(['_setDomainName', 'greghendershott.com']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();</script></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist" style="margin-bottom: 1em;"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">►</a></td><td></td><td><a href="" class="tocviewselflink" pltdoc="x">Fear of Macros</a></td></tr></table></div><div class="tocviewsublistonly" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="#(part._.Preface)" class="tocviewlink" pltdoc="x">Preface</a></td></tr><tr><td align="right">2 </td><td><a href="#(part._.Our_plan_of_attack)" class="tocviewlink" pltdoc="x">Our plan of attack</a></td></tr><tr><td align="right">3 </td><td><a href="#(part._.Transform_)" class="tocviewlink" pltdoc="x">Transform!</a></td></tr><tr><td align="right">4 </td><td><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocviewlink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td align="right">5 </td><td><a href="#(part._.Syntax_parameters)" class="tocviewlink" pltdoc="x">Syntax parameters</a></td></tr><tr><td align="right">6 </td><td><a href="#(part._.What_s_the_point_of_splicing-let_)" class="tocviewlink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td align="right">7 </td><td><a href="#(part._.Robust_macros__syntax-parse)" class="tocviewlink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td align="right">8 </td><td><a href="#(part._.References_and_.Acknowledgments)" class="tocviewlink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td align="right">9 </td><td><a href="#(part._.Epilogue)" class="tocviewlink" pltdoc="x">Epilogue</a></td></tr></table></div></div></div><div class="tocsub"><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">1<tt> </tt></span><a href="#(part._.Preface)" class="tocsubseclink" pltdoc="x">Preface</a></td></tr><tr><td><span class="tocsublinknumber">2<tt> </tt></span><a href="#(part._.Our_plan_of_attack)" class="tocsubseclink" pltdoc="x">Our plan of attack</a></td></tr><tr><td><span class="tocsublinknumber">3<tt> </tt></span><a href="#(part._.Transform_)" class="tocsubseclink" pltdoc="x">Transform!</a></td></tr><tr><td><span class="tocsublinknumber">3.1<tt> </tt></span><a href="#(part._.What_is_a_syntax_transformer_)" class="tocsubseclink" pltdoc="x">What is a syntax transformer?</a></td></tr><tr><td><span class="tocsublinknumber">3.2<tt> </tt></span><a href="#(part._.What_s_the_input_)" class="tocsubseclink" pltdoc="x">What’s the input?</a></td></tr><tr><td><span class="tocsublinknumber">3.3<tt> </tt></span><a href="#(part._.Actually_transforming_the_input)" class="tocsubseclink" pltdoc="x">Actually transforming the input</a></td></tr><tr><td><span class="tocsublinknumber">3.4<tt> </tt></span><a href="#(part._.Compile_time_vs__run_time)" class="tocsubseclink" pltdoc="x">Compile time vs. run time</a></td></tr><tr><td><span class="tocsublinknumber">3.5<tt> </tt></span><a href="#(part._begin-for-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">begin-<wbr></wbr>for-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4<tt> </tt></span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocsubseclink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td><span class="tocsublinknumber">4.1<tt> </tt></span><a href="#(part._.Pattern_variable_vs__template---fight_)" class="tocsubseclink" pltdoc="x">Pattern variable vs. template—<wbr></wbr>fight!</a></td></tr><tr><td><span class="tocsublinknumber">4.1.1<tt> </tt></span><a href="#(part._with-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">with-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.2<tt> </tt></span><a href="#(part._format-id)" class="tocsubseclink" pltdoc="x"><span class="RktSym">format-<wbr></wbr>id</span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.3<tt> </tt></span><a href="#(part._.Another_example)" class="tocsubseclink" pltdoc="x">Another example</a></td></tr><tr><td><span class="tocsublinknumber">4.2<tt> </tt></span><a href="#(part._.Making_our_own_struct)" class="tocsubseclink" pltdoc="x">Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.3<tt> </tt></span><a href="#(part._hash..refs)" class="tocsubseclink" pltdoc="x">Using dot notation for nested hash lookups</a></td></tr><tr><td><span class="tocsublinknumber">5<tt> </tt></span><a href="#(part._.Syntax_parameters)" class="tocsubseclink" pltdoc="x">Syntax parameters</a></td></tr><tr><td><span class="tocsublinknumber">6<tt> </tt></span><a href="#(part._.What_s_the_point_of_splicing-let_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td><span class="tocsublinknumber">7<tt> </tt></span><a href="#(part._.Robust_macros__syntax-parse)" class="tocsubseclink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td><span class="tocsublinknumber">7.1<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_functions)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for functions</a></td></tr><tr><td><span class="tocsublinknumber">7.2<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_macros)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for macros</a></td></tr><tr><td><span class="tocsublinknumber">7.3<tt> </tt></span><a href="#(part._.Using_syntax_parse)" class="tocsubseclink" pltdoc="x">Using <span class="RktSym">syntax/<span class="mywbr"> </span>parse</span></a></td></tr><tr><td><span class="tocsublinknumber">8<tt> </tt></span><a href="#(part._.References_and_.Acknowledgments)" class="tocsubseclink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td><span class="tocsublinknumber">9<tt> </tt></span><a href="#(part._.Epilogue)" class="tocsubseclink" pltdoc="x">Epilogue</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><h2><a name="(part._.Fear_of_.Macros)"></a>Fear of Macros</h2><div class="SAuthorListBox"><span class="SAuthorList"><p class="author"><a href="http://www.greghendershott.com">Greg Hendershott</a></p></span></div><p><div class="SIntrapara"></div><div class="SIntrapara"><img src="fear-of-macros.jpg" alt="" />
-</div><div class="SIntrapara"><span class="Smaller">Copyright (c) 2012 by Greg Hendershott. All rights reserved.</span></div><div class="SIntrapara"><span class="Smaller">Last updated 2012-11-12 19:48:10</span></div><div class="SIntrapara">Feedback and corrections are <a href="https://github.com/greghendershott/fear-of-macros/issues">welcome here</a>.</div></p><p>Contents:</p><table cellspacing="0"><tr><td><p><span class="hspace"> </span><a href="#(part._.Preface)" class="toptoclink" pltdoc="x">1<span class="hspace"> </span>Preface</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Our_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>Our plan of attack</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Transform_)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transform!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_is_a_syntax_transformer_)" class="toclink" pltdoc="x">3.1<span class="hspace"> </span>What is a syntax transformer?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_input_)" class="toclink" pltdoc="x">3.2<span class="hspace"> </span>What’s the input?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Actually_transforming_the_input)" class="toclink" pltdoc="x">3.3<span class="hspace"> </span>Actually transforming the input</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Compile_time_vs__run_time)" class="toclink" pltdoc="x">3.4<span class="hspace"> </span>Compile time vs. run time</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._begin-for-syntax)" class="toclink" pltdoc="x">3.5<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="toptoclink" pltdoc="x">4<span class="hspace"> </span>Pattern matching: syntax-case and syntax-rules</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_variable_vs__template---fight_)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Pattern variable vs. template—<wbr></wbr>fight!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._with-syntax)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">with-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._format-id)" class="toclink" pltdoc="x">4.1.2<span class="hspace"> </span><span class="RktSym">format-id</span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Another_example)" class="toclink" pltdoc="x">4.1.3<span class="hspace"> </span>Another example</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Making_our_own_struct)" class="toclink" pltdoc="x">4.2<span class="hspace"> </span>Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._hash..refs)" class="toclink" pltdoc="x">4.3<span class="hspace"> </span>Using dot notation for nested hash lookups</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Syntax_parameters)" class="toptoclink" pltdoc="x">5<span class="hspace"> </span>Syntax parameters</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_splicing-let_)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-let</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_functions)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>Error-handling strategies for functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_macros)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>Error-handling strategies for macros</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Using_syntax_parse)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>Using <span class="RktSym">syntax/parse</span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.References_and_.Acknowledgments)" class="toptoclink" pltdoc="x">8<span class="hspace"> </span>References and Acknowledgments</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Epilogue)" class="toptoclink" pltdoc="x">9<span class="hspace"> </span>Epilogue</a></p></td></tr></table><h3>1<tt> </tt><a name="(part._.Preface)"></a>Preface</h3><p>I learned Racket after 25 years of mostly using C and C++.</p><p>Some psychic whiplash resulted.</p><p>"All the parentheses" was actually not a big deal. Instead, the first
+<html><head><meta http-equiv="content-type" content="text-html; charset=utf-8" /><title>Fear of Macros</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default" /><link rel="stylesheet" type="text/css" href="racket.css" title="default" /><link rel="stylesheet" type="text/css" href="scribble-style.css" title="default" /><link rel="stylesheet" type="text/css" href="gh.css" title="default" /><script type="text/javascript" src="scribble-common.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--><meta name="keywords" content="Racket,macros,Scheme"><meta name="description" content="Practical Racket macros"><meta name="author" content="Greg Hendershott"><meta name="charset" content="utf-8"><link href='http://fonts.googleapis.com/css?family=Fenix' rel='stylesheet' type='text/css'><script type="text/javascript">var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-29709446-1']);_gaq.push(['_setDomainName', 'greghendershott.com']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();</script></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist" style="margin-bottom: 1em;"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">►</a></td><td></td><td><a href="" class="tocviewselflink" pltdoc="x">Fear of Macros</a></td></tr></table></div><div class="tocviewsublistonly" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="#(part._.Preface)" class="tocviewlink" pltdoc="x">Preface</a></td></tr><tr><td align="right">2 </td><td><a href="#(part._.Our_plan_of_attack)" class="tocviewlink" pltdoc="x">Our plan of attack</a></td></tr><tr><td align="right">3 </td><td><a href="#(part._.Transform_)" class="tocviewlink" pltdoc="x">Transform!</a></td></tr><tr><td align="right">4 </td><td><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocviewlink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td align="right">5 </td><td><a href="#(part._.Syntax_parameters)" class="tocviewlink" pltdoc="x">Syntax parameters</a></td></tr><tr><td align="right">6 </td><td><a href="#(part._.What_s_the_point_of_splicing-let_)" class="tocviewlink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td align="right">7 </td><td><a href="#(part._.Robust_macros__syntax-parse)" class="tocviewlink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td align="right">8 </td><td><a href="#(part._.References_and_.Acknowledgments)" class="tocviewlink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td align="right">9 </td><td><a href="#(part._.Epilogue)" class="tocviewlink" pltdoc="x">Epilogue</a></td></tr></table></div></div></div><div class="tocsub"><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">1<tt> </tt></span><a href="#(part._.Preface)" class="tocsubseclink" pltdoc="x">Preface</a></td></tr><tr><td><span class="tocsublinknumber">2<tt> </tt></span><a href="#(part._.Our_plan_of_attack)" class="tocsubseclink" pltdoc="x">Our plan of attack</a></td></tr><tr><td><span class="tocsublinknumber">3<tt> </tt></span><a href="#(part._.Transform_)" class="tocsubseclink" pltdoc="x">Transform!</a></td></tr><tr><td><span class="tocsublinknumber">3.1<tt> </tt></span><a href="#(part._.What_is_a_syntax_transformer_)" class="tocsubseclink" pltdoc="x">What is a syntax transformer?</a></td></tr><tr><td><span class="tocsublinknumber">3.2<tt> </tt></span><a href="#(part._.What_s_the_input_)" class="tocsubseclink" pltdoc="x">What’s the input?</a></td></tr><tr><td><span class="tocsublinknumber">3.3<tt> </tt></span><a href="#(part._.Actually_transforming_the_input)" class="tocsubseclink" pltdoc="x">Actually transforming the input</a></td></tr><tr><td><span class="tocsublinknumber">3.4<tt> </tt></span><a href="#(part._.Compile_time_vs__run_time)" class="tocsubseclink" pltdoc="x">Compile time vs. run time</a></td></tr><tr><td><span class="tocsublinknumber">3.5<tt> </tt></span><a href="#(part._begin-for-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">begin-<wbr></wbr>for-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4<tt> </tt></span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="tocsubseclink" pltdoc="x">Pattern matching:<span class="mywbr"> </span> syntax-<wbr></wbr>case and syntax-<wbr></wbr>rules</a></td></tr><tr><td><span class="tocsublinknumber">4.1<tt> </tt></span><a href="#(part._.Pattern_variable_vs__template---fight_)" class="tocsubseclink" pltdoc="x">Pattern variable vs. template—<wbr></wbr>fight!</a></td></tr><tr><td><span class="tocsublinknumber">4.1.1<tt> </tt></span><a href="#(part._with-syntax)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">with-<wbr></wbr>syntax</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.2<tt> </tt></span><a href="#(part._with-syntax_)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktStxLink">with-<wbr></wbr>syntax*</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.3<tt> </tt></span><a href="#(part._format-id)" class="tocsubseclink" pltdoc="x"><span class="RktSym"><span class="RktValLink">format-<wbr></wbr>id</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.1.4<tt> </tt></span><a href="#(part._.Another_example)" class="tocsubseclink" pltdoc="x">Another example</a></td></tr><tr><td><span class="tocsublinknumber">4.2<tt> </tt></span><a href="#(part._.Making_our_own_struct)" class="tocsubseclink" pltdoc="x">Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></td></tr><tr><td><span class="tocsublinknumber">4.3<tt> </tt></span><a href="#(part._hash..refs)" class="tocsubseclink" pltdoc="x">Using dot notation for nested hash lookups</a></td></tr><tr><td><span class="tocsublinknumber">5<tt> </tt></span><a href="#(part._.Syntax_parameters)" class="tocsubseclink" pltdoc="x">Syntax parameters</a></td></tr><tr><td><span class="tocsublinknumber">6<tt> </tt></span><a href="#(part._.What_s_the_point_of_splicing-let_)" class="tocsubseclink" pltdoc="x">What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-<wbr></wbr>let</span></span>?</a></td></tr><tr><td><span class="tocsublinknumber">7<tt> </tt></span><a href="#(part._.Robust_macros__syntax-parse)" class="tocsubseclink" pltdoc="x">Robust macros:<span class="mywbr"> </span> syntax-<wbr></wbr>parse</a></td></tr><tr><td><span class="tocsublinknumber">7.1<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_functions)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for functions</a></td></tr><tr><td><span class="tocsublinknumber">7.2<tt> </tt></span><a href="#(part._.Error-handling_strategies_for_macros)" class="tocsubseclink" pltdoc="x">Error-<wbr></wbr>handling strategies for macros</a></td></tr><tr><td><span class="tocsublinknumber">7.3<tt> </tt></span><a href="#(part._.Using_syntax_parse)" class="tocsubseclink" pltdoc="x">Using <span class="RktSym">syntax/<span class="mywbr"> </span>parse</span></a></td></tr><tr><td><span class="tocsublinknumber">8<tt> </tt></span><a href="#(part._.References_and_.Acknowledgments)" class="tocsubseclink" pltdoc="x">References and Acknowledgments</a></td></tr><tr><td><span class="tocsublinknumber">9<tt> </tt></span><a href="#(part._.Epilogue)" class="tocsubseclink" pltdoc="x">Epilogue</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><h2><a name="(part._.Fear_of_.Macros)"></a>Fear of Macros</h2><div class="SAuthorListBox"><span class="SAuthorList"><p class="author"><a href="http://www.greghendershott.com">Greg Hendershott</a></p></span></div><p><div class="SIntrapara"></div><div class="SIntrapara"><img src="fear-of-macros.jpg" alt="" />
+</div><div class="SIntrapara"><span class="Smaller">Copyright (c) 2012 by Greg Hendershott. All rights reserved.</span></div><div class="SIntrapara"><span class="Smaller">Last updated 2012-11-12 23:13:02</span></div><div class="SIntrapara">Feedback and corrections are <a href="https://github.com/greghendershott/fear-of-macros/issues">welcome here</a>.</div></p><p>Contents:</p><table cellspacing="0"><tr><td><p><span class="hspace"> </span><a href="#(part._.Preface)" class="toptoclink" pltdoc="x">1<span class="hspace"> </span>Preface</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Our_plan_of_attack)" class="toptoclink" pltdoc="x">2<span class="hspace"> </span>Our plan of attack</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Transform_)" class="toptoclink" pltdoc="x">3<span class="hspace"> </span>Transform!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_is_a_syntax_transformer_)" class="toclink" pltdoc="x">3.1<span class="hspace"> </span>What is a syntax transformer?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_input_)" class="toclink" pltdoc="x">3.2<span class="hspace"> </span>What’s the input?</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Actually_transforming_the_input)" class="toclink" pltdoc="x">3.3<span class="hspace"> </span>Actually transforming the input</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Compile_time_vs__run_time)" class="toclink" pltdoc="x">3.4<span class="hspace"> </span>Compile time vs. run time</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._begin-for-syntax)" class="toclink" pltdoc="x">3.5<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">begin-for-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_matching__syntax-case_and_syntax-rules)" class="toptoclink" pltdoc="x">4<span class="hspace"> </span>Pattern matching: syntax-case and syntax-rules</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Pattern_variable_vs__template---fight_)" class="toclink" pltdoc="x">4.1<span class="hspace"> </span>Pattern variable vs. template—<wbr></wbr>fight!</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._with-syntax)" class="toclink" pltdoc="x">4.1.1<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">with-syntax</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._with-syntax_)" class="toclink" pltdoc="x">4.1.2<span class="hspace"> </span><span class="RktSym"><span class="RktStxLink">with-syntax*</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._format-id)" class="toclink" pltdoc="x">4.1.3<span class="hspace"> </span><span class="RktSym"><span class="RktValLink">format-id</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Another_example)" class="toclink" pltdoc="x">4.1.4<span class="hspace"> </span>Another example</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Making_our_own_struct)" class="toclink" pltdoc="x">4.2<span class="hspace"> </span>Making our own <span class="RktSym"><span class="RktStxLink">struct</span></span></a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._hash..refs)" class="toclink" pltdoc="x">4.3<span class="hspace"> </span>Using dot notation for nested hash lookups</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Syntax_parameters)" class="toptoclink" pltdoc="x">5<span class="hspace"> </span>Syntax parameters</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.What_s_the_point_of_splicing-let_)" class="toptoclink" pltdoc="x">6<span class="hspace"> </span>What’s the point of <span class="RktSym"><span class="RktStxLink">splicing-let</span></span>?</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Robust_macros__syntax-parse)" class="toptoclink" pltdoc="x">7<span class="hspace"> </span>Robust macros: syntax-parse</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_functions)" class="toclink" pltdoc="x">7.1<span class="hspace"> </span>Error-handling strategies for functions</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Error-handling_strategies_for_macros)" class="toclink" pltdoc="x">7.2<span class="hspace"> </span>Error-handling strategies for macros</a></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Using_syntax_parse)" class="toclink" pltdoc="x">7.3<span class="hspace"> </span>Using <span class="RktSym">syntax/parse</span></a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.References_and_.Acknowledgments)" class="toptoclink" pltdoc="x">8<span class="hspace"> </span>References and Acknowledgments</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace"> </span><a href="#(part._.Epilogue)" class="toptoclink" pltdoc="x">9<span class="hspace"> </span>Epilogue</a></p></td></tr></table><h3>1<tt> </tt><a name="(part._.Preface)"></a>Preface</h3><p>I learned Racket after 25 years of mostly using C and C++.</p><p>Some psychic whiplash resulted.</p><p>"All the parentheses" was actually not a big deal. Instead, the first
mind warp was functional programming. Before long I wrapped my brain
around it, and went on to become comfortable and effective with many
other aspects and features of Racket.</p><p>But two final frontiers remained: Macros and continuations.</p><p>I found that simple macros were easy and understandable, plus there
@@ -210,7 +210,7 @@ a template, and its value will go in the template.</p><p>We might have one more&
Let’s try to use our new version:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/wrong1.2</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">foo-bar: undefined;</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">cannot reference an identifier before its definition</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in module: 'program</span></p></td></tr></table></blockquote><p>Hmm. <span class="RktSym">foo-bar</span> is <span style="font-style: italic">still</span> not defined. Back to the Macro
Stepper. It says now we’re expanding to:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">|#<syntax:11:24foo>-#<syntax:11:28 bar>|</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></p></blockquote><p>Oh right: <span class="RktRdr">#'</span><span class="RktSym">a</span> and <span class="RktRdr">#'</span><span class="RktSym">b</span> are syntax objects. Therefore</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote><p>is the printed form of both syntax objects, joined by a hyphen:</p><blockquote class="SCodeFlow"><p><span class="RktSym">|#<syntax:11:24foo>-#<syntax:11:28 bar>|</span></p></blockquote><p>Instead we want the datum in the syntax objects, such as the symbols
<span class="RktSym">foo</span> and <span class="RktSym">bar</span>. Which we get using
-<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</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)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></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="RktSym">name</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>And now it works!</p><h5>4.1.1<tt> </tt><a name="(part._with-syntax)"></a><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></h5><p>Now for two shortcuts.</p><p>Instead of an additional, nested <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>, we could use
+<span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</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)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></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="RktSym">name</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok1</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>And now it works!</p><p>Next, some shortcuts.</p><h5>4.1.1<tt> </tt><a name="(part._with-syntax)"></a><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></h5><p>Instead of an additional, nested <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>, we could use
<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="refelem"><span class="refcolumn"><span class="refcontent">Another name for
<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> could be, "define pattern variable".</span></span></span>. This
rearranges the <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> to look more like a <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>
@@ -218,18 +218,21 @@ statement—<wbr></wbr>first the name, then the value. Also it’s more
if we need to define more than one pattern variable.</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-syntax))" class="RktStxLink" pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok2</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/symbols.html#(def._((quote._~23~25kernel)._string-~3esymbol))" class="RktValLink" pltdoc="x">string->symbol</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._format))" class="RktValLink" pltdoc="x">format</a></span><span class="hspace"> </span><span class="RktVal">"~a-~a"</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._syntax-~3edatum))" class="RktValLink" pltdoc="x">syntax->datum</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok2</span><span class="hspace"> </span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>Whether you use an additional <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> or use
<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>, either way you are simply defining an additional
pattern variable. Don’t let the terminology and structure make it seem
-mysterious.</p><h5>4.1.2<tt> </tt><a name="(part._format-id)"></a><span class="RktSym">format-id</span></h5><p>Also, there is a utility function in <span class="RktSym">racket/syntax</span> called
-<span class="RktSym">format-id</span> that lets us format identifier names more
-succinctly. As we’ve learned, we need to <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> the module
-using <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>, since we need it at compile time:</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">hyphen-define/ok3</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">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</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok3</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktSym">baz</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">bar-baz</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>Using <span class="RktSym">format-id</span> is convenient as it handles the tedium of
+mysterious.</p><h5>4.1.2<tt> </tt><a name="(part._with-syntax_)"></a><span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(form._((lib._racket%2Fsyntax..rkt)._with-syntax*))" class="RktStxLink" pltdoc="x">with-syntax*</a></span></h5><p>We may recall that <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> doesn’t let us use a definition in a
+subsequent clause:</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/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">a</span><span class="hspace"> </span><span class="RktVal">0</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">b</span><span class="hspace"> </span><span class="RktSym">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/values.html#(def._((quote._~23~25kernel)._values))" class="RktValLink" pltdoc="x">values</a></span><span class="hspace"> </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></table></td></tr><tr><td><p><span class="RktErr">a: 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>We could nest <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>s:</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/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">a</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/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">b</span><span class="hspace"> </span><span class="RktSym">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/values.html#(def._((quote._~23~25kernel)._values))" class="RktValLink" pltdoc="x">values</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr></table></blockquote><p>Or we could use <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>:</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/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">a</span><span class="hspace"> </span><span class="RktVal">0</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">b</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="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr></table></blockquote><p>Similarly there is a <span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(form._((lib._racket%2Fsyntax..rkt)._with-syntax*))" class="RktStxLink" pltdoc="x">with-syntax*</a></span> variation 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>:</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">foo</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="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/syntax-util.html#(form._((lib._racket%2Fsyntax..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">b</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">a</span><span class="RktPn">]</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</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="RktSym">c</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>One gotcha is that <span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(form._((lib._racket%2Fsyntax..rkt)._with-syntax*))" class="RktStxLink" pltdoc="x">with-syntax*</a></span> isn’t provided by
+<span class="RktSym">racket/base</span>. We must <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="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)._for-syntax))" class="RktStxLink" pltdoc="x">for-syntax</a></span><span class="stt"> </span><span class="RktSym">racket/syntax</span><span class="RktPn">)</span><span class="RktPn">)</span>. Otherwise we may get a rather bewildering error
+message:</p><p><span style="font-style: italic"><span class="stt">...: ellipses not allowed as an expression in: ...</span></span>.</p><h5>4.1.3<tt> </tt><a name="(part._format-id)"></a><span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></span></h5><p>There is a utility function in <span class="RktSym">racket/syntax</span> called
+<span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></span> that lets us format identifier names more
+succinctly than what we did above:</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">hyphen-define/ok3</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._syntax-case))" class="RktStxLink" pltdoc="x">syntax-case</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt).__))" class="RktStxLink" pltdoc="x">_</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._with-syntax))" class="RktStxLink" pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">b</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define/ok3</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktSym">baz</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">#t</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">bar-baz</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#t</span></p></td></tr></table></blockquote><p>Using <span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></span> is convenient as it handles the tedium of
converting from syntax to symbol datum to string ... and all the way
-back.</p><h5>4.1.3<tt> </tt><a name="(part._.Another_example)"></a>Another example</h5><p>Finally, here’s a variation that accepts an arbitary number of name
+back.</p><h5>4.1.4<tt> </tt><a name="(part._.Another_example)"></a>Another example</h5><p>Finally, here’s a variation that accepts an arbitary number of name
parts to be joined with hyphens:</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/string</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">hyphen-define*</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="RktPn">(</span><span class="RktSym">names</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/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">names/sym</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="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/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">names</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">names/str</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="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="RktSym">names/sym</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">name/str</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((lib._racket%2Fstring..rkt)._string-join))" class="RktValLink" pltdoc="x">string-join</a></span><span class="hspace"> </span><span class="RktSym">names/str</span><span class="hspace"> </span><span class="RktVal">"-"</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">name/sym</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">name/str</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">name</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stxops.html#(def._((quote._~23~25kernel)._datum-~3esyntax))" class="RktValLink" pltdoc="x">datum->syntax</a></span><span class="hspace"> </span><span class="RktSym">stx</span><span class="hspace"> </span><span class="RktSym">name/sym</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktRdr">#`</span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">name</span><span class="hspace"> </span><span class="RktSym">args</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktSym">body0</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/stx-patterns.html#(form._((lib._racket%2Fprivate%2Fstxcase-scheme..rkt)._......))" class="RktStxLink" pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">hyphen-define*</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">foo</span><span class="hspace"> </span><span class="RktSym">bar</span><span class="hspace"> </span><span class="RktSym">baz</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">v</span><span class="RktPn">)</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">*</a></span><span class="hspace"> </span><span class="RktVal">2</span><span class="hspace"> </span><span class="RktSym">v</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">foo-bar-baz</span><span class="hspace"> </span><span class="RktVal">50</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">100</span></p></td></tr></table></blockquote><p>To review:</p><ul><li><p>You can’t use a pattern variable outside of a template. But
you can 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 a pattern variable to make
an ad hoc, "fun size" template.</p></li><li><p>If you want to munge pattern variables for use in the
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, because it lets you
create new pattern variables.</p></li><li><p>Usually you’ll 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
+interesting value inside.</p></li><li><p><span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></span> is convenient for formatting 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>Let’s apply what we just learned to a more-realistic 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 write a macro to provide our own
@@ -240,9 +243,9 @@ represent structures as a <span class="RktSym"><a href="http://docs.racket-lang.
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:78: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:81: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
+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"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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:83:0 "blah"></span></p></td></tr></table></blockquote><p>The error message is not very helpful. It’s coming from
+<span class="RktSym"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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"><a href="http://docs.racket-lang.org/reference/syntax-util.html#(def._((lib._racket%2Fsyntax..rkt)._format-id))" class="RktValLink" pltdoc="x">format-id</a></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:86: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._hash..refs)"></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
@@ -251,7 +254,7 @@ 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><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Nested `hasheq</span><span class="RktCmt">'</span><span class="RktCmt">s 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></table></blockquote><p>In 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"><p><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></p></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 better. 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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">If the optional `default</span><span class="RktCmt">'</span><span class="RktCmt"> is missing, assume it</span><span class="RktCmt">'</span><span class="RktCmt">s #f.</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/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/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><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Try finding a key that doesn</span><span class="RktCmt">'</span><span class="RktCmt">t exist:</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.blah</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">#f</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Try finding a key that doesn</span><span class="RktCmt">'</span><span class="RktCmt">t exist, specifying the default:</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.blah</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">did-not-exist</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">'did-not-exist</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. Let’s try to do that here.</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">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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check for no args at all</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check that chain is a symbol, not e.g. a number or string</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check that we have at least hash.key</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">See if we catch each of the misuses</span></td></tr><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:91: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:93: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:94: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:95: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. Of course, the version with error-checking is quite a bit
+messages when used in error. Let’s try to do that here.</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">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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check for no args at all</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check that chain is a symbol, not e.g. a number or string</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="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Check that we have at least hash.key</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">See if we catch each of the misuses</span></td></tr><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:96: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:98: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:99: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:100: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. Of course, the version with error-checking is quite a bit
longer. Error-checking code generally tends to obscure the logic, and
does here. Fortuantely we’ll soon 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> can
help mitigate that, in much the same way as contracts in normal
@@ -295,7 +298,7 @@ user thinks they’re calling <span class="RktSym">misuse</span>, but is get
message from <span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span>. In this simple example they
could probably guess what’s happening, but in most cases they won’t.</p><p>2. Write some error handling code.</p><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/define.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket%2Fprivate%2Fletstx-scheme..rkt)._unless))" class="RktStxLink" pltdoc="x">unless</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/exns.html#(def._((quote._~23~25kernel)._error))" class="RktValLink" pltdoc="x">error</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">misuse</span><span class="hspace"> </span><span class="RktVal">"expected a string, but got ~a"</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">misuse: expected a string, but got 0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I goofed, and understand why! It</span><span class="RktCmt">'</span><span class="RktCmt">s a shame the writer of the</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">function had to work so hard to tell me.</span></td></tr></table></blockquote><p>Unfortunately the error code tends to overwhelm and/or obscure our
function definition. Also, the error message is good but not
-great. Improving it would require even more error code.</p><p>3. Use a contract.</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/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">misuse</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</a></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/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</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/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">misuse: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: string?, given: 0</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the 1st argument of</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(-> string? string?)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (function misuse)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: program</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:125.0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I goofed, and understand why! I hear the writer of the function is</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">happier.</span></td></tr></table></blockquote><p>This is the best of both worlds.</p><p>The contract is a simple and concise. Even better, it’s
+great. Improving it would require even more error code.</p><p>3. Use a contract.</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/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">misuse</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</a></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/strings.html#(def._((quote._~23~25kernel)._string~3f))" class="RktValLink" pltdoc="x">string?</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/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">User of the function:</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">misuse: contract violation</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">expected: string?, given: 0</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: the 1st argument of</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">(-> string? string?)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">contract from: (function misuse)</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">blaming: program</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">at: eval:130.0</span></p></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">I goofed, and understand why! I hear the writer of the function is</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">happier.</span></td></tr></table></blockquote><p>This is the best of both worlds.</p><p>The contract is a simple and concise. Even better, it’s
declarative. We say what we want, without needing to spell out what to
do.</p><p>On the other hand the user of our function gets a very detailed error
message. Plus, the message is in a standard, familiar format.</p><p>4. Use Typed Racket.</p><p><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="RktMeta">#lang</span><span class="hspace"> </span><span class="RktMeta"></span><a href="http://docs.racket-lang.org/ts-reference/index.html" class="RktModLink" pltdoc="x"><span class="RktSym">typed/racket</span></a><span class="RktMeta"></span></td></tr></table></blockquote></div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">:</span><span class="hspace"> </span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">String</span><span class="hspace"> </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="hspace"> </span><span class="RktSym">String</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))" class="RktStxLink" pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktSym">s</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPlain"><span class="hspace"> </span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http://docs.racket-lang.org/reference/strings.html#(def._((quote._~23~25kernel)._string-append))" class="RktValLink" pltdoc="x">string-append</a></span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktVal">" snazzy suffix"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">misuse</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">eval:3:0: Type Checker: Expected String, but got Zero</span></p></td></tr><tr><td><p><span class="RktErr"></span><span class="hspace"> </span><span class="RktErr">in: (quote 0)</span></p></td></tr></table></blockquote></div></p><p>With respect to error handling, Typed Racket has the same benefits as