515 lines
236 KiB
HTML
515 lines
236 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>1.1 Evaluation Model</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="extras.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="icons.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 Reference</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="model.html" class="tocviewselflink" data-pltdoc="x">Language Model</a></td></tr><tr><td align="right">2 </td><td><a href="notation.html" class="tocviewlink" data-pltdoc="x">Notation for Documentation</a></td></tr><tr><td align="right">3 </td><td><a href="syntax.html" class="tocviewlink" data-pltdoc="x">Syntactic Forms</a></td></tr><tr><td align="right">4 </td><td><a href="data.html" class="tocviewlink" data-pltdoc="x">Datatypes</a></td></tr><tr><td align="right">5 </td><td><a href="structures.html" class="tocviewlink" data-pltdoc="x">Structures</a></td></tr><tr><td align="right">6 </td><td><a href="mzlib_class.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">7 </td><td><a href="mzlib_unit.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">8 </td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">9 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Control Flow</a></td></tr><tr><td align="right">11 </td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Parallelism</a></td></tr><tr><td align="right">12 </td><td><a href="Macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">13 </td><td><a href="input-and-output.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">14 </td><td><a href="security.html" class="tocviewlink" data-pltdoc="x">Reflection and Security</a></td></tr><tr><td align="right">15 </td><td><a href="os.html" class="tocviewlink" data-pltdoc="x">Operating System</a></td></tr><tr><td align="right">16 </td><td><a href="memory.html" class="tocviewlink" data-pltdoc="x">Memory Management</a></td></tr><tr><td align="right">17 </td><td><a href="unsafe.html" class="tocviewlink" data-pltdoc="x">Unsafe Operations</a></td></
|
||
|
to obtain values. For example, just as an elementary-school student
|
||
|
simplifies</p><p><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt"></span><span class="hspace"> </span><span class="stt">1 + 1 = 2</span></p></td></tr></table></p><p>Racket evaluation simplifies</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVal">2</span></p></blockquote><p>The arrow → replaces the more traditional <span class="stt">=</span> to
|
||
|
emphasize that evaluation proceeds in a particular direction toward
|
||
|
simpler expressions. In particular, a <a name="(tech._value)"></a><span style="font-style: italic">value</span>, such as the number <span class="RktVal">2</span>,
|
||
|
is an expression that evaluation simplifies no further.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""cont-model"">1.1.1<tt> </tt><a name="(part._cont-model)"></a>Sub-expression Evaluation and Continuations</h5><p>Some simplifications require more than one step. For example:</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="hspace"> </span><span class="RktVal">4</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="hspace"> </span>→<span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span></span><span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVal">2</span></p></blockquote><p>An expression that is not a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> can always be partitioned
|
||
|
into two parts: a <a name="(tech._redex)"></a><span style="font-style: italic">redex</span> (“reducible expression”),
|
||
|
which is the part that can change in a
|
||
|
single-step simplification (highlighted), and the
|
||
|
<a name="(tech._continuation)"></a><span style="font-style: italic">continuation</span>, which is the evaluation
|
||
|
context surrounding the redex. In <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span>, the redex is <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span>, and
|
||
|
the continuation is <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span>[]<span class="RktPn">)</span>, where [] takes the place
|
||
|
of the <a href="eval-model.html#%28tech._redex%29" class="techoutside" data-pltdoc="x"><span class="techinside">redex</span></a> as it is reduced. That is, the continuation says how to “continue”
|
||
|
after the <a href="eval-model.html#%28tech._redex%29" class="techoutside" data-pltdoc="x"><span class="techinside">redex</span></a> is reduced to a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>.</p><p>Before some expressions can be evaluated, some or all of their sub-expressions must be
|
||
|
evaluated. For example, in the application <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span>, the
|
||
|
application of <span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span> cannot be reduced until the sub-expression
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> is reduced.
|
||
|
Thus, the specification of each syntactic form specifies how (some of)
|
||
|
its sub-expressions are evaluated and then how the results are
|
||
|
combined to reduce the form away.</p><p>The <a name="(tech._dynamic._extent)"></a><span style="font-style: italic">dynamic extent</span> of an expression is the sequence of
|
||
|
evaluation steps during which the expression contains the <a href="eval-model.html#%28tech._redex%29" class="techoutside" data-pltdoc="x"><span class="techinside">redex</span></a>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Tail_Position"">1.1.2<tt> </tt><a name="(part._.Tail_.Position)"></a>Tail Position</h5><p>An expression <span class="RktVar">expr1</span> is in <a name="(tech._tail._position)"></a><span style="font-style: italic">tail position</span> with
|
||
|
respect to an enclosing expression <span class="RktVar">expr2</span> if, whenever
|
||
|
<span class="RktVar">expr1</span> becomes a redex, its <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a> is the same
|
||
|
as was the enclosing <span class="RktVar">expr2</span>’s <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a>.</p><p>For example, the <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> expression is <span style="font-style: italic">not</span> in <a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">tail
|
||
|
position</span></a> with respect to <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span>. To illustrate, we use
|
||
|
the notation <span class="RktVar">C</span>[<span class="RktVar">expr</span>] to mean the expression that is produced by
|
||
|
substituting <span class="RktVar">expr</span> in place of [] in some <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a>
|
||
|
<span class="RktVar">C</span>:</p><blockquote class="SCodeFlow"><p><span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span>]<span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span>]</p></blockquote><p>In this case, the <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a> for reducing <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> is
|
||
|
<span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktVal">4</span><span class="stt"> </span>[]<span class="RktPn">)</span>], not just <span class="RktVar">C</span>. The requirement specified in the first paragraph above is not met.</p><p>In contrast, <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span> is in <a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">tail position</span></a> with respect
|
||
|
to <span class="RktPn">(</span><span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="number-types.html#%28def._%28%28quote._~23~25kernel%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span> because, for any continuation
|
||
|
<span class="RktVar">C</span>,</p><blockquote class="SCodeFlow"><p><span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="number-types.html#%28def._%28%28quote._~23~25kernel%29._zero~3f%29%29" class="RktValLink" data-pltdoc="x">zero?</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span>]<span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="stt"> </span><span class="RktVal">#t</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span>]<span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVar">C</span>[<span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span>]</p></blockquote><p>The requirement specified in the first paragraph is met.
|
||
|
The steps in this reduction sequence are driven by the definition of
|
||
|
<span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span>, and they do not depend on the <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a>
|
||
|
<span class="RktVar">C</span>. The “then” branch of an <span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> form is always in
|
||
|
<a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">tail position</span></a> with respect to the <span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> form. Due to a
|
||
|
similar reduction rule for <span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> and <span class="RktVal">#f</span>, the “else”
|
||
|
branch of an <span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span> form is also in <a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">tail position</span></a>.</p><p><a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">Tail-position</span></a> specifications provide a guarantee about the
|
||
|
asymptotic space consumption of a computation. In general, the
|
||
|
specification of <a href="eval-model.html#%28tech._tail._position%29" class="techoutside" data-pltdoc="x"><span class="techinside">tail positions</span></a> accompanies the description of
|
||
|
each syntactic form, such as <span class="RktSym"><a href="if.html#%28form._%28%28quote._~23~25kernel%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""values-model"">1.1.3<tt> </tt><a name="(part._values-model)"></a>Multiple Return Values</h5><p>A Racket expression can evaluate to <a name="(tech._multiple._value)"></a><span style="font-style: italic">multiple values</span>, to
|
||
|
provide symmetry with the fact that a procedure can accept multiple arguments.</p><p>Most <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuations</span></a> expect a certain number of result
|
||
|
<a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>, although some <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuations</span></a> can accept
|
||
|
an arbitrary number. Indeed, most <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuations</span></a>, such as <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span>[]<span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span>, expect a single <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>. The <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a>
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="let.html#%28form._%28%28quote._~23~25kernel%29._let-values%29%29" class="RktStxLink" data-pltdoc="x">let-values</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktSym">y</span><span class="RktPn">)</span><span class="stt"> </span>[]<span class="RktPn">]</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVar">expr</span><span class="RktPn">)</span> expects two result
|
||
|
<a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>; the first result replaces <span class="RktSym">x</span> in the body
|
||
|
<span class="RktVar">expr</span>, and the second replaces <span class="RktSym">y</span> in
|
||
|
<span class="RktVar">expr</span>. The <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a> <span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="stt"> </span>[]<span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span> accepts any number of result <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>, because it ignores
|
||
|
the result(s).</p><p>In general, the specification of a syntactic form indicates the
|
||
|
number of <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a> that it produces and the number that it
|
||
|
expects from each of its sub-expressions. In addition, some procedures
|
||
|
(notably <span class="RktSym"><a href="values.html#%28def._%28%28quote._~23~25kernel%29._values%29%29" class="RktValLink" data-pltdoc="x">values</a></span>) produce multiple <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>, and some
|
||
|
procedures (notably <span class="RktSym"><a href="values.html#%28def._%28%28quote._~23~25kernel%29._call-with-values%29%29" class="RktValLink" data-pltdoc="x">call-with-values</a></span>) create continuations
|
||
|
internally that accept a certain number of <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Top-Level_Variables"">1.1.4<tt> </tt><a name="(part._.Top-.Level_.Variables)"></a>Top-Level Variables</h5><p>Given</p><p><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt"></span><span class="hspace"> </span><span class="stt">x = 10</span></p></td></tr></table></p><p>then an algebra student simplifies <span class="stt">x + 1</span> as follows:</p><p><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt"></span><span class="hspace"> </span><span class="stt">x + 1 = 10 + 1 = 11</span></p></td></tr></table></p><p>Racket works much the same way, in that a set of <a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level
|
||
|
variables</span></a> (see also <a href="eval-model.html#%28part._vars-and-locs%29" data-pltdoc="x">Variables and Locations</a>) are available for substitutions on demand during
|
||
|
evaluation. For example, given</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></p></blockquote><p>then</p><blockquote class="SCodeFlow"><p><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></span><span class="hspace"> </span>→<span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">10</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span></span><span class="hspace"> </span>→<span class="hspace"> </span><span class="RktVal">11</span></p></blockquote><p>In Racket, the way definitions are created is just as important as the way
|
||
|
they are used. Racket evaluation thus keeps track of both
|
||
|
definitions and the current expression, and it extends the set of
|
||
|
definitions in response to evaluating forms such as <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span>.</p><p>Each evaluation step, then, transforms the current set of definitions and
|
||
|
program into a new set of definitions and program. Before a
|
||
|
<span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span> can be moved into the set of definitions, its
|
||
|
expression (i.e., its right-hand side) must be reduced to a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>.
|
||
|
(The left-hand side is not an expression position, and so it is not evaluated.)</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">9</span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">1</span></span><span class="highlighted"><span class="RktPn">)</span></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktSym">x</span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">10</span></span><span class="highlighted"><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28fo
|
||
|
existing <a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level variable</span></a>:</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktSym">x</span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">8</span></span><span class="highlighted"><span class="RktPn">)</span></span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">8</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="void.html#%28def._%28%28quote._~23~25kernel%29._void%29%29" class="RktValLink" data-pltdoc="x">void</a></span></span><span class="highlighted"><span class="RktPn">)</span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktSym">x</span></span><span class="highlighted"><span class="RktPn">)</span></span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">8</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td va
|
||
|
variables</span></a>, various procedures enable the modification of elements
|
||
|
within a compound data structure. For example, <span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector-set%21%29%29" class="RktValLink" data-pltdoc="x">vector-set!</a></span>
|
||
|
modifies the content of a vector.</p><p>To explain such modifications to data, we must distinguish between
|
||
|
<a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a>, which are the results of expressions, and
|
||
|
<a name="(tech._object)"></a><span style="font-style: italic">objects</span>, which actually hold data.</p><p>A few kinds of <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a> can serve directly as values, including
|
||
|
booleans, <span class="RktPn">(</span><span class="RktSym"><a href="void.html#%28def._%28%28quote._~23~25kernel%29._void%29%29" class="RktValLink" data-pltdoc="x">void</a></span><span class="RktPn">)</span>, and small exact integers. More generally,
|
||
|
however, a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> is a reference to an <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a> stored somewhere
|
||
|
else. For example, a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> can refer to a particular vector that
|
||
|
currently holds the value <span class="RktVal">10</span> in its first slot. If an
|
||
|
<a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a> is modified via one <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>,
|
||
|
then the modification is visible through
|
||
|
all the <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">values</span></a> that reference the <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a>.</p><p>In the evaluation model, a set of <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a> must be carried along
|
||
|
with each step in evaluation, just like the definition set. Operations
|
||
|
that create <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a>, such as <span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector%29%29" class="RktValLink" data-pltdoc="x">vector</a></span>, add to the set of
|
||
|
<a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a>:</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector%29%29" class="RktValLink" data-pltdoc="x">vector</a></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">10</span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">20</span></span><span class="highlighted"><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector-set%21%29%29" class="RktValLink" data-pltdoc="x">vector-set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">0</span><span class="hspace"> </span><span class="RktVal">11</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector-ref%29%29" class="RktValLink" data-pltdoc="x">vector-ref</a></span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><o1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="vect
|
||
|
reference is crucial. A <a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level variable</span></a> is not a
|
||
|
<a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>, so it must be evaluated. Each time
|
||
|
a <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> expression is evaluated, the
|
||
|
value of the variable is extracted from the current set of definitions. An object
|
||
|
reference, in contrast, is a value and therefore needs no further
|
||
|
evaluation. The evaluation steps above use angle-bracketed
|
||
|
<span class="RktSym"><o1></span> for an object reference to distinguish it from a
|
||
|
<a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> name.</p><p>An object reference can never appear directly in a text-based source
|
||
|
program. A program representation created with
|
||
|
<span class="RktSym"><a href="stxops.html#%28def._%28%28quote._~23~25kernel%29._datum-~3esyntax%29%29" class="RktValLink" data-pltdoc="x">datum->syntax</a></span>, however, can embed direct references to
|
||
|
existing <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""gc-model"">1.1.6<tt> </tt><a name="(part._gc-model)"></a>Garbage Collection</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="memory.html" data-pltdoc="x">Memory Management</a> for functions related to
|
||
|
garbage collection.</p></blockquote></blockquote></blockquote><p>In the program state</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><o1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector%29%29" class="RktValLink" data-pltdoc="x">vector</a></span><span class="hspace"> </span><span class="RktVal">10</span><span class="hspace"> </span><span class="RktVal">20</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><o2></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector%29%29" class="RktValLink" data-pltdoc="x">vector</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktSym"><o1></span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktVal">1</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr></table></p><p>evaluation cannot depend on <span class="RktSym"><o2></span>, because it is not part of
|
||
|
the program to evaluate, and it is not referenced by any definition
|
||
|
that is accessible by the program. The object is said to not
|
||
|
be <a name="(tech._reachable)"></a><span style="font-style: italic">reachable</span>. The <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a> <span class="RktSym"><o2></span> may
|
||
|
therefore be removed from the program state by <a name="(tech._garbage._collection)"></a><span style="font-style: italic">garbage
|
||
|
collection</span>.</p><p>A few special compound datatypes hold <a name="(tech._weak._reference)"></a><span style="font-style: italic">weak references</span> to
|
||
|
objects. Such weak references are treated specially by the garbage
|
||
|
collector in determining which <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">objects</span></a> are reachable for the
|
||
|
remainder of the computation. If an <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a> is reachable <span style="font-style: italic">only</span>
|
||
|
via a <a href="eval-model.html#%28tech._weak._reference%29" class="techoutside" data-pltdoc="x"><span class="techinside">weak reference</span></a>, then the object can be reclaimed, and the
|
||
|
<a href="eval-model.html#%28tech._weak._reference%29" class="techoutside" data-pltdoc="x"><span class="techinside">weak reference</span></a> is replaced by a different <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>
|
||
|
(typically <span class="RktVal">#f</span>).</p><p>As a special case, a <a href="numbers.html#%28tech._fixnum%29" class="techoutside" data-pltdoc="x"><span class="techinside">fixnum</span></a> is always considered reachable by
|
||
|
the garbage collector. Many other values are always reachable due to
|
||
|
the way they are implemented and used: A <a href="characters.html#%28tech._character%29" class="techoutside" data-pltdoc="x"><span class="techinside">character</span></a> in the
|
||
|
Latin-1 range is always reachable, because <span class="RktSym"><a href="Equality.html#%28def._%28%28quote._~23~25kernel%29._equal~3f%29%29" class="RktValLink" data-pltdoc="x">equal?</a></span> Latin-1
|
||
|
characters are always <span class="RktSym"><a href="Equality.html#%28def._%28%28quote._~23~25kernel%29._eq~3f%29%29" class="RktValLink" data-pltdoc="x">eq?</a></span>, and all of the Latin-1 characters
|
||
|
are referenced by an internal module. Similarly, <span class="RktSym"><a href="pairs.html#%28def._%28%28quote._~23~25kernel%29._null%29%29" class="RktValLink" data-pltdoc="x">null</a></span>,
|
||
|
<span class="RktVal">#t</span>, <span class="RktVal">#f</span>, <span class="RktSym"><a href="port-ops.html#%28def._%28%28quote._~23~25kernel%29._eof%29%29" class="RktValLink" data-pltdoc="x">eof</a></span>, and <a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=guide&rel=void_undefined.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="nobreak"><span class="RktRes">#<void></span></span></a> are
|
||
|
always reachable. Values produced by <span class="RktSym"><a href="quote.html#%28form._%28%28quote._~23~25kernel%29._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</a></span> remain reachable
|
||
|
when the <span class="RktSym"><a href="quote.html#%28form._%28%28quote._~23~25kernel%29._quote%29%29" class="RktStxLink" data-pltdoc="x">quote</a></span> expression itself is reachable.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""Procedure_Applications_and_Local_Variables"">1.1.7<tt> </tt><a name="(part._.Procedure_.Applications_and_.Local_.Variables)"></a>Procedure Applications and Local Variables</h5><p>Given</p><p><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt"></span><span class="hspace"> </span><span class="stt">f(x) = x + 10</span></p></td></tr></table></p><p>an algebra student simplifies <span class="stt">f(7)</span> as follows:</p><p><table cellspacing="0" cellpadding="0" class="SVerbatim"><tr><td><p><span class="stt"></span><span class="hspace"> </span><span class="stt">f(7) = 7 + 10 = 17</span></p></td></tr></table></p><p>The key step in this simplification is to take the body of the defined
|
||
|
function <span class="stt">f</span> and replace each <span class="stt">x</span> with the actual
|
||
|
<a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> <span class="stt">7</span>.</p><p>Racket procedure application works much the same way. A procedure is
|
||
|
an <a href="eval-model.html#%28tech._object%29" class="techoutside" data-pltdoc="x"><span class="techinside">object</span></a>, so evaluating <span class="RktPn">(</span><span class="RktSym">f</span><span class="stt"> </span><span class="RktVal">7</span><span class="RktPn">)</span> starts with a
|
||
|
<a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> lookup:</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">f</span></span><span class="hspace"> </span><span class="RktVal">7</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">f</sp
|
||
|
argument variable can be changed in the body of a procedure by using
|
||
|
<span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span>, as in the example <span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span>. Since the <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> associated with argument variable <span class="RktSym">x</span> should be
|
||
|
able to change, we cannot just substitute the value in for <span class="RktSym">x</span> when
|
||
|
we first apply the procedure.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>We do not use the term “parameter variable” to refer to
|
||
|
the argument variable names declared with a function. This choice avoids
|
||
|
confusion with <a href="eval-model.html#%28tech._parameter%29" class="techoutside" data-pltdoc="x"><span class="techinside">parameters</span></a>.</p></blockquote></blockquote></blockquote><p>Instead, a new <a name="(tech._location)"></a><span style="font-style: italic">location</span> is created for each <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a>
|
||
|
on each application. The argument <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> is placed in the
|
||
|
<a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a>, and each instance of the <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> in the
|
||
|
procedure body is replaced with the new <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a>:</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="highlighted"><span class="RktPn">(</span></span><span class="highlighted"><span class="RktSym"><p1></span></span><span class="highlighted"><span class="hspace"> </span></span><span class="highlighted"><span class="RktVal">7</span></span><span class="highlighted"><span class="RktPn">)</span></span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="
|
||
|
a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> is generated, it (conceptually) uses a name that has
|
||
|
not been used before and that cannot be generated again or
|
||
|
accessed directly.</p><p>Generating a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> in this way means that <span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span>
|
||
|
evaluates for <a href="eval-model.html#%28tech._local._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">local variables</span></a>, including argument
|
||
|
variables, in the same way as for
|
||
|
<a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level variables</span></a>, because the <a href="eval-model.html#%28tech._local._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">local variable</span></a> is
|
||
|
always replaced with a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> by the time the <span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span>
|
||
|
form is evaluated:</p><p><table cellspacing="0" cellpadding="0"><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</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 valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>defined:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">f</span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>evaluate:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="highlighted"><span class="RktSym">f</span></span><span class="hspace"> </span><span class="RktVal">7</span><span class="RktPn">)</span></td></tr><tr><td valign="baseline"><p> </p></td><td valign="baseline"><p>→</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><p>objects:</p></td><td valign="baseline"><p> </p></td><td valign="baseline"><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym"><p1></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">3</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span>
|
||
|
application requires that the argument is a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>. Therefore,
|
||
|
in <span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktSym">x</span><span class="stt"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span>, the <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span>
|
||
|
sub-expression must be simplified to the <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a> <span class="RktVal">3</span>, and
|
||
|
then <span class="RktVal">3</span> can be placed into a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> for
|
||
|
<span class="RktSym">x</span>. In other words, Racket is a <a name="(tech._call._by._value)"></a><span style="font-style: italic">call-by-value</span>
|
||
|
language.</p><p>Evaluation of a local-variable form, such as <span class="RktPn">(</span><span class="RktSym"><a href="let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="stt"> </span><span class="RktVar">expr</span><span class="RktPn">)</span>, is the same as for a procedure call. After <span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">2</span><span class="RktPn">)</span> produces a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>, it is stored in a fresh <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a>
|
||
|
that replaces every instance of <span class="RktSym">x</span> in <span class="RktVar">expr</span>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""vars-and-locs"">1.1.8<tt> </tt><a name="(part._vars-and-locs)"></a>Variables and Locations</h5><p>A <a name="(tech._variable)"></a><span style="font-style: italic">variable</span> is a placeholder for a <a href="eval-model.html#%28tech._value%29" class="techoutside" data-pltdoc="x"><span class="techinside">value</span></a>, and
|
||
|
expressions in an initial program refer to <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variables</span></a>. A
|
||
|
<a name="(tech._top._level._variable)"></a><span style="font-style: italic">top-level variable</span> is both a <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> and a
|
||
|
<a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a>. Any other <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> is always replaced by a
|
||
|
<a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> at run-time; thus, evaluation of expressions
|
||
|
involves only <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">locations</span></a>. A single <a name="(tech._local._variable)"></a><span style="font-style: italic">local variable</span>
|
||
|
(i.e., a non-top-level, non-module-level <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a>), such as an
|
||
|
argument variable, can correspond to different <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">locations</span></a>
|
||
|
during different applications.</p><p>For example, in the program</p><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">y</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="generic-numbers.html#%28def._%28%28quote._~23~25kernel%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="let.html#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29" class="RktStxLink" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">5</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">6</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote><p>both <span class="RktSym">y</span> and <span class="RktSym">x</span> are <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variables</span></a>. The <span class="RktSym">y</span>
|
||
|
<a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> is a <a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level variable</span></a>, and the <span class="RktSym">x</span> is
|
||
|
a <a href="eval-model.html#%28tech._local._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">local variable</span></a>. When this code is evaluated, a
|
||
|
<a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> is created for <span class="RktSym">x</span> to hold the value
|
||
|
<span class="RktVal">5</span>, and a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> is also created for <span class="RktSym">y</span> to
|
||
|
hold the value <span class="RktVal">11</span>.</p><p>The replacement of a <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> with a <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> during
|
||
|
evaluation implements Racket’s <a name="(tech._lexical._scoping)"></a><span style="font-style: italic">lexical scoping</span>.
|
||
|
<span class="refelem"><span class="refcolumn"><span class="refcontent">For the purposes of substituting <span class="RktSym">xloc</span> for <span class="RktSym">x</span>,
|
||
|
all variable bindings must use distinct names, so no <span class="RktSym">x</span> that
|
||
|
is really a different variable will get replaced. Ensuring that
|
||
|
distinction is one of the jobs of the macro expander; see <a href="syntax-model.html" data-pltdoc="x">Syntax Model</a>.</span></span></span>
|
||
|
For example, when an argument variable <span class="RktSym">x</span> is replaced by
|
||
|
the <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a> <span class="RktSym">xloc</span>, it is replaced <span style="font-style: italic">throughout</span> the
|
||
|
body of the procedure, including any nested <span class="RktSym"><a href="lambda.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span>
|
||
|
forms. As a result, future references to the <a href="eval-model.html#%28tech._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">variable</span></a> always
|
||
|
access the same <a href="eval-model.html#%28tech._location%29" class="techoutside" data-pltdoc="x"><span class="techinside">location</span></a>.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""module-eval-model"">1.1.9<tt> </tt><a name="(part._module-eval-model)"></a>Modules and Module-Level Variables</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="module.html" data-pltdoc="x">Modules: <span class="RktSym"><span class="RktStxLink">module</span></span>, <span class="RktSym"><span class="RktStxLink">module*</span></span>, ...</a> for the syntax of modules.</p></blockquote></blockquote></blockquote><p>Most definitions in Racket are in <a name="(tech._module)"></a><span style="font-style: italic">modules</span>. In terms of evaluation,
|
||
|
a module is essentially a prefix on a defined name, so that different
|
||
|
modules can define the same name. That is, a <a name="(tech._module._level._variable)"></a><span style="font-style: italic">module-level
|
||
|
variable</span> is like a <a href="eval-model.html#%28tech._top._level._variable%29" class="techoutside" data-pltdoc="x"><span class="techinside">top-level variable</span></a> from the perspective of
|
||
|
evaluation.</p><p>One difference between a module and a top-level definition
|
||
|
is that a module can be <a name="(tech._declare)"></a><span style="font-style: italic">declared</span>
|
||
|
without instantiating its module-level definitions.
|
||
|
Evaluation of a <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span> <a name="(tech._instantiate)"></a><span style="font-style: italic">instantiates</span>
|
||
|
(i.e., triggers the <a name="(tech._instantiation)"></a><span style="font-style: italic">instantiation</span> of) the declared
|
||
|
module, which creates variables that correspond to its
|
||
|
module-level definitions.</p><p>For example, given the module declaration</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">m</span><span class="hspace"> </span><span class="RktSym">racket</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">x</span><span class="hspace"> </span><span class="RktVal">10</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>the evaluation of <span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">m</span><span class="RktPn">)</span> creates the variable <span class="RktSym">x</span>
|
||
|
and installs <span class="RktVal">10</span> as its value. This <span class="RktSym">x</span> is unrelated to
|
||
|
any top-level definition of <span class="RktSym">x</span> (as if it were given a unique,
|
||
|
module-specific prefix).</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""module-phase"">1.1.9.1<tt> </tt><a name="(part._module-phase)"></a>Phases</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="finger.png" alt="+" width="24" height="24"/></span>See also <a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=guide&rel=phases.html&version=8.6" class="Sq" data-pltdoc="x">General Phase Levels</a> in <a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=guide&rel=index.html&version=8.6" class="Sq" data-pltdoc="x">The Racket Guide</a>.</p></blockquote></blockquote></blockquote><p>The purpose of <a name="(tech._phase)"></a><span style="font-style: italic">phases</span> is to
|
||
|
address the necessary separation of names defined at execution time versus
|
||
|
names defined at expansion time.</p><p>A module can be <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d in multiple <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phases</span></a>. A
|
||
|
phase is an integer that, like a module name, is effectively a prefix on the names
|
||
|
of module-level definitions. Phase 0 is the execution-time phase.</p><p>A top-level <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>
|
||
|
<a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiates</span></a> a module at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 0, if the module is not
|
||
|
already <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at phase 0. A top-level
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-syntax%29%29" class="RktStxLink" data-pltdoc="x">for-syntax</a></span><span class="stt"> </span><span class="RktSym">....</span><span class="RktPn">)</span><span class="RktPn">)</span> <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiates</span></a> a module at
|
||
|
<a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 1 (if it is not already <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at that
|
||
|
phase); <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-syntax%29%29" class="RktStxLink" data-pltdoc="x">for-syntax</a></span> also has a different binding
|
||
|
effect on further program parsing, as described in
|
||
|
<a href="syntax-model.html#%28part._intro-binding%29" data-pltdoc="x">Introducing Bindings</a>.</p><p>Within a module, some definitions are already shifted by a phase: the
|
||
|
<span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">begin-for-syntax</a></span> form is similar to <span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin%29%29" class="RktStxLink" data-pltdoc="x">begin</a></span>, but it
|
||
|
shifts expressions and definitions by a relative <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> +1.
|
||
|
Likewise, the <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">define-for-syntax</a></span> form is similar to <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span>,
|
||
|
but shifts the definition by +1.
|
||
|
Thus, if the module is <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at phase 1,
|
||
|
the variables defined with <span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">begin-for-syntax</a></span> are created at phase 2,
|
||
|
and so on. Moreover, this relative phase acts as another layer of
|
||
|
prefixing, so that <span class="RktSym">x</span> defined with <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span> and
|
||
|
<span class="RktSym">x</span> defined with <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">define-for-syntax</a></span> can co-exist in a module
|
||
|
without colliding. A <span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">begin-for-syntax</a></span> form can be nested
|
||
|
within a <span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">begin-for-syntax</a></span> form, in which case the inner definitions and
|
||
|
expressions are in relative <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> +2, and so on. Higher phases are
|
||
|
mainly related to program parsing instead of normal evaluation.</p><p>If a module <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> <span style="font-style: italic">n</span>
|
||
|
<span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>s another module, then the <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>d module is
|
||
|
first <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at phase <span style="font-style: italic">n</span>, and so on
|
||
|
transitively. (Module <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>s cannot form cycles.) If a
|
||
|
module <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at phase <span style="font-style: italic">n</span> <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>s
|
||
|
another module <span class="RktVar">M</span> <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-syntax%29%29" class="RktStxLink" data-pltdoc="x">for-syntax</a></span>, then <span class="RktVar">M</span> becomes
|
||
|
<a name="(tech._available)"></a><span style="font-style: italic">available</span> at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> <span style="font-style: italic">n+</span>1<span style="font-style: italic"></span>, and it later may be
|
||
|
<a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> <span style="font-style: italic">n+</span>1<span style="font-style: italic"></span>. If a module that is
|
||
|
<a href="eval-model.html#%28tech._available%29" class="techoutside" data-pltdoc="x"><span class="techinside">available</span></a> at phase <span style="font-style: italic">n</span> (for <span style="font-style: italic">n></span>0<span style="font-style: italic"></span>) <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>s
|
||
|
another module <span class="RktVar">M</span> <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-template%29%29" class="RktStxLink" data-pltdoc="x">for-template</a></span>, then <span class="RktVar">M</span> becomes
|
||
|
<a href="eval-model.html#%28tech._available%29" class="techoutside" data-pltdoc="x"><span class="techinside">available</span></a> at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> <span style="font-style: italic">n-</span>1<span style="font-style: italic"></span>, and so
|
||
|
on. <a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">Instantiation</span></a>s of <a href="eval-model.html#%28tech._available%29" class="techoutside" data-pltdoc="x"><span class="techinside">available</span></a> modules above
|
||
|
<a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 0 are triggered on demand as described in
|
||
|
<a href="syntax-model.html#%28part._mod-parse%29" data-pltdoc="x">Module Expansion, Phases, and Visits</a>.</p><p>A final distinction among module <a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiations</span></a> is that
|
||
|
multiple <a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiations</span></a> may exist at <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 1 and
|
||
|
higher. These <a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiations</span></a> are created by the parsing of
|
||
|
module forms (see <a href="syntax-model.html#%28part._mod-parse%29" data-pltdoc="x">Module Expansion, Phases, and Visits</a>), and are, again, conceptually
|
||
|
distinguished by prefixes.</p><p>Top-level variables can exist in multiple phases in the same way as
|
||
|
within modules. For example, <span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span> within <span class="RktSym"><a href="begin.html#%28form._%28%28quote._~23~25kernel%29._begin-for-syntax%29%29" class="RktStxLink" data-pltdoc="x">begin-for-syntax</a></span> creates a
|
||
|
<a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 1 variable. Furthermore, reflective operations like
|
||
|
<span class="RktSym"><a href="Namespaces.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._make-base-namespace%29%29" class="RktValLink" data-pltdoc="x">make-base-namespace</a></span> and <span class="RktSym"><a href="eval.html#%28def._%28%28quote._~23~25kernel%29._eval%29%29" class="RktValLink" data-pltdoc="x">eval</a></span> provide access to
|
||
|
top-level variables in higher <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phases</span></a>, while module
|
||
|
<a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiations</span></a> (triggered by <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>) relative to such
|
||
|
top-levels are in correspondingly higher <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a>s.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""separate-compilation"">1.1.9.2<tt> </tt><a name="(part._separate-compilation)"></a>The Separate Compilation Guarantee</h5><p>When a module is compiled, its <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> 1 is instantiated. This
|
||
|
can, in turn, trigger the transitive instantiation of many other
|
||
|
modules at other phases, including phase 1. Racket provides a very
|
||
|
strong guarantee about this instantiation called
|
||
|
<a name="(idx._(gentag._0._(lib._scribblings/reference/reference..scrbl)))"></a>“The Separate
|
||
|
Compilation Guarantee”:</p><blockquote><p>Any <a href="eval-model.html#%28tech._effect%29" class="techoutside" data-pltdoc="x"><span class="techinside">effects</span></a> of the instantiation of the module’s phase 1 due
|
||
|
to compilation on the Racket runtime system are <a href="eval-model.html#%28tech._discarded%29" class="techoutside" data-pltdoc="x"><span class="techinside">discarded</span></a>.</p></blockquote><p>The guarantee concerns <a name="(tech._effect)"></a><span style="font-style: italic">effects</span>. There are two different
|
||
|
kinds of effects: internal and external.</p><p>Internal effects are exemplified by mutation. Mutation is the action
|
||
|
of a function such as <span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._set-box%21%29%29" class="RktValLink" data-pltdoc="x">set-box!</a></span>, which changes the value
|
||
|
contained in the box. The modified box is not observable outside
|
||
|
Racket, so the effect is said to be “internal.” By definition,
|
||
|
internal effects are not detectable outside the Racket program.</p><p>External effects are exemplified by input/output (I/O). I/O is the
|
||
|
action of a function such as <span class="RktSym"><a href="tcp.html#%28def._%28%28lib._racket%2Ftcp..rkt%29._tcp-connect%29%29" class="RktValLink" data-pltdoc="x">tcp-connect</a></span>, which communicates
|
||
|
with the operating system to send network packets outside the
|
||
|
machine running Racket. The transmission of these packets is
|
||
|
observable outside Racket, in particular by the receiving computer
|
||
|
or any routers in between. External effects exist to be detectable
|
||
|
outside the Racket program and are often detectable using physical
|
||
|
processes.</p><p>An effect is <a name="(tech._discarded)"></a><span style="font-style: italic">discarded</span> when it is no longer detectable. For
|
||
|
instance, the mutation of a box from <span class="RktVal">3</span> to <span class="RktVal">4</span> is
|
||
|
discarded when it ceases to be detectable that it was ever changed and
|
||
|
thus would still contain <span class="RktVal">3</span>. Because external effects are
|
||
|
intrinsically observable outside Racket, they are irreversible and
|
||
|
cannot be discarded.</p><p>Thus, The Separate Compilation Guarantee only concerns effects like
|
||
|
mutation, because they are exclusively effects “on the Racket runtime
|
||
|
system” and not “on the physical universe.”</p><p>There are many things a Racket program can do that appear to be
|
||
|
internal effects but are actually external effects. For instance,
|
||
|
<span class="RktSym"><a href="bytestrings.html#%28def._%28%28quote._~23~25kernel%29._bytes-set%21%29%29" class="RktValLink" data-pltdoc="x">bytes-set!</a></span> is typically an internal effect, except when the
|
||
|
bytes are created by <span class="RktSym"><a href="bytestrings.html#%28def._%28%28quote._~23~25kernel%29._make-shared-bytes%29%29" class="RktValLink" data-pltdoc="x">make-shared-bytes</a></span>, which allocates in
|
||
|
space observable by other processes. Thus, effects which modify those
|
||
|
bytes are not discardable, so <span class="RktSym"><a href="bytestrings.html#%28def._%28%28quote._~23~25kernel%29._bytes-set%21%29%29" class="RktValLink" data-pltdoc="x">bytes-set!</a></span>, in this case, has an
|
||
|
external effect.</p><p>The opposite is also true: some things which appear to be external are
|
||
|
actually internal. For instance, if a Racket program starts multiple
|
||
|
threads and uses mutation to communicate between them, that mutation
|
||
|
is purely internal, because Racket’s threads are defined entirely
|
||
|
internally (they are not related to operating system threads).</p><p>Furthermore, whenever a Racket program calls an <a href="unsafe.html#%28tech._unsafe%29" class="techoutside" data-pltdoc="x"><span class="techinside">unsafe</span></a>
|
||
|
function, the Racket runtime system makes no promises about its
|
||
|
effects. For instance, all foreign calls use
|
||
|
<a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=foreign&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">ffi/unsafe</span></a>, so all foreign calls are unsafe and their
|
||
|
effects cannot be discarded by Racket.</p><p>Finally, The Separate Compilation Guarantee only concerns
|
||
|
instantiations at phase 1 during compilation and not all phase 1
|
||
|
instantiations generally, such as when its phase 1 is required and
|
||
|
used for effects via reflective mechanisms.</p><p>The practical consequence of this guarantee is that because effects
|
||
|
are never visible, no module can detect whether a module it
|
||
|
<span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span>s is already compiled. Thus, it can never change the
|
||
|
compilation of one module to have already compiled a different module.
|
||
|
In particular, if module A is shared by the phase 1 portion of modules
|
||
|
X and Y, then any internal effects while X is compiled are not visible
|
||
|
during the compilation of Y, regardless of whether X and Y are
|
||
|
compiled during the same execution of Racket’s runtime system and
|
||
|
regardless of the order of compilation.</p><p>The following set of modules demonstrate this guarantee. First, we
|
||
|
define a module with the ability to observe effects via a
|
||
|
<span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._box%29%29" class="RktValLink" data-pltdoc="x">box</a></span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._box%29%29" class="RktValLink" data-pltdoc="x">box</a></span><span class="hspace"> </span><span class="RktSym">racket/base</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29" class="RktStxLink" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._all-defined-out%29%29" class="RktStxLink" data-pltdoc="x">all-defined-out</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">b</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._box%29%29" class="RktValLink" data-pltdoc="x">box</a></span><span class="hspace"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Next, we define two syntax transformers that use and mutate this box:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">transformers</span><span class="hspace"> </span><span class="RktSym">racket/base</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29" class="RktStxLink" data-pltdoc="x">provide</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._all-defined-out%29%29" class="RktStxLink" data-pltdoc="x">all-defined-out</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-syntax%29%29" class="RktStxLink" data-pltdoc="x">for-syntax</a></span><span class="hspace"> </span><span class="RktSym">racket/base</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">box</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-syntax%29%29" class="RktStxLink" data-pltdoc="x">define-syntax</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">sett</span><span class="hspace"> </span><span class="RktSym">stx</span><span class="RktPn">)</span></td></tr>
|
||
|
transformers and the <span class="RktSym">user</span> module:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">test</span><span class="hspace"> </span><span class="RktSym">racket/base</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">box</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">transformers</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">user</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktSym">gott</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gett</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="RktPn">(</span><span class="RktSym">sett</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gett</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="RktPn">(</span><span class="RktSym"><a href="Writing.html#%28def._%28%28lib._racket%2Fprivate%2Fmisc..rkt%29._displayln%29%29" class="RktValLink" data-pltdoc="x">displayln</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._unbox%29%29" class="RktValLink" data-pltdoc="x">unbox</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></blockquote><p><div class="SIntrapara">This module displays:
|
||
|
</div><div class="SIntrapara"><ul><li><p><span class="RktInBG"><span class="hspace"></span><span class="RktIn">2</span><span class="hspace"></span></span>, because the <span class="RktPn">(</span><span class="RktSym">gett</span><span class="RktPn">)</span> in module <span class="RktSym">user</span> expanded to <span class="RktVal">2</span>.</p></li><li><p><span class="RktInBG"><span class="hspace"></span><span class="RktIn">0</span><span class="hspace"></span></span>, because the effects of compiling <span class="RktSym">user</span> were discarded.</p></li><li><p><span class="RktInBG"><span class="hspace"></span><span class="RktIn">2</span><span class="hspace"></span></span>, because the effect of <span class="RktPn">(</span><span class="RktSym">sett</span><span class="RktPn">)</span> inside <span class="RktSym">test</span> has
|
||
|
not yet been discarded.</p></li><li><p><span class="RktInBG"><span class="hspace"></span><span class="RktIn">0</span><span class="hspace"></span></span>, because the effects of <span class="RktSym">sett</span> at
|
||
|
phase 1 are irrelevant to the phase 0 use of <span class="RktSym">b</span> in <span class="RktPn">(</span><span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._unbox%29%29" class="RktValLink" data-pltdoc="x">unbox</a></span><span class="stt"> </span><span class="RktSym">b</span><span class="RktPn">)</span>.</p></li></ul></div></p><p>Furthermore, this display will never change, regardless of which order
|
||
|
these modules are compiled in or whether they are compiled at the same
|
||
|
time or separately.</p><p>In contrast, if these modules were changed to store the value of
|
||
|
<span class="RktSym">b</span> in a file on the filesystem, then the program would only
|
||
|
display <span class="RktInBG"><span class="hspace"></span><span class="RktIn">2</span><span class="hspace"></span></span>.</p><p>The Separate Compilation Guarantee is described in more detail
|
||
|
in the paper “Composable and Compilable Macros” [<a href="doc-bibliography.html#%28cite._.Flatt02%29" data-pltdoc="x">Flatt02</a>], including
|
||
|
informative examples. The paper “Advanced Macrology and the
|
||
|
implementation of Typed Scheme” [<a href="doc-bibliography.html#%28cite._.Culpepper07%29" data-pltdoc="x">Culpepper07</a>] also contains an
|
||
|
extended example of why it is important and how to design effectful
|
||
|
syntactic extensions in its presence.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""cross-phase persistent-modules"">1.1.9.3<tt> </tt><a name="(part._cross-phase._persistent-modules)"></a>Cross-Phase Persistent Modules</h5><p>Module declarations that fit a highly constrained
|
||
|
form—<wbr></wbr>including a
|
||
|
<span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._~23~25declare%29%29" class="RktStxLink" data-pltdoc="x">#%declare</a></span><span class="stt"> </span><span class="RktPn">#:cross-phase-persistent</span><span class="RktPn">)</span> form in the
|
||
|
module body—<wbr></wbr>create <a name="(tech._cross._phase._persistent)"></a><span style="font-style: italic">cross-phase persistent</span>
|
||
|
modules. A <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module’s
|
||
|
instantiations across all phases share the variables
|
||
|
produced by the first instantiation of the module.
|
||
|
Additionally, <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module
|
||
|
instantiations persist across <a href="syntax-model.html#%28tech._module._registry%29" class="techoutside" data-pltdoc="x"><span class="techinside">module registries</span></a> when
|
||
|
they share a common module declaration.</p><p><div class="SIntrapara">Examples:</div><div class="SIntrapara"><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="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">cross</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">#%kernel</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._~23~25declare%29%29" class="RktStxLink" data-pltdoc="x">#%declare</a></span><span class="hspace"> </span><span class="RktPn">#:cross-phase-persistent</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="require.html#%28form._%28%28quote._~23~25kernel%29._~23~25provide%29%29" class="RktStxLink" data-pltdoc="x">#%provide</a></span><span class="hspace"> </span><span class="RktSym">x</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="define.html#%28form._%28%28quote._~23~25kernel%29._define-values%29%29" class="RktStxLink" data-pltdoc="x">define-values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="symbols.html#%28def._%28%28quote._~23~25kernel%29._gensym%29%29" class="RktValLink" data-pltdoc="x">gensym</a></span><span class="RktPn">)</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="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span><span class="hspace"> </span><span class="RktSym">noncross</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">#%kernel</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="require.html#%28form._%28%28quote._~23~25kernel%29._~23~25provide%29%29" class="RktStxLink" data-pltdoc="x">#%provide</a></span><span class="hspace"> </span><span class="RktSym">x</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="define.html#%28form._%28%28quote._~23~25kernel%29._define-values%29%29" class="RktStxLink" data-pltdoc="x">define-values</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="symbols.html#%28def._%28%28quote._~23~25kernel%29._gensym%29%29" class="RktValLink" data-pltdoc="x">gensym</a></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"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">ns</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="Namespaces.html#%28def._%28%28quot
|
||
|
recognizable after <a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a> crossings. For example, when a macro
|
||
|
transformer running in phase 1 raises a syntax error as represented by
|
||
|
an <span class="RktSym"><a href="exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail~3asyntax%29%29" class="RktValLink" data-pltdoc="x">exn:fail:syntax</a></span> instance, the instance is recognizable by a
|
||
|
phase-0 exception handler wrapping a call to <span class="RktSym"><a href="eval.html#%28def._%28%28quote._~23~25kernel%29._eval%29%29" class="RktValLink" data-pltdoc="x">eval</a></span> or
|
||
|
<span class="RktSym"><a href="Expanding_Top-Level_Forms.html#%28def._%28%28quote._~23~25kernel%29._expand%29%29" class="RktValLink" data-pltdoc="x">expand</a></span> that triggered the syntax error, because the
|
||
|
<span class="RktSym"><a href="exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail~3asyntax%29%29" class="RktValLink" data-pltdoc="x">exn:fail:syntax</a></span> structure type is defined by a
|
||
|
<a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module.</p><p>A <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module imports only other <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> modules,
|
||
|
and it contains only definitions that bind variables to functions,
|
||
|
structure types and related functions, or structure-type properties
|
||
|
and related functions. A <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module never includes syntax
|
||
|
literals (via <span class="RktSym"><a href="Syntax_Quoting__quote-syntax.html#%28form._%28%28quote._~23~25kernel%29._quote-syntax%29%29" class="RktStxLink" data-pltdoc="x">quote-syntax</a></span>) or variable references (via
|
||
|
<span class="RktSym"><a href="Locations____variable-reference.html#%28form._%28%28quote._~23~25kernel%29._~23~25variable-reference%29%29" class="RktStxLink" data-pltdoc="x">#%variable-reference</a></span>). See <a href="syntax-model.html#%28part._cross-phase._persistent-grammar%29" data-pltdoc="x">Cross-Phase Persistent Module Declarations</a> for
|
||
|
the syntactic specification of a <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module
|
||
|
declaration.</p><p>A documented module should be assumed non–<a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> unless it
|
||
|
is specified as <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> (such as
|
||
|
<a href="Kernel_Forms_and_Functions.html" class="RktModLink" data-pltdoc="x"><span class="RktSym">racket/kernel</span></a>).</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""module-redeclare"">1.1.9.4<tt> </tt><a name="(part._module-redeclare)"></a><a name="(idx._(gentag._1._(lib._scribblings/reference/reference..scrbl)))"></a>Module Redeclarations</h5><p>When a module is declared using a name with which a module is already
|
||
|
declared, the new declaration’s definitions replace and extend the old
|
||
|
declarations. If a variable in the old declaration has no counterpart
|
||
|
in the new declaration, the old variable continues to exist, but its
|
||
|
binding is not included in the <a href="syntax-model.html#%28tech._lexical._information%29" class="techoutside" data-pltdoc="x"><span class="techinside">lexical information</span></a> for the
|
||
|
module body. If a new variable definition has a counterpart in the old
|
||
|
declaration, it effectively assigns to the old variable.</p><p>If a module is <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d in the current namespace’s
|
||
|
<a href="syntax-model.html#%28tech._base._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">base phase</span></a> before the module is redeclared, the redeclaration
|
||
|
of the module is immediately <a href="eval-model.html#%28tech._instantiate%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiate</span></a>d in that
|
||
|
<a href="eval-model.html#%28tech._phase%29" class="techoutside" data-pltdoc="x"><span class="techinside">phase</span></a>.</p><p>If the current <a href="inspectors.html#%28tech._inspector%29" class="techoutside" data-pltdoc="x"><span class="techinside">inspector</span></a> does not manage a module’s declaration
|
||
|
inspector (see <a href="modprotect.html" data-pltdoc="x">Code Inspectors</a>), then the module cannot be
|
||
|
redeclared. Similarly, a <a href="eval-model.html#%28tech._cross._phase._persistent%29" class="techoutside" data-pltdoc="x"><span class="techinside">cross-phase persistent</span></a> module cannot be redeclared.
|
||
|
Even if redeclaration succeeds, instantiation of a module that is
|
||
|
previously instantiated may fail if instantiation for the
|
||
|
redeclaration attempts to modify variables that are constant (see
|
||
|
<span class="RktSym"><a href="eval.html#%28def._%28%28quote._~23~25kernel%29._compile-enforce-module-constants%29%29" class="RktValLink" data-pltdoc="x">compile-enforce-module-constants</a></span>).</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""submodules"">1.1.9.5<tt> </tt><a name="(part._submodules)"></a>Submodules</h5><p>A <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span> or <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%2A%29%29" class="RktStxLink" data-pltdoc="x">module*</a></span> form within a top-level
|
||
|
<span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span> form declares a <a name="(tech._submodule)"></a><span style="font-style: italic">submodule</span>. A submodule is
|
||
|
accessed relative to its enclosing module, usually with a
|
||
|
<span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._submod%29%29" class="RktStxLink" data-pltdoc="x">submod</a></span> path. Submodules can be nested to any depth.</p><p>Although a submodule is lexically nested within a module, it cannot
|
||
|
necessarily access the bindings of its enclosing module directly.
|
||
|
More specifically, a submodule declared with <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span> cannot
|
||
|
<span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span> from its enclosing module, but the enclosing module
|
||
|
can <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span> the submodule. In contrast, a submodule declared
|
||
|
with <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%2A%29%29" class="RktStxLink" data-pltdoc="x">module*</a></span> conceptually follows its enclosing module, so
|
||
|
can <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span> from its enclosing module, but the enclosing
|
||
|
module cannot <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29" class="RktStxLink" data-pltdoc="x">require</a></span> the submodule. Unless a submodule
|
||
|
imports from its enclosing module or vice versa, then <a href="syntax-model.html#%28tech._visit%29" class="techoutside" data-pltdoc="x"><span class="techinside">visits</span></a> or
|
||
|
<a href="eval-model.html#%28tech._instantiation%29" class="techoutside" data-pltdoc="x"><span class="techinside">instantiations</span></a> of the two modules are independent, and their
|
||
|
implementations may even be loaded from bytecode sources at different times.</p><p>A submodule declared with <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span> can import any preceding
|
||
|
submodule declared with <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span>. A submodule declared with
|
||
|
<span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%2A%29%29" class="RktStxLink" data-pltdoc="x">module*</a></span> can import any preceding module declared with
|
||
|
<span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%2A%29%29" class="RktStxLink" data-pltdoc="x">module*</a></span> and any submodule declared with <span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29" class="RktStxLink" data-pltdoc="x">module</a></span>.</p><p>When a submodule declaration has the form <span class="RktPn">(</span><span class="RktSym"><a href="module.html#%28form._%28%28quote._~23~25kernel%29._module%2A%29%29" class="RktStxLink" data-pltdoc="x">module*</a></span><span class="stt"> </span><span class="RktVar">name</span><span class="stt"> </span><span class="RktVal">#f</span><span class="stt"> </span><span class="RktSym">....</span><span class="RktPn">)</span>, then all of the bindings of the enclosing module’s bodies are
|
||
|
visible in the submodule’s body, and the submodule implicitly imports
|
||
|
the enclosing module. The submodule can <span class="RktSym"><a href="require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29" class="RktStxLink" data-pltdoc="x">provide</a></span> any bindings
|
||
|
that it inherits from its enclosing module.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""mark-model"">1.1.10<tt> </tt><a name="(part._mark-model)"></a>Continuation Frames and Marks</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="contmarks.html" data-pltdoc="x">Continuation Marks</a> for continuation-mark forms and functions.</p></blockquote></blockquote></blockquote><p>Every continuation <span class="RktVar">C</span> can be partitioned into
|
||
|
<a name="(tech._continuation._frame)"></a><span style="font-style: italic">continuation frames</span> <span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">1</span></span>, <span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">2</span></span>, ..., <span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">n</span></span>
|
||
|
such that <span class="RktVar">C</span> = <span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">1</span></span>[<span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">2</span></span>[...[<span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">n</span></span>]]], and no frame <span class="RktVar">C<span style="vertical-align: sub; font-size: 80%">i</span></span> can be itself partitioned
|
||
|
into smaller continuations. Evaluation steps add frames to and remove frames from
|
||
|
the current continuation, typically one at a time.</p><p>Each frame is conceptually annotated with a set of
|
||
|
<a name="(tech._continuation._mark)"></a><span style="font-style: italic">continuation marks</span>. A mark consists of a key and its value.
|
||
|
The key is an arbitrary value, and each frame includes at most one
|
||
|
mark for any given key. Various operations set and extract marks from
|
||
|
continuations, so that marks can be used to attach information to a
|
||
|
<a href="eval-model.html#%28tech._dynamic._extent%29" class="techoutside" data-pltdoc="x"><span class="techinside">dynamic extent</span></a>. For example, marks can be used to record information
|
||
|
for a “stack trace” to be presented when an exception is raised, or
|
||
|
to implement dynamic scope.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""prompt-model"">1.1.11<tt> </tt><a name="(part._prompt-model)"></a>Prompts, Delimited Continuations, and Barriers</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="cont.html" data-pltdoc="x">Continuations</a> for continuation and prompt functions.</p></blockquote></blockquote></blockquote><p>A <a name="(tech._prompt)"></a><span style="font-style: italic">prompt</span> is a special kind of continuation frame that is
|
||
|
annotated with a specific <a name="(tech._prompt._tag)"></a><span style="font-style: italic">prompt tag</span> (essentially a
|
||
|
<a href="eval-model.html#%28tech._continuation._mark%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation mark</span></a>). Various operations allow the capture of frames in
|
||
|
the continuation from the redex position out to the nearest enclosing
|
||
|
prompt with a particular prompt tag; such a continuation is sometimes
|
||
|
called a <a name="(tech._delimited._continuation)"></a><span style="font-style: italic">delimited continuation</span>. Other operations allow the
|
||
|
current continuation to be extended with a captured continuation
|
||
|
(specifically, a <a name="(tech._composable._continuation)"></a><span style="font-style: italic">composable continuation</span>). Yet other
|
||
|
operations abort the computation to the nearest enclosing prompt with
|
||
|
a particular tag, or replace the continuation to the nearest enclosing
|
||
|
prompt with another one. When a delimited continuation is captured,
|
||
|
the marks associated with the relevant frames are also captured.</p><p>A <a name="(tech._continuation._barrier)"></a><span style="font-style: italic">continuation barrier</span> is another kind of continuation frame
|
||
|
that prohibits certain replacements of the current continuation with
|
||
|
another. Specifically, a continuation can be replaced by another only
|
||
|
when the replacement does not introduce any continuation barriers.
|
||
|
A continuation barrier
|
||
|
thus prevents “downward jumps” into a continuation that is protected
|
||
|
by a barrier. Certain operations install barriers automatically; in
|
||
|
particular, when an exception handler is called, a continuation
|
||
|
barrier prohibits the continuation of the handler from capturing the
|
||
|
continuation past the exception point.</p><p>An <a name="(tech._escape._continuation)"></a><span style="font-style: italic">escape continuation</span> is essentially a derived concept. It
|
||
|
combines a prompt for escape purposes with a continuation for
|
||
|
mark-gathering purposes. As the name implies, escape continuations are
|
||
|
used only to abort to the point of capture.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""thread-model"">1.1.12<tt> </tt><a name="(part._thread-model)"></a>Threads</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="concurrency.html" data-pltdoc="x">Concurrency and Parallelism</a> for thread and synchronization functions.</p></blockquote></blockquote></blockquote><p>Racket supports multiple <a name="(tech._thread)"></a><span style="font-style: italic">threads</span> of evaluation. Threads run
|
||
|
concurrently, in the sense that one thread can preempt another without
|
||
|
its cooperation, but threads currently all run on the same processor
|
||
|
(i.e., the same underlying operating system process and thread).</p><p>Threads are created explicitly by functions such as <span class="RktSym"><a href="threads.html#%28def._%28%28quote._~23~25kernel%29._thread%29%29" class="RktValLink" data-pltdoc="x">thread</a></span>.
|
||
|
In terms of the evaluation model, each step in evaluation
|
||
|
actually deals with multiple concurrent
|
||
|
expressions, up to one per thread, rather than a single expression. The expressions all
|
||
|
share the same objects and top-level variables, so that they can
|
||
|
communicate through shared state, and <span style="font-style: italic">sequential consistency</span> [<a href="doc-bibliography.html#%28cite._.Lamport79%29" data-pltdoc="x">Lamport79</a>] is
|
||
|
guaranteed (i.e., the result is consistent with some global sequence
|
||
|
imposed on all evaluation steps across threads). Most evaluation steps involve a
|
||
|
single step in a single thread, but certain synchronization
|
||
|
primitives require multiple threads to progress together in one step; for example,
|
||
|
an exchange of a value through a <a href="channel.html#%28tech._channel%29" class="techoutside" data-pltdoc="x"><span class="techinside">channel</span></a> progresses in two
|
||
|
threads simultaneously.</p><p>Unless otherwise noted, all constant-time procedures and operations
|
||
|
provided by Racket are thread-safe in the sense that they are
|
||
|
<span style="font-style: italic">atomic</span>: they happen as a single evaluation step.
|
||
|
For example, <span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span> assigns to a variable as an atomic action
|
||
|
with respect to all threads, so that no thread can see a
|
||
|
“half-assigned” variable. Similarly, <span class="RktSym"><a href="vectors.html#%28def._%28%28quote._~23~25kernel%29._vector-set%21%29%29" class="RktValLink" data-pltdoc="x">vector-set!</a></span> assigns to
|
||
|
a vector atomically. Note that the evaluation of a <span class="RktSym"><a href="set_.html#%28form._%28%28quote._~23~25kernel%29._set%21%29%29" class="RktStxLink" data-pltdoc="x">set!</a></span>
|
||
|
expression with its subexpression is not necessarily atomic, because
|
||
|
evaluating the subexpression involves a separate step of evaluation.
|
||
|
Only the assignment action itself (which takes after the subexpression
|
||
|
is evaluated to obtain a value) is atomic. Similarly, a procedure
|
||
|
application can involve multiple steps that are not atomic, even if
|
||
|
the procedure itself performs an atomic action.</p><p>The <span class="RktSym"><a href="hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-set%21%29%29" class="RktValLink" data-pltdoc="x">hash-set!</a></span> procedure is not atomic, but the table is
|
||
|
protected by a lock; see <a href="hashtables.html" data-pltdoc="x">Hash Tables</a> for more information.
|
||
|
Port operations are generally not atomic, but they are thread-safe in
|
||
|
the sense that a byte consumed by one thread from an input port will
|
||
|
not be returned also to another thread, and procedures like
|
||
|
<span class="RktSym"><a href="Byte_and_String_Input.html#%28def._%28%28quote._~23~25kernel%29._port-commit-peeked%29%29" class="RktValLink" data-pltdoc="x">port-commit-peeked</a></span> and <span class="RktSym"><a href="Byte_and_String_Output.html#%28def._%28%28quote._~23~25kernel%29._write-bytes-avail%29%29" class="RktValLink" data-pltdoc="x">write-bytes-avail</a></span> offer
|
||
|
specific concurrency guarantees.</p><p>In addition to the state that is shared among all threads, each thread
|
||
|
has its own private state that is accessed through <a name="(tech._thread._cell)"></a><span style="font-style: italic">thread
|
||
|
cells</span>. A thread cell is similar to a normal mutable object, but a
|
||
|
change to the value inside a thread cell is seen only when extracting
|
||
|
a value from that cell in the same thread. A thread cell can be
|
||
|
<a name="(tech._preserved)"></a><span style="font-style: italic">preserved</span>; when a new thread is created, the creating
|
||
|
thread’s value for a preserved thread cell serves as the initial value
|
||
|
for the cell in the created thread. For a non-preserved thread cell, a
|
||
|
new thread sees the same initial value (specified when the thread cell
|
||
|
is created) as all other threads.</p><p><a href="futures.html#%28tech._future%29" class="techoutside" data-pltdoc="x"><span class="techinside">Futures</span></a> and <a href="places.html#%28tech._place%29" class="techoutside" data-pltdoc="x"><span class="techinside">places</span></a> offer different kinds of concurrency
|
||
|
and parallelism, and they have weaker guarantees about shared state.
|
||
|
(Places can share state through functions like
|
||
|
<span class="RktSym"><a href="bytestrings.html#%28def._%28%28quote._~23~25kernel%29._make-shared-bytes%29%29" class="RktValLink" data-pltdoc="x">make-shared-bytes</a></span>.) Each thread of evaluation in a future or
|
||
|
place is constrained to behave consistent with the possibility of some
|
||
|
other thread that might inspect any shared data starting at any point
|
||
|
that a future or place starts. In the case that two futures or two
|
||
|
places share state, each read or write operation to shared state
|
||
|
corresponds to a read or write operation at the virtual-memory level,
|
||
|
and the operations are constrained to the order they could be observed
|
||
|
or affected by a thread. However, Racket does not enforce additional
|
||
|
guarantees about reordering that might be performed at the
|
||
|
virtual-memory level or below, except in the case of operations that
|
||
|
specify such guarantees explicitly (e.g., <span class="RktSym"><a href="boxes.html#%28def._%28%28quote._~23~25kernel%29._box-cas%21%29%29" class="RktValLink" data-pltdoc="x">box-cas!</a></span>).</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""parameter-model"">1.1.13<tt> </tt><a name="(part._parameter-model)"></a>Parameters</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="parameters.html" data-pltdoc="x">Parameters</a> for parameter forms and functions.</p></blockquote></blockquote></blockquote><p><a name="(tech._parameter)"></a><span style="font-style: italic">Parameters</span> are essentially a derived concept in Racket; they
|
||
|
are defined in terms of <a href="eval-model.html#%28tech._continuation._mark%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation marks</span></a> and <a href="eval-model.html#%28tech._thread._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">thread
|
||
|
cells</span></a>. However, parameters are also “built in,” due to the fact that some
|
||
|
primitive procedures consult parameter values. For example, the
|
||
|
default output stream for primitive output operations is specified by
|
||
|
a parameter.</p><p>A parameter is a setting that is both thread-specific and
|
||
|
continuation-specific. In the empty continuation, each parameter
|
||
|
corresponds to a <a href="eval-model.html#%28tech._preserved%29" class="techoutside" data-pltdoc="x"><span class="techinside">preserved</span></a> <a href="eval-model.html#%28tech._thread._cell%29" class="techoutside" data-pltdoc="x"><span class="techinside">thread cell</span></a>; a corresponding
|
||
|
<a name="(tech._parameter._procedure)"></a><span style="font-style: italic">parameter procedure</span> accesses and sets the thread cell’s
|
||
|
value for the current thread.</p><p>In a non-empty continuation, a parameter’s value is determined through
|
||
|
a <a name="(tech._parameterization)"></a><span style="font-style: italic">parameterization</span> that is associated with the nearest
|
||
|
enclosing continuation frame via a continuation mark (whose key is
|
||
|
not directly accessible). A parameterization maps each parameter to a
|
||
|
preserved thread cell, and the combination of the thread cell and the current
|
||
|
thread yields the parameter’s value. A <a href="eval-model.html#%28tech._parameter._procedure%29" class="techoutside" data-pltdoc="x"><span class="techinside">parameter procedure</span></a> sets or
|
||
|
accesses the relevant thread cell for its parameter.</p><p>Various operations, such as <span class="RktSym"><a href="parameters.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._parameterize%29%29" class="RktStxLink" data-pltdoc="x">parameterize</a></span> or
|
||
|
<span class="RktSym"><a href="parameters.html#%28def._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._call-with-parameterization%29%29" class="RktValLink" data-pltdoc="x">call-with-parameterization</a></span>, install a parameterization into
|
||
|
the current continuation’s frame.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""exn-model"">1.1.14<tt> </tt><a name="(part._exn-model)"></a>Exceptions</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="exns.html" data-pltdoc="x">Exceptions</a> for exception forms, functions, and types.</p></blockquote></blockquote></blockquote><p><a name="(tech._exception)"></a><span style="font-style: italic">Exceptions</span> are essentially a derived concept in Racket; they
|
||
|
are defined in terms of continuations, prompts, and continuation
|
||
|
marks. However, exceptions are also “built in,” due to the fact that
|
||
|
primitive forms and procedures may raise exceptions.</p><p>An <a name="(tech._exception._handler)"></a><span style="font-style: italic">exception handler</span> to <a name="(tech._catch)"></a><span style="font-style: italic">catch</span> exceptions can be associated
|
||
|
with a continuation frame though a <a href="eval-model.html#%28tech._continuation._mark%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation mark</span></a> (whose key
|
||
|
is not directly accessible). When an exception is raised, the current
|
||
|
continuation’s marks determine a chain of <a href="eval-model.html#%28tech._exception._handler%29" class="techoutside" data-pltdoc="x"><span class="techinside">exception handler</span></a>
|
||
|
procedures that are consulted to handle the exception.
|
||
|
A handler for uncaught exceptions is designated through a built-in <a href="eval-model.html#%28tech._parameter%29" class="techoutside" data-pltdoc="x"><span class="techinside">parameter</span></a>.</p><p>One potential action of an <a href="eval-model.html#%28tech._exception._handler%29" class="techoutside" data-pltdoc="x"><span class="techinside">exception handler</span></a> is to abort the
|
||
|
current <a href="eval-model.html#%28tech._continuation%29" class="techoutside" data-pltdoc="x"><span class="techinside">continuation</span></a> up to an enclosing <a href="eval-model.html#%28tech._prompt%29" class="techoutside" data-pltdoc="x"><span class="techinside">prompt</span></a> with a
|
||
|
particular <a href="eval-model.html#%28tech._prompt._tag%29" class="techoutside" data-pltdoc="x"><span class="techinside">prompt tag</span></a>. The default handler for uncaught
|
||
|
exceptions, in particular, aborts to a particular tag for which a
|
||
|
prompt is always present, because the prompt is installed in the
|
||
|
outermost frame of the continuation for any new thread.</p><h5 x-source-module="(lib "scribblings/reference/reference.scrbl")" x-source-pkg="racket-doc" x-part-tag=""custodian-model"">1.1.15<tt> </tt><a name="(part._custodian-model)"></a>Custodians</h5><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><span class="imageleft"><img src="magnify.png" alt="+" width="24" height="24"/></span>See <a href="custodians.html" data-pltdoc="x">Custodians</a> for custodian functions.</p></blockquote></blockquote></blockquote><p>A <a name="(tech._custodian)"></a><span style="font-style: italic">custodian</span> manages a collection of threads,
|
||
|
<a href="file-ports.html#%28tech._file._stream._port%29" class="techoutside" data-pltdoc="x"><span class="techinside">file-stream ports</span></a>, TCP ports, <a href="tcp.html#%28tech._tcp._listener%29" class="techoutside" data-pltdoc="x"><span class="techinside">TCP listeners</span></a>, <a href="udp.html#%28tech._udp._socket%29" class="techoutside" data-pltdoc="x"><span class="techinside">UDP
|
||
|
sockets</span></a>, <a href="bytestrings.html#%28tech._byte._converter%29" class="techoutside" data-pltdoc="x"><span class="techinside">byte converters</span></a>, and <a href="places.html#%28tech._place%29" class="techoutside" data-pltdoc="x"><span class="techinside">places</span></a>. Whenever a thread, etc<span class="Sendabbrev">.</span>, is
|
||
|
created, it is placed under the management of the <a name="(tech._current._custodian)"></a><span style="font-style: italic">current
|
||
|
custodian</span> as determined by the <span class="RktSym"><a href="custodians.html#%28def._%28%28quote._~23~25kernel%29._current-custodian%29%29" class="RktValLink" data-pltdoc="x">current-custodian</a></span>
|
||
|
<a href="eval-model.html#%28tech._parameter%29" class="techoutside" data-pltdoc="x"><span class="techinside">parameter</span></a>.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Custodians also manage eventspaces from
|
||
|
<a href="https://download.racket-lang.org/releases/8.6/doc/local-redirect/index.html?doc=gui&rel=index.html&version=8.6" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">racket/gui/base</span></a>.</p></blockquote></blockquote></blockquote><p>Except for the root custodian, every <a href="eval-model.html#%28tech._custodian%29" class="techoutside" data-pltdoc="x"><span class="techinside">custodian</span></a> itself is
|
||
|
managed by a <a href="eval-model.html#%28tech._custodian%29" class="techoutside" data-pltdoc="x"><span class="techinside">custodian</span></a>, so that custodians form a hierarchy.
|
||
|
Every object managed by a subordinate custodian is also managed by the
|
||
|
custodian’s owner.</p><p>When a <a href="eval-model.html#%28tech._custodian%29" class="techoutside" data-pltdoc="x"><span class="techinside">custodian</span></a> is shut down via
|
||
|
<span class="RktSym"><a href="custodians.html#%28def._%28%28quote._~23~25kernel%29._custodian-shutdown-all%29%29" class="RktValLink" data-pltdoc="x">custodian-shutdown-all</a></span>, it forcibly and immediately closes
|
||
|
the ports, TCP connections, etc<span class="Sendabbrev">.</span>, that it manages, as well as
|
||
|
terminating (or suspending) its threads. A custodian that has been
|
||
|
shut down cannot manage new objects. After the current custodian is shut
|
||
|
down, if a procedure is called that attempts to create a managed resource (e.g.,
|
||
|
<span class="RktSym"><a href="file-ports.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._open-input-file%29%29" class="RktValLink" data-pltdoc="x">open-input-file</a></span>, <span class="RktSym"><a href="threads.html#%28def._%28%28quote._~23~25kernel%29._thread%29%29" class="RktValLink" data-pltdoc="x">thread</a></span>), then the
|
||
|
<span class="RktSym"><a href="exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail~3acontract%29%29" class="RktValLink" data-pltdoc="x">exn:fail:contract</a></span> exception is raised.</p><p>A thread can have multiple managing custodians, and a suspended thread
|
||
|
created with <span class="RktSym"><a href="threads.html#%28def._%28%28quote._~23~25kernel%29._thread%2Fsuspend-to-kill%29%29" class="RktValLink" data-pltdoc="x">thread/suspend-to-kill</a></span> can have zero
|
||
|
custodians. Extra custodians become associated with a thread through
|
||
|
<span class="RktSym"><a href="threads.html#%28def._%28%28quote._~23~25kernel%29._thread-resume%29%29" class="RktValLink" data-pltdoc="x">thread-resume</a></span> (see <a href="threads.html#%28part._threadkill%29" data-pltdoc="x">Suspending, Resuming, and Killing Threads</a>). When a thread
|
||
|
has multiple custodians, it is not necessarily killed by a
|
||
|
<span class="RktSym"><a href="custodians.html#%28def._%28%28quote._~23~25kernel%29._custodian-shutdown-all%29%29" class="RktValLink" data-pltdoc="x">custodian-shutdown-all</a></span>. Instead, shut-down custodians are removed
|
||
|
from the thread’s managing custodian set, and the thread is killed when its
|
||
|
managing set becomes empty.</p><p>The values managed by a custodian are semi-weakly held by the
|
||
|
custodian: a <a href="willexecutor.html#%28tech._will%29" data-pltdoc="x">will</a> can be executed for a value that is
|
||
|
managed by a custodian; in addition, weak references via weak
|
||
|
<a href="hashtables.html#%28tech._hash._table%29" class="techoutside" data-pltdoc="x"><span class="techinside">hash tables</span></a>, <a href="ephemerons.html#%28tech._ephemeron%29" class="techoutside" data-pltdoc="x"><span class="techinside">ephemerons</span></a>, or <a href="weakbox.html#%28tech._weak._box%29" class="techoutside" data-pltdoc="x"><span class="techinside">weak box</span></a>es can be
|
||
|
dropped on the <a href="implementations.html#%28tech._bc%29" class="techoutside" data-pltdoc="x"><span class="techinside">BC</span></a> implementation of Racket, but not on the <a href="implementations.html#%28tech._c%29" class="techoutside" data-pltdoc="x"><span class="techinside">CS</span></a>
|
||
|
implementation. For all variants, a custodian only weakly
|
||
|
references its subordinate custodians; if a subordinate custodian is
|
||
|
unreferenced but has its own subordinates, then the custodian may be
|
||
|
garbage collected, at which point its subordinates become immediately
|
||
|
subordinate to the collected custodian’s superordinate (owner) custodian.</p><p>In addition to the other entities managed by a custodian, a
|
||
|
<a name="(tech._custodian._box)"></a><span style="font-style: italic">custodian box</span> created with <span class="RktSym"><a href="custodians.html#%28def._%28%28quote._~23~25kernel%29._make-custodian-box%29%29" class="RktValLink" data-pltdoc="x">make-custodian-box</a></span>
|
||
|
strongly holds onto a value placed in the box until the box’s
|
||
|
custodian is shut down. However, the custodian only weakly retains the box
|
||
|
itself, so the box and its content can be collected if there
|
||
|
are no other references to them.</p><p>When Racket is compiled with support for per-custodian memory
|
||
|
accounting (see <span class="RktSym"><a href="custodians.html#%28def._%28%28quote._~23~25kernel%29._custodian-memory-accounting-available~3f%29%29" class="RktValLink" data-pltdoc="x">custodian-memory-accounting-available?</a></span>), the
|
||
|
<span class="RktSym"><a href="garbagecollection.html#%28def._%28%28quote._~23~25kernel%29._current-memory-use%29%29" class="RktValLink" data-pltdoc="x">current-memory-use</a></span> procedure can report a custodian-specific
|
||
|
result. This result determines how much memory is occupied by objects
|
||
|
that are <a href="eval-model.html#%28tech._reachable%29" class="techoutside" data-pltdoc="x"><span class="techinside">reachable</span></a> from the custodian’s managed values, especially its
|
||
|
threads, and including its sub-custodians’ managed values. If an
|
||
|
object is reachable from two custodians where neither is an ancestor
|
||
|
of the other, an object is arbitrarily charged to one or the other,
|
||
|
and the choice can change after each collection; objects reachable
|
||
|
from both a custodian and its descendant, however, are reliably
|
||
|
charged to the custodian and not to the descendants, unless the
|
||
|
custodian can reach the objects only through a descendant custodian or
|
||
|
a descendant’s thread. Reachability for per-custodian accounting does
|
||
|
not include weak references, references to threads managed by other
|
||
|
custodians, references to other custodians, or references to custodian
|
||
|
boxes for other custodians.</p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "8.6", "../");"/></form> <a href="https://docs.racket-lang.org/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="model.html" title="backward to "1 Language Model"" data-pltdoc="x">← prev</a> <a href="model.html" title="up to "1 Language Model"" data-pltdoc="x">up</a> <a href="syntax-model.html" title="forward to "1.2 Syntax Model"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html>
|