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