Functional Programming in JavaScript SoCal Code Camp 12+13 Nov 2016
Troy Miles • Troy Miles aka the RocknCoder • Over 37 years of programming experience • Speaker and author • Author of jQuery Essentials • bit.ly/rc-jquerybook • rockncoder@gmail.com • @therockncoder
Build Mobile Apps! • Develop mobile apps with Ionic and AngularJS • Learn the Ionic CLI • Fetch data via ajax • Deploy your app to Android & iOS • bit.ly/ionicvideo
Code + Slides Online • https://github.com/Rockncoder/FP-JS • http://www.slideshare.net/rockncoder/functional- programming-in-javascript-66576643
The book • The Magical World of Functional Programming: Part 1: Thinking Functionally • by K Anand Kumar • http://amzn.to/1HPzRro
Our Agenda • What’s wrong with object-oriented programming? • A little background • Functional code samples • Let’s do a job interview • Summary
–Morpheus “What you know you can't explain, but you feel it. You've felt it your entire life, that there's something wrong with the world. You don't know what it is, but it's there, like a splinter in your mind, driving you mad.”
The Problem • JavaScript is one of the top languages in the world • It is difficult to develop big apps • It is tough to make readable code • Even tougher to make reusable code • It doesn’t fit well into an OOPs world
Maybe we’re doing it wrong.
–Brendan Eich “As I’ve often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of “doing Scheme” in the browser. Whether that language should be Scheme was an open question, but Scheme was the bait I went for in joining Netscape. Previously, at SGI, Nick Thompson had turned me on to SICP.”
What is Scheme? • One of two principal dialects of Lisp • Created at MIT AI Lab in the 1970’s • Developed by Guy L. Steele and Gerald Jay Susan
What is Lisp? • Created in 1958 by John McCarthy • Second oldest high-level language still in use today • Influenced by Alonzo Church’s lambda calculus
Lisp Innovations • recursive function • dynamically allocated memory • garbage collection • macros • lexical closures
What is Functional Programming?
Key Functional Features • Pure functions • First-class / High order functions • Immutable data • Recursion • Referential transparency
Functional vs. Imperative what? functional imperative primary construct function class instance state change bad important order of execution not important important flow control function calls recursion loops, conditionals, method calls
Sample Languages mostly functional mixed mostly imperative Lisp/Scheme JavaScript Java ML Scala C# Haskell Python C++ Clojure Dart Swift F# Lua Ruby Erlang R Kotlin
Pure Functions • Must return a value • Can’t produce any side-effects • Must return the same output for a given input
Pure Functions Are Super • Cacheable • Portable • Self-documenting • Testable • Reasonable
First-Class Functions • Treats functions as first class citizens • Assigned to variables & stored in arrays • Anonymous and nested functions • Higher-order functions
Higher-Order Functions • Takes one or more functions as arguments • Or returns a function as its results • Allows for the creation of function factories • This is the core of the curry function
Code Samples
Pure Function 4 5 function pure(age){ 6 const minimum = 21; 7 return age >= minimum; 8 } 9
Partial Application 4 (function(){ 5 'use strict'; 6 7 // a simple function factory 8 function addN(n){ 9 10 // a function is returned!!! 11 return function(x){ 12 return n + x; 13 } 14 } 15 16 // let's create two functions, add10 and add50 17 let add10 = addN(10); 18 let add50 = addN(50); 19 20 // they don't interfere with each other or share variable or state 21 console.info(add10(1)); 22 console.info(add50(1)); 23 console.info(add10(5)); 24 }());
Composition • Combines simple functions to create more complex ones • Almost all programming languages allow it • but those with first-class functions make it easier • encourages factoring functions and code reuse
Composition 1 // JS doesn't have compose built-in 2 3 let compose = function(f, g){ 4 return function(x){ 5 return f(g(x)); 6 } 7 }; 8
Recursion • Functional languages use recursion instead loops • Recursion allows to break the problem into smaller bits • Unfortunately most non-functional languages implement recursion poorly
Recursive Function 7 function printNumbers(from, to) { 8 console.info(from); 9 if (from !== to) { 10 printNumbers(from + 1, to); 11 } 12 } 13 14 printNumbers(1, 100); 15
Let’s code fizz buzz
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
fizz buzz - chapter 1 Just make it work • The code looks like it came from a 1st year comp sci majors homework assignment • It works, but it you really have to think about what it does and why
fizz buzz - chapter 2 Separation of concerns • It could be argued that we made things worse • Our 12 line program is now 36 lines (with comments and spacing) • But it is easy to understand
ES5 Array Methods • .isArray() • .every() • .forEach() • .indexOf() • .lastIndexOf() • .some() • .map() • .reduce() • .filter()
map let junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // map iterates over all of the elements and // returns a new array with the same number of elements 
 let nums2 = nums.map((elem) => elem * 2); console.info(nums2);
filter let junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // filter iterates over the array and returns a new array with only the elements // that pass the test 
 let nums3 = nums.filter((elem) => !!(elem % 2));
 console.info(nums3);
reduce let junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // reduce iterates over the array passing the previous value and the current
 // element it is up to you what the reduction does, let's concatenate the strings 
 let letters2 = letters.reduce((previous, current) => previous + current);
 console.info(letters2);
 
 // reduceRight does the same but goes from right to left 
 let letters3 = letters.reduceRight((previous, current) => previous + current);
 console.info(letters3);
every let junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // every makes sure that all the elements match the expression 
 let isEveryNumbers = junk.every((elem) => typeof elem === 'number');
 console.info('Are all members of junk numbers: ' + isEveryNumbers);
forEach let junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // forEach iterates over the array, once for each element, // but there is no way to break out of the loop (break doesn't work) 
 nums.forEach(function (elem, index, arr) {
 console.info(index + ': ' + elem);
 });
fizz buzz - chapter 3 Hidden jewels from ES5 • In this version we take advantage of the array methods from ES5 • The controller uses the map and forEach methods • We use the reduce method to de-clutter formatOutput()
fizz buzz - chapter 4 Harnessing functions • The test function has been a bit of a mess • We break into 3 functions, initialize, fizz, and buzz • Each function is descriptive and we follow the flow
fizz buzz - side bar #1 A little more of array.from • Creates arrays from something else • Can convert a string, arguments, or anything with a length and indexed elements • We use it to create our initial array
fizz buzz - chapter 5 Fun, fun, function factory • The code from our last chapter had redundancies • Each test was the same except, test value and the message • A function factory now creates the test for us • Technical term is a partial application
fizz buzz - chapter 6 Move to a higher level • Functional programming is a level of abstraction above imperative • We focus on what we want, not so much how to it • Now we easily add a new test
fizz buzz - chapter 7 Better together • Another functional concept is composition • It allows us to combine functions together to build new functions • We use it to combine our test and format functions
fizz buzz - chapter 8 Are we done yet? • We have a created another partial application to create our controller • We pass it the test, format, and print functions • We should probably stop here
fizz buzz - chapter 9 The step too far • We should have stopped but we didn’t • There are a lot unneeded intermediate variables • We’ve chucked them and simply pass the controllerMaker() everything • Since it returns us a function, we don’t have to save it, we can just invoke it
Functional Libraries • Partial applications, compose, and other functional constructs should be part of the language • For this reason JavaScript isn’t consider a true functional language • You don’t have code it all yourself • There are several libraries out there to help you
Functional JS Libraries • http://underscorejs.org/ • https://lodash.com/ • http://ramdajs.com/ • http://eliperelman.com/fn.js/
Resources • http://amzn.to/1HPzRro • http://sarabander.github.io/sicp/ • http://c2.com/cgi/wiki?FizzBuzzTest • https://kangax.github.io/compat-table/es6/ • https://github.com/Rockncoder/FP-JS • http://www.slideshare.net/rockncoder/functional- programming-in-javascript-55110091
Next Steps… • Play with the code • Read the “Magical World of Functional Programming” • Read Structure and Interpretation of Computer Programs (SICP) free online
Summary • Functional techniques can give us a higher degree of reusability of code than is normally possible with OOP • Pure functions permit memoization, a caching technique • JavaScript supports many FP concepts • Most of those it lacks can be created
–Edsger Dijkstra “Object-oriented programming is an exceptionally bad idea which could only have originated in California.”

Functional Programming in JavaScript

  • 1.
  • 2.
    Troy Miles • TroyMiles aka the RocknCoder • Over 37 years of programming experience • Speaker and author • Author of jQuery Essentials • bit.ly/rc-jquerybook • rockncoder@gmail.com • @therockncoder
  • 3.
    Build Mobile Apps! •Develop mobile apps with Ionic and AngularJS • Learn the Ionic CLI • Fetch data via ajax • Deploy your app to Android & iOS • bit.ly/ionicvideo
  • 6.
    Code + SlidesOnline • https://github.com/Rockncoder/FP-JS • http://www.slideshare.net/rockncoder/functional- programming-in-javascript-66576643
  • 7.
    The book • TheMagical World of Functional Programming: Part 1: Thinking Functionally • by K Anand Kumar • http://amzn.to/1HPzRro
  • 8.
    Our Agenda • What’swrong with object-oriented programming? • A little background • Functional code samples • Let’s do a job interview • Summary
  • 9.
    –Morpheus “What you knowyou can't explain, but you feel it. You've felt it your entire life, that there's something wrong with the world. You don't know what it is, but it's there, like a splinter in your mind, driving you mad.”
  • 10.
    The Problem • JavaScriptis one of the top languages in the world • It is difficult to develop big apps • It is tough to make readable code • Even tougher to make reusable code • It doesn’t fit well into an OOPs world
  • 11.
  • 12.
    –Brendan Eich “As I’veoften said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of “doing Scheme” in the browser. Whether that language should be Scheme was an open question, but Scheme was the bait I went for in joining Netscape. Previously, at SGI, Nick Thompson had turned me on to SICP.”
  • 13.
    What is Scheme? •One of two principal dialects of Lisp • Created at MIT AI Lab in the 1970’s • Developed by Guy L. Steele and Gerald Jay Susan
  • 14.
    What is Lisp? •Created in 1958 by John McCarthy • Second oldest high-level language still in use today • Influenced by Alonzo Church’s lambda calculus
  • 15.
    Lisp Innovations • recursivefunction • dynamically allocated memory • garbage collection • macros • lexical closures
  • 16.
    What is FunctionalProgramming?
  • 17.
    Key Functional Features •Pure functions • First-class / High order functions • Immutable data • Recursion • Referential transparency
  • 18.
    Functional vs. Imperative what?functional imperative primary construct function class instance state change bad important order of execution not important important flow control function calls recursion loops, conditionals, method calls
  • 19.
    Sample Languages mostly functionalmixed mostly imperative Lisp/Scheme JavaScript Java ML Scala C# Haskell Python C++ Clojure Dart Swift F# Lua Ruby Erlang R Kotlin
  • 20.
    Pure Functions • Mustreturn a value • Can’t produce any side-effects • Must return the same output for a given input
  • 21.
    Pure Functions AreSuper • Cacheable • Portable • Self-documenting • Testable • Reasonable
  • 22.
    First-Class Functions • Treatsfunctions as first class citizens • Assigned to variables & stored in arrays • Anonymous and nested functions • Higher-order functions
  • 23.
    Higher-Order Functions • Takesone or more functions as arguments • Or returns a function as its results • Allows for the creation of function factories • This is the core of the curry function
  • 24.
  • 25.
    Pure Function 4 5 functionpure(age){ 6 const minimum = 21; 7 return age >= minimum; 8 } 9
  • 26.
    Partial Application 4 (function(){ 5'use strict'; 6 7 // a simple function factory 8 function addN(n){ 9 10 // a function is returned!!! 11 return function(x){ 12 return n + x; 13 } 14 } 15 16 // let's create two functions, add10 and add50 17 let add10 = addN(10); 18 let add50 = addN(50); 19 20 // they don't interfere with each other or share variable or state 21 console.info(add10(1)); 22 console.info(add50(1)); 23 console.info(add10(5)); 24 }());
  • 27.
    Composition • Combines simplefunctions to create more complex ones • Almost all programming languages allow it • but those with first-class functions make it easier • encourages factoring functions and code reuse
  • 28.
    Composition 1 // JSdoesn't have compose built-in 2 3 let compose = function(f, g){ 4 return function(x){ 5 return f(g(x)); 6 } 7 }; 8
  • 29.
    Recursion • Functional languagesuse recursion instead loops • Recursion allows to break the problem into smaller bits • Unfortunately most non-functional languages implement recursion poorly
  • 30.
    Recursive Function 7 functionprintNumbers(from, to) { 8 console.info(from); 9 if (from !== to) { 10 printNumbers(from + 1, to); 11 } 12 } 13 14 printNumbers(1, 100); 15
  • 31.
  • 32.
    Write a programthat prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
  • 33.
    fizz buzz -chapter 1 Just make it work • The code looks like it came from a 1st year comp sci majors homework assignment • It works, but it you really have to think about what it does and why
  • 34.
    fizz buzz -chapter 2 Separation of concerns • It could be argued that we made things worse • Our 12 line program is now 36 lines (with comments and spacing) • But it is easy to understand
  • 35.
    ES5 Array Methods •.isArray() • .every() • .forEach() • .indexOf() • .lastIndexOf() • .some() • .map() • .reduce() • .filter()
  • 36.
    map let junk =[1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // map iterates over all of the elements and // returns a new array with the same number of elements 
 let nums2 = nums.map((elem) => elem * 2); console.info(nums2);
  • 37.
    filter let junk =[1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // filter iterates over the array and returns a new array with only the elements // that pass the test 
 let nums3 = nums.filter((elem) => !!(elem % 2));
 console.info(nums3);
  • 38.
    reduce let junk =[1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // reduce iterates over the array passing the previous value and the current
 // element it is up to you what the reduction does, let's concatenate the strings 
 let letters2 = letters.reduce((previous, current) => previous + current);
 console.info(letters2);
 
 // reduceRight does the same but goes from right to left 
 let letters3 = letters.reduceRight((previous, current) => previous + current);
 console.info(letters3);
  • 39.
    every let junk =[1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // every makes sure that all the elements match the expression 
 let isEveryNumbers = junk.every((elem) => typeof elem === 'number');
 console.info('Are all members of junk numbers: ' + isEveryNumbers);
  • 40.
    forEach let junk =[1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}];
 let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
 let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
 console.info(nums);
 
 // forEach iterates over the array, once for each element, // but there is no way to break out of the loop (break doesn't work) 
 nums.forEach(function (elem, index, arr) {
 console.info(index + ': ' + elem);
 });
  • 41.
    fizz buzz -chapter 3 Hidden jewels from ES5 • In this version we take advantage of the array methods from ES5 • The controller uses the map and forEach methods • We use the reduce method to de-clutter formatOutput()
  • 42.
    fizz buzz -chapter 4 Harnessing functions • The test function has been a bit of a mess • We break into 3 functions, initialize, fizz, and buzz • Each function is descriptive and we follow the flow
  • 43.
    fizz buzz -side bar #1 A little more of array.from • Creates arrays from something else • Can convert a string, arguments, or anything with a length and indexed elements • We use it to create our initial array
  • 44.
    fizz buzz -chapter 5 Fun, fun, function factory • The code from our last chapter had redundancies • Each test was the same except, test value and the message • A function factory now creates the test for us • Technical term is a partial application
  • 45.
    fizz buzz -chapter 6 Move to a higher level • Functional programming is a level of abstraction above imperative • We focus on what we want, not so much how to it • Now we easily add a new test
  • 46.
    fizz buzz -chapter 7 Better together • Another functional concept is composition • It allows us to combine functions together to build new functions • We use it to combine our test and format functions
  • 47.
    fizz buzz -chapter 8 Are we done yet? • We have a created another partial application to create our controller • We pass it the test, format, and print functions • We should probably stop here
  • 48.
    fizz buzz -chapter 9 The step too far • We should have stopped but we didn’t • There are a lot unneeded intermediate variables • We’ve chucked them and simply pass the controllerMaker() everything • Since it returns us a function, we don’t have to save it, we can just invoke it
  • 49.
    Functional Libraries • Partialapplications, compose, and other functional constructs should be part of the language • For this reason JavaScript isn’t consider a true functional language • You don’t have code it all yourself • There are several libraries out there to help you
  • 50.
    Functional JS Libraries •http://underscorejs.org/ • https://lodash.com/ • http://ramdajs.com/ • http://eliperelman.com/fn.js/
  • 51.
    Resources • http://amzn.to/1HPzRro • http://sarabander.github.io/sicp/ •http://c2.com/cgi/wiki?FizzBuzzTest • https://kangax.github.io/compat-table/es6/ • https://github.com/Rockncoder/FP-JS • http://www.slideshare.net/rockncoder/functional- programming-in-javascript-55110091
  • 52.
    Next Steps… • Playwith the code • Read the “Magical World of Functional Programming” • Read Structure and Interpretation of Computer Programs (SICP) free online
  • 53.
    Summary • Functional techniquescan give us a higher degree of reusability of code than is normally possible with OOP • Pure functions permit memoization, a caching technique • JavaScript supports many FP concepts • Most of those it lacks can be created
  • 54.
    –Edsger Dijkstra “Object-oriented programmingis an exceptionally bad idea which could only have originated in California.”