{"categories":["Principles of Programming Languages"],"contentHtml":"<p>We can do a lot of cool things with functions besides calling them in OCaml.</p>\n<h2>Anonymous Functions</h2>\n<p>Values are a subset of expressions, as previously stated. All expressions can evaluate to values, but values are final.</p>\n<p><strong>Anonymous functions</strong> are also values. Sometimes, it's more convenient not to create and name a whole new function for our purpose. Anonymous functions are ad hoc functions that exist as values in expressions. They are expressed using the keyword <code>fun</code>.</p>\n<pre><code>let y = fun x -&gt; x + 3\n</code></pre>\n<p>This might not seem to have much benefit compared to a full function definition, but it is very useful within <code>let</code> expressions. Since anonymous functions are values, not just expressions, they can be manipulated far more powerfully than even general expressions.</p>\n<pre><code>let y = (fun x -&gt; x + 1) 2 in\n(fun z -&gt; z - 2) y\n</code></pre>\n<p>This code might seem a little hard to parse, but it's easier to think about if we rewrite it to use traditional function definitions.</p>\n<pre><code>let f x =\n    x + 1\nlet g z =\n    z - 2\nlet y = f 2 in\ng y\n</code></pre>\n<p>Now we can tell that <code>y</code> is 3 in the function <code>g</code>, which then evaluates to 1. However, the former code snippet is a much terser way to write this expression  if we don't need the functions <code>f</code> and <code>g</code> anymore.</p>\n<p>One good way to think about it is that anonymous functions are to regular functions as literals are to variables. If we only need to use the value <code>\"really_long_string\"</code> once, we don't need to store it in a variable. On the other hand, it can be useful to store that literal in a variable <code>s</code> that is much shorter to write. Similarly, if we only need to use the function <code>x -&gt; x + 1</code> once, we don't need to store it in a function variable.</p>\n<p>In fact, this isn't even an analogy. Functions are first-class in OCaml, so regular functions are just variables that store anonymous functions:</p>\n<pre><code>let f x = body\n(* this is sugar for this *)\nlet f = fun x -&gt; body\n</code></pre>\n<p>And in the same vein, we can name functions within <code>let</code> expressions in an anonymous ways.</p>\n<pre><code>let move l x =\n    let left x = x - 1 in\n    let right x = x + 1 in\n    if l then left x\n    else      right x\n;;\n(* same as *)\nlet move' l x =\n    if l then (fun y -&gt; y - 1) x\n    else      (fun y -&gt; y + 1) x\n</code></pre>\n<p>Note also that the local variable in the anonymous function doesn't actually matter to the expression it's used in; this is a consequence of the shadowing rules of OCaml.</p>\n<p>There are several functions in the standard library of OCaml that use higher order functions.</p>\n<h2>Map</h2>\n<p><code>map</code> is a function in the <code>List</code> module of OCaml. Like the name implies, this function maps a function onto every element of a list and returns that list. It has type <code>('a -&gt; 'b) -&gt; 'a list -&gt; 'b list</code>.</p>\n<pre><code>let rec map f l =\n    match l with\n    | [] -&gt; []\n    | h :: t -&gt; (f h) :: (map f t)\n</code></pre>\n<p>This is a simple, yet powerful and useful function. That's why it is included in the <code>List</code> module, although it's trivial to write yourself.</p>\n<h2>Fold</h2>\n<p><code>fold</code> is another function in the <code>List</code> module in OCaml, that iterates over a list. The essential idea is that you have an accumulator variable that you want to get based on the values in a list.</p>\n<pre><code>let rec fold f acc l =\n    match l with\n    | [] -&gt; acc\n    | h :: t -&gt; fold f (f acc h) t\n</code></pre>\n<p>For example, this is a way to implement a sum function using <code>fold</code>.</p>\n<pre><code>let rec sum acc l =\n    match l with\n    | [] -&gt; acc\n    | h :: t -&gt; sum (acc + h) t\nsum 0 [2; 5; 100; 53];;\n(* same as *)\nfold (fun acc x -&gt; acc + x) 0 [2; 5; 100; 53];;\n</code></pre>\n<p>Its type is <code>('a -&gt; 'b -&gt; 'a) -&gt; 'a -&gt; 'b list -&gt; 'a</code>. We can deconstruct that and understand each part of the function. The initial function <code>f</code> applies the type <code>'b</code> to <code>'a</code> and returns <code>'a</code>. Then for the next two arguments, we keep the same <code>'a</code> accumulator and iterate over the <code>'b list</code>.</p>\n<p>The use of an accumulator makes <code>fold</code> very versatile, since you can put anything in there.</p>\n<p>We can combine <code>map</code> and <code>fold</code> to create the <em>map/reduce</em> framework which can be massively parallelized. We first map a function over our list, then we reduce the list into a single accumulator value.</p>\n<p>There is also an alternative version of <code>fold</code> called <code>fold_right</code> that works in reverse, which can be better for certain problems. However, it comes with steep performance cost: every recursive call builds a new stack frame. The original <code>fold</code> is able to optimize this call away by using tail recursion.</p>","contentMarkdown":"We can do a lot of cool things with functions besides calling them in OCaml.\n\n## Anonymous Functions\n\nValues are a subset of expressions, as previously stated. All expressions can evaluate to values, but values are final.\n\n**Anonymous functions** are also values. Sometimes, it's more convenient not to create and name a whole new function for our purpose. Anonymous functions are ad hoc functions that exist as values in expressions. They are expressed using the keyword `fun`.\n\n```ocaml\nlet y = fun x -> x + 3\n```\n\nThis might not seem to have much benefit compared to a full function definition, but it is very useful within `let` expressions. Since anonymous functions are values, not just expressions, they can be manipulated far more powerfully than even general expressions.\n\n```ocaml\nlet y = (fun x -> x + 1) 2 in\n(fun z -> z - 2) y\n```\n\nThis code might seem a little hard to parse, but it's easier to think about if we rewrite it to use traditional function definitions.\n\n```ocaml\nlet f x =\n    x + 1\nlet g z =\n    z - 2\nlet y = f 2 in\ng y\n```\n\nNow we can tell that `y` is 3 in the function `g`, which then evaluates to 1. However, the former code snippet is a much terser way to write this expression  if we don't need the functions `f` and `g` anymore.\n\nOne good way to think about it is that anonymous functions are to regular functions as literals are to variables. If we only need to use the value `\"really_long_string\"` once, we don't need to store it in a variable. On the other hand, it can be useful to store that literal in a variable `s` that is much shorter to write. Similarly, if we only need to use the function `x -> x + 1` once, we don't need to store it in a function variable.\n\nIn fact, this isn't even an analogy. Functions are first-class in OCaml, so regular functions are just variables that store anonymous functions:\n\n```ocaml\nlet f x = body\n(* this is sugar for this *)\nlet f = fun x -> body\n```\n\nAnd in the same vein, we can name functions within `let` expressions in an anonymous ways.\n\n```ocaml\nlet move l x =\n    let left x = x - 1 in\n    let right x = x + 1 in\n    if l then left x\n    else      right x\n;;\n(* same as *)\nlet move' l x =\n    if l then (fun y -> y - 1) x\n    else      (fun y -> y + 1) x\n```\n\nNote also that the local variable in the anonymous function doesn't actually matter to the expression it's used in; this is a consequence of the shadowing rules of OCaml.\n\nThere are several functions in the standard library of OCaml that use higher order functions.\n\n## Map\n\n`map` is a function in the `List` module of OCaml. Like the name implies, this function maps a function onto every element of a list and returns that list. It has type `('a -> 'b) -> 'a list -> 'b list`.\n\n```ocaml\nlet rec map f l =\n    match l with\n    | [] -> []\n    | h :: t -> (f h) :: (map f t)\n```\n\nThis is a simple, yet powerful and useful function. That's why it is included in the `List` module, although it's trivial to write yourself.\n\n## Fold\n\n`fold` is another function in the `List` module in OCaml, that iterates over a list. The essential idea is that you have an accumulator variable that you want to get based on the values in a list. \n\n```ocaml\nlet rec fold f acc l =\n    match l with\n    | [] -> acc\n    | h :: t -> fold f (f acc h) t\n```\n\nFor example, this is a way to implement a sum function using `fold`.\n\n```ocaml\nlet rec sum acc l =\n    match l with\n    | [] -> acc\n    | h :: t -> sum (acc + h) t\nsum 0 [2; 5; 100; 53];;\n(* same as *)\nfold (fun acc x -> acc + x) 0 [2; 5; 100; 53];;\n```\n\nIts type is `('a -> 'b -> 'a) -> 'a -> 'b list -> 'a`. We can deconstruct that and understand each part of the function. The initial function `f` applies the type `'b` to `'a` and returns `'a`. Then for the next two arguments, we keep the same `'a` accumulator and iterate over the `'b list`.\n\nThe use of an accumulator makes `fold` very versatile, since you can put anything in there.\n\nWe can combine `map` and `fold` to create the *map/reduce* framework which can be massively parallelized. We first map a function over our list, then we reduce the list into a single accumulator value.\n\nThere is also an alternative version of `fold` called `fold_right` that works in reverse, which can be better for certain problems. However, it comes with steep performance cost: every recursive call builds a new stack frame. The original `fold` is able to optimize this call away by using tail recursion.","dataUrl":"https://sharifhsn.dev/api/posts/higher-order-functions.json","date":"2022-02-08","datePublished":"2022-02-08","description":"We can do a lot of cool things with functions besides calling them in OCaml.","site":"https://sharifhsn.dev","slug":"higher-order-functions","source":"Archive","sourceUrl":null,"tags":["Principles of Programming Languages"],"title":"Higher Order Functions in OCaml","url":"https://sharifhsn.dev/blog/higher-order-functions/","version":"1","wordCount":863}