diff options
author | Alan Pearce | 2017-10-24 12:04:46 +0200 |
---|---|---|
committer | Alan Pearce | 2017-10-24 12:05:23 +0200 |
commit | e5cb8f1ef60c36d29d66bf8dbb25365423b9b3c8 (patch) | |
tree | 2c320e6ff4d0985bb954cd4fe48b89898ea68609 /static/talks/fp-js/slides.html | |
parent | f4dcf84c09035725b0a735b072064c560ef39840 (diff) | |
download | website-e5cb8f1ef60c36d29d66bf8dbb25365423b9b3c8.tar.lz website-e5cb8f1ef60c36d29d66bf8dbb25365423b9b3c8.tar.zst website-e5cb8f1ef60c36d29d66bf8dbb25365423b9b3c8.zip |
Add fp-js talk
Diffstat (limited to 'static/talks/fp-js/slides.html')
-rw-r--r-- | static/talks/fp-js/slides.html | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/static/talks/fp-js/slides.html b/static/talks/fp-js/slides.html new file mode 100644 index 0000000..e90650c --- /dev/null +++ b/static/talks/fp-js/slides.html @@ -0,0 +1,431 @@ +<!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> |