Doc: Initiate transition to next generation documentation
[shapes.git] / doc / parts / syntax / binding.sxml
blob9d13587ea2e4bbbbb35b8f874192ea8cc41531ac
1 <!-- This file is part of Shapes.                                           -->
2 <!--                                                                        -->
3 <!-- Shapes is free software: you can redistribute it and/or modify         -->
4 <!-- it under the terms of the GNU General Public License as published by   -->
5 <!-- the Free Software Foundation, either version 3 of the License, or      -->
6 <!-- any later version.                                                     -->
7 <!--                                                                        -->
8 <!-- Shapes is distributed in the hope that it will be useful,              -->
9 <!-- but WITHOUT ANY WARRANTY; without even the implied warranty of         -->
10 <!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          -->
11 <!-- GNU General Public License for more details.                           -->
12 <!--                                                                        -->
13 <!-- You should have received a copy of the GNU General Public License      -->
14 <!-- along with Shapes.  If not, see <http://www.gnu.org/licenses/>.        -->
15 <!--                                                                        -->
16 <!-- Copyright 2008 Henrik Tidefelt                                         -->
18 <section id="syntax/binding">
19 <title>Bindings and scoping</title>
20 <top>
21 <p><str-Shapes /> supports both lexical and dynamic bindings.  This section describe how to create such bindings, what their scopes are, and how to access the values of a binding.  Note that a binding can never be changed.</p>
22 </top>
24 <section id="syntax/binding/lexical">
25 <title>Lexical binding</title>
26 <body>
27 <p>A <em>lexical binding</em> is a variable whose definition can (easily) be found by a look at the source code.  Code brackets and functions play an essential role for the semantics here.</p>
29 <p>Lexical binding is perhaps most easily understood from an implementation point of view.  Whenever an expression is evaluated, the current lexical scope is defined by the <em>(lexical) environment</em>.  The environment has its own bindings, that is, mapping from some identifiers to values, and a parent environment (with the exception of the global environment, which has no parent).  When a lexical variable is evaluated, it is searched in the current environment, and if it is found, the variable evaluates to the value mapped to.  If the variable is not found, the search continues in the parent environment, and so forth.  If the search continues to the global environment, and fails there, it is an error; the variable is not bound.  To understand this process in more detail, one must understand where in the source code new environments are set up, and how they are populated with mappings from identifiers to values.</p>
31 <p>First, functions set up a new environment for the passed arguments when they are called.  The parent of the new environment is the environment that was in scope where the function was created (this is typically not the current environment where the function is called).  The body of the function is then evaluated in the new environment.  These rules simply ensure that the variables that were in scope were the function was created are also in scope when the body of the function is evaluated (except in case of shadowing).</p>
33 <p>A classic example of how lexical scoping works is the <user-value name="addn" /> function:
34 <pre>
35 <![CDATA[addn: \ n → \ x → x + n
36 inc: [addn '1]
37 •stdout << [inc '3]]]>
38 </pre>
39 </p>
40 <p>The above program prints the integer 4.  Note that <arg name="n" /> must be in scope when <inline>x + n</inline> is evaluated, even though <arg name="n" /> is not in scope where <user-value name="inc" /> is invoked.  What is important is that <arg name="n" /> is in scope where the function bound to <user-value name="inc" /> was created.</p>
42 <p>Second, every code bracket sets up a new environment, under the current environment.  The new environment is both home for bindings introduced in the code bracket, and becomes the current environment for the expressions evaluated in the code bracket.  This means that the following is a valid code bracket:
43 <pre>
44 <![CDATA[{
45   a: '1
46   b: a + '1
47   b
48 }]]>
49 </pre>
50 </p>
51 <p>So far, this seems similar to the semantics of <foreign lang="Scheme">let*</foreign> in Scheme.  However, the following code bracket is equivalent:
52 <pre>
53 <![CDATA[{
54   b: a + '1
55   a: '1
56   b
57 }]]>
58 </pre>
59   This reminds more of <foreign lang="Scheme">letrec</foreign> in Scheme, but the reason it works has another explanation: laziness.  The variables <user-value name="b" /> and <user-value name="a" /> are bound to thunks before the expression <user-value name="b" /> is evaluated.
60 </p>
62 <p>
63         It is possible to <em>reach out</em> from the current lexical scope to circumvent <em>shadowing</em> bindings.  The syntax for this is
64         <syntax-table>
65                 <tr> <td><syntax name="reach-out" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>"../"</lexerregexp> <syntax name="expr" /></td></tr>
66         </syntax-table>
67 </p>
69 <p>In theory, the semantics of this is simple; evaluate <syntax name="expr" /> in the lexical environment which is the parent of the current lexical environment.  However, sometimes a deeper understanding of the language is required to see how many generations one must walk up the chain of environments to avoid a given binding.  On the other hand, with this problem in mind, empty environments are never optimized away.</p>
71 <p>As an example of reach out, suppose we regret how we defined the paramter <arg name="depth" /> long time ago.  Now we have to live with it since our function is part of a library with many users which we don't want to bother with the off-by-one change that would make our implementation of the function more natural.  The following is not an option, since the function may be called with named arguments:</p>
72 <pre class="bad">
73 <![CDATA[\ off_by_one_depth →
74   {
75     depth: off_by_one_depth - '1
76     /**
77      ** Rest of body.
78      **/
79   }]]>
80 </pre>
81 <p>Of course, we could use a new name for the adjusted depth, but pretend we are really keen to use the name <arg name="depth" />.  Then we could use a reach-out:
82 <pre>
83 <![CDATA[\ depth →
84   {
85     /** Important!  We deal with the off-by-one mistake here, once and for all.
86      **/
87     depth: ../depth - '1
89     /**
90      ** Rest of body.
91      **/
92   }]]>
93 </pre>
94 </p>
95 <p>Note that this changes the binding for <user-value name="depth" /> in all of the code bracket, and hence it is a very good idea for readability to introduce the binding at the top of the code bracket.</p>
97 <example-with-output title="Example" internal-id="example:lex-scopes">
98 <source file="features/scopes.blank">
99 <![CDATA[<!--#include depth="0" virtual="$(BUILDDIR)$(EXAMPLES)features/scopes.blank" -->]]>
100 </source>
101 <stdout>
102 <![CDATA[<!--#include depth="0" virtual="$(BUILDDIR)$(EXAMPLES)features/scopes.stdout" -->]]>
103 </stdout>
104 <caption>
105         <p>Mutually recursive function definitions and reach-outs.</p>
106 </caption>
107 </example-with-output>
109 </body>
110 </section>
113 <section id="syntax/binding/dynamic">
114 <title>Dynamic binding</title>
115 <body>
116 <p>The value of a <em>dynamic binding</em> is determined by the current <em>dynamic environment</em> and cannot be determined by a simple lexical analysis.  The dynamic environment is changed by the special construct
117         <syntax-table>
118                 <tr> <td><syntax name="with-dynamic" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="DynamicBindings" /><bnf>&gt;</bnf> | <syntax name="expr" /></td></tr>
119         </syntax-table>
120         (Note that the vertical bar is not part of the BNF structure, but is the operator that indicates a change of dynamic scope.)
121 </p>
123 <p>The semantics is simply that a new dynamic environment is set up under the current dynamic environment, and populated with the provided bindings.  So far, except that the bindings are provided though special values instead of by using special syntax, this is how code brackets work.  The difference is when it comes to functions.  Calling a function <em>does not</em> change the dynamic environment.  One can think of dynamic variables as a way of passing parameters to functions without explicitly providing them as arguments; the dynamic environment is always passed implicitly.</p>
126         Dynamic bindings are constructed with the following syntax:
127         <syntax-table>
128                 <tr> <td><syntax name="dynamic-bindings" /></td> <td><bnf>::</bnf></td> <td><named-type name="DynamicBindings" /></td></tr>
129                 <tr> <td><syntax name="dynamic-binding" /></td> <td><bnf>::</bnf></td> <td><named-type name="DynamicBinding" /></td></tr>
130                 <tr> <td><syntax name="dynamic-bindings" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="DynamicBinding" /><bnf>&gt;</bnf></td></tr>
131                 <tr> <td></td> <td><bnf>|</bnf></td> <td><bnf>&lt;</bnf><named-type name="DynamicBindings" /><bnf>&gt;</bnf> <lexerregexp>&amp;</lexerregexp> <bnf>&lt;</bnf><named-type name="DynamicBindings" /><bnf>&gt;</bnf></td></tr>
132                 <tr> <td></td> <td><bnf>|</bnf></td> <td><bnf>&lt;</bnf><named-type name="DynamicBindings" /><bnf>&gt;</bnf> <lexerregexp>"&amp;|"</lexerregexp> <bnf>&lt;</bnf><named-type name="DynamicBindings" /><bnf>&gt;</bnf></td></tr>
133                 <tr> <td><syntax name="dynamic-binding" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="dyn-var" /> <lexerregexp>:</lexerregexp> <syntax name="expr" /></td></tr>
134                 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="dyn-var" /> <lexerregexp>:</lexerregexp> <lexerregexp>dynamic</lexerregexp> <syntax name="expr" /></td></tr>
135                 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="dyn-state" /> <lexerregexp>:</lexerregexp> <syntax name="state" /></td></tr>
136         </syntax-table>
137 </p>
140         If a dynamic variable is bound to a <em>dynamic expression</em>, this expression is re-evaluated in the current dynamic environment each time the dynamic variable is accessed.  This way, one dynamic variable can be defined relative another dynamic variable.  For instance:
141 <pre>
142 <![CDATA[dynamic @smallskip identity 2cm
143 dynamic @bigskip identity 5cm
144 test: \ •dst → { •dst << @bigskip << "{n} }
145 @bigskip : dynamic 4 * @smallskip
148   [test •stdout]
149   @smallskip:1cm | [test •stdout]
151 [test •stdout]]]>
152 </pre>
153 </p>
154 <p>The program prints <inline>8<unit>cm</unit></inline>, followed by <inline>4<unit>cm</unit></inline>, and finally <inline>5<unit>cm</unit></inline>.</p>
157         Dynamic variables are used extensively for controlling all parts of the graphics state.  For instance, if <user-value name="pth" /> is a path to be stroked, the color and width of the stroke can be set as follows:
158 <pre>
159 <![CDATA[•page << @stroking:rgb_RED & @width:2cm | [stroke pth]]]>
160 </pre>
161 or, if there are several paths to be stroked with the same pen:
162 <pre>
163 <![CDATA[  @stroking:rgb_RED
164 & @width:2cm
167   •page << [stroke pth1]
168   •page << [stroke pth2]
169 }]]>
170 </pre>
171 </p>
173 <example-with-output title="Example" internal-id="example:dyn-scopes">
174 <source file="features/dynamic.blank">
175 <![CDATA[<!--#include depth="0" virtual="$(BUILDDIR)$(EXAMPLES)features/dynamic.blank" -->]]>
176 </source>
177 <stdout>
178 <![CDATA[<!--#include depth="0" virtual="$(BUILDDIR)$(EXAMPLES)features/dynamic.stdout" -->]]>
179 </stdout>
180 <caption>
181         <p>Dynamic variables, dynamic expressions, and dynamic bindings.</p>
182 </caption>
183 </example-with-output>
185 </body>
186 </section>
188 </section><!-- end of syntax-binding -->