<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <!-- 2017-10-16 Mon 10:10 --> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Functional Programming in JavaScript</title> <meta name="generator" content="Org mode" /> <meta name="author" content="Alan Pearce" /> <meta name="version" content="S5 1.2a2" /> <meta name='defaultView' content='slideshow' /> <meta name='controlVis' content='hidden' /> <!-- style sheet links --> <link rel='stylesheet' href='ui/default/outline.css' type='text/css' media='screen' id='outlineStyle' /> <link rel='stylesheet' href='ui/default/print.css' type='text/css' media='print' id='slidePrint' /> <link rel='stylesheet' href='ui/default/opera.css' type='text/css' media='projection' id='operaFix' /> <link rel='stylesheet' href='ui/default/slides.css' type='text/css' media='screen' id='slideProj' /> <!-- S5 JS --> <script src='ui/default/slides.js' type='text/javascript'></script> </head> <body> <div class="layout"> <div id="controls"><!-- no edit --></div> <div id="currentSlide"><!-- no edit --></div> <div id="header" class="status">   </div> <div id="footer" class="status"> <h1>Alan Pearce - Functional Programming in JavaScript</h1> </div> </div> <div id="content" class="presentation"> <div id='title-slide' class='slide'> <h1>Functional Programming in JavaScript</h1> <h2></h2> <h2>Alan Pearce</h2> <h3><a href="mailto:alan@alanpearce.eu">alan@alanpearce.eu</a></h3> <h4></h4> </div> <div id='table-of-contents' class='slide'> <h1>Table of Contents</h1> <div id="text-table-of-contents"> <ul> <li>1. Why?</li> <li>2. Concepts</li> <li>3. Further concepts</li> <li>4. First-class functions</li> <li>5. Higher-order functions</li> <li>6. Higher-order functions (cont.)</li> <li>7. Pure functions</li> <li>8. Recursion</li> <li>9. Partial application</li> <li>10. Partial application (cont.)</li> <li>11. Currying</li> <li>12. Easy Currying</li> <li>13. Practical Currying</li> <li>14. Functional composition</li> <li>15. Functional composition (cont.)</li> <li>16. pipe</li> <li>17. Point-free programming</li> <li>18. Further Resources</li> </ul> </div> </div> <div id="outline-container-org05e10f9" class="outline-1 slide"> <h1 id="org05e10f9"><span class="section-number-1">1</span> Why?</h1> <div class="outline-text-1" id="text-1"> <p> Imperative programming is concerned with <b>how</b> </p> <p> Functional programming is concerned with <b>what</b> </p> </div> </div> <div id="outline-container-org14fa5d9" class="outline-1 slide"> <h1 id="org14fa5d9"><span class="section-number-1">2</span> Concepts</h1> <div class="outline-text-1" id="text-2"> <ul class="org-ul"> <li>First-class Functions</li> <li>Higher-order Functions</li> <li>Recursion</li> <li>Pure functions</li> <li>Currying & Partial Application</li> </ul> </div> </div> <div id="outline-container-orgd930436" class="outline-1 slide"> <h1 id="orgd930436"><span class="section-number-1">3</span> Further concepts</h1> <div class="outline-text-1" id="text-3"> <ul class="org-ul"> <li>Lazy Evaluation</li> <li>Types & Data Structures</li> <li>Category Theory</li> </ul> </div> </div> <div id="outline-container-orgbd39891" class="outline-1 slide"> <h1 id="orgbd39891"><span class="section-number-1">4</span> First-class functions</h1> <div class="outline-text-1" id="text-4"> <ul class="org-ul"> <li>Are values</li> <li>Have no restriction on their use</li> <li>Enable the use of callback functions in JavaScript</li> </ul> <p> </p> <div class="org-src-container"> <pre><code class="src src-js">var fn = function () { return 2 } </code></pre> </div> </div> </div> <div id="outline-container-org8d1ee8a" class="outline-1 slide"> <h1 id="org8d1ee8a"><span class="section-number-1">5</span> Higher-order functions</h1> <div class="outline-text-1" id="text-5"> <p> Functions that operate on other functions are higher-order functions </p> <p> </p> <div class="org-src-container"> <pre><code class="src src-js">var succ = function (x) { return x + 1 } var arr = [1, 2, 3, 4] arr.map(succ) </code></pre> </div> <p> Here, <code>Array.prototype.map</code> is the higher-order function </p> </div> </div> <div id="outline-container-org3bbf4ac" class="outline-1 slide"> <h1 id="org3bbf4ac"><span class="section-number-1">6</span> Higher-order functions (cont.)</h1> <div class="outline-text-1" id="text-6"> <p> Functions that return functions are also higher-order functions </p> <p> </p> <div class="org-src-container"> <pre><code class="src src-js">function <span style="font-weight: bold;">adder</span> (n) { return function (x) { return n + x } } var add1 = adder(1) </code></pre> </div> <p> <code>adder</code> is a higher-order function </p> </div> </div> <div id="outline-container-orgfb6eee2" class="outline-1 slide"> <h1 id="orgfb6eee2"><span class="section-number-1">7</span> Pure functions</h1> <div class="outline-text-1" id="text-7"> <p> Functions without side-effects </p> <div class="org-src-container"> <pre><code class="src src-js">var succ = (x) => x + 1 console.log(succ(succ(1))) <span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">// </span><span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">could be optimised away by a compiler, e.g.:</span> console.log(3) </code></pre> </div> </div> </div> <div id="outline-container-org16e9966" class="outline-1 slide"> <h1 id="org16e9966"><span class="section-number-1">8</span> Recursion</h1> <div class="outline-text-1" id="text-8"> <p> Functions that call themselves </p> <div class="org-src-container"> <pre><code class="src src-js">function <span style="font-weight: bold;">fibonacci</span> (n) { switch (n) { case 0: case 1: return 1 default: return fibonacci(n - 1) + fibonacci(n - 2) } } </code></pre> </div> </div> </div> <div id="outline-container-org1b7b0af" class="outline-1 slide"> <h1 id="org1b7b0af"><span class="section-number-1">9</span> Partial application</h1> <div class="outline-text-1" id="text-9"> <p> The infamous <code>Function.prototype.bind</code> in JavaScript </p> <div class="org-src-container"> <pre><code class="src src-js">function <span style="font-weight: bold;">add</span> (x, y) { return x + y } var add1 = add.bind(add, 1) add1(3) <span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">// </span><span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">= 4</span> </code></pre> </div> </div> </div> <div id="outline-container-org796e6d3" class="outline-1 slide"> <h1 id="org796e6d3"><span class="section-number-1">10</span> Partial application (cont.)</h1> <div class="outline-text-1" id="text-10"> <p> After ES6 introduced arrow functions, partial application has become more popular </p> <div class="org-src-container"> <pre><code class="src src-js">var add = x => y => x + y </code></pre> </div> </div> </div> <div id="outline-container-orgeb4d67b" class="outline-1 slide"> <h1 id="orgeb4d67b"><span class="section-number-1">11</span> Currying</h1> <div class="outline-text-1" id="text-11"> <p> Related to partial application, but more implicit and general </p> <p> Translates <b><i>1</i> function of arity <i>n</i></b> to <b><i>n</i> functions of arity <i>1</i></b> </p> <div class="org-src-container"> <pre><code class="src src-js">function <span style="font-weight: bold;">volume</span> (w, d, h) { return w * d * h } var vol = curry(volume) vol(10)(20)(30) <span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">// </span><span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">is strictly equivalent to</span> volume(10, 20, 30) </code></pre> </div> </div> </div> <div id="outline-container-orgdfd8353" class="outline-1 slide"> <h1 id="orgdfd8353"><span class="section-number-1">12</span> Easy Currying</h1> <div class="outline-text-1" id="text-12"> <p> In order to make currying (and partial application) easier to use, move the <b>most important</b> argument to a function to the end: </p> <div class="org-src-container"> <pre><code class="src src-js">var badMap = (arr, fn) => arr.map(fn) var goodMap = (fn, arr) => arr.map(fn) var curriedBadMap = curry(badmap) var curriedGoodMap = curry(goodMap) var goodDoubleArray = goodMap(x => x * 2) var badDoubleArray = badMap(_, x => x * 2) </code></pre> </div> <p> The bad version requires the curry function to support a magic placeholder argument and doesn't look as clean. </p> </div> </div> <div id="outline-container-org30accd5" class="outline-1 slide"> <h1 id="org30accd5"><span class="section-number-1">13</span> Practical Currying</h1> <div class="outline-text-1" id="text-13"> <p> Currying is not automatic in JavaScript, as in other languages </p> <p> External tools aren't (so far) able to statically analyse curried functions </p> <p> Solution: Don't expose curried functions Instead, write functions as if currying were automatic </p> <p> If consumers want to curry, they can. If they don't, their editor or language server will show them the arguments </p> </div> </div> <div id="outline-container-org5f352dc" class="outline-1 slide"> <h1 id="org5f352dc"><span class="section-number-1">14</span> Functional composition</h1> <div class="outline-text-1" id="text-14"> <p> Creating functions from other functions </p> <p> Usually provided by <code>compose</code> (right-to-left) and <code>pipe</code> (left-to-right) </p> <p> A very simple definition of <code>compose</code> for only two functions would look like this </p> <div class="org-src-container"> <pre><code class="src src-js">function <span style="font-weight: bold;">compose</span> (f, g) { return function (...args) { return f(g(...args)) } } </code></pre> </div> </div> </div> <div id="outline-container-org0c2c4f9" class="outline-1 slide"> <h1 id="org0c2c4f9"><span class="section-number-1">15</span> Functional composition (cont.)</h1> <div class="outline-text-1" id="text-15"> <div class="org-src-container"> <pre><code class="src src-js">var plusOne = x => x + 1 var timesTwo = x => x * 2 var plusOneTimesTwo = compose(timesTwo, plusOne) var timesTwoPlusOne = compose(plusOne, timesTwo) nextDoubled(3) <span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">// </span><span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">= (3 + 1) * 2 = 8</span> doubledPlusOne(3) <span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">// </span><span style="color: #b8b8b8; background-color: #f8f8f8; font-style: italic;">= (3 * 2) + 1 = 7</span> </code></pre> </div> </div> </div> <div id="outline-container-orgddc61f6" class="outline-1 slide"> <h1 id="orgddc61f6"><span class="section-number-1">16</span> pipe</h1> <div class="outline-text-1" id="text-16"> <p> What about <code>pipe</code>? </p> <p> <code>pipe</code> does the same thing, but runs the functions the other way around </p> <p> <code>pipe(f, g)</code> is the same as <code>compose(g, f)</code> </p> </div> </div> <div id="outline-container-org7426c58" class="outline-1 slide"> <h1 id="org7426c58"><span class="section-number-1">17</span> Point-free programming</h1> <div class="outline-text-1" id="text-17"> <p> With currying and higher-order functions, we (often) don't need to declare function arguments </p> <div class="org-src-container"> <pre><code class="src src-js">var modulo = a => b => b % a var eq = a => b => a === b var isEven = x => eq(0)(modulo(2)(x)) var isEvenPointFree = compose(eq(0), modulo(2)) </code></pre> </div> </div> </div> <div id="outline-container-org8868cfb" class="outline-1 slide"> <h1 id="org8868cfb"><span class="section-number-1">18</span> Further Resources</h1> <div class="outline-text-1" id="text-18"> <ul class="org-ul"> <li><a href="https://drboolean.gitbooks.io/mostly-adequate-guide/content/">Mostly adequate guide to FP (in javascript)</a></li> <li><a href="http://ramdajs.com/">Ramda</a>, a general-purpose FP library</li> <li><a href="https://sanctuary.js.org/">Sanctuary</a>, a JavaScript library for Haskellers</li> </ul> </div> </div> </div> </body> </html>