Functional Programming in Javascript Teaches Javascript Developers Lauderdale, FL
Total Page:16
File Type:pdf, Size:1020Kb
217 » Hello FP! » Why Javascript? Functional Programming » Functional Programming » Functional Techniques » Functional Data Types in JavaScript CONTENTS » Interacting with the DOM, and more... By Luis Atencio DZone.com/refcardz Visit HELLO FP! with shorter notation compared to traditional function declaration. You could have lambda functions of multiple Functional programming is a software paradigm that will lines, but one-liners are the more common use case. Here’s radically change the way in which you approach any a simple example of a function used to add 2 numbers: programming endeavor. This is evident in this simple example: var add = (a, b) => a + b; document.getElementById('message').innerHTML = add(2, 3); //-> 5 '<h1>Hello FP!</h1>'; While this program is very trivial, without any effort, it can Get More Refcardz! Get More Refcardz! quickly become problematic. What if you wanted to change the formatting from an <h1> to an <h2>? Or change the target element? Inevitably, you would have to rewrite this statement again. Consider wrapping it all inside a function and making these data points function parameters. Let’s explore this further, but instead of using one big function, we’ll create smaller HIGH-ORDER FUNCTIONS functions and combine them all with a function called compose: In JavaScript, functions are first-class objects, which means they can be used in a first-class manner just like any other compose(addToDom, h1, echo('Hello FP!')); object. Hence, you can intuitively expect that functions Combining simple functions to create more meaningful can be assigned to variables, passed in as parameters, and programs is the central theme of functional programming. returned from other functions. This versatility is what gives It also creates very extensible code as I can easily swap any JavaScript functions the title of high-order functions. function (like h1 for an h2) without running the risk of breaking // assign function to variable other parts of the program. What is compose? There’s a lot var multiplier = (a,b) => a * b; more to cover to understand this, so let’s dive in! // pass function as argument var applyOperation = (a, b, opt) => opt(a,b); If you’re feeling adventurous, you can play with this applyOperation (2, 3, multiplier); //-> 6 program here: http://jsbin.com/guwiji/edit?html,js,output // return functions from other functions function add(a) { return function (b) { WHY JAVASCRIPT? return a + b; } The answer is simple: omnipresence. JavaScript is a } add(3)(3); //-> 6 dynamically typed, object-oriented, functional, general- purpose language that contains an immensely expressive syntax. It’s one of the most ubiquitous languages ever created and can be seen in the development of mobile DZONE REFCARD #216 applications, websites, web servers, desktop and embedded applications, and even databases. Java Caching: From its ancestors Lisp and Scheme, JavaScript inherits Strategies and the JCache API high-order functions, closures, array literals, and other features that make JavaScript a superb platform for applying functional programming techniques. In fact, functions are the primary “unit of work” in JavaScript. Learn proper caching This Refcard assumes a good understanding of JavaScript, strategies for improved but here are some points to consider: application performance. LAMBDA EXPRESSIONS DOWNLOAD NOW Known as fat arrow functions in the JavaScript world, lambda expressions encode simple one-line anonymous functions FUNCTIONAL PROGRAMMING JAVASCRIPT IN FUNCTIONAL © DZONE, INC. | DZONE.COM FUNCTIONAL PROGRAMMING 2 IN JAVASCRIPT You can try out high-order functions here: http://jsbin.com/ isEmpty :: String -> Boolean kiruba/edit?js,console Functional programming is based on the premise that you will CLOSURES build immutable programs solely based on pure functions. A A closure is a data structure that binds a function to its environment pure function has the following qualities: at the moment it’s declared. It is based on the textual location of the function declaration; therefore, a closure is also called • It depends only on the input provided—and not on any a static or lexical scope surrounding the function definition. hidden or external state that may change as a function’s Because closures give functions access to its surrounding state, evaluation proceeds or between function calls. you can solve many problems in a terse and concise way. • It does not inflict changes beyond its scope (like modifying For a thorough exploration of JavaScript, try reading Secrets of a a global object or a parameter reference). JavaScript Ninja 2nd Edition (Manning 2016). Both points refer to the presence of side effects in your code; behavior that is to be avoided at all costs: DOES FUNCTIONAL PROGRAMMING REPLACE OBJECT-ORIENTED? It’s important to know that JavaScript is as functional as it is object-oriented—and both of these are useful for implementing mid-to-large size applications. The good news is that functional programming and object-oriented programming are not mutually exclusive and can be used simultaneously. In fact, platforms like Scala and F# have blended both paradigms successfully into a single language, making them very pragmatic and geared towards productivity. JavaScript is The concept of pure functions leads into another concept in another hybrid language that provides the freedom to use functional programming: referential transparency. these orthogonal paradigms in the same code base. REFERENTIAL TRANSPARENCY FUNCTIONAL PROGRAMING Referential transparency (RT) is a more formal way of defining Functional programming is a software development style that a pure function. Purity in this sense refers to the existence of a emphasizes the use functions. Its main purpose is to abstract pure mapping between a function’s arguments and its return control flow and operations on data with functions in order to value. Hence, if a function consistently yields the same result avoid side effects and reduce mutation of state in your code. on the same input, it is said to be referentially transparent. The multiplier and adder functions shown earlier were RT. Here’s There is a small set of very important concepts—borrowed an example of a non-RT program: from mathematics—that form the backbone of all functional programming. var nums = [80, null, 90, 100]; var total = 0; var validNums = 0; PURE FUNCTIONS function average() { In order to understand functional programming, you must first // Depends on the external variable nums, // total, validNums understand functions in the mathematical sense as being a for(let i = 0; i < nums.length; i++) { mapping of types. The set of a function’s input values is called if(nums[i] !== null || nums[i] !== undefined) { the domain and the set of possible values returned is the range. total+= nums[i]; validNums++; Visually: } } var newAverage = total / validNums; return Math.round(newAverage); } The problems with this program are due to its exposure to side effects by relying on external variables: nums, total, and validNums. If any of these variables change in-between calls to average, it yields different results. RT exercise: http://jsbin.com/lipewu/edit?js,console FUNCTIONAL TECHNIQUES Simply, the function isEmpty—used to validate whether a Functional programming contains a set of very compelling string has length zero—is a mapping from String to Boolean. techniques that drive your application’s control and data flow. This is written as: Pure functional programs have many of these techniques built © DZONE, INC. | DZONE.COM FUNCTIONAL PROGRAMMING 3 IN JAVASCRIPT into them, such as automatic currying (which we’ll see in a We can transform a list of numerical grades into letter grades: bit). Unfortunately, JavaScript doesn’t. Now, this doesn’t mean _.map([20, 98, 100, 73, 85, 50], toLetter); you can’t use JS functionally. In fact, because JavaScript has //-> [F, A, A, C, B, F] support for closures and high-order functions, you can very easily extend the platform via functional libraries to support all _.FILTER of the most important functional techniques you’ll need. Filter transforms an array by mapping a predicate function (function with a boolean return value) onto each element. The AWAY WITH LOOPS! resulting array is made up of, potentially, a subset of elements A noticeable quality of functional programs is the absence of for which the predicate returns true. the standard looping mechanisms: for, while, and do-while. The reason here is that pure functional programs don’t mutate _.filter(['Spain', 'USA', 'Serbia', 'Uganda'] ,(name) => name.substring(0,1) === 'S'); variables (like a loop counter) after they’ve been initialized. //-> [Spain, Serbia] Instead, we will take advantage of high-order functions—like: forEach, map, reduce, and filter—to abstract iteration schemes, The function supplied to _.filter has the same arguments as which also help us remove a few if-else conditionals while _.map. As you can see from the code above, _.filter abstracts we’re at it. JavaScript has native implementations of these the task of performing an if-else check to remove elements functions, but it’s worth considering the implementations from the array, where the condition clause is encoded as the provided in the library Lodash.js, as they are more extensible. predicate function. You can download Lodash.js here: https://lodash.com _.REDUCE Lodash.js defines a global object wrapper _ (an underscore), Typically used as a terminal operation originating from _.map, which can be used to unlock all of its functionality, starting _.reduce can be used to fold or gather the contents of an array by compressing it into a single value. Each successive with _.forEach: invocation is supplied the return value of the previous. _.reduce _.FOREACH is typically seen as combined with _.map and _.filter: This function iterates over the elements of a collection, invoking _([1, 2, 3, 4, 5, 6, 7, 8, 9]) the provided iteratee function on each one.