133 lines
120 KiB
HTML
133 lines
120 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>16.2.6 General Phase Levels</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="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><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="index.html" class="tocviewlink" data-pltdoc="x">The Racket Guide</a></td></tr></table></div><div class="tocviewsublisttop" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="intro.html" class="tocviewlink" data-pltdoc="x">Welcome to Racket</a></td></tr><tr><td align="right">2 </td><td><a href="to-scheme.html" class="tocviewlink" data-pltdoc="x">Racket Essentials</a></td></tr><tr><td align="right">3 </td><td><a href="datatypes.html" class="tocviewlink" data-pltdoc="x">Built-<wbr></wbr>In Datatypes</a></td></tr><tr><td align="right">4 </td><td><a href="scheme-forms.html" class="tocviewlink" data-pltdoc="x">Expressions and Definitions</a></td></tr><tr><td align="right">5 </td><td><a href="define-struct.html" class="tocviewlink" data-pltdoc="x">Programmer-<wbr></wbr>Defined Datatypes</a></td></tr><tr><td align="right">6 </td><td><a href="modules.html" class="tocviewlink" data-pltdoc="x">Modules</a></td></tr><tr><td align="right">7 </td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">8 </td><td><a href="i_o.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">9 </td><td><a href="regexp.html" class="tocviewlink" data-pltdoc="x">Regular Expressions</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Exceptions and Control</a></td></tr><tr><td align="right">11 </td><td><a href="for.html" class="tocviewlink" data-pltdoc="x">Iterations and Comprehensions</a></td></tr><tr><td align="right">12 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">13 </td><td><a href="classes.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">14 </td><td><a href="units.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">15 </td><td><a href="reflection.html" class="tocviewlink" data-pltdoc="x">Reflection and Dynamic Evaluation</a></td></tr><tr><td align="right">16 </td><td><a href="macros.html" class="tocviewselflink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">17 </td><td><a href="languages.html" class="tocviewlink" data-pltdoc="x">Creating Languages</a></td></tr><tr><td align="right">18 </td><td><a href="concurrency.html" class="to
|
||
|
a pipeline of processes where one produces code that is used by the
|
||
|
next. (E.g., a pipeline that consists of a preprocessor process, a
|
||
|
compiler, and an assembler.)</p><p>Imagine starting two Racket processes for this purpose. If you ignore
|
||
|
inter-process communication channels like sockets and files, the
|
||
|
processes will have no way to share anything other than the text that is
|
||
|
piped from the standard output of one process into the standard input of
|
||
|
the other. Similarly, Racket effectively allows multiple invocations of
|
||
|
a module to exist in the same process but separated by phase. Racket
|
||
|
enforces <span class="emph">separation</span> of such phases, where different phases cannot
|
||
|
communicate in any way other than via the protocol of macro expansion,
|
||
|
where the output of one phase is the code used in the next.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Phases_and_Bindings"">16.2.6.1<tt> </tt><a name="(part._.Phases_and_.Bindings)"></a>Phases and Bindings</h5><p>Every binding of an identifier exists in a particular phase. The link
|
||
|
between a binding and its phase is represented by an integer
|
||
|
<a name="(tech._phase._level)"></a><span style="font-style: italic">phase level</span>. Phase level 0 is the phase used for “plain”
|
||
|
(or “runtime”) definitions, so</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span></p></blockquote><p>adds a binding for <span class="RktSym">age</span> into phase level 0. The identifier
|
||
|
<span class="RktSym">age</span> can be defined at a higher phase level using
|
||
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>With a single <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span> wrapper, <span class="RktSym">age</span> is
|
||
|
defined at phase level 1. We can easily mix these two definitions in
|
||
|
the same module or in a top-level namespace, and there is no clash
|
||
|
between the two <span class="RktSym">age</span>s that are defined at different phase
|
||
|
levels:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktVal">9</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote><p>The <span class="RktSym">age</span> binding at phase level 0 has a value of 3, and the
|
||
|
<span class="RktSym">age</span> binding at phase level 1 has a value of 9.</p><p>Syntax objects capture binding information as a first-class value.
|
||
|
Thus,</p><blockquote class="SCodeFlow"><p><span class="RktRdr">#'</span><span class="RktSym">age</span></p></blockquote><p>is a syntax object that represents the <span class="RktSym">age</span> binding—<wbr></wbr>but
|
||
|
since there are two <span class="RktSym">age</span>s (one at phase level 0 and one at
|
||
|
phase level 1), which one does it capture? In fact, Racket imbues
|
||
|
<span class="RktRdr">#'</span><span class="RktSym">age</span> with lexical information for all phase levels, so the
|
||
|
answer is that <span class="RktRdr">#'</span><span class="RktSym">age</span> captures both.</p><p>The relevant binding of <span class="RktSym">age</span> captured by <span class="RktRdr">#'</span><span class="RktSym">age</span> is
|
||
|
determined when <span class="RktRdr">#'</span><span class="RktSym">age</span> is eventually used. As an example, we
|
||
|
bind <span class="RktRdr">#'</span><span class="RktSym">age</span> to a pattern variable so we can use it in a
|
||
|
template, and then we <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span>uate the template: <span class="refelem"><span class="refcolumn"><span class="refcontent">We
|
||
|
use <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span> here to demonstrate phases, but see
|
||
|
<a href="reflection.html" data-pltdoc="x">Reflection and Dynamic Evaluation</a> for caveats about <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span>.</span></span></span></p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._with-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">age</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fmisc..rkt%2529._displayln%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktOut">3</span></p></td></tr></table></blockquote><p>The result is <span class="RktVal">3</span> because <span class="RktSym">age</span> is used at phase 0 level.
|
||
|
We can try again with the use of <span class="RktSym">age</span> inside
|
||
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._with-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">with-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">age</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">age</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fmisc..rkt%2529._displayln%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">age</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><p><span class="RktOut">9</span></p></td></tr></table></blockquote><p>In this case, the answer is <span class="RktVal">9</span>, because we are using
|
||
|
<span class="RktSym">age</span> at phase level 1 instead of 0 (i.e.,
|
||
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span> evaluates its expressions at phase level 1).
|
||
|
So, you can see that we started with the same syntax object,
|
||
|
<span class="RktRdr">#'</span><span class="RktSym">age</span>, and we were able to use it in two different ways: at
|
||
|
phase level 0 and at phase level 1.</p><p>A syntax object has a lexical context from the moment it first exists.
|
||
|
A syntax object that is provided from a module retains its lexical
|
||
|
context, and so it references bindings in the context of its source
|
||
|
module, not the context of its use. The following example defines
|
||
|
<span class="RktSym">button</span> at phase level 0 and binds it to <span class="RktVal">0</span>, while
|
||
|
<span class="RktSym">see-button</span> binds the syntax object for <span class="RktSym">button</span> in
|
||
|
module <span class="RktSym">a</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">Why not </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktSym">see-button</span><span class="stt"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span><span class="RktCmt">? We explain later.</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-for-syntax</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span c
|
||
|
which is <span class="RktRdr">#'</span><span class="RktSym">button</span> with the lexical context of the <span class="RktSym">a</span>
|
||
|
module. Even though there is another <span class="RktSym">button</span> in <span class="RktSym">b</span>, the
|
||
|
second <span class="RktSym">button</span> will not confuse Racket, because the lexical
|
||
|
context of <span class="RktRdr">#'</span><span class="RktSym">button</span> (the value bound to <span class="RktSym">see-button</span>) is
|
||
|
<span class="RktSym">a</span>.</p><p>Note that <span class="RktSym">see-button</span> is bound at phase level 1 by virtue of
|
||
|
defining it with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-for-syntax</a></span>. Phase level 1 is needed
|
||
|
because <span class="RktSym">m</span> is a macro, so its body executes at one phase higher
|
||
|
than the context of its definition. Since <span class="RktSym">m</span> is defined at
|
||
|
phase level 0, its body is at phase level 1, so any bindings referenced
|
||
|
by the body must be at phase level 1.</p><h5 x-source-module="(lib "scribblings/guide/guide.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Phases_and_Modules"">16.2.6.2<tt> </tt><a name="(part._.Phases_and_.Modules)"></a>Phases and Modules</h5><p>A <a href="phases.html#%28tech._phase._level%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase level</span></a> is a module-relative concept. When importing from
|
||
|
another module via <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span>, Racket lets us shift imported
|
||
|
bindings to a phase level that is different from the original one:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktVal">"a.rkt"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">import with no phase shift</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktVal">"a.rkt"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">shift phase by +1</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-template%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-template</a></span><span class="hspace"> </span><span class="RktVal">"a.rkt"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">shift phase by -1</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-meta%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-meta</a></span><span class="hspace"> </span><span class="RktVal">5</span><span class="hspace"> </span><span class="RktVal">"a.rkt"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">shift phase by +5</span></td></tr></table></blockquote><p>That is, using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbas
|
||
|
the bindings from that module will have their phase levels increased by
|
||
|
one. A binding that is <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span>d at phase level 0 and imported
|
||
|
with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span> becomes a phase-level 1 binding:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">defined at phase level 0</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">d</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">c</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">has a binding at phase level 1, not 0:</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktRdr"
|
||
|
<span class="RktRdr">#'</span><span class="RktSym">button</span> syntax object at phase level 0:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Now both <span class="RktSym">button</span> and <span class="RktSym">see-button</span> are defined at phase
|
||
|
0. The lexical context of <span class="RktRdr">#'</span><span class="RktSym">button</span> will know that there is a
|
||
|
binding for <span class="RktSym">button</span> at phase 0. In fact, it seems like things
|
||
|
are working just fine if we try to <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span> <span class="RktSym">see-button</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=eval.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._eval%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">eval</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktRes">0</span></p></td></tr></table></blockquote><p>Now, let’s use <span class="RktSym">see-button</span> in a macro:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">m</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym">m</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">see-button: 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: top-level</span></p></td></tr></table></blockquote><p>Clearly, <span class="RktSym">see-button</span> is not defined at phase level 1, so we
|
||
|
cannot refer to it inside the macro body. Let’s try to use
|
||
|
<span class="RktSym">see-button</span> in another module by putting the button definitions
|
||
|
in a module and importing it at phase level 1. Then, we will get
|
||
|
<span class="RktSym">see-button</span> at phase level 1:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktCmt">;</span><span class="RktCmt"> </span><span class="RktCmt">gets </span><span class="RktS
|
||
|
imported at phase level 1, we have the following bindings:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">button</span><span class="hspace"> </span>at phase level 1</td></tr><tr><td><span class="RktSym">see-button</span><span class="hspace"> </span>at phase level 1</td></tr></table></blockquote><p>So the macro <span class="RktSym">m</span> can see a binding for <span class="RktSym">see-button</span> at
|
||
|
phase level 1 and will return the <span class="RktRdr">#'</span><span class="RktSym">button</span> syntax object, which
|
||
|
refers to <span class="RktSym">button</span> binding at phase level 1. But the use of
|
||
|
<span class="RktSym">m</span> is at phase level 0, and there is no <span class="RktSym">button</span> at phase
|
||
|
level 0 in <span class="RktSym">b</span>. That is why <span class="RktSym">see-button</span> needs to be
|
||
|
bound at phase level 1, as in the original <span class="RktSym">a</span>. In the original
|
||
|
<span class="RktSym">b</span>, then, we have the following bindings:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">button</span><span class="hspace"> </span>at phase level 0</td></tr><tr><td><span class="RktSym">see-button</span><span class="hspace"> </span>at phase level 1</td></tr></table></blockquote><p>In this scenario, we can use <span class="RktSym">see-button</span> in the macro, since
|
||
|
<span class="RktSym">see-button</span> is bound at phase level 1. When the macro expands,
|
||
|
it will refer to a <span class="RktSym">button</span> binding at phase level 0.</p><p>Defining <span class="RktSym">see-button</span> with <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="stt"> </span><span class="RktSym">see-button</span><span class="stt"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span> isn’t inherently wrong; it depends on how we intend to use
|
||
|
<span class="RktSym">see-button</span>. For example, we can arrange for <span class="RktSym">m</span> to
|
||
|
sensibly use <span class="RktSym">see-button</span> because it puts it in a phase level 1
|
||
|
context using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><
|
||
|
<span class="RktSym">see-button</span> bound at phase level 1. The expansion of the macro
|
||
|
is</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=begin.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._begin-for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">begin-for-syntax</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=Writing.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fmisc..rkt%2529._displayln%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>which works, because <span class="RktSym">button</span> is bound at phase level 1.</p><p>Now, you might try to cheat the phase system by importing <span class="RktSym">a</span> at
|
||
|
both phase level 0 and phase level 1. Then you would have the following
|
||
|
bindings</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktSym">button</span><span class="hspace"> </span>at phase level 0</td></tr><tr><td><span class="RktSym">see-button</span><span class="hspace"> </span>at phase level 0</td></tr><tr><td><span class="RktSym">button</span><span class="hspace"> </span>at phase level 1</td></tr><tr><td><span class="RktSym">see-button</span><span class="hspace"> </span>at phase level 1</td></tr></table></blockquote><p>You might expect now that <span class="RktSym">see-button</span> in a macro would work, but
|
||
|
it doesn’t:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span><spa
|
||
|
<span class="RktSym">see-button</span> is at phase 0, and its value is the syntax object
|
||
|
for <span class="RktSym">button</span>, which shows the only visible <span class="RktSym">button</span>
|
||
|
binding is at the same phase. (That is the key detail.)
|
||
|
As discussed, the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span> import shifts the phase level of <span class="emph">both</span>
|
||
|
up one, so the phase 1 binding of <span class="RktSym">see-button</span> used in module
|
||
|
<span class="RktSym">b</span> is the binding from the module <span class="RktSym">a</span> that is shifted
|
||
|
into phase 1, which refers to <span class="RktSym">button</span> in <span class="RktSym">a</span> at phase
|
||
|
1.
|
||
|
The fact that in module <span class="RktSym">b</span> there is also a phase 0 variable
|
||
|
<span class="RktSym">button</span> from a different instantiation of module <span class="RktSym">a</span>
|
||
|
does not matter, because there is no way to reach it
|
||
|
from the (shifted) <span class="RktSym">see-button</span> from <span class="RktSym">a</span>.</p><p>This kind of phase-level mismatch between instantiations can be repaired
|
||
|
with <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stxops.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._syntax-shift-phase-level%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">syntax-shift-phase-level</a></span>. Recall that a syntax object like
|
||
|
<span class="RktRdr">#'</span><span class="RktSym">button</span> captures lexical information at <span class="emph">all</span> phase levels.
|
||
|
The problem here is that <span class="RktSym">see-button</span> is
|
||
|
invoked at phase 1, but needs to return a syntax object that can be
|
||
|
evaluated at phase 0. By default, <span class="RktSym">see-button</span> is bound to
|
||
|
<span class="RktRdr">#'</span><span class="RktSym">button</span> at the same phase level. But with
|
||
|
<span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stxops.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._syntax-shift-phase-level%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">syntax-shift-phase-level</a></span>, we can make <span class="RktSym">see-button</span>
|
||
|
refer to <span class="RktRdr">#'</span><span class="RktSym">button</span> at a different relative phase level.
|
||
|
In this case, we use a phase shift of <span class="RktVal"><span class="nobreak">-1</span></span> to make <span class="RktSym">see-button</span>
|
||
|
at phase 1 refer to <span class="RktRdr">#'</span><span class="RktSym">button</span> at phase 0. (Because the phase shift
|
||
|
happens at every level, it will also make <span class="RktSym">see-button</span> at phase 0
|
||
|
refer to <span class="RktRdr">#'</span><span class="RktSym">button</span> at phase -1.)</p><p>Note that <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stxops.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._syntax-shift-phase-level%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">syntax-shift-phase-level</a></span> merely creates a reference
|
||
|
across phases. To make that reference work, we still need to instantiate our
|
||
|
module at both phases so the reference and its target have their bindings
|
||
|
available. Thus, in module <span class="RktVal">'</span><span class="RktVal">b</span>,
|
||
|
we still import module <span class="RktVal">'</span><span class="RktVal">a</span> at both phase 0 and phase
|
||
|
1—<wbr></wbr>using <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="RktPn">)</span><span class="RktPn">)</span>—<wbr></wbr>so we have a phase-1
|
||
|
binding for <span class="RktSym">see-button</span> and a phase-0 binding for <span class="RktSym">button</span>.
|
||
|
Now macro <span class="RktSym">m</span> will work.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stxops.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._syntax-shift-phase-level%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">syntax-shift-phase-level</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</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="R
|
||
|
Its <span class="RktRdr">#'</span><span class="RktSym">button</span> binding has likewise been shifted, but to phase -1. Since
|
||
|
<span class="RktSym">button</span> itself isn’t bound at phase -1, if we try to evaluate
|
||
|
<span class="RktSym">see-button</span> at phase 0, we get an error. In other words, we haven’t permanently
|
||
|
cured our mismatch problem—<wbr></wbr>we’ve just shifted it to a less bothersome location.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">a</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stxops.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._syntax-shift-phase-level%2529%2529&version=8.6" class="RktValLink Sq" data-pltdoc="x">syntax-shift-phase-level</a></span><span class="hspace"> </span><span class="RktRdr">#'</span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal"><span class="nobreak">-1</span></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktSym">see-button</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">a</span><span class="hspace">&nb
|
||
|
literal bindings—<wbr></wbr>using <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._syntax-case%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">syntax-case</a></span> or <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=syntax&rel=Parsing_Syntax.html%23%2528form._%2528%2528lib._syntax%252Fparse..rkt%2529._syntax-parse%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">syntax-parse</a></span>.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktSym">syntax/parse</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-template%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-template</a></span><span class="hspace"> </span><span class="RktSym">racket/base</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._all-defined-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">all-defined-out</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivat
|
||
|
level 2, and it returns the <span class="RktRdr">#'</span><span class="RktSym">button</span> syntax object—<wbr></wbr>which
|
||
|
refers to <span class="RktSym">button</span> bound at phase level 0 inside <span class="RktSym">x</span> and
|
||
|
at phase level 2 in <span class="RktSym">y</span> from <span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-meta%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-meta</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">x</span><span class="RktPn">)</span>. The
|
||
|
<span class="RktSym">process</span> macro is imported at phase level 1 from
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-meta%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-meta</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">x</span><span class="RktPn">)</span>, and it knows that <span class="RktSym">button</span> should be
|
||
|
bound at phase level 1. When the <span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=syntax&rel=Parsing_Syntax.html%23%2528form._%2528%2528lib._syntax%252Fparse..rkt%2529._syntax-parse%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">syntax-parse</a></span> is executed
|
||
|
inside <span class="RktSym">process</span>, it is looking for <span class="RktSym">button</span> bound at
|
||
|
phase level 1 but it sees only a phase level 2 binding and doesn’t
|
||
|
match.</p><p>To fix the example, we can provide <span class="RktSym">make</span> at phase level 1
|
||
|
relative to <span class="RktSym">x</span>, and then we import it at phase level 1 in
|
||
|
<span class="RktSym">y</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=module.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._module%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-syntax%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktSym">syntax/parse</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for-template%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">for-template</a></span><span class="hspace"> </span><span class="RktSym">racket/base</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._provide%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._all-defined-out%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">all-defined-out</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=8.6" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">button</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fpriva
|