summaryrefslogtreecommitdiff
path: root/libs/phoenix/doc/html/phoenix/basics.html
blob: ed7a403faa3ce3a6de948db78df19a84d921871e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Basics</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Phoenix 3.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Phoenix 3.0">
<link rel="prev" href="starter_kit/more.html" title="More">
<link rel="next" href="organization.html" title="Organization">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="starter_kit/more.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="organization.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="phoenix.basics"></a><a class="link" href="basics.html" title="Basics">Basics</a>
</h2></div></div></div>
<p>
      Almost everything is a function in the Phoenix library that can be evaluated
      as <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...,</span> a/n/<span class="special">)</span></code>, where <span class="emphasis"><em>n</em></span> is the function's
      arity, or number of arguments that the function expects. Operators are also
      functions. For example, <code class="computeroutput"><span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span></code> is just
      a function with arity == 2 (or binary). <code class="computeroutput"><span class="identifier">a</span>
      <span class="special">+</span> <span class="identifier">b</span></code>
      is the same as <code class="computeroutput"><span class="identifier">add</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code>, <code class="computeroutput"><span class="identifier">a</span>
      <span class="special">+</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span></code> is the
      same as <code class="computeroutput"><span class="identifier">add</span><span class="special">(</span><span class="identifier">add</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></code>.
    </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
        Amusingly, functions may even return functions. We shall see what this means
        in a short while.
      </p></td></tr>
</table></div>
<h4>
<a name="phoenix.basics.h0"></a>
      <span><a name="phoenix.basics.partial_function_application"></a></span><a class="link" href="basics.html#phoenix.basics.partial_function_application">Partial
      Function Application</a>
    </h4>
<p>
      Think of a function as a black box. You pass arguments and it returns something
      back. The figure below depicts the typical scenario.
    </p>
<p>
      <span class="inlinemediaobject"><img src="../images/fbox.png" alt="fbox"></span>
    </p>
<p>
      A fully evaluated function is one in which all the arguments are given. All
      functions in plain C++ are fully evaluated. When you call the <code class="computeroutput"><span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code> function, you have to pass a number x. The
      function will return a result in return: the sin of x. When you call the <code class="computeroutput"><span class="identifier">add</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span></code>
      function, you have to pass two numbers x and y. The function will return the
      sum of the two numbers. The figure below is a fully evaluated <code class="computeroutput"><span class="identifier">add</span></code> function.
    </p>
<p>
      <span class="inlinemediaobject"><img src="../images/adder.png" alt="adder"></span>
    </p>
<p>
      A partially applied function, on the other hand, is one in which not all the
      arguments are supplied. If we are able to partially apply the function <code class="computeroutput"><span class="identifier">add</span></code> above, we may pass only the first argument.
      In doing so, the function does not have all the required information it needs
      to perform its task to compute and return a result. What it returns instead
      is another function, a lambda function. Unlike the original <code class="computeroutput"><span class="identifier">add</span></code>
      function which has an arity of 2, the resulting lambda function has an arity
      of 1. Why? because we already supplied part of the input: <code class="computeroutput"><span class="number">2</span></code>
    </p>
<p>
      <span class="inlinemediaobject"><img src="../images/add2.png" alt="add2"></span>
    </p>
<p>
      Now, when we shove in a number into our lambda function, it will return 2 plus
      whatever we pass in. The lambda function essentially remembers 1) the original
      function, <code class="computeroutput"><span class="identifier">add</span></code>, and 2) the partial
      input, 2. The figure below illustrates a case where we pass 3 to our lambda
      function, which then returns 5:
    </p>
<p>
      <span class="inlinemediaobject"><img src="../images/add2_call.png" alt="add2_call"></span>
    </p>
<p>
      Obviously, partially applying the <code class="computeroutput"><span class="identifier">add</span></code>
      function, as we see above, cannot be done directly in C++ where we are expected
      to supply all the arguments that a function expects. That's where the Phoenix
      library comes in. The library provides the facilities to do partial function
      application. And even more, with Phoenix, these resulting functions won't be
      black boxes anymore.
    </p>
<h4>
<a name="phoenix.basics.h1"></a>
      <span><a name="phoenix.basics.stl_and_higher_order_functions"></a></span><a class="link" href="basics.html#phoenix.basics.stl_and_higher_order_functions">STL
      and higher order functions</a>
    </h4>
<p>
      So, what's all the fuss? What makes partial function application so useful?
      Recall our original example in the <a class="link" href="starter_kit/lazy_operators.html" title="Lazy Operators">previous
      section</a>:
    </p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">find_if</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">end</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="number">1</span><span class="special">)</span>
</pre>
<p>
      The expression <code class="computeroutput"><span class="identifier">arg1</span> <span class="special">%</span>
      <span class="number">2</span> <span class="special">==</span> <span class="number">1</span></code> evaluates to a lambda function. <code class="computeroutput"><span class="identifier">arg1</span></code> is a placeholder for an argument to
      be supplied later. Hence, since there's only one unsupplied argument, the lambda
      function has an arity 1. It just so happens that <code class="computeroutput"><span class="identifier">find_if</span></code>
      supplies the unsupplied argument as it loops from <code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span></code>
      to <code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span></code>.
    </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
        Higher order functions are functions which can take other functions as arguments,
        and may also return functions as results. Higher order functions are functions
        that are treated like any other objects and can be used as arguments and
        return values from functions.
      </p></td></tr>
</table></div>
<h4>
<a name="phoenix.basics.h2"></a>
      <span><a name="phoenix.basics.lazy_evaluation"></a></span><a class="link" href="basics.html#phoenix.basics.lazy_evaluation">Lazy
      Evaluation</a>
    </h4>
<p>
      In Phoenix, to put it more accurately, function evaluation has two stages:
    </p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
          Partial application
        </li>
<li class="listitem">
          Final evaluation
        </li>
</ol></div>
<p>
      The first stage is handled by a set of generator functions. These are your
      front ends (in the client's perspective). These generators create (through
      partial function application), higher order functions that can be passed on
      just like any other function pointer or function object. The second stage,
      the actual function call, can be invoked or executed anytime in the future,
      or not at all; hence <span class="emphasis"><em>"lazy"</em></span>.
    </p>
<p>
      If we look more closely, the first step involves partial function application:
    </p>
<pre class="programlisting"><span class="identifier">arg1</span> <span class="special">%</span> <span class="number">2</span> <span class="special">==</span> <span class="number">1</span>
</pre>
<p>
      The second step is the actual function invocation (done inside the <code class="computeroutput"><span class="identifier">find_if</span></code> function. These are the back-ends
      (often, the final invocation is never actually seen by the client). In our
      example, the <code class="computeroutput"><span class="identifier">find_if</span></code>, if we
      take a look inside, we'll see something like:
    </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InputIterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Predicate</span><span class="special">&gt;</span>
<span class="identifier">InputIterator</span>
<span class="identifier">find_if</span><span class="special">(</span><span class="identifier">InputIterator</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">InputIterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">Predicate</span> <span class="identifier">pred</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">while</span> <span class="special">(</span><span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">pred</span><span class="special">(*</span><span class="identifier">first</span><span class="special">))</span>  <span class="comment">// &lt;--- The lambda function is called here</span>
        <span class="special">++</span><span class="identifier">first</span><span class="special">;</span>                            <span class="comment">//      passing in *first</span>
    <span class="keyword">return</span> <span class="identifier">first</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      Again, typically, we, as clients, see only the first step. However, in this
      document and in the examples and tests provided, don't be surprised to see
      the first and second steps juxtaposed in order to illustrate the complete semantics
      of Phoenix expressions. Examples:
    </p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</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="number">1</span><span class="special">)(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 1 or true</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</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="number">1</span><span class="special">)(</span><span class="identifier">y</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 0 or false</span>
</pre>
<h4>
<a name="phoenix.basics.h3"></a>
      <span><a name="phoenix.basics.forwarding_function_problem"></a></span><a class="link" href="basics.html#phoenix.basics.forwarding_function_problem">Forwarding
      Function Problem</a>
    </h4>
<p>
      Usually, we, as clients, write the call-back functions while libraries (such
      as STL) provide the callee (e.g. <code class="computeroutput"><span class="identifier">find_if</span></code>).
      In case the role is reversed, e.g. if you have to write an STL algorithm that
      takes in a predicate, or develop a GUI library that accepts event handlers,
      you have to be aware of a little known problem in C++ called the "<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">Forwarding
      Function Problem</a>".
    </p>
<p>
      Look again at the code above:
    </p>
<pre class="programlisting"><span class="special">(</span><span class="identifier">arg1</span> <span class="special">%</span> <span class="number">2</span> <span class="special">==</span> <span class="number">1</span><span class="special">)(</span><span class="identifier">x</span><span class="special">)</span>
</pre>
<p>
      Notice that, in the second-stage (the final evaluation), we used a variable
      <code class="computeroutput"><span class="identifier">x</span></code>.
    </p>
<p>
      In Phoenix we emulated perfect forwarding through preprocessor macros generating
      code to allow const and non-const references.
    </p>
<p>
      We generate these second-stage overloads for Phoenix expression up to <code class="computeroutput"><span class="identifier">BOOST_PHOENIX_PERFECT_FORWARD_LIMIT</span></code>
    </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
        You can set <code class="computeroutput"><span class="identifier">BOOST_PHOENIX_PERFECT_FORWARD_LIMIT</span></code>,
        the predefined maximum perfect forward arguments an actor can take. By default,
        <code class="computeroutput"><span class="identifier">BOOST_PHOENIX_PERFECT_FORWARDLIMIT</span></code>
        is set to 3.
      </p></td></tr>
</table></div>
<h4>
<a name="phoenix.basics.h4"></a>
      <span><a name="phoenix.basics.polymorphic_functions"></a></span><a class="link" href="basics.html#phoenix.basics.polymorphic_functions">Polymorphic
      Functions</a>
    </h4>
<p>
      Unless otherwise noted, Phoenix generated functions are fully polymorphic.
      For instance, the <code class="computeroutput"><span class="identifier">add</span></code> example
      above can apply to integers, floating points, user defined complex numbers
      or even strings. Example:
    </p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">h</span><span class="special">(</span><span class="string">"Hello"</span><span class="special">);</span>
<span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">w</span> <span class="special">=</span> <span class="string">" World"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">r</span> <span class="special">=</span> <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="identifier">h</span><span class="special">,</span> <span class="identifier">w</span><span class="special">);</span>
</pre>
<p>
      evaluates to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"Hello
      World"</span><span class="special">)</span></code>. The observant
      reader might notice that this function call in fact takes in heterogeneous
      arguments where <code class="computeroutput"><span class="identifier">arg1</span></code> is of
      type <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> and <code class="computeroutput"><span class="identifier">arg2</span></code>
      is of type <code class="computeroutput"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span></code>. <code class="computeroutput"><span class="identifier">add</span></code>
      still works because the C++ standard library allows the expression <code class="computeroutput"><span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span></code>
      where <code class="computeroutput"><span class="identifier">a</span></code> is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
      and <code class="computeroutput"><span class="identifier">b</span></code> is a <code class="computeroutput"><span class="keyword">char</span>
      <span class="keyword">const</span><span class="special">*</span></code>.
    </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005, 2010 Joel de Guzman, Dan Marsden, Thomas Heller<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="starter_kit/more.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="organization.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>