Fix doc toc misses
[shapes.git] / doc / parts / syntax / functions.sxml
blobde54ab46172d8a4ea4f22f16a2a1731110ef77af
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, 2010 Henrik Tidefelt                                   -->
18 <section id="syntax/fun-apply">
19 <title>Function application and evaluated cuts</title>
20 <top>
21 <p>The basic syntax for applying (or <em>calling</em>) functions is borrowed from the Scheme language.  However, there is a predefined set of operators with fixed priorities that allow exceptions to this rule.  In addition, special syntax is used when a function is applied over a structure, and there is syntactic sugar for calling functions of just one argument.  A similar operation to calling a function is to define a new function by providing values for only some of the arguments — this is referred to as an <a href="http://srfi.schemers.org/srfi-26/srfi-26.html"><em>evaluated cut</em></a>.</p>
22 </top>
24 <section id="syntax/fun-apply/basic">
25 <title>Basic function application</title>
26 <body>
27 <p>
28         Besides ordinary functions, there are some other objects which the function calling syntax accepts.  The other possible types of objects are affine transforms (which <em>should</em> behave just as functions of a single geometric object), and paths (which can accept a path time or an arctime).  The general form of a function application is
29         <syntax-table>
30                 <tr> <td><syntax name="basic-call" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>"["</lexerregexp> <bnf>&lt;</bnf><named-type name="Applicable" /><bnf>&gt;</bnf> <bnf>(</bnf> <syntax name="arg-item" /> <bnf>|</bnf> <syntax name="state-item" /> <bnf>)*</bnf> <lexerregexp>"]"</lexerregexp></td></tr>
31                 <tr> <td><syntax name="arg-item" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="expr" /> <bnf>|</bnf> <syntax name="named-expr" /></td></tr>
32                 <tr> <td><syntax name="named-expr" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="identifier" /> <lexerregexp>:</lexerregexp> <syntax name="expr" /></td></tr>
33                 <tr> <td><syntax name="state-item" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="state" /> <bnf>|</bnf> <syntax name="named-state" /></td></tr>
34                 <tr> <td><syntax name="named-state" class="new" /></td> <td><bnf>→</bnf></td> <td><syntax name="identifier" /> <lexerregexp>:</lexerregexp> <syntax name="state" /></td></tr>
35                 <tr> <td><named-type name="Applicable" /></td> <td><bnf>=</bnf></td> <td><union-type><named-type name="Function" /><named-type name="AffineTransform" /><named-type name="Path" /></union-type></td> </tr>
36         </syntax-table>
37 </p>
39 <p>The syntax <syntax name="arg-item" /> and <syntax name="state-item" /> defined above can each be either <em>ordered</em> (that is, not named) or <em>named</em>, but there is a rule for how these may be ordered.  The rule exist to avoid confusing situations; not because it is necessary to define the semantics.  The rule is that ordered arguments (represented by <syntax name="expr" />) must go before named arguments (represented by <syntax name="named-expr" />), and ordered states (represented by <syntax name="state" />) before named states (represented by <syntax name="named-state" />).</p>
41 <note>
42         <p>Of the conceivable semantics that could be defined if named arguments were allowed to appear before ordered arguments were allowed, two will be ruled out here.  First, one could simply ignore the order of appearance, and treat all named arguments just as if they appeared after the ordered arguments.  This would obscure the actual position of ordered arguments without adding any power to the language.  Second, one could add some power to the language by interpreting the position of ordered arguments in view of what unbound arguments there are, given the named and ordered arguments seen so far in a left to right scan.  However, such semantics would also obscure the actual position of ordered arguments severely.</p>
43 </note>
45 <p>Arguments and states may appear in any order, since they do not interact at all.</p>
47 <p>It is not allowed to specify the same argument or state more than once by name.</p>
49 <p>Recall that the formal parameters of a function is an ordered list where each element has a name (with some exceptions).  To define the semantics of a function call, it must be described how items in the application is mapped to formal parameters.  Let us first consider the passing of arguments (as opposed to states).  First, the ordered arguments in the application are mapped to the corresponding positions in the list of formal parameters.  Then, the formal parameters which have not been specified by ordered arguments may be addressed by named arguemnts.  Finally, default values are used for formal parameters which are still unassigned.  It is an error if an unassigned formal parameter has no default value.</p>
51 <p>It is an error if there are too many arguments or if a named argument does not match the name of any formal parameter, unless the function has a sink.</p>
53 <p>The semantics for passing states is analogous to that of passing arguments.</p>
55 <p>The evaluation of argument expressions is typically delayed by passing a thunk instead of a value unless one of the following conditions hold:
56         <ul>
57                 <li>the argument expression is immediate</li>
58                 <li>the corresponding formal parameter requires the argument to be forced</li>
59         </ul>
60   (Most elementary functions in the kernel will require all their arguments to be forced, while user-defined functions only take thunks by default.)</p>
61 <p>If a state is passed as a state to a non-pure function, it may not be free in a non-immediate argument expression of the same call — it must be clear from the call expression that the argument expression where the state is free will be evaluated before the function is called.</p>
62 <note>
63         <p>Delaying the evaluation of argument expressions with free states could lead to some very strange behavior if the same state is also passed as a state argument; consider the following example:
64 <pre>
65 <![CDATA[f: \ •dst img → ( [[shift (~1cm,0cm)] (•dst)] & img & [[shift (1cm,0cm)] (•dst)] )
66 •tmp: newGroup
67 •tmp << [stroke [circle 3mm]]
68 •page << [f •tmp { •tmp << [[shift (0cm,1cm)] [stroke [circle 2mm]]]  (•tmp) }]]]>
69 </pre>
70 Here, looking at the definition of <inline>f</inline>, you would expect that the program produce one two shifted copies of <inline>(•dst)</inline> and one copy of <inline>img</inline>.  However, the accessing of <inline>img</inline> would change the result of <inline>(•dst)</inline> if the expression for <inline>img</inline> would not have been evaluated before the application of <inline>f</inline>.
71 </p>
72         <p>On the other hand, delaying the evaluation of argument expressions with free states is exactly what one would expect in other situations.  For instance,
73 <pre>
74 <![CDATA[[if false { •page << [stroke [circle 1cm]] } { •page << [stroke [rotate 45°][][rectangle (~1cm,~1cm) (1cm,1cm)]] }]]]>
75 </pre>
76 Here, one would certainly not expect <em>both</em> the circle and the rectangle to appear on the page.
77         </p>
78         <p>Clearly, both problems would be avoided by implicitly making immediate any argument expression with a free state that is also passed as state.  However, it is thought to add valuable clarity to programs to require that the mark for immediate evaluation is written out explicitly.</p>
79 </note>
80 </body>
81 </section>
83 <section id="syntax/fun-apply/unary">
84 <title>Unary function application</title>
85 <body>
86 <p>
87         To apply a function to a single argument, one may use either of
88         <syntax-table>
89                 <tr> <td><syntax name="unary-call" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="Applicable" /><bnf>&gt;</bnf> <lexerregexp>"[]"</lexerregexp> <syntax name="expr" /></td></tr>
90                 <tr> <td></td> <td><bnf>|</bnf></td> <td><syntax name="expr" /> <lexerregexp>(≫|"&gt;&gt;")</lexerregexp> <bnf>&lt;</bnf><named-type name="Applicable" /><bnf>&gt;</bnf></td></tr>
91         </syntax-table>
92         Note that the <operator name="[]"/> must be written as a single token without whitespace between the brackets.  There is no corresponding sugar for passing states.
93 </p>
95 <p>Both operators are left associative, and have equal precedence.  Use the <operator name="[]"/> when applying hard-wired curry functions:
96 <pre>
97 <![CDATA[fun: \ a → \ b → 10 * a + b
98 fun [] 2 [] 1]]>
99 </pre>
100 and use <operator name="≫"/> when applying a chain of unary functions:
101 <pre>
102 <![CDATA[•world << [cicle 1cm] >> stroke >> immerse >> [Geometry3D..rotate dir:(1,1,1) angle:15°]*[shift (2cm,0cm,0cm)]]]>
103 </pre>
104 </p>
105 <p>When neither is the intention to obtain curried looks nor has the chain of functions more than one function, the choice becomes a matter of taste.  Although messy, the following would still work:
106 <pre>
107 <![CDATA[•world << stroke [] [cicle 1cm] >> immerse >> [Geometry3D..rotate dir:(1,1,1) angle:15°]*[shift (2cm,0cm,0cm)]]]>
108 </pre>
109 </p>
110 </body>
111 </section>
113 <section id="syntax/fun-apply/structures">
114 <title>Structures in function application</title>
115 <body>
117         Structures are special values that contain ordered as well as named components.  Applying a function to a structure has the same semantics as if the ordered and named components were split in a basic function application.  The syntax for calling a function with a structure is:
118         <syntax-table>
119                 <tr> <td><syntax name="split-call" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="Applicable" /><bnf>&gt;</bnf> <lexerregexp>"[]"</lexerregexp> <lexerregexp>&lt;&gt;</lexerregexp> <bnf>&lt;</bnf><named-type name="Structure" /><bnf>&gt;</bnf></td></tr>
120         </syntax-table>
121         Note that the <inline>[]</inline> and <inline>&lt;&gt;</inline> must each be written as a single token without whitespace.
122 </p>
123 </body>
124 </section>
126 <section id="syntax/fun-apply/cute-basic">
127 <title>Basic evaluated cuts</title>
128 <body>
130         The syntax for the basic evaluated cut is simple:
131         <syntax-table>
132                 <tr> <td><syntax name="basic-cute" class="new" /></td> <td><bnf>→</bnf></td> <td><lexerregexp>"["</lexerregexp> <bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <syntax name="expr" /><bnf>*</bnf> <syntax name="named-expr" /><bnf>*</bnf> <lexerregexp>"..."</lexerregexp> <lexerregexp>"]"</lexerregexp></td></tr>
133         </syntax-table>
134 </p>
136 <p>Note that states cannot be bound in evaluated cuts, since this would store a reference to the state in a manner that does not match a functional language.  Also note that, as in function application, ordered arguments must be passed before named arguments.</p>
138 <p>The semantics of the evaluated cut may not be quite as everone expects.  Ordered arguments are simply mapped to the corresponding positions in the callee's list of formal parameters, and are bound without possibility to override in the evaluated cut.  Named arguments, however, are not actually bound to the addressed formal parameters, but only assigns (or replaces) the default value for that parameter.  Hence, named arguments in the evaluated cut are possible to override.</p>
140 <p>Note that it is a bad idea to use ordered arguments with a function whose list of formal parameters is unavailable for inspection.  It is such a bad idea that it would be pointless at best to allow named arguments to bind permanentally to a formal parameter in an evaluated cut, since the use of this would be to change the positions of ordered arguments in an obscure way.</p>
141 </body>
142 </section>
144 <section id="syntax/fun-apply/cute-unary">
145 <title>Unary evaluated cuts</title>
146 <body>
148         The following allows evaluated cuts to be constructed as easy as an unary function application:
149         <syntax-table>
150                 <tr> <td><syntax name="unary-cute" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <lexerregexp>"[...]"</lexerregexp> <syntax name="expr" /></td></tr>
151                 <tr> <td></td> <td><bnf>|</bnf></td> <td><bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <lexerregexp>"[...]"</lexerregexp> <syntax name="named-expr" /></td></tr>
152         </syntax-table>
153         Note that the <operator name="[...]" /> must be written as a single token without whitespace.
154 </p>
155 </body>
156 </section>
158 <section id="syntax/fun-apply/cute-structure">
159 <title>Structures and evaluated cuts</title>
160 <body>
162         The syntax to use a structure for an evaluated cut is
163         <syntax-table>
164                 <tr> <td><syntax name="split-cute" class="new" /></td> <td><bnf>→</bnf></td> <td><bnf>&lt;</bnf><named-type name="Function" /><bnf>&gt;</bnf> <lexerregexp>"[...]"</lexerregexp> <lexerregexp>&lt;&gt;</lexerregexp> <bnf>&lt;</bnf><named-type name="Structure" /><bnf>&gt;</bnf></td></tr>
165         </syntax-table>
166 </p>
167 </body>
168 </section>
170 <section id="syntax/fun-apply/mutator-caller">
171 <title>Mutator-callers</title>
172 <body>
173         <p><em>This section assumes that the reader is familiar with <syntax name="code-bracket" />.</em></p>
174         <p>Since mutators are not values in <str-Shapes />, they cannot be used in evaluated cuts in the same way as functions.  However, there is sometimes a need to create a function which takes just one state argument, and invokes a mutator on that state when called.</p>
175         <p>For instance, suppose <inline>newMap</inline> spawns a state that is used to build up a key-value map.  New key-value pairs are inserted into the state using its mutator <inline>insert</inline>, as in the following example:
176 <pre>
177 <![CDATA[•map: newMap
178 •map.[insert '1 `One´]
179 •map.[insert '10 `Ten´]
180 •map.[insert 'a `A symbol´]
181 map: freeze •map]]>
182 </pre>
183 We could get the same result without introducing the state <inline>•map</inline> explicitly (recall <syntax name="unnamed-state-expr" />),
184 <pre>
185 <![CDATA[map: ( newMap
186        << >> \ •tmp → •tmp.[insert '1 `One´]
187        << >> \ •tmp → •tmp.[insert '10 `Ten´]
188        << >> \ •tmp → •tmp.[insert 'a `A symbol´]
189      )]]>
190 </pre>
191 but the amount of notation used here is just too much.  To support the use of unnamed states in this situation, <str-Shapes /> defines a syntactic sugar which allows the repeated “<inline>\ •tmp → •tmp</inline>” to be removed:
192         <syntax-table>
193                 <tr> <td><syntax name="mutator-caller" class="new" /></td> <td><bnf>→</bnf></td> <td><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>
194         </syntax-table>
195 </p>
197         Using the syntactic sugar, the code above simplifies to
198 <pre>
199 <![CDATA[map: ( newMap
200        << >>.[insert '1 `One´]
201        << >>.[insert '10 `Ten´]
202        << >>.[insert 'a `A symbol´]
203      )]]>
204 </pre>
205 which is almost as compact as the first formulation.  At the same time, it has the advantage that it is clear that the construct is free of side effects since it does not even mention a state.  (The other two require more careful analysis to check whether the referred states are local to the construct or not.)
206 </p>
207 </body>
208 </section>
210 </section><!-- end of syntax-fun-apply -->