• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4
5<html xmlns="http://www.w3.org/1999/xhtml">
6  <head>
7    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
9    <title>Point-free style programming &#8212; Boost.HigherOrderFunctions 0.6 documentation</title>
10
11    <link rel="stylesheet" href="../../_static/boostbook.css" type="text/css" />
12    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
13
14    <script type="text/javascript">
15      var DOCUMENTATION_OPTIONS = {
16        URL_ROOT:    '../../',
17        VERSION:     '0.6',
18        COLLAPSE_INDEX: false,
19        FILE_SUFFIX: '.html',
20        HAS_SOURCE:  true,
21        SOURCELINK_SUFFIX: '.txt'
22      };
23    </script>
24    <script type="text/javascript" src="../../_static/jquery.js"></script>
25    <script type="text/javascript" src="../../_static/underscore.js"></script>
26    <script type="text/javascript" src="../../_static/doctools.js"></script>
27    <link rel="index" title="Index" href="../../genindex.html" />
28    <link rel="search" title="Search" href="../../search.html" />
29    <link rel="next" title="Overview" href="overview.html" />
30    <link rel="prev" title="More examples" href="more_examples.html" />
31  </head>
32  <body role="document">
33<table cellpadding="2" width="100%"><tr>
34<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86"src="../../_static/boost.png"></td>
35</tr></table>
36
37<div class="spirit-nav">
38<a accesskey="p"  href="more_examples.html"><img src="../../_static/prev.png" alt="Prev"></a>
39<a accesskey="u" href="intro.html"><img src="../../_static/up.png" alt="Up"></a>
40<a accesskey="h" href="../index.html"><img src="../../_static/home.png" alt="Home"></a>
41<a accesskey="n"  href="overview.html"><img src="../../_static/next.png" alt="Next"></a>
42</div>
43
44
45    <div class="document">
46  <div class="chapter">
47      <div class="body" role="main">
48
49  <!-- Copyright 2018 Paul Fultz II
50     Distributed under the Boost Software License, Version 1.0.
51     (http://www.boost.org/LICENSE_1_0.txt)
52--><div class="section" id="point-free-style-programming">
53<h1>Point-free style programming<a class="headerlink" href="#point-free-style-programming" title="Permalink to this headline">¶</a></h1>
54<p><a class="reference external" href="https://en.wikipedia.org/wiki/Tacit_programming">Point-free style</a> programing(or tacit programming) is a style where the arguments to the function are not explicity defined. Rather, the function is defined as the composition of other functions where function adaptors manipulate the function arguments. The advantage of using point-free style in C++ is the template machinery involved with function arguments can be avoided.</p>
55<div class="section" id="variadic-print">
56<h2>Variadic print<a class="headerlink" href="#variadic-print" title="Permalink to this headline">¶</a></h2>
57<p>For example, if we want to write a variadic print function that prints each argument, like this:</p>
58<div class="highlight-cpp"><div class="highlight"><pre><span class="n">print</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">,</span> <span class="s">&quot;World&quot;</span><span class="p">);</span>
59</pre></div>
60</div>
61<p>We would write something like the following, which would recursively iterate over the arguments using varidiac templates:</p>
62<div class="highlight-cpp"><div class="highlight"><pre><span class="c1">// Base case</span>
63<span class="kt">void</span> <span class="nf">print</span><span class="p">()</span>
64<span class="p">{}</span>
65
66<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="n">class</span><span class="p">...</span> <span class="n">Ts</span><span class="o">&gt;</span>
67<span class="kt">void</span> <span class="n">print</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">Ts</span><span class="o">&amp;</span><span class="p">...</span> <span class="n">xs</span><span class="p">)</span>
68<span class="p">{</span>
69    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">;</span>
70    <span class="n">print</span><span class="p">(</span><span class="n">xs</span><span class="p">...);</span>
71<span class="p">}</span>
72</pre></div>
73</div>
74<p>Instead with point-free style, we can write this using the <code class="docutils literal"><span class="pre">proj</span></code> adaptor, which calls a function on each arguments. Of course, <code class="docutils literal"><span class="pre">std::cout</span></code> is not a function, but we can make it one by using <code class="docutils literal"><span class="pre">BOOST_HOF_LIFT</span></code>:</p>
75<div class="highlight-cpp"><div class="highlight"><pre><span class="n">BOOST_HOF_STATIC_FUNCTION</span><span class="p">(</span><span class="n">simple_print</span><span class="p">)</span> <span class="o">=</span> <span class="n">BOOST_HOF_LIFT</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">_</span><span class="p">);</span>
76</pre></div>
77</div>
78<p>This uses the <a class="reference internal" href="../../include/boost/hof/placeholders.html"><span class="doc">placeholders</span></a> to create a function that prints to <code class="docutils literal"><span class="pre">std::cout</span></code>. Then we can pass <code class="docutils literal"><span class="pre">simple_print</span></code> to the <code class="docutils literal"><span class="pre">proj</span></code> adaptor:</p>
79<div class="highlight-cpp"><div class="highlight"><pre><span class="n">BOOST_HOF_STATIC_FUNCTION</span><span class="p">(</span><span class="n">print</span><span class="p">)</span> <span class="o">=</span> <span class="n">proj</span><span class="p">(</span><span class="n">simple_print</span><span class="p">);</span>
80</pre></div>
81</div>
82<p>As the <code class="docutils literal"><span class="pre">proj</span></code> adaptor calls the function for each argument passed in, <code class="docutils literal"><span class="pre">b(f)(x,</span> <span class="pre">y)</span></code> is the equivalent of calling <code class="docutils literal"><span class="pre">f(x)</span></code> and then <code class="docutils literal"><span class="pre">f(y)</span></code>. In this case, it will call <code class="docutils literal"><span class="pre">simple_print(x)</span></code> and then <code class="docutils literal"><span class="pre">simple_print(y)</span></code>:</p>
83<div class="highlight-cpp"><div class="highlight"><pre><span class="n">print</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">,</span> <span class="s">&quot;World&quot;</span><span class="p">);</span>
84</pre></div>
85</div>
86<p>Which prints out:</p>
87<div class="highlight-cpp"><div class="highlight"><pre><span class="n">HelloWorld</span>
88</pre></div>
89</div>
90<p>Of course, this puts all the output together, but we can further extend this to print a new line for each item by composing it:</p>
91<div class="highlight-cpp"><div class="highlight"><pre><span class="n">BOOST_HOF_STATIC_FUNCTION</span><span class="p">(</span><span class="n">print_lines</span><span class="p">)</span> <span class="o">=</span> <span class="n">proj</span><span class="p">(</span><span class="n">flow</span><span class="p">(</span><span class="n">simple_print</span><span class="p">,</span> <span class="n">_</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="sc">&#39;\n&#39;</span><span class="o">&gt;</span><span class="p">{}));</span>
92</pre></div>
93</div>
94<p>The <a class="reference internal" href="../../include/boost/hof/flow.html"><span class="doc">flow</span></a> adaptor does function composition but the functions are called from left-to-right. That is <code class="docutils literal"><span class="pre">flow(f,</span> <span class="pre">g)(x)</span></code> is equivalent to <code class="docutils literal"><span class="pre">g(f(x))</span></code>. So in this case, it will call <code class="docutils literal"><span class="pre">simple_print</span></code> on the argument which returns <code class="docutils literal"><span class="pre">std::cout</span></code> and then pass that to the next function which calls the stream with the newline character. In the above, we write <code class="docutils literal"><span class="pre">std::integral_constant&lt;char,</span> <span class="pre">'\n'&gt;{}</span></code> instead of just <code class="docutils literal"><span class="pre">'\n'</span></code> because the function is statically defined, so all values must be defined statically.</p>
95<p>So now calling <code class="docutils literal"><span class="pre">print_lines</span></code>:</p>
96<div class="highlight-cpp"><div class="highlight"><pre><span class="n">print_lines</span><span class="p">(</span><span class="s">&quot;Hello&quot;</span><span class="p">,</span> <span class="s">&quot;World&quot;</span><span class="p">);</span>
97</pre></div>
98</div>
99<p>It will print out:</p>
100<div class="highlight-cpp"><div class="highlight"><pre><span class="n">Hello</span>
101<span class="n">World</span>
102</pre></div>
103</div>
104<p>With each argument on its own line.</p>
105</div>
106<div class="section" id="variadic-sum">
107<h2>Variadic sum<a class="headerlink" href="#variadic-sum" title="Permalink to this headline">¶</a></h2>
108<p>Another example, say we would like to write a varidiac version of <code class="docutils literal"><span class="pre">max</span></code>. We could implement it like this:</p>
109<div class="highlight-cpp"><div class="highlight"><pre><span class="c1">// Base case</span>
110<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="o">&gt;</span>
111<span class="n">T</span> <span class="n">max</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">)</span>
112<span class="p">{</span>
113    <span class="k">return</span> <span class="n">x</span><span class="p">;</span>
114<span class="p">}</span>
115
116<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="n">class</span><span class="p">...</span> <span class="n">Ts</span><span class="o">&gt;</span>
117<span class="n">T</span> <span class="n">max</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">y</span><span class="p">,</span> <span class="k">const</span> <span class="n">Ts</span><span class="o">&amp;</span><span class="p">...</span> <span class="n">xs</span><span class="p">)</span>
118<span class="p">{</span>
119    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">max</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">xs</span><span class="p">...));</span>
120<span class="p">}</span>
121</pre></div>
122</div>
123<p>With point-free style programming, we can recognize this is a <a class="reference external" href="https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29">fold</a>, and write it using the <a class="reference internal" href="../../include/boost/hof/fold.html"><span class="doc">fold</span></a> adaptor, which will do a fold over the variadic parameters:</p>
124<div class="highlight-cpp"><div class="highlight"><pre><span class="n">BOOST_HOF_STATIC_FUNCTION</span><span class="p">(</span><span class="n">max</span><span class="p">)</span> <span class="o">=</span> <span class="n">fold</span><span class="p">(</span><span class="n">BOOST_HOF_LIFT</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">));</span>
125</pre></div>
126</div>
127<p><a class="reference internal" href="../../include/boost/hof/lift.html"><span class="doc">BOOST_HOF_LIFT</span></a> is used to grab the entire overload set of <code class="docutils literal"><span class="pre">std::max</span></code> function, which is needed since <code class="docutils literal"><span class="pre">std::max</span></code> is templated and we want the variadic <code class="docutils literal"><span class="pre">std::max</span></code> function to handle any types as well. So now it can be called like this:</p>
128<div class="highlight-cpp"><div class="highlight"><pre><span class="k">auto</span> <span class="n">n</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span> <span class="c1">// Returns 4</span>
129<span class="k">auto</span> <span class="n">m</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">);</span> <span class="c1">// Returns 0.5</span>
130</pre></div>
131</div>
132<p>By using <a class="reference internal" href="../../include/boost/hof/fold.html"><span class="doc">fold</span></a>, <code class="docutils literal"><span class="pre">max(1,</span> <span class="pre">2,</span> <span class="pre">4,</span> <span class="pre">3)</span></code> will call <code class="docutils literal"><span class="pre">std::max</span></code> like <code class="docutils literal"><span class="pre">std::max(std::max(std::max(1,</span> <span class="pre">2),</span> <span class="pre">4),</span> <span class="pre">3)</span></code> and <code class="docutils literal"><span class="pre">max(0.1,</span> <span class="pre">0.2,</span> <span class="pre">0.5,</span> <span class="pre">0.4)</span></code> will be called like <code class="docutils literal"><span class="pre">std::max(std::max(std::max(0.1,</span> <span class="pre">0.2),</span> <span class="pre">0.5),</span> <span class="pre">0.4)</span></code>.</p>
133</div>
134</div>
135
136
137      </div>
138  </div>
139      <div class="clearer"></div>
140    </div>
141    <div class="footer" role="contentinfo">
142    <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
143    <td align="left"></td>
144    <td align="right"><div class="copyright-footer">
145            &#169; Copyright 2016, Paul Fultz II.
146
147          Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
148          <p>Distributed under the Boost Software License, Version 1.0.
149          (See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
150          <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
151          </p>
152    </div></td>
153    </tr></table>
154    </div>
155  </body>
156</html>