spirit/classic/phoenix/doc/place_holders.html
Joel de Guzman 994d4e48cc moving stuff to classic spirit
[SVN r44163]
2008-04-10 23:51:31 +00:00

99 lines
9.4 KiB
HTML

<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Place holders</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="lazy_functions.html">
<link rel="next" href="polymorphic_functions.html">
</head>
<body>
<table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
<tr>
<td width="10">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Place holders</b></font>
</td>
<td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="lazy_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="polymorphic_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
So far, apart from the quick start appetizer, we presented some examples of lazy functions using the ? symbol to act as a placeholder for yet unsupplied arguments. While this is understandable and simple, it is not adequate when we are dealing with complex composition of functions in addition to binary infix, unary prefix and postfix operators.</p>
<p>
When an arbitrarily complex function composition has M-N = U unsupplied arguments, the ? symbol maps this onto the actual non- lazy function taking U arguments. For example:</p>
<code><pre>
<span class=identifier>f1</span><span class=special>(</span><span class=identifier>f2</span><span class=special>(?, </span><span class=number>2</span><span class=special>), </span><span class=identifier>f3</span><span class=special>(?, </span><span class=identifier>f4</span><span class=special>(?))) --&gt; </span><span class=identifier>unnamed_f</span><span class=special>(</span><span class=identifier>a</span><span class=special>, </span><span class=identifier>b</span><span class=special>, </span><span class=identifier>c</span><span class=special>)
</span></pre></code>
<p>
Since there is only 1 supplied argument (N) and we are expecting 4 arguments (M), hence U = 3.</p>
<p>
It might not be immediately apparent how mapping takes place. It can naively be read from left to right; the first ? in our example maps to a, the second to b, and the last ? maps to c. Yet for even more complex compositions possibly with operators added in the mix, this becomes rather confusing. Also, this is not so flexible: in many occassions, we want to map two or more unknown arguments to a single place-holder.</p>
<p>
To avoid confusion, rather than using the ? as a symbol for unsupplied arguments, we use a more meaningful and precise representation. This is realized by supplying a numeric representation of the actual argument position (1 to N) in the resulting (right hand) function. Here's our revised example using this scheme:</p>
<code><pre>
<span class=identifier>f1</span><span class=special>(</span><span class=identifier>f2</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=number>2</span><span class=special>), </span><span class=identifier>f3</span><span class=special>(</span><span class=identifier>arg2</span><span class=special>, </span><span class=identifier>f4</span><span class=special>(</span><span class=identifier>arg3</span><span class=special>))) --&gt; </span><span class=identifier>unnamed_f</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg2</span><span class=special>, </span><span class=identifier>arg3</span><span class=special>)
</span></pre></code>
<p>
Now, arg1, arg2 and arg3 are used as placeholders instead of ?. Take note that with this revised scheme, we can now map two or more unsupplied arguments to a single actual argument. Example:</p>
<code><pre>
<span class=identifier>f1</span><span class=special>(</span><span class=identifier>f2</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=number>2</span><span class=special>), </span><span class=identifier>f3</span><span class=special>(</span><span class=identifier>arg2</span><span class=special>, </span><span class=identifier>f4</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>))) --&gt; </span><span class=identifier>unnamed_f</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg2</span><span class=special>)
</span></pre></code>
<p>
Notice how we mapped the leftmost and the rightmost unnamed argument to arg1. Consequently, the resulting (right hand) function now expects only two arguments (arg1 and arg2) instead of three. Here are some interesting snippets where this might be useful:</p>
<code><pre>
<span class=identifier>plus</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg1</span><span class=special>) --&gt; </span><span class=identifier>mult_2</span><span class=special>(</span><span class=identifier>x</span><span class=special>)
</span><span class=identifier>mult</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg1</span><span class=special>) --&gt; </span><span class=identifier>square</span><span class=special>(</span><span class=identifier>x</span><span class=special>)
</span><span class=identifier>mult</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>mult</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg1</span><span class=special>)) --&gt; </span><span class=identifier>cube</span><span class=special>(</span><span class=identifier>x</span><span class=special>)
</span></pre></code>
<a name="extra_arguments"></a><h2>Extra arguments</h2><p>
In C and C++, a function can have extra arguments that are not at all used by the function body itself. For instance, call-back functions may provide much more information than is actually needed at once. These extra arguments are just ignored.</p>
<p>
Phoenix also allows extra arguments to be passed. For example, recall our original add function:</p>
<code><pre>
<span class=identifier>add</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg2</span><span class=special>)
</span></pre></code>
<p>
We know now that partially evaluating this function results to a function that expects 2 arguments. However, the framework is a bit more lenient and allows the caller to supply more arguments than is actually required. Thus, our partially evaluated plus(arg1, arg2) function actually allows 2 *or more* arguments to be passed in. For instance, with:</p>
<code><pre>
<span class=identifier>add</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg2</span><span class=special>)(</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>, </span><span class=number>3</span><span class=special>)
</span><span class=identifier>the </span><span class=identifier>third </span><span class=identifier>argument </span><span class=literal>'3' </span><span class=identifier>is </span><span class=identifier>merely </span><span class=identifier>ignored</span><span class=special>.
</span></pre></code>
<p>
Taking this further, in-between arguments may even be ignored. Example:</p>
<code><pre>
<span class=identifier>add</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>, </span><span class=identifier>arg5</span><span class=special>)(</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>, </span><span class=number>3</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>5</span><span class=special>)
</span></pre></code>
<p>
Here, arguments 2, 3, and 4 are ignored. The function add just takes in the first argument (arg1) and the fifth argument (arg5). The result is of course six (6).</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> <b>Strict Arity</b><br><br>There are a few reasons why enforcing strict arity is not desireable. A case in point is the callback function. Typical callback functions provide more information than is actually needed. Lambda functions are often used as callbacks. </td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="lazy_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="polymorphic_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br>
<br>
<font size="2">Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt) </font> </p>
</body>
</html>