blob: 2efb8ab3b33eb8c46c83f9ee9745ba3d3ecfd754 [file] [log] [blame]
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Lazy functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="architecture.html">
<link rel="next" href="place_holders.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>Lazy functions</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="architecture.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="place_holders.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
When currying or partial function evaluation takes place, supplying N actual arguments to a function that expects M arguments where N &lt; M will result in a higher order function with M-N arguments. Technically, when N == M, the function has all the arguments needed to do a full evaluation:</p>
<code><pre>
<span class=identifier>plus</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=number>2</span><span class=special>) </span><span class=identifier>full </span><span class=identifier>evaluation
</span><span class=identifier>plus</span><span class=special>(?, </span><span class=number>6</span><span class=special>) </span><span class=identifier>partial </span><span class=identifier>evaluation
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> Lazy functions are subsets of partial function evaluation or currying </td>
</tr>
</table>
<p>
Now, we shall revisit the concept of lazy functions introduced before in passing. That is, the first function invocation will not really &quot;fully evaluate&quot; the function regardless if all or some of the arguments are supplied. A second function invocation will always be needed to perform the actual evaluation. At the point in the second call, the caller is expected to supply all arguments that are still missing. Still vague? To clarify, a partially evaluated function:</p>
<code><pre>
<span class=identifier>f</span><span class=special>(</span><span class=number>1</span><span class=special>, ?, ?)
</span></pre></code>
<p>
results to an unnamed function unnamed_f(a, b) that expects the two (2) more arguments that are still missing when the first function, f, is invoked. Since unnamed_f(a, b) is already a second level evaluation, all arguments must be supplied when it is called and the result is finally evaluated. Example:</p>
<code><pre>
<span class=identifier>f</span><span class=special>(</span><span class=number>1</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></pre></code>
<p>
then</p>
<code><pre>
<span class=identifier>unnamed_f</span><span class=special>(</span><span class=number>2</span><span class=special>, </span><span class=number>3</span><span class=special>) ---&gt; </span><span class=identifier>evaluate_and_return_value_for </span><span class=identifier>f</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></pre></code>
<p>
This function call sequence can be concatenated:</p>
<code><pre>
<span class=identifier>f</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></pre></code>
<p>
The second level function unnamed_f is not curryable. All of its still missing arguments must be supplied when it is called.</p>
<p>
As mentioned, even though we have all the arguments in the first call, the function is not yet evaluated (thus lazy). For example, a function call:</p>
<code><pre>
<span class=identifier>f</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></pre></code>
<p>
remember that the first function invocation will not really evaluate the function even if all the arguments are fully supplied. Thus:</p>
<code><pre>
<span class=identifier>f</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>) ---&gt; </span><span class=identifier>unnamed_f</span><span class=special>()
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <b>Generators</b><br><br>In FP, unnamed_f() is a generator; a function that has no arguments but returns a result. Not to be confused with Phoenix generators to be discussed later. </td>
</tr>
</table>
<p>
Then:</p>
<code><pre>
<span class=identifier>unnamed_f</span><span class=special>() ---&gt; </span><span class=identifier>evaluate_and_return_value_for </span><span class=identifier>f</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></pre></code>
<p>
This function call sequence can be concatenated as:</p>
<code><pre>
<span class=identifier>f</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></pre></code>
<p>
Lambda (unnamed) functions and currying (partial function evaluation) can also be applied to operators. However, unlike lazy functions, operators are fully evaluated once all the arguments are known and supplied, unless some sort of intervention is applied to coerce the operator expression to be lazily evaluated. We shall see more details on this and how this is done later.</p>
<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="architecture.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="place_holders.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>