Doc: Updating language definition to mirror the new and refined static analysis.
[shapes.git] / doc / parts / syntax / bracket.sxml
blob3791f76e8feb9cf70cb02f6145108971ce36015e
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/bracket">
19 <title>Code bracket</title>
20 <top>
21 <p>The code bracket is a rather complicated kind of expression.  It is the home of many program elements, and its sementics is defined to avoid unnecessary nesting of scoping constructs.  The general form is</p>
22 <syntax-table>
23 <tr> <td><syntax name="code-bracket" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>{</lexerregexp> <syntax name="bracket-item" /><bnf>*</bnf> <lexerregexp>}</lexerregexp></td></tr>
24 <tr> <td><syntax name="bracket-item" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="expr" /></td></tr>
25 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="variable-definition" /></td></tr>
26 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="split-definition" /></td></tr>
27 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="state-item" /></td></tr>
28 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="dynamic-variable-declaration" /></td></tr>
29 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="dynamic-state-declaration" /></td></tr>
30 </syntax-table>
32 <p>The top level semantics of the code brackets is defined by two phases.  In the first phase, all items in the bracket that can be evaluated at any time and without evaluation of sub-expressions, are evaluated.  This includes variable definitions whose right hand side can be delayed due to absence of free states.  (Any items with free states are excluded from this phase.)</p>
34 <p>In the second phase, the remaining items are evaluated in order of appearance.  The value of the last item is used as the value of the whole code bracket.</p>
36 <p>It is an error to place a pure expression (that is one which does not interact with states) anywhere but at the end of the code bracket.  It is also an error to let a non-pure expression return with a value other than at the end of the code bracket.  See <a id="syntax/misc-expr">expressions</a> for the details of pure and non-pure expressions.</p>
38 <p>Note that <syntax name="split-definition" /> was defined under <a id="syntax/compound/structures">structures</a>.</p>
39 </top>
41 <section id="syntax/bracket/var-def">
42 <title>Variable definitions</title>
43 <body>
44 <syntax-table>
45 <tr> <td><syntax name="variable-definition" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="identifier" /> <lexerregexp>:</lexerregexp> <syntax name="expr" /></td></tr>
46 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="identifier" /> <lexerregexp>:</lexerregexp> <syntax name="lex-state" /> <lexerregexp>;</lexerregexp></td></tr>
47 </syntax-table>
48 <p>The latter form is at the same time a kind of state item, and as such it is always evaluated in the second phase of the code bracket evaluation..</p>
50 <p>The semantics of the variable definitions is simple.  Bind the the variable to the value of expression, or freeze the state and bind to the final value of the state.  The former form is delayed unless the expression in the right hand side is immediate (see <a id="syntax/misc-expr/laziness">laziness control</a>) or has free states.</p>
51 </body>
52 </section>
54 <section id="syntax/bracket/state-items">
55 <title>State items</title>
56 <body>
57 <syntax-table>
58 <tr> <td><syntax name="state-item" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="lex-state" /> <lexerregexp>:</lexerregexp> <bnf>&lt;</bnf><named-type name="Hot" /><bnf>&gt;</bnf></td></tr>
59 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="state" /> <bnf>(</bnf> <lexerregexp>≪|"&lt;&lt;"</lexerregexp> <syntax name="expr" /> <bnf>)+</bnf>  </td></tr>
60 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="lex-state" /> <lexerregexp>;</lexerregexp></td></tr>
61 </syntax-table>
62 <p>The state items are always evaluated in order of appearance in the code bracket (note also the special kind of variable definition involving a state).</p>
64 <p>The first form introduces a state.  It requires a value of the special type <named-type name="Hot" /> in the right hand side.  Values of this type has the special ability to spawn fresh states.  Note that a value of type <named-type name="Hot" /> will always spawn identical fresh states, since being a <em>value</em> it has no internal state of its own.  On the other hand, it never spawns the <em>same</em> state twice, so each state it spawns lives its own life.</p>
66 <p>The second form modifies the state.  Note that states may also be modified by <a id="syntax/misc-expr">non-pure expressions</a>.  It evaluates the right hand side expressions in order of appearance, and lets the state <em>tack on</em> the resulting values.</p>
68 <p>The last form, denoted a <em>freeze</em>, prohibits future use of the state, and evaluates to the final value of the state.  It is used as the end of a code bracket to return the accumulated value of a sequential computation.</p>
70 <p>A related concept is to <em>peek</em> a state.  This <em>should</em> result in the same value that would be obtained if the state was frozen.  However, it does not have to obey this rule.  In addition, not all states allow the peek operation for efficiency reasons — peeking would involve an expensive deep copy in some cases.  Other types of states may be possible to peek, but not to freeze.  Also note that peeking a state may <em>poke</em> it at the same time, that is, peeking may have side effects on the state, so two consecutive peeks need not result in the same value. The syntax is:
71         <syntax-table>
72                 <tr> <td><syntax name="peek-state" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>"("</lexerregexp> <syntax name="state" /> <lexerregexp>")"</lexerregexp></td></tr>
73         </syntax-table>
74         Note that a <syntax name="state" /> without surrounding parentheses is not an expression, and can only appear as part of a few constructs.
75 </p>
76 <p>Peeking a state, as well as the tack-on and freeze operations described above, are special cases of <em>mutator calls</em>.  Ordinary mutator calls (that is, without dedicated syntax), are similar to calls to non-pure functions.  Recall that state arguments can not be bound with curry.  For the same reason, there is no such thing as a <em>mutator value</em>; instead, when a mutator on a state is selected, it must be immediately applied.  The syntax is simple:
77         <syntax-table>
78                 <tr> <td><syntax name="mutator-call" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="state" /> <lexerregexp>"."</lexerregexp> <lexerregexp>"["</lexerregexp> <syntax name="identifier" /> <bnf>(</bnf> <syntax name="arg-item" /> <bnf>|</bnf> <syntax name="state-item" /> <bnf>)*</bnf> <lexerregexp>"]"</lexerregexp></td></tr>
79         </syntax-table>
80         Evaluation of a <syntax name="mutator-call" /> is just like an application of a non-pure function (denoted by the <syntax name="identifier" />) stored in the state, with the state itself prepended to the list of arguments.
81 </p>
82 <p>Note that while tack-on and peek could have been provided (although less conveniently) as ordinary mutators, the freeze operation has a side effect which ordinary mutators should not have; the freeze operation should release all resources used by the state, and any later references to the state are illegal.</p>
83 <note>
84         <p>The important thing to realize about mutator calls is that it would break semantics if a mutator could be accessed like a field of the state.  To illustrate this, imagine that there was a method called <varname>peek</varname>, which we could apply like this:
85 <pre class="bad">
86 <![CDATA[•rnd: [newRandom (•time)]
87 rnd1: [•rnd.peek]]]>
88 </pre>
89 The problem is that this suggests that <inline>•rnd.peek</inline> is an expression, but expressions must evaluate to values — not states!  The following makes it clear that breaking the fundamental semantic rules would be very confusing:
90 <pre class="bad">
91 <![CDATA[•rnd: [newRandom (•time)]
92 mutator: •rnd.peek
93 rnd1: [mutator]
94 rnd2: [mutator]]]>
95 </pre>
96 Here, it looks as if <inline>mutator</inline> was a reference to an ordinary function, which should result in the same value both times it is being invoked.</p>
97 <p>
98         The correct way of writing (if there was a mutator called <varname>peek</varname>) is:
99 <pre>
100 <![CDATA[•rnd: [newRandom (•time)]
101 rnd1: •rnd.[peek]
102 rnd2: •rnd.[peek]]]>
103 </pre>
104 The presence of <inline>•rnd</inline> in each mutator call makes it clear that the state may be modified by each call.  Now, it is clear that a new random number may result in each call.
105 </p>
107         Of course, the mutator in this example refers to the special syntax <syntax name="peek-state" />, so while the example above would not compile, the following would:
108 <pre>
109 <![CDATA[•rnd: [newRandom (•time)]
110 rnd1: (•rnd)
111 rnd2: (•rnd)]]>
112 </pre>
113 </p>
114 </note>
115 </body>
116 </section>
118 <section id="syntax/bracket/dyn-decl">
119 <title>Dynamic declarations</title>
120 <body>
121 <syntax-table>
122 <tr> <td><syntax name="dynamic-variable-declaration" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>dynamic</lexerregexp> <syntax name="dyn-var" /> <bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <syntax name="expr" /></td></tr>
123 <tr> <td></td> <td><bnf>|</bnf></td> <td><lexerregexp>dynamic</lexerregexp> <syntax name="dyn-var" /> <bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <lexerregexp>dynamic</lexerregexp> <syntax name="expr" /></td></tr>
124 </syntax-table>
125 <p>To declare a dynamic variable one needs to provide a <em>filter</em> and a top level value.  The filter is applied to each new value the dynamic variable is bound to, and is primarily indended for type and range checks, but may also be used to transform values before they are actually bound.  The filter must be a function of one argument.  The top level value is the value of the dynamic variable until it is changed further down in the dynamic environment.  The top level value is <em>not</em> passed through the filter.  The evaluation of the top level value is delayed, which has some nice applications.</p>
127 <p>A dynamic variable may also be bound to a dynamic expression at the top level, and this is obtained using the second form of the declaration.</p>
130         Typical dynamic variable declarations may not care about the possibility to use the filter for type and range checks, and look like this:
131 <pre>
132 dynamic @tex_bbox_grow_abs identity 1bp
133 dynamic @tex_bbox_grow_rel identity 1.01
134 </pre>
135 </p>
137         A simple filter could look like this:
138 <pre>
139 <![CDATA[dynamic @tex_bbox_grow_rel
140   \ new →
141     [if not [typeof new].isa[]Float
142       [error `Type mismatch for @tex_bbox_grow_rel: required a Float.´]
143       [if new ≤ 0
144         [error `Out of range error for @tex_bbox_grow_rel: required a positive value.´]
145         new]]
146   1.01]]>
147 </pre>
148 </p>
151         Dynamic states would be a language feature with subtleties.  It is not part of the language at this time, but there is a dedicated syntax:
152         <syntax-table>
153                 <tr> <td><syntax name="dynamic-state-declaration" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>dynamic</lexerregexp> <syntax name="dyn-state" /> <syntax name="state" /></td></tr>
154         </syntax-table>
155 </p>
156 </body>
157 </section>
159 </section><!-- end of syntax-bracket -->