Jekyll2019-11-16T15:07:31+05:30https://haptork.github.io/easyLambda/feed.xmleasyLambdaParallel Dataflows and functional list processing with C++14 and MPI. Powerful abstractions for easy composition and declarative interface in C++ and MPI.haptorkEasy Unary Predicates2016-10-02T00:00:00+05:302016-10-02T00:00:00+05:30https://haptork.github.io/easyLambda/algorithm/easy-unary-predicates<p>Predicates are functions that return a boolean value. Unary predicates take a
single parameter to decide the return value
<a href="http://www.drdobbs.com/effective-standard-c-library-unary-predi/184403777">[drdobbs]</a>
<a href="http://en.cppreference.com/w/cpp/concept/Predicate">[cppref]</a>. They are useful
in many higher order functions e.g. ‘_if’ algorithms in standard library such
as find_if or remove_if, partition etc. With increase in functional style
programming and libraries within C++, predicates are going to be used more
often.</p>
<p>This blog post shows cute, little unary predicates that save some keystrokes
and work together well. We will walk through the implementation that begins with
thinking generic and towards the end embarks on an often used metaprogramming
pattern. Let’s have a look at what these predicates look like in the first
place and observe their behavior.</p>
<p><strong>Example-1</strong>: Relational operators with logical</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">auto</span> <span class="n">a</span> <span class="o">=</span> <span class="n">gt</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span> <span class="o">||</span> <span class="n">lt</span><span class="p">(</span><span class="mi">40</span><span class="p">);</span> <span class="c1">// gt for greater than & lt for lesser</span>
<span class="k">auto</span> <span class="n">a_notone_odd</span> <span class="o">=</span> <span class="n">a</span> <span class="o">&&</span> <span class="o">!</span><span class="n">eq</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">&&</span> <span class="p">([](</span><span class="kt">int</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">x</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span> <span class="p">});</span>
<span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">==</span> <span class="nb">true</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">a_notone_odd</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="nb">false</span><span class="p">);</span></code></pre></figure>
<p><strong>Example-2</strong>: Multiple elements and element selection</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">auto</span> <span class="n">v</span> <span class="o">=</span> <span class="n">vector</span><span class="o"><</span><span class="n">tuple</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">>></span><span class="p">{};</span>
<span class="n">v</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="sc">'a'</span><span class="p">,</span> <span class="mi">11</span><span class="p">);</span>
<span class="n">v</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="sc">'b'</span><span class="p">,</span> <span class="mi">22</span><span class="p">);</span>
<span class="n">v</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="sc">'c'</span><span class="p">,</span> <span class="mi">33</span><span class="p">);</span>
<span class="c1">// second element/index lt 'b' or whole tuple equals (3, 'c', 33)</span>
<span class="k">auto</span> <span class="n">c</span> <span class="o">=</span> <span class="n">count_if</span><span class="p">(</span><span class="n">begin</span><span class="p">(</span><span class="n">v</span><span class="p">),</span> <span class="n">end</span><span class="p">(</span><span class="n">v</span><span class="p">),</span> <span class="n">lt</span><span class="o"><</span><span class="mi">2</span><span class="o">></span><span class="p">(</span><span class="sc">'b'</span><span class="p">)</span> <span class="o">||</span> <span class="n">eq</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="sc">'c'</span><span class="p">,</span> <span class="mi">33</span><span class="p">));</span>
<span class="n">assert</span><span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="mi">2</span><span class="p">);</span></code></pre></figure>
<p>Now, let us see an interesting real world example.</p>
<p><strong>Example-3</strong>: A unit circle at origin</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"> <span class="c1">// returns if a point is inside a unit radius circle at origin</span>
<span class="k">auto</span> <span class="n">in_unit_circle</span> <span class="o">=</span> <span class="p">[]</span> <span class="p">(</span><span class="k">auto</span> <span class="n">p</span><span class="p">)</span> <span class="p">{</span>
<span class="k">auto</span> <span class="n">x</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">0</span><span class="o">></span><span class="p">(</span><span class="n">p</span><span class="p">),</span> <span class="n">y</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">1</span><span class="o">></span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
<span class="k">return</span> <span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">*</span><span class="n">y</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">auto</span> <span class="n">points</span> <span class="o">=</span> <span class="n">vector</span><span class="o"><</span><span class="n">array</span><span class="o"><</span><span class="kt">double</span><span class="p">,</span> <span class="mi">2</span><span class="o">>></span> <span class="p">{{</span> <span class="mf">.1</span><span class="p">,</span> <span class="mf">.2</span><span class="p">},</span> <span class="p">{</span><span class="o">-</span><span class="mf">5.</span><span class="p">,</span> <span class="mf">.1</span><span class="p">},</span>
<span class="p">{</span><span class="mf">5.</span><span class="p">,</span> <span class="mf">.1</span><span class="p">},</span> <span class="p">{</span><span class="o">-</span><span class="mf">0.4</span><span class="p">,</span> <span class="o">-</span><span class="mf">.9</span><span class="p">}};</span>
<span class="c1">// In first quadrant and in unit circle </span>
<span class="k">auto</span> <span class="n">a</span> <span class="o">=</span> <span class="n">gt</span><span class="o"><</span><span class="mi">1</span><span class="o">></span><span class="p">(</span><span class="mf">0.</span><span class="p">)</span> <span class="o">&&</span> <span class="n">gt</span><span class="o"><</span><span class="mi">2</span><span class="o">></span><span class="p">(</span><span class="mf">0.</span><span class="p">)</span> <span class="o">&&</span> <span class="n">in_unit_circle</span><span class="p">;</span>
<span class="k">auto</span> <span class="n">out_unit_circle</span> <span class="o">=</span> <span class="o">!</span><span class="p">(</span><span class="n">tautology</span><span class="p">()</span> <span class="o">&&</span> <span class="n">in_unit_circle</span><span class="p">);</span>
<span class="c1">// In second, third or fourth quadrant or outside unit circle</span>
<span class="k">auto</span> <span class="n">b</span> <span class="o">=</span> <span class="n">lt</span><span class="o"><</span><span class="mi">1</span><span class="o">></span><span class="p">(</span><span class="mf">0.</span><span class="p">)</span> <span class="o">||</span> <span class="n">lt</span><span class="o"><</span><span class="mi">2</span><span class="o">></span><span class="p">(</span><span class="mf">0.</span><span class="p">)</span> <span class="o">||</span> <span class="n">out_unit_circle</span><span class="p">;</span>
<span class="c1">// a == !b</span>
<span class="n">for_each</span><span class="p">(</span><span class="n">begin</span><span class="p">(</span><span class="n">points</span><span class="p">),</span> <span class="n">end</span><span class="p">(</span><span class="n">points</span><span class="p">),</span>
<span class="p">[</span><span class="o">&</span><span class="p">](</span><span class="k">auto</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span> <span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">==</span> <span class="o">!</span><span class="n">b</span><span class="p">(</span><span class="n">x</span><span class="p">));</span> <span class="p">});</span>
<span class="c1">// point can be anything that supports get</span>
<span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">(</span><span class="n">tuple</span><span class="o"><</span><span class="kt">double</span><span class="p">,</span> <span class="kt">double</span><span class="o">></span><span class="p">{</span><span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">})</span> <span class="o">==</span> <span class="nb">true</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">(</span><span class="n">array</span><span class="o"><</span><span class="kt">double</span><span class="p">,</span> <span class="mi">2</span><span class="o">></span><span class="p">{</span><span class="mf">0.45</span><span class="p">,</span> <span class="mf">0.9</span><span class="p">})</span> <span class="o">==</span> <span class="nb">false</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">(</span><span class="n">pair</span><span class="o"><</span><span class="kt">double</span><span class="p">,</span> <span class="kt">double</span><span class="o">></span><span class="p">{</span><span class="mf">0.3</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.3</span><span class="p">})</span> <span class="o">==</span> <span class="nb">false</span><span class="p">);</span></code></pre></figure>
<h2 id="implementation">Implementation</h2>
<p>We begin with a simple implementation of relational operators. A relational
predicate, like equals or greater than, takes a reference value initially.
Each time the predicate is called with a parameter, it compares the parameter
value with the reference value and returns a boolean. Since, the reference
type and parameter type are not some fixed type, we express it with generic
programming as follows.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Ref</span><span class="o">></span> <span class="k">class</span> <span class="nc">Eq</span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="n">Eq</span><span class="p">(</span><span class="n">Ref</span> <span class="n">r</span><span class="p">)</span> <span class="o">:</span> <span class="n">_ref</span><span class="p">{</span><span class="n">r</span><span class="p">}</span> <span class="p">{}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&</span><span class="n">row</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">row</span> <span class="o">==</span> <span class="n">_ref</span><span class="p">;</span> <span class="p">}</span>
<span class="nl">private:</span>
<span class="n">Ref</span> <span class="n">_ref</span><span class="p">;</span>
<span class="p">};</span></code></pre></figure>
<p>The parameter type of the function call operator overload is not required to be
same as the type of reference (Ref). However, it is necessary that comparing
the values of two types with <code class="language-plaintext highlighter-rouge">==</code> is semantically valid. This is because
templates follow <a href="https://en.wikipedia.org/wiki/Duck_typing">Duck typing</a>.</p>
<p>Similarly, we can have Gt and Lt classes for greater than and less than,
respectively.</p>
<p>Till now there is no logical operator to connect the different predicate
classes. We know that the behavior of a logical operator is same for all the
predicates. It implies we should not be writing operator overloads for logical
operators separately in each predicate. Let us first try to frame a generic
logical operator.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Pred1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Pred2</span><span class="o">></span>
<span class="k">class</span> <span class="nc">And</span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="n">And</span><span class="p">(</span><span class="n">Pred1</span> <span class="o">&&</span><span class="n">p1</span><span class="p">,</span> <span class="n">Pred2</span> <span class="o">&&</span><span class="n">p2</span><span class="p">)</span> <span class="o">:</span> <span class="n">_pred1</span><span class="p">{</span><span class="n">forward</span><span class="o"><</span><span class="n">Pred1</span><span class="o">></span><span class="p">(</span><span class="n">p1</span><span class="p">)},</span>
<span class="n">_pred2</span><span class="p">{</span><span class="n">forward</span><span class="o"><</span><span class="n">Pred2</span><span class="o">></span><span class="p">(</span><span class="n">p2</span><span class="p">)}</span> <span class="p">{}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">T</span><span class="o">></span> <span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&</span><span class="n">row</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">_pred1</span><span class="p">(</span><span class="n">row</span><span class="p">)</span> <span class="o">&&</span> <span class="n">_pred2</span><span class="p">(</span><span class="n">row</span><span class="p">);</span>
<span class="p">}</span>
<span class="nl">private:</span>
<span class="n">Pred1</span> <span class="n">_pred1</span><span class="p">;</span>
<span class="n">Pred2</span> <span class="n">_pred2</span><span class="p">;</span>
<span class="p">};</span></code></pre></figure>
<p>Notice that the And class itself is a predicate (returns boolean on function
call) which is what we expect it to be. The class implementation simply says
that it can be instantiated with any two predicates and each time the
instantiated object will be called with a parameter, it will return the
conjunction of the results of the two predicates for that parameter. The
templates let us express this in a generic way with only duck-typing
rules to follow. The <code class="language-plaintext highlighter-rouge">&&</code> and <code class="language-plaintext highlighter-rouge">forward</code> are there to express that the
template predicate types can be either lvalue or rvalue and in either case
predicate values will not be copied to the class members. In former case the
member predicates (_pred1 and _pred2) reference to the constructor parameters
(p1 and p2) while in latter case the constructor parameters are moved to the
members. A simple way to understand lvalue and rvalue is that lvalue is held by
a declared variable while an rvalue is a temporary that is not assigned to any
variable. E.g. In the <code class="language-plaintext highlighter-rouge">a && !eq(1)</code> expression of Example-1, <code class="language-plaintext highlighter-rouge">a</code> is an lvalue
while <code class="language-plaintext highlighter-rouge">eq(1)</code> is an rvalue. Supporting predicates without copy is important
since predicates by definition can be non-copiable like a lambda function.</p>
<p>Similarly, we can create a class for other two logical operators viz. or and
not.</p>
<p>Now, let us create an umbrella class with all the logical operator overloads,
so that we can reuse it to add logical operator overloads to any predicate.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">class</span> <span class="nc">Logical_ops</span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Base</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Pred</span><span class="o">></span>
<span class="k">auto</span> <span class="k">operator</span><span class="o">||</span><span class="p">(</span><span class="n">Base</span> <span class="o">&&</span><span class="n">base</span><span class="p">,</span> <span class="n">Pred</span> <span class="o">&&</span><span class="n">pred</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">Or</span><span class="o"><</span><span class="n">Base</span><span class="p">,</span> <span class="n">Pred</span><span class="o">></span><span class="p">{</span><span class="n">forward</span><span class="o"><</span><span class="n">Base</span><span class="o">></span><span class="p">(</span><span class="n">base</span><span class="p">),</span>
<span class="n">forward</span><span class="o"><</span><span class="n">Pred</span><span class="o">></span><span class="p">(</span><span class="n">pred</span><span class="p">)};</span>
<span class="p">}</span>
<span class="p">};</span></code></pre></figure>
<p>We add similar operator overloads for <code class="language-plaintext highlighter-rouge">&&</code> and <code class="language-plaintext highlighter-rouge">!</code>.</p>
<p>It is however not yet clear how these pieces especially the Logical_ops class
will be used along with others. Let us tie these pieces together.</p>
<p>We know, inheritance gives a direct way of reusing the code. With public
inheritance we can provide the public interface of logical operator overloads
to the predicates. It looks like we need to inherit every relational operator
class from Logical_ops class.</p>
<p>But, in the current form they don’t fit together. The operator overload method
for a logical operator in a predicate class takes the first operand implicitly
to be <code class="language-plaintext highlighter-rouge">this</code> similar to any other method, while in current implementation of
Logical_ops we have both the operands as parameter. The first implicit operand
can vary in a restricted sense i.e. it is same as the predicate class that
inherits from Logical_ops e.g. in Eq class the type of first operand will be Eq
while the second operand can be any other predicate while in Gt the type of
first operand would only be Gt. This smells like generic programming but has a
wee bit more to it. Let us change the Logical_ops to have an implicit first
operand of any generic template class type.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Base</span><span class="o">></span> <span class="k">class</span> <span class="nc">Logical_ops</span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Pred</span><span class="o">></span> <span class="k">auto</span> <span class="k">operator</span><span class="o">||</span><span class="p">(</span><span class="n">Pred</span> <span class="o">&&</span><span class="n">pred</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">Or</span><span class="o"><</span><span class="n">Base</span><span class="p">,</span> <span class="n">Pred</span><span class="o">></span><span class="p">{</span><span class="o">*</span><span class="p">(</span><span class="n">Base</span> <span class="o">*</span><span class="p">)</span><span class="k">this</span><span class="p">,</span> <span class="n">forward</span><span class="o"><</span><span class="n">Pred</span><span class="o">></span><span class="p">(</span><span class="n">pred</span><span class="p">)};</span>
<span class="p">}</span>
<span class="p">};</span></code></pre></figure>
<p>Finally, we need to change relational predicates to inherit from Logical_ops while
passing the correct template types to it.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Ref</span><span class="o">></span> <span class="k">class</span> <span class="nc">Eq</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Logical_ops</span><span class="o"><</span><span class="n">Eq</span><span class="o"><</span><span class="n">Ref</span><span class="o">>></span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="n">Eq</span><span class="p">(</span><span class="n">Ref</span> <span class="n">r</span><span class="p">)</span> <span class="o">:</span> <span class="n">_ref</span><span class="p">{</span><span class="n">r</span><span class="p">}</span> <span class="p">{}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">T</span><span class="o">></span>
<span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&</span><span class="n">row</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">row</span> <span class="o">==</span> <span class="n">_ref</span><span class="p">;</span> <span class="p">}</span>
<span class="nl">private:</span>
<span class="n">Ref</span> <span class="n">_ref</span><span class="p">;</span>
<span class="p">};</span></code></pre></figure>
<p>And, same for logical predicate classes so that we can continue chaining them
with more logical operators.</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Pred1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Pred2</span><span class="o">></span>
<span class="k">class</span> <span class="nc">And</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Logical_ops</span><span class="o"><</span><span class="n">And</span><span class="o"><</span><span class="n">Pred1</span><span class="p">,</span> <span class="n">Pred2</span><span class="o">>></span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="n">And</span><span class="p">(</span><span class="n">Pred1</span> <span class="o">&&</span><span class="n">p1</span><span class="p">,</span> <span class="n">Pred2</span> <span class="o">&&</span><span class="n">p2</span><span class="p">)</span>
<span class="o">:</span> <span class="n">_pred1</span><span class="p">{</span><span class="n">forward</span><span class="o"><</span><span class="n">Pred1</span><span class="o">></span><span class="p">(</span><span class="n">p1</span><span class="p">)},</span> <span class="n">_pred2</span><span class="p">{</span><span class="n">forward</span><span class="o"><</span><span class="n">Pred2</span><span class="o">></span><span class="p">(</span><span class="n">p2</span><span class="p">)}</span> <span class="p">{}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">T</span><span class="o">></span> <span class="kt">bool</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&</span><span class="n">row</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">_pred1</span><span class="p">(</span><span class="n">row</span><span class="p">)</span> <span class="o">&&</span> <span class="n">_pred2</span><span class="p">(</span><span class="n">row</span><span class="p">);</span>
<span class="p">}</span>
<span class="nl">private:</span>
<span class="n">Pred1</span> <span class="n">_pred1</span><span class="p">;</span>
<span class="n">Pred2</span> <span class="n">_pred2</span><span class="p">;</span>
<span class="p">};</span></code></pre></figure>
<p>The idea of passing itself as a template parameter for the base class sounds
unusual and so does its name, CRTP (curiously recurring template pattern) which in
general known as f-bounded polymorphism (even weird). It is a no overhead
abstraction, since it enables static binding rather than dynamic dispatch of
virtual functions.</p>
<p>We skipped over a couple of small details like overloading the logical
operators for ltype and rtype separately, object generators, adding element
selection to logical operators etc. These details can be found in the code
<a href="https://github.com/haptork/easyLambda/blob/master/include/ezl/algorithms/predicates.hpp">here</a>
and examples can be found
<a href="https://github.com/haptork/easyLambda/blob/master/examples/demoPredicates.cpp">here</a>.
It is part of the <a href="https://haptork.github.io/easyLambda/">easyLambda</a> library
for data processing. The predicates and examples can be used separately without
any dependence on the easyLambda library. Don’t forget to check the library as
well.</p>
<p>This is just one way out of many possible ways to implement such predicates.
Please suggest improvements and how you would implement this.</p>
<p>I am not sure how much useful these predicates are in general but I have found
them to be pretty useful for data processing. They appear in many
<a href="https://haptork.github.io/easyLambda/docs/real-world/">examples</a> in
easyLambda. I have also found element selection quite useful in reusing the
predicates. The technique defined for combining with logical operators can be
applied to any general predicate. I believe that a library with geometrical
predicates like <code class="language-plaintext highlighter-rouge">in_circle</code> etc. would also be of use in various cases.</p>haptorkPredicates are functions that return a boolean value. Unary predicates take a single parameter to decide the return value [drdobbs] [cppref]. They are useful in many higher order functions e.g. ‘_if’ algorithms in standard library such as find_if or remove_if, partition etc. With increase in functional style programming and libraries within C++, predicates are going to be used more often.