{"id":5150,"date":"2017-01-26T21:14:15","date_gmt":"2017-01-26T21:14:15","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/higher-order-functions\/"},"modified":"2024-07-22T16:29:03","modified_gmt":"2024-07-22T16:29:03","slug":"higher-order-functions","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/higher-order-functions\/","title":{"rendered":"Higher-Order Functions"},"content":{"rendered":"<p>Higher-order functions are the pendant to <a href=\"https:\/\/www.modernescpp.com\/index.php\/first-class-functions\">First-Class Functions<\/a> because higher-order functions can take functions as an argument or return them as a result.<\/p>\n<p><!--more--><\/p>\n<h2>Higher-order functions<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5145\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeHigherOrderFunctionsEng.png\" alt=\"\" width=\"600\" height=\"601\" data-alt=\"CharakteristikeHigherOrderFunctionsEng\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeHigherOrderFunctionsEng.png 453w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeHigherOrderFunctionsEng-300x300.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeHigherOrderFunctionsEng-150x150.png 150w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h3>The three classics: map, filter, and fold<\/h3>\n<p>Each programming language supporting programming in the functional style supports at least three functions <span style=\"font-family: courier new,courier;\">map,<\/span> <span style=\"font-family: courier new,courier;\">filter,<\/span> and <span style=\"font-family: courier new,courier;\">fold.<\/span> <span style=\"font-family: courier new,courier;\">map<\/span> applies a function to each element of its list. <span style=\"font-family: courier new,courier;\">filter<\/span> removes all elements of a list not satisfying a condition. <span style=\"font-family: courier new,courier;\">fold<\/span> is the most powerful of the three ones. <span style=\"font-family: courier new,courier;\">fold<\/span> successively applies a binary operation to list pairs and reduces the list to a value.<\/p>\n<p>I can do better:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5146\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterReduce.jpg\" alt=\"MapFilterReduce\" width=\"700\" height=\"527\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterReduce.jpg 980w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterReduce-300x226.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterReduce-768x578.jpg 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<h4>The name variations<\/h4>\n<p>The statement that each programming language supporting programming in a functional style has to support the three functions <span style=\"font-family: courier new,courier;\">map,<\/span> <span style=\"font-family: courier new,courier;\">filter,<\/span> and <span style=\"font-family: courier new,courier;\">reduce,<\/span> has few restrictions. The names of the three functions have variations in the different programming languages. You can see in the table the names of the Haskell functions in comparison with their names in C++ and Python.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5147\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterFold.png\" alt=\"MapFilterFold\" width=\"600\" height=\"157\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterFold.png 719w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapFilterFold-300x78.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>I want to stress two points. Firstly, Haskell has four variations of <span style=\"font-family: courier new,courier;\">the fold.<\/span> The variations are due to whether the binary operation starts at the beginning or at the end of the list and whether it has an initial value. Secondly, string concatenation of map and reduce (fold) gives MapReduce. This is no accident. The Google framework is based on a map and a reduce phase and is, therefore, based on the ideas of the functions <span style=\"font-family: courier new,courier;\">map<\/span> and <span style=\"font-family: courier new,courier;\">reduce<\/span> <span style=\"font-family: courier new,courier;\">(fold).<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5148\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng.png\" alt=\"MapReduceEng\" width=\"700\" height=\"295\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng.png 2000w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng-300x126.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng-1024x432.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng-768x324.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/MapReduceEng-1536x647.png 1536w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>The easiest way to understand the functions is to use them. As input, I choose a list <span style=\"font-family: courier new,courier;\">(vec)<\/span> with the integers from 0 to 9 and a list <span style=\"font-family: courier new,courier;\">(str)<\/span> with the words <span style=\"font-family: courier new,courier;\">&#8220;Programming&#8221;,&#8221;in&#8221;,&#8221;a&#8221;,&#8221;functional&#8221;,&#8221;style.&#8221;<\/span> In the case of C++, the list is a <span style=\"font-family: courier new,courier;\">std::vector.<\/span><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><strong><span style=\"color: #008000;\">\/\/ Haskell<\/span><\/strong>\nvec = [1..9]\nstr = [<span style=\"color: #a31515;\">\"Programming\"<\/span>,<span style=\"color: #a31515;\">\"in\"<\/span>,<span style=\"color: #a31515;\">\"a\"<\/span>,<span style=\"color: #a31515;\">\"functional\"<\/span>,<span style=\"color: #a31515;\">\"style.\"<\/span>]\n\n<strong><span style=\"color: #008000;\">\/\/ Python<\/span><\/strong>\nvec=range(1, 10)\nstr=[<span style=\"color: #a31515;\">\"Programming\"<\/span>, <span style=\"color: #a31515;\">\"in\"<\/span>, <span style=\"color: #a31515;\">\"a\"<\/span>, <span style=\"color: #a31515;\">\"functional\"<\/span>, <span style=\"color: #a31515;\">\"style.\"<\/span>]\n\n<strong><span style=\"color: #008000;\">\/\/ C++<\/span><\/strong>\nstd::vector&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; vec{1, 2, 3, 4, 5, 6, 7, 8, 9}\nstd::vector&lt;string&gt; str{<span style=\"color: #a31515;\">\"Programming\"<\/span>, <span style=\"color: #a31515;\">\"in\"<\/span>, <span style=\"color: #a31515;\">\"a\"<\/span>, <span style=\"color: #a31515;\">\"functional\"<\/span>, <span style=\"color: #a31515;\">\"style.\"<\/span>}\n<\/pre>\n<\/div>\n<p>For simplicity reasons, I will directly display the results in the list syntax of Haskell.<\/p>\n<h4>map<\/h4>\n<p><span style=\"font-family: courier new,courier;\">map<\/span> applies a callable to each element of a list. A callable is all that behaves like a function. A callable can be, in C++, a function, a function object, or a lambda function. The best fit for higher-order functions is often a lambda function. That is for two reasons. On the one hand, you can concisely express your intent, and the code is easier to understand. On the other hand, the lambda function defines its functionality precisely where it is used. Because of that, the compiler gets maximum insight into the source code and has the maximum potential to optimize. That is the reason that you will often get more performant executables with a lambda function<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><strong><span style=\"color: #008000;\">\/\/ Haskell<\/span><\/strong>\nmap(\\a -&gt; a * a) vec\nmap(\\a -&gt; length a) str\n\n<strong><span style=\"color: #008000;\">\/\/ Python<\/span><\/strong>\nmap(lambda x :x*x , vec)\nmap(lambda x : len(x), str)\n\n<strong><span style=\"color: #008000;\">\/\/ C++<\/span><\/strong>\nstd::transform(vec.begin(), vec.end(), vec.begin(),\n              [](<span style=\"color: #2b91af;\">int<\/span> i){ <span style=\"color: #0000ff;\">return<\/span> i*i;} );\nstd::transform(str.begin(), str.end(), std::back_inserter(vec2),\n     [](std::string s){ <span style=\"color: #0000ff;\">return<\/span> s.length ();} );\n\n<strong><span style=\"color: #008000;\">\/\/ [1,4,9,16,25,36,49,64,81]<\/span>\n<\/strong><span style=\"color: #008000;\"><strong>\/\/ [11,2,1,10,6]<\/strong>\n<\/span>\n<\/pre>\n<\/div>\n<p>Of course, the syntax of lambda functions in Haskell, Python, and C++ is different. Therefore, a lambda function will be introduced in Haskell by a slash <span style=\"font-family: courier new,courier;\">\\a \u2192 a*a<\/span>, but will be introduced in Python by the <span style=\"font-family: courier new,courier;\">lambda: lambda x: x*x. <\/span>In C++, you have to use square brackets: <span style=\"font-family: courier new,courier;\">[](int i){ return i*i; }<\/span>. These are only syntactical differences. More interesting is that you invoke functions in Haskell without braces and that Haskell and Python generate a list, while you can modify in C++ the existing <span style=\"font-family: courier new,courier;\">std::vector<\/span> or fill a new one.<\/p>\n<h4>filter<\/h4>\n<p><span style=\"font-family: courier new,courier;\">filter<\/span> keeps only these elements in the list that satisfy the predicate. A predicate is a callable that returns a boolean. Here is an example.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><strong><span style=\"color: #008000;\">\/\/ Haskell<\/span><\/strong>\nfilter (\\x-&gt; x &lt;3 || x&gt; 8) vec\nfilter (\\x -&gt; isupper (head x)) sts\n\n<strong><span style=\"color: #008000;\">\/\/ Python<\/span><\/strong>\nfilter(lambda x: x&lt;3 or x&gt;8 , vec)\nfilter(lambda x: x[0].isupper(), str)\n\n<strong><span style=\"color: #008000;\">\/\/ C++<\/span><\/strong>\n<span style=\"color: #0000ff;\">auto<\/span> it = std::remove_if(vec.begin(), vec.end (),\n     [](<span style=\"color: #2b91af;\">int<\/span> i){<span style=\"color: #0000ff;\">return<\/span> ((i &lt;3) or (i&gt; 8))!});\n<span style=\"color: #0000ff;\">auto<\/span> it2 = std::remove_if(str.begin(),  str.end (), \n     [](std::string s) {<span style=\"color: #0000ff;\">return<\/span> !(std::isupper (s[0]));});\n\n<strong><span style=\"color: #008000;\">\/\/ [1,2,9]<\/span>\n<\/strong><span style=\"color: #008000;\"><strong>\/\/ [\"Programming\"]<\/strong>\n<\/span>\n<\/pre>\n<\/div>\n<p>The function composition <span style=\"font-family: courier new,courier;\">isUpper(head x)<\/span> checks for each word if it starts (<span style=\"font-family: courier new,courier;\">head x<\/span>) with a capital letter\u00a0 (<span style=\"font-family: courier new,courier;\">isUpper<\/span>) ist.<\/p>\n<p>Two quick remarks to <span style=\"font-family: courier new,courier;\">std::remove_if. std::remove_if<\/span> removes no element but returns the list&#8217;s new logical end. Afterward, you have to apply the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Erase%E2%80%93remove_idiom\">erase-remove idiom<\/a>. The logic of <span style=\"font-family: courier new,courier;\">std::remove_if<\/span> is the other way around. It will remove the elements satisfying the condition. Therefore, I have to negate the condition.<\/p>\n<h4>fold<\/h4>\n<p><span style=\"font-family: courier new,courier;\">fold<\/span> is the most powerful of the three higher-order functions. You can implement <span style=\"font-family: courier new,courier;\">map<\/span> and <span style=\"font-family: courier new,courier;\">filter<\/span> by using <span style=\"font-family: courier new,courier;\">fold.<\/span> The code snippet shows the calculation of the faculty of 9 and string concatenation in Haskell, Python, and C++.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ Haskell<\/span>\nfoldl (\\a b -&gt; a * b) 1 vec\nfoldl (\\a b -&gt; a ++ <span style=\"color: #a31515;\">\":\"<\/span> ++ b ) <span style=\"color: #a31515;\">\"\"<\/span> str\n\n<strong><span style=\"color: #008000;\">\/\/Python<\/span><\/strong>\nreduce(lambda a , b: a * b, vec, 1)\nreduce(lambda a, b: a + <span style=\"color: #a31515;\">\":\"<\/span> + b, str, <span style=\"color: #a31515;\">\"\"<\/span>)\n\n<span style=\"color: #008000;\">\/\/ C++<\/span>\nstd::accumulate(vec.begin(), vec.end(), 1,\n                [](<span style=\"color: #2b91af;\">int<\/span> a, <span style=\"color: #2b91af;\">int<\/span> b){ <span style=\"color: #0000ff;\">return<\/span> a*b; });  \nstd::accumulate(str.begin(), str.end(), string(<span style=\"color: #a31515;\">\"\"<\/span>),\n                [](std::string a,std::string b){ <span style=\"color: #0000ff;\">return<\/span> a+<span style=\"color: #a31515;\">\":\"<\/span>+b; });\n\n<strong><span style=\"color: #008000;\">\/\/ 362800 <\/span>\n<span style=\"color: #008000;\">\/\/ \":Programming:in:a:functional:style.\"\n<\/span><\/strong>\n<\/pre>\n<\/div>\n<p><span style=\"font-family: courier new,courier;\">foldl<\/span> needs as the Python pendant <span style=\"font-family: courier new,courier;\">reduce<\/span> and the C++ pendant <span style=\"font-family: courier new,courier;\">std::accumulate<\/span> an initial value. This is in the case of the faculty the 1; this is in the case of the string concatenation the empty string &#8220;&#8221;.\u00a0 Haskell requires two ++ symbols for adding two strings; Python and C++ only one.<\/p>\n<p>The strategy of <span style=\"font-family: courier new,courier;\">std::accumulate<\/span> is a little bit difficult to get. Therefore, I have a graphic visualization of the processing.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5149\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/fold.png\" alt=\"fold\" width=\"600\" height=\"295\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/fold.png 845w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/fold-300x148.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/fold-768x378.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>In the first iteration, the initial value 1 together with the first value of the input sequence is used as the arguments for the lambda function: <span style=\"font-family: courier new,courier;\">1*1= 1<\/span>. The result 1 is the first argument for the lambda function in the second iteration: <span style=\"font-family: courier new,courier;\">1*2= 2.<\/span> The third iteration has the previous result 2 as the first argument: <span style=\"font-family: courier new,courier;\">2*3= 6<\/span>. The last iteration returns the final result 24.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Pure functional languages such as Haskell have the characteristic that their data is immutable. Therefore, Haskell can not have a <span style=\"font-family: courier new,courier;\">for,<\/span> <span style=\"font-family: courier new,courier;\">while,<\/span> or <span style=\"font-family: courier new,courier;\">until<\/span> loop. In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/immutable-data\">next post<\/a>, I will write about the consequences of Haskell.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Higher-order functions are the pendant to First-Class Functions because higher-order functions can take functions as an argument or return them as a result.<\/p>\n","protected":false},"author":21,"featured_media":5145,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[],"class_list":["post-5150","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5150"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5150\/revisions"}],"predecessor-version":[{"id":9771,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5150\/revisions\/9771"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5145"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}