functional.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <html>
  2. <head>
  3. <title>Functional</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  5. <link rel="stylesheet" href="theme/style.css" type="text/css">
  6. </head>
  7. <body>
  8. <table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  9. <tr>
  10. <td width="10">
  11. </td>
  12. <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functional</b></font>
  13. </td>
  14. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  15. </tr>
  16. </table>
  17. <br>
  18. <table border="0">
  19. <tr>
  20. <td width="10"></td>
  21. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  22. <td width="30"><a href="parametric_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
  23. <td width="30"><a href="phoenix.html"><img src="theme/r_arr.gif" border="0"></a></td>
  24. </tr>
  25. </table>
  26. <p>If you look more closely, you'll notice that Spirit is all about composition
  27. of <i>parser functions</i>. A parser is just a function that accepts a scanner
  28. and returns a match. Parser <i>functions</i> are composed to form increasingly
  29. complex <i>higher order forms</i>. Notice too that the parser, albeit an object,
  30. is immutable and constant. All primitive and composite parser objects are <tt>const</tt>.
  31. The parse member function is even declared as <tt>const</tt>:</p>
  32. <pre>
  33. <code><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt;
  34. </span><span class=keyword>typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>self_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type
  35. </span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>) </span><span class=keyword>const</span><span class=special>;</span></code></pre>
  36. <p> In all accounts, this looks and feels a lot like <b>Functional Programming</b>.
  37. And indeed it is. Spirit is by all means an application of Functional programming
  38. in the imperative C++ domain. In Haskell, for example, there is what are called
  39. <a href="references.html#combinators">parser combinators</a> which are strikingly
  40. similar to the approach taken by Spirit- parser functions which are composed
  41. using various operators to create higher order parser functions that model a
  42. top-down recursive descent parser. Those smart Haskell folks have been doing
  43. this way before Spirit.</p>
  44. <p> Functional style programming (or FP) libraries are gaining momentum in the
  45. C++ community. Certainly, we'll see more of FP in Spirit now and in the future.
  46. Actually, if one looks more closely, even the C++ standard library has an FP
  47. flavor. Stealthily beneath the core of the standard C++ library, a closer look
  48. into STL gives us a glimpse of a truly FP paradigm already in place. It is obvious
  49. that the authors of STL know and practice FP.</p>
  50. <h2>Semantic Actions in the FP Perspective</h2>
  51. <h3>STL style FP</h3>
  52. <p> A more obvious application of STL-style FP in Spirit is the semantic action.
  53. What is STL-style FP? It is primarily the use of functors that can be composed
  54. to form higher order functors.</p>
  55. <table width="80%" border="0" align="center">
  56. <tr>
  57. <td class="note_box"> <img src="theme/note.gif" width="16" height="16"> <strong>Functors</strong><br>
  58. <br>
  59. A Function Object, or Functor is simply any object that can be called as
  60. if it is a function. An ordinary function is a function object, and so is
  61. a function pointer; more generally, so is an object of a class that defines
  62. operator(). </td>
  63. </tr>
  64. </table>
  65. <p> This STL-style FP can be seen everywhere these days. The following example
  66. is taken from <a href="https://www.boost.org/sgi/stl/">SGI's Standard Template
  67. Library Programmer's Guide</a>:</p>
  68. <pre>
  69. <code><span class=comment>// Computes sin(x)/(x + DBL_MIN) for each element of a range.
  70. </span><span class=identifier>transform</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>first</span><span class=special>,
  71. </span><span class=identifier>compose2</span><span class=special>(</span><span class=identifier>divides</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;(),
  72. </span><span class=identifier>ptr_fun</span><span class=special>(</span><span class=identifier>sin</span><span class=special>),
  73. </span><span class=identifier>bind2nd</span><span class=special>(</span><span class=identifier>plus</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt;(), </span><span class=identifier>DBL_MIN</span><span class=special>)));</span></code></pre>
  74. <p align="left"> Really, this is just <i>currying</i> in FP terminology.</p>
  75. <table width="80%" border="0" align="center">
  76. <tr>
  77. <td class="note_box"> <img src="theme/lens.gif" width="15" height="16"> <strong>Currying</strong><br>
  78. <br>
  79. What is &quot;currying&quot;, and where does it come from?<br>
  80. <br>
  81. Currying has its origins in the mathematical study of functions. It was
  82. observed by Frege in 1893 that it suffices to restrict attention to functions
  83. of a single argument. For example, for any two parameter function <tt>f(x,y)</tt>,
  84. there is a one parameter function <tt>f'</tt> such that <tt>f'(x)</tt> is
  85. a function that can be applied to y to give <tt>(f'(x))(y) = f (x,y)</tt>.
  86. This corresponds to the well known fact that the sets <tt>(AxB -&gt; C)</tt>
  87. and <tt>(A -&gt; (B -&gt; C))</tt> are isomorphic, where <tt>&quot;x&quot;</tt>
  88. is cartesian product and <tt>&quot;-&gt;&quot;</tt> is function space. In
  89. functional programming, function application is denoted by juxtaposition,
  90. and assumed to associate to the left, so that the equation above becomes
  91. <tt>f' x y = f(x,y)</tt>. </td>
  92. </tr>
  93. </table>
  94. <p> In the context of Spirit, the same FP style functor composition may be applied
  95. to semantic actions. <a href="../example/fundamental/full_calc.cpp">full_calc.cpp</a> is a good example. Here's a snippet from that sample:</p>
  96. <pre>
  97. <code><span class=identifier>expression </span><span class=special>=
  98. </span><span class=identifier>term
  99. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=special>(</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>)[</span><span class=identifier>make_op</span><span class=special>(</span><span class=identifier>plus</span><span class=special>&lt;</span><span class=keyword>long</span><span class=special>&gt;(), </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>eval</span><span class=special>)]
  100. </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>)[</span><span class=identifier>make_op</span><span class=special>(</span><span class=identifier>minus</span><span class=special>&lt;</span><span class=keyword>long</span><span class=special>&gt;(), </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>eval</span><span class=special>)]
  101. </span><span class=special>)
  102. </span><span class=special>;</span></code></pre>
  103. <p> <img height="16" width="15" src="theme/lens.gif"> The full source code can be <a href="../example/fundamental/full_calc.cpp">viewed here</a>. This is part of the Spirit distribution.</p>
  104. <h3>Boost style FP</h3>
  105. <p> Boost takes the FP paradigm further. There are libraries in boost that focus
  106. specifically on Function objects and higher-order programming.</p>
  107. <table width="90%" border="0" align="center">
  108. <tr>
  109. <td class="table_title" colspan="14"> Boost FP libraries </td>
  110. </tr>
  111. <tr>
  112. <td class="table_cells"><a href="http://www.boost.org/libs/bind/bind.html">bind</a>
  113. and <a href="http://www.boost.org/libs/bind/mem_fn.html">mem_fn</a></td>
  114. <td class="table_cells">Generalized binders for function/object/pointers and
  115. member functions, from Peter Dimov</td>
  116. </tr>
  117. <td class="table_cells"><a href="http://www.boost.org/libs/function/index.html">function</a></td>
  118. <td class="table_cells">Function object wrappers for deferred calls or callbacks,
  119. from Doug Gregor</td>
  120. </tr>
  121. <td class="table_cells"><a href="http://www.boost.org/libs/functional/index.html">functional</a></td>
  122. <td class="table_cells">Enhanced function object adaptors, from Mark Rodgers</td>
  123. </tr>
  124. <td class="table_cells"><a href="http://www.boost.org/libs/lambda/index.html">lambda</a></td>
  125. <td class="table_cells">Define small unnamed function objects at the actual
  126. call site, and more, from Jaakko Järvi and Gary Powell</td>
  127. </tr>
  128. <td class="table_cells"><a href="http://www.boost.org/libs/bind/ref.html">ref</a></td>
  129. <td class="table_cells">A utility library for passing references to generic
  130. functions, from Jaako Järvi, Peter Dimov, Doug Gregor, and Dave Abrahams</td>
  131. </tr>
  132. </table>
  133. <p> The following is an example that uses boost <strong>Bind</strong> to use a
  134. member function as a Spirit semantic action. You can see this example in full
  135. in the file<a href="../example/fundamental/bind.cpp"> bind.cpp</a>.</p>
  136. <pre>
  137. <code><span class=keyword>class </span><span class=identifier>list_parser
  138. </span><span class=special>{
  139. </span><span class=keyword>public</span><span class=special>:
  140. </span><span class=keyword>typedef </span><span class=identifier>list_parser </span><span class=identifier>self_t</span><span class=special>;
  141. </span><span class=keyword>bool
  142. </span><span class=identifier>parse</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>)
  143. </span><span class=special>{
  144. </span><span class=keyword>return </span><span class=identifier>spirit</span><span class=special>::</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>str</span><span class=special>,
  145. </span><span class=comment>// Begin grammar
  146. </span><span class=special>(
  147. </span><span class=identifier>real_p
  148. </span><span class=special>[
  149. </span><span class=identifier>bind</span><span class=special>(&amp;</span><span class=identifier>self_t</span><span class=special>::</span><span class=identifier>add</span><span class=special>, </span><span class=keyword>this</span><span class=special>, </span><span class=identifier>_1</span><span class=special>)
  150. </span><span class=special>]
  151. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=literal>','
  152. </span><span class=special>&gt;&gt; </span><span class=identifier>real_p
  153. </span><span class=special>[
  154. </span><span class=identifier>bind</span><span class=special>(&amp;</span><span class=identifier>self_t</span><span class=special>::</span><span class=identifier>add</span><span class=special>, </span><span class=keyword>this</span><span class=special>, </span><span class=identifier>_1</span><span class=special>)
  155. </span><span class=special>]
  156. </span><span class=special>)
  157. </span><span class=special>)
  158. </span><span class=special>,
  159. </span><span class=comment>// End grammar
  160. </span><span class=identifier>space_p</span><span class=special>).</span><span class=identifier>full</span><span class=special>;
  161. </span><span class=special>}
  162. </span><span class=keyword>void
  163. </span><span class=identifier>add</span><span class=special>(</span><span class=keyword>double </span><span class=identifier>n</span><span class=special>)
  164. </span><span class=special>{
  165. </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>n</span><span class=special>);
  166. </span><span class=special>}
  167. </span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt; </span><span class=identifier>v</span><span class=special>;
  168. </span><span class=special>};
  169. </span></code></pre>
  170. <p> <img height="16" width="15" src="theme/lens.gif"> The full source code can be <a href="../example/fundamental/bind.cpp">viewed here</a>. This is part of the Spirit distribution.</p>
  171. <p>This parser parses a comma separated list of real numbers and stores them
  172. in a vector&lt;double&gt;. Boost.bind creates a Spirit conforming semantic action
  173. from the <tt>list_parser</tt>'s member function <tt>add</tt>.</p>
  174. <h3>Lambda and Phoenix</h3>
  175. <p> There's a library, authored by yours truly, named <a href="../phoenix/index.html">Phoenix</a>.
  176. While this is not officially part of the Spirit distribution, this library has
  177. been used extensively to experiment on advanced FP techniques in C++. This library
  178. is highly influenced by <a href="https://people.cs.umass.edu/~yannis/fc++/">FC++</a>
  179. and boost Lambda (<a href="http://www.boost.org/libs/lambda/index.html">BLL</a>).</p>
  180. <table width="80%" border="0" align="center">
  181. <tr>
  182. <td class="note_box"> <b><img src="theme/lens.gif" width="15" height="16">
  183. BLL</b><br>
  184. <br>
  185. In as much as Phoenix is influenced by boost Lambda (<a href="http://www.boost.org/libs/lambda/index.html">BLL</a>),
  186. Phoenix innovations such as local variables, local functions and adaptable
  187. closures, in turn influenced BLL. Currently, BLL is very similar to Phoenix.
  188. Most importantly, BLL incorporated Phoenix's adaptable closures. In the
  189. future, Spirit will fully support BLL. </td>
  190. </tr>
  191. </table>
  192. <p> Phoenix allows one to write semantic actions inline in C++ through lambda
  193. (an unnamed function) expressions. Here's a snippet from the <a href="../example/fundamental/phoenix_calc.cpp">phoenix_calc.cpp</a> example:</p>
  194. <pre>
  195. <code><span class=identifier>expression
  196. </span><span class=special>= </span><span class=identifier>term</span><span class=special>[</span><span class=identifier>expression</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=identifier>arg1</span><span class=special>]
  197. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=special>(</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>[</span><span class=identifier>expression</span><span class=special>.</span><span class=identifier>val </span><span class=special>+= </span><span class=identifier>arg1</span><span class=special>])
  198. </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>[</span><span class=identifier>expression</span><span class=special>.</span><span class=identifier>val </span><span class=special>-= </span><span class=identifier>arg1</span><span class=special>])
  199. </span><span class=special>)
  200. </span><span class=special>;
  201. </span><span class=identifier>term
  202. </span><span class=special>= </span><span class=identifier>factor</span><span class=special>[</span><span class=identifier>term</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=identifier>arg1</span><span class=special>]
  203. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=special>(</span><span class=literal>'*' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>[</span><span class=identifier>term</span><span class=special>.</span><span class=identifier>val </span><span class=special>*= </span><span class=identifier>arg1</span><span class=special>])
  204. </span><span class=special>| </span><span class=special>(</span><span class=literal>'/' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>[</span><span class=identifier>term</span><span class=special>.</span><span class=identifier>val </span><span class=special>/= </span><span class=identifier>arg1</span><span class=special>])
  205. </span><span class=special>)
  206. </span><span class=special>;
  207. </span><span class=identifier>factor
  208. </span><span class=special>= </span><span class=identifier>ureal_p</span><span class=special>[</span><span class=identifier>factor</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=identifier>arg1</span><span class=special>]
  209. </span><span class=special>| </span><span class=literal>'(' </span><span class=special>&gt;&gt; </span><span class=identifier>expression</span><span class=special>[</span><span class=identifier>factor</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=identifier>arg1</span><span class=special>] </span><span class=special>&gt;&gt; </span><span class=literal>')'
  210. </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>[</span><span class=identifier>factor</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=special>-</span><span class=identifier>arg1</span><span class=special>])
  211. </span><span class=special>| </span><span class=special>(</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>[</span><span class=identifier>factor</span><span class=special>.</span><span class=identifier>val </span><span class=special>= </span><span class=identifier>arg1</span><span class=special>])
  212. </span><span class=special>;</span></code></pre>
  213. <p> <img height="16" width="15" src="theme/lens.gif"> The full source code can be <a href="../example/fundamental/phoenix_calc.cpp">viewed here</a>. This is part of the Spirit distribution.</p>
  214. <p>You do not have to worry about the details for now. There is a lot going on here that needs to be explained. The succeeding chapters will be enlightening.</p>
  215. <p>Notice the use of lambda expressions such as:</p>
  216. <pre>
  217. <code><span class=identifier>expression</span><span class=special>.</span><span class=identifier>val </span><span class=special>+= </span><span class=identifier>arg1</span></code></pre>
  218. <table width="80%" border="0" align="center">
  219. <tr>
  220. <td class="note_box"> <b><img src="theme/lens.gif" width="15" height="16">
  221. <a name="lambda"></a>Lambda Expressions?</b><br>
  222. <br>
  223. Lambda expressions are actually unnamed partially applied functions where
  224. placeholders (e.g. arg1, arg2) are provided in place of some of the arguments.
  225. The reason this is called a lambda expression is that traditionally, such
  226. placeholders are written using the Greek letter lambda <img src="theme/lambda.png" width="15" height="22">.</td>
  227. </tr>
  228. </table>
  229. <p>where <tt>expression.val</tt> is a closure variable of the expression rule
  230. (see <a href="closures.html">Closures</a>). <code><span class=identifier><tt>arg1</tt></span></code>
  231. is a placeholder for the first argument that the semantic action will receive
  232. (see <a href="../phoenix/doc/place_holders.html">Phoenix Place-holders</a>).
  233. In Boost.Lambda (BLL), this corresponds to <tt>_1</tt>. </p>
  234. <table border="0">
  235. <tr>
  236. <td width="10"></td>
  237. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  238. <td width="30"><a href="parametric_parsers.html"><img src="theme/l_arr.gif" border="0"></a></td>
  239. <td width="30"><a href="phoenix.html"><img src="theme/r_arr.gif" border="0"></a></td>
  240. </tr>
  241. </table>
  242. <br>
  243. <hr size="1">
  244. <p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
  245. <br>
  246. <font size="2">Use, modification and distribution is subject to the Boost Software
  247. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  248. http://www.boost.org/LICENSE_1_0.txt)</font></p>
  249. <p class="copyright">&nbsp;</p>
  250. </body>
  251. </html>