在JavaScript中的函数式编程


www.it-ebooks.info Functional Programming in JavaScript Unlock the powers of functional programming hidden within JavaScript to build smarter, cleaner, and more reliable web apps Dan Mantyla BIRMINGHAM - MUMBAI www.it-ebooks.info Functional Programming in JavaScript Copyright © 2015 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. First published: March 2015 Production reference: 1230315 Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK ISBN 978-1-78439-822-4 www.packtpub.com Cover Image by Dan Mantyla www.it-ebooks.info Credits Author Dan Mantyla Reviewers Dom Derrien Joe Dorocak Peter Ehrlich Edward E. Griebel Jr. Commissioning Editor Julian Ursell Acquisition Editor Owen Roberts Content Development Editor Kirti Patil Technical Editor Abhishek R. Kotian Copy Editors Aditya Nair Aarti Saldanha Vikrant Phadkey Project Coordinator Nidhi Joshi Proofreaders Stephen Copestake Maria Gould Paul Hindle Indexer Tejal Daruwale Soni Production Coordinator Aparna Bhagat Cover Work Aparna Bhagat www.it-ebooks.info About the Author Dan Mantyla works as a web application developer for the University of Kansas. He enjoys contributing to open source web frameworks and wrenching on motorcycles. Dan is currently living in Lawrence, Kansas, USA—the birthplace of Python Django and home to Linux News Media. Dan has also clicked the cover image, which was taken outside his home in Lawrence, Kansas, USA, where the sunflower fields are in bloom for only one short week in September. www.it-ebooks.info About the Reviewers Dom Derrien is a full stack web developer who has recently been defining application environments with a focus on high availability and scalability. He's been in the development field for more than 15 years and has worked for big and small companies and as an entrepreneur. He's currently working for the game company Ubisoft, where he defines the next generation services platform for its successful AAA games. To extend the gamer experience on to the Web and on mobiles, he provides technical means that are transparent, efficient, and highly flexible. Having developed smart clients before the introduction of XHR, using a frameset tag to keep the context and a hidden frame of size=0 to dynamically exchange data with servers, he had a great pleasure of reviewing this book, which pushes the language to its limits. He hopes that it will help developers improve their programming skills. I want to thank my wife, Sophie, and our sons, Erwan and Goulven, with whom I enjoy a peaceful life in Montréal, Québec, Canada. www.it-ebooks.info Joe Dorocak, whose Internet moniker is Joe Codeswell, is a very experienced programmer. He enjoys creating readable code that implements project requirements efficiently and in a manner that can be easily understood. He considers writing code akin to writing poetry. Joe prides himself on the ability to communicate clearly and professionally. He considers his code to be communication, not only with the machine platforms on which it runs, but also with human programmers who might read it in the future. Joe has worked as an employee as well as in a contractual role for major brands such as IBM, HP, GTE/Sprint, and other top-shelf companies. He is presently consulting on web, mobile, and desktop applications, which are coded primarily, but not exclusively, in Python and JavaScript. For more details about him, please visit https://www.linkedin.com/in/joedorocak. Peter Ehrlich taught himself web programming in 2007, and now works on performance JavaScript and WebGL at Leap Motion, Inc. In his spare time, he enjoys dancing, rock climbing, and taking naps. Edward E. Griebel Jr. has been developing enterprise software for over 20 years in C, C++, and Java. He has a bachelor of science degree in computer engineering. He is currently a middleware architect at a leading payroll and financial services provider in the U.S., focusing on systems integration and UI and server development. www.it-ebooks.info www.PacktPub.com Support files, eBooks, discount offers and more For support files and downloads related to your book, please visit www.PacktPub.com. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub. com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@packtpub.com for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks. TM https://www2.packtpub.com/books/subscription/packtlib Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can access, read and search across Packt's entire library of books.  Why Subscribe? • Fully searchable across every book published by Packt • Copy and paste, print and bookmark content • On demand and accessible via web browser Free Access for Packt account holders If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view nine entirely free books. Simply use your login credentials for immediate access. www.it-ebooks.info www.it-ebooks.info [ i ] Table of Contents Preface v Chapter 1: The Powers of JavaScript's Functional Side – a Demonstration 1 Introduction 1 The demonstration 2 The application – an e-commerce website 2 Imperative methods 2 Functional programming 4 Summary 7 Chapter 2: Fundamentals of Functional Programming 9 Functional programming languages 9 What makes a language functional? 10 Advantages 11 Cleaner code 11 Modularity 12 Reusability 12 Reduced coupling 12 Mathematically correct 12 Functional programming in a nonfunctional world 14 Is JavaScript a functional programming language? 15 Working with functions 17 Self-invoking functions and closures 18 Higher-order functions 19 Pure functions 20 Anonymous functions 21 Method chains 23 Recursion 24 Divide and conquer 25 Lazy evaluation 26 www.it-ebooks.info Table of Contents [ ii ] The functional programmer's toolkit 27 Callbacks 28 Array.prototype.map() 29 Array.prototype.filter() 30 Array.prototype.reduce() 31 Honorable mentions 32 Array.prototype.forEach 32 Array.prototype.concat 33 Array.prototype.reverse 34 Array.prototype.sort 34 Array.prototype.every and Array.prototype.some 35 Summary 35 Chapter 3: Setting Up the Functional Programming Environment 37 Introduction 37 Functional libraries for JavaScript 38 Underscore.js 38 Fantasy Land 41 Bilby.js 42 Lazy.js 44 Bacon.js 45 Honorable mentions 46 Development and production environments 48 Browsers 48 Server-side JavaScript 49 A functional use case in the server-side environment 49 CLI 50 Using functional libraries with other JavaScript modules 50 Functional languages that compile into JavaScript 51 Summary 52 Chapter 4: Implementing Functional Programming Techniques in JavaScript 53 Partial function application and currying 54 Function manipulation 54 Apply, call, and the this keyword 54 Binding arguments 55 Function factories 56 Partial application 57 Partial application from the left 58 Partial application from the right 59 Currying 60 www.it-ebooks.info Table of Contents [ iii ] Function composition 62 Compose 62 Sequence – compose in reverse 63 Compositions versus chains 64 Programming with compose 65 Mostly functional programming 68 Handling events 70 Functional reactive programming 71 Reactivity 72 Putting it all together 73 Summary 75 Chapter 5: Category Theory 77 Category theory 78 Category theory in a nutshell 78 Type safety 80 Object identities 82 Functors 83 Creating functors 84 Arrays and functors 84 Function compositions, revisited 85 Monads 87 Maybes 88 Promises 90 Lenses 92 jQuery is a monad 94 Implementing categories 95 Summary 98 Chapter 6: Advanced Topics and Pitfalls in JavaScript 99 Recursion 100 Tail recursion 100 The Tail-call elimination 101 Trampolining 103 The Y-combinator 106 Memoization 108 Variable scope 109 Scope resolutions 109 Global scope 110 Local scope 110 Object properties 111 Closures 112 Gotchas 113 www.it-ebooks.info Table of Contents [ iv ] Function declarations versus function expressions versus the function constructor 114 Function declarations 114 Function expressions 115 The function constructor 115 Unpredictable behavior 116 Summary 117 Chapter 7: Functional and Object-oriented Programming in JavaScript 119 JavaScript – the multi-paradigm language 120 JavaScript's object-oriented implementation – using prototypes 121 Inheritance 121 JavaScript's prototype chain 122 Inheritance in JavaScript and the Object.create() method 123 Mixing functional and object-oriented programming in JavaScript 125 Functional inheritance 125 Strategy Pattern 126 Mixins 128 Classical mixins 129 Functional mixins 130 Summary 133 Appendix A: Common Functions for Functional Programming in JavaScript 135 Appendix B: Glossary of Terms 143 Index 147 www.it-ebooks.info [ v ] Preface Functional programming is a style that emphasizes and enables the writing of smarter code, which minimizes complexity and increases modularity. It's a way of writing cleaner code through clever ways of mutating, combining, and using functions. JavaScript provides an excellent medium for this approach. JavaScript, the Internet's scripting language, is actually a functional language at heart. By learning how to expose its true identity as a functional language, we can implement web applications that are powerful, easier to maintain, and more reliable. By doing this, JavaScript's odd quirks and pitfalls will suddenly become clear and the language as a whole will make infinitely more sense. Learning how to use functional programming will make you a better programmer for life. This book is a guide for both new and experienced JavaScript developers who are interested in learning functional programming. With a focus on the progression of functional programming techniques, styles, and detailed information about JavaScript libraries, this book will help you to write smarter code and become a better programmer. What this book covers Chapter 1, The Powers of JavaScript's Functional Side – a Demonstration, sets the pace of the book by creating a small web application with the help of both traditional methods and functional programming. It then compares these two methods to underline the importance of functional programming. Chapter 2, Fundamentals of Functional Programming, introduces you to the core concepts of functional programming as well as built-in JavaScript functions. Chapter 3, Setting Up the Functional Programming Environment, explores different JavaScript libraries and how they can be optimized for functional programming. www.it-ebooks.info Preface [ vi ] Chapter 4, Implementing Functional Programming Techniques in JavaScript, explains the functional paradigm in JavaScript. It covers several styles of functional programming and demonstrates how they can be employed in different scenarios. Chapter 5, Category Theory, explains the concept of Category Theory in detail and then implements it in JavaScript. Chapter 6, Advanced Topics and Pitfalls in JavaScript, highlights various drawbacks you may face while programming in JavaScript, and the various ways to successfully deal with them. Chapter 7, Functional and Object-oriented Programming in JavaScript, relates both functional and object-oriented programming to JavaScript, and shows you how the two paradigms can complement each other and coexist side by side. Appendix A, Common Functions for Functional Programming in JavaScript, contains common functions used to perform functional programming in JavaScript. Appendix B, Glossary of Terms, includes a glossary of terms used throughout the book. What you need for this book Only a browser is needed to get you up and running. Who this book is for If you are a JavaScript developer interested in learning functional programming, looking for a quantum leap toward mastering the JavaScript language, or just want to become a better programmer in general, then this book is ideal for you. This guide is aimed at programmers involved in developing reactive frontend applications, server-side applications that wrangle with reliability and concurrency, and everything else in between. Conventions In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning. Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "We can include other contexts through the use of the include directive." www.it-ebooks.info Preface [ vii ] A block of code is set as follows: Function.prototype.partialApply = function() { var func = this; args = Array.prototype.slice.call(arguments); return function() { return func.apply(this, args.concat( Array.prototype.slice.call(arguments) )); }; }; When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold: var messages = ['Hi', 'Hello', 'Sup', 'Hey', 'Hola']; messages.map(function(s,i){ return printSomewhere(s, i*10, i*10); }).forEach(document.body.appendChild); New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "Clicking the Next button moves you to the next screen." Warnings or important notes appear in a box like this. Tips and tricks appear like this. Reader feedback Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail feedback@packtpub.com, and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors. www.it-ebooks.info Preface [ viii ] Customer support Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase. Downloading the example code You can download the example code files from your account at http://www. packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. Errata Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub. com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/ content/support and enter the name of the book in the search field. The required information will appear under the Errata section. Piracy Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at copyright@packtpub.com with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content. www.it-ebooks.info Preface [ ix ] Questions If you have a problem with any aspect of this book, you can contact us at questions@packtpub.com, and we will do our best to address the problem. www.it-ebooks.info www.it-ebooks.info [ 1 ] The Powers of JavaScript's Functional Side – a Demonstration Introduction For decades, functional programming has been the darling of computer science aficionados, prized for its mathematical purity and puzzling nature that kept it hidden in dusty computer labs occupied by data scientists and PhD hopefuls. But now, it is going through a resurgence, thanks to modern languages such as Python, Julia, Ruby, Clojure and—last but not least—JavaScipt. JavaScript, you say? The web's scripting language? Yes! JavaScript has proven to be an important technology that isn't going away for quite a while. This is largely due to the fact that it is capable of being reborn and extended with new frameworks and libraries, such as backbone.js, jQuery, Dojo, underscore. js, and many more. This is directly related to JavaScript's true identity as a functional programming language. An understanding of functional programming with JavaScript will be welcome and useful for a long time for programmers of any skill level. Why so? Functional programming is very powerful, robust, and elegant. It is useful and efficient on large data structures. It can be very advantageous to use JavaScript—a client-side scripting language, as a functional means to manipulate the DOM, sort API responses or perform other tasks on increasingly complex websites. www.it-ebooks.info The Powers of JavaScript's Functional Side – a Demonstration [ 2 ] In this book, you will learn everything you need to know about functional programming with JavaScript: how to empower your JavaScript web applications with functional programming, how to unlock JavaScript's hidden powers, and how to write better code that is both more powerful and—because it is smaller—easier to maintain, faster to download, and takes less overhead. You will also learn the core concepts of functional programming, how to apply them to JavaScript, how to side-step the caveats and issues that may arise when using JavaScript as a functional language, and how to mix functional programming with object-oriented programming in JavaScript. But before we begin, let's perform an experiment. The demonstration Perhaps a quick demonstration will be the best way to introduce functional programming with JavaScript. We will perform the same task using JavaScript—once using traditional, native methods, and once with functional programming. Then, we will compare the two methods. The application – an e-commerce website In pursuit of a real-world application, let's say we need an e-commerce web application for a mail-order coffee bean company. They sell several types of coffee and in different quantities, both of which affect the price. Imperative methods First, let's go with the procedural route. To keep this demonstration down to earth, we'll have to create objects that hold the data. This allows the ability to fetch the values from a database if we need to. But for now, we'll assume they're statically defined: // create some objects to store the data. var columbian = { name: 'columbian', basePrice: 5 }; var frenchRoast = { name: 'french roast', basePrice: 8 }; var decaf = { name: 'decaf', www.it-ebooks.info Chapter 1 [ 3 ] basePrice: 6 }; // we'll use a helper function to calculate the cost // according to the size and print it to an HTML list function printPrice(coffee, size) { if (size == 'small') { var price = coffee.basePrice + 2; } else if (size == 'medium') { var price = coffee.basePrice + 4; } else { var price = coffee.basePrice + 6; } // create the new html list item var node = document.createElement("li"); var label = coffee.name + ' ' + size; var textnode = document.createTextNode(label+' price: $'+price); node.appendChild(textnode); document.getElementById('products').appendChild(node); } // now all we need to do is call the printPrice function // for every single combination of coffee type and size printPrice(columbian, 'small'); printPrice(columbian, 'medium'); printPrice(columbian, 'large'); printPrice(frenchRoast, 'small'); printPrice(frenchRoast, 'medium'); printPrice(frenchRoast, 'large'); printPrice(decaf, 'small'); printPrice(decaf, 'medium'); printPrice(decaf, 'large'); Downloading the example code You can download example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www. packtpub.com/support and register to have the files e-mailed directly to you. www.it-ebooks.info The Powers of JavaScript's Functional Side – a Demonstration [ 4 ] As you can see, this code is very basic. What if there were many more coffee styles than just the three we have here? What if there were 20? 50? What if, in addition to size, there were organic and non-organic options. That could increase the lines of code extremely quickly! Using this method, we are telling the machine what to print for each coffee type and for each size. This is fundamentally what is wrong with imperative code. Functional programming While imperative code tells the machine, step-by-step, what it needs to do to solve the problem, functional programming instead seeks to describe the problem mathematically so that the machine can do the rest. With a more functional approach, the same application can be written as follows: // separate the data and logic from the interface var printPrice = function(price, label) { var node = document.createElement("li"); var textnode = document.createTextNode(label+' price: $'+price); node.appendChild(textnode); document.getElementById('products 2').appendChild(node); } // create function objects for each type of coffee var columbian = function(){ this.name = 'columbian'; this.basePrice = 5; }; var frenchRoast = function(){ this.name = 'french roast'; this.basePrice = 8; }; var decaf = function(){ this.name = 'decaf'; this.basePrice = 6; }; // create object literals for the different sizes var small = { getPrice: function(){return this.basePrice + 2}, getLabel: function(){return this.name + ' small'} }; var medium = { www.it-ebooks.info Chapter 1 [ 5 ] getPrice: function(){return this.basePrice + 4}, getLabel: function(){return this.name + ' medium'} }; var large = { getPrice: function(){return this.basePrice + 6}, getLabel: function(){return this.name + ' large'} }; // put all the coffee types and sizes into arrays var coffeeTypes = [columbian, frenchRoast, decaf]; var coffeeSizes = [small, medium, large]; // build new objects that are combinations of the above // and put them into a new array var coffees = coffeeTypes.reduce(function(previous, current) { var newCoffee = coffeeSizes.map(function(mixin) { // `plusmix` function for functional mixins, see Ch.7 var newCoffeeObj = plusMixin(current, mixin); return new newCoffeeObj(); }); return previous.concat(newCoffee); },[]); // we've now defined how to get the price and label for each // coffee type and size combination, now we can just print them coffees.forEach(function(coffee){ printPrice(coffee.getPrice(),coffee.getLabel()); }); The first thing that should be obvious is that it is much more modular. This makes adding a new size or a new coffee type as simple as shown in the following code snippet: var peruvian = function(){ this.name = 'peruvian'; this.basePrice = 11; }; var extraLarge = { getPrice: function(){return this.basePrice + 10}, getLabel: function(){return this.name + ' extra large'} }; coffeeTypes.push(Peruvian); coffeeSizes.push(extraLarge); www.it-ebooks.info The Powers of JavaScript's Functional Side – a Demonstration [ 6 ] Arrays of coffee objects and size objects are "mixed" together,—that is, their methods and member variables are combined—with a custom function called plusMixin (see Chapter 7, Functional and Object-oriented Programming in JavaScript). The coffee type classes contain the member variables and the sizes contain methods to calculate the name and price. The "mixing" happens within a map operation, which applies a pure function to each element in an array and returns a new function inside a reduce() operation—another higher-order function similar to the map function, except that all the elements in the array are combined into one. Finally, the new array of all possible combinations of types and sizes is iterated through with the forEach() method The forEach() method is yet another higher-order function that applies a callback function to each object in an array. In this example, we provide it as an anonymous function that instantiates the objects and calls the printPrice() function with the object's getPrice() and getLabel() methods as arguments. Actually, we could make this example even more functional by removing the coffees variable and chaining the functions together—another little trick in functional programming. coffeeTypes.reduce(function(previous, current) { var newCoffee = coffeeSizes.map(function(mixin) { // `plusMixin` function for functional mixins, see Ch.7 var newCoffeeObj = plusMixin(current, mixin); return new newCoffeeObj(); }); return previous.concat(newCoffee); },[]).forEach(function(coffee) { printPrice(coffee.getPrice(),coffee.getLabel()); }); Also, the control flow is not as top-to-bottom as the imperative code was. In functional programming, the map() function and other higher-order functions take the place of for and while loops and very little importance is placed on the order of execution. This makes it a little trickier for newcomers to the paradigm to read the code but, once you get the hang of it, it's not hard at all to follow and you'll see that it is much better. This example barely touched on what functional programming can do in JavaScript. Throughout this book, you will see even more powerful examples of the functional approach. www.it-ebooks.info Chapter 1 [ 7 ] Summary First, the benefits of adopting a functional style are clear. Second, don't be scared of functional programming. Yes, it is often thought of as pure logic in the form of computer language, but we don't need to understand Lambda calculus to be able to apply it to everyday tasks. The fact is, by allowing our programs to be broken down into smaller pieces, they're easier to understand, simpler to maintain, and more reliable. map() and reduce() function's are lesser- known built-in functions in JavaScript, but we'll look at them. JavaScript is a scripting language, interactive and approachable. No compiling is necessary. We don't even need to download any development software, your favorite browser works as the interpreter and as the development environment. Interested? Alright, let's get started! www.it-ebooks.info www.it-ebooks.info [ 9 ] Fundamentals of Functional Programming By now, you've seen a small glimpse of what functional programming can do. But what exactly is functional programming? What makes one language functional and not another? What makes one programming style functional and not another? In this chapter, we will first answer these questions and then cover the core concepts of functional programming: • Using functions and arrays for control flow • Writing pure functions, anonymous functions, recursive functions, and more • Passing functions around like objects • Utilizing the map(), filter(), and reduce() functions Functional programming languages Functional programming languages are languages that facilitate the functional programming paradigm. At the risk of oversimplifying, we could say that, if a language includes the features required for functional programming, then it is a functional language—as simple as that. In most cases, it's the programming style that truly determines whether a program is functional or not. www.it-ebooks.info Fundamentals of Functional Programming [ 10 ] What makes a language functional? Functional programming cannot be performed in C. Functional programming cannot be performed in Java (without a lot of cumbersome workarounds for "almost" functional programming). Those and many more languages simply don't contain the constructs to support it. They are purely object-oriented and strictly non-functional languages. At the same time, object-oriented programming cannot be performed on purely functional languages, such as Scheme, Haskell, and Lisp, just to name a few. However, there are certain languages that support both models. Python is a famous example, but there are others: Ruby, Julia, and—here's the one we're interested in—JavaScript. How can these languages support two design patterns that are very different from each other? They contain the features required for both programming paradigms. However, in the case of JavaScript, the functional features are somewhat hidden. But really, it's a little more involved than that. So what makes a language functional? Characteristic Imperative Functional Programming Style Perform step-by-step tasks and manage changes in state Define what the problem is and what data transformations are needed to achieve the solution State Changes Important Non-existent Order of Execution Important Not as important Primary Flow Control Loops, conditionals, and function calls Function calls and recursion Primary Manipulation Unit Structures and class objects Functions as first-class objects and data sets The syntax of the language must allow for certain design patterns, such as an inferred type system, and the ability to use anonymous functions. Essentially, the language must implement Lambda calculus. Also, the interpreter's evaluation strategy should be non-strict and call-by-need (also known as deferred execution), which allows for immutable data structures and non-strict, lazy evaluation. www.it-ebooks.info Chapter 2 [ 11 ] Advantages You could say that the profound enlightenment you experience when you finally "get it" will make learning functional programming worth it. An experience such as this will make you a better programmer for the rest of your life, whether you actually become a full-time functional programmer or not. But we're not talking about learning to meditate; we're talking about learning an extremely useful tool that will make you a better programmer. Formally speaking, what exactly are the practical advantages of using functional programming? Cleaner code Functional programs are cleaner, simpler, and smaller. This simplifies debugging, testing, and maintenance. For example, let's say we need a function that converts a two-dimensional array into a one-dimensional array. Using only imperative techniques, we could write it the following way: function merge2dArrayIntoOne(arrays) { var count = arrays.length; var merged = new Array(count); var c = 0; for (var i = 0; i < count; ++i) { for (var j = 0, jlen = arrays[i].length; j < jlen; ++j) { merged[c++] = arrays[i][j]; } } return merged } And using functional techniques, it could be written as follows: varmerge2dArrayIntoOne2 = function(arrays) { return arrays.reduce( function(p,n){ return p.concat(n); }); }; Both of these functions take the same input and return the same output. However, the functional example is much more concise and clean. www.it-ebooks.info Fundamentals of Functional Programming [ 12 ] Modularity Functional programming forces large problems to be broken down into smaller instances of the same problem to be solved. This means that the code is more modular. Programs that are modular are clearly specified, easier to debug, and simpler to maintain. Testing is easier because each piece of modular code can potentially be checked for correctness. Reusability Functional programs share a variety of common helper functions, due to the modularity of functional programming. You'll find that many of these functions can be reused for a variety of different applications. Many of the most common functions will be covered later in this chapter. However, as you work as a functional programmer, you will inevitably compile your own library of little functions that can be used over and over again. For example, a well-designed function that searches through the lines of a configuration file could also be used to search through a hash table. Reduced coupling Coupling is the amount of dependency between modules in a program. Because the functional programmer works to write first-class, higher-order, pure functions that are completely independent of each other with no side effects on global variables, coupling is greatly reduced. Certainly, functions will unavoidably rely on each other. But modifying one function will not change another, so long as the one-to-one mapping of inputs to outputs remains correct. Mathematically correct This last one is on a more theoretical level. Thanks to its roots in Lambda calculus, functional programs can be mathematically proven to be correct. This is a big advantage for researchers who need to prove the growth rate, time complexity, and mathematical correctness of a program. Let's look at Fibonacci's sequence. Although it's rarely used for anything other than a proof-of-concept, it illustrates this concept quite well. The standard way of evaluating a Fibonacci sequence is to create a recursive function that expresses fibonnaci(n) = fibonnaci(n-2) + fibonnaci(n–1) with a base case to return 1 when n < 2, which makes it possible to stop the recursion and begin adding up the values returned at each step in the recursive call stack. www.it-ebooks.info Chapter 2 [ 13 ] This describes the intermediary steps involved in calculating the sequence. var fibonacci = function(n) { if (n < 2) { return 1; } else { return fibonacci(n - 2) + fibonacci(n - 1); } } console.log( fibonacci(8) ); // Output: 34 However, with the help of a library that implements a lazy execution strategy, an indefinite sequence can be generated that states the mathematical equation that defines the entire sequence of numbers. Only as many numbers as needed will be computed. var fibonacci2 = Lazy.generate(function() { var x = 1, y = 1; return function() { var prev = x; x = y; y += prev; return prev; }; }()); console.log(fibonacci2.length());// Output: undefined console.log(fibonacci2.take(12).toArray());// Output: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] var fibonacci3 = Lazy.generate(function() { var x = 1, y = 1; return function() { var prev = x; x = y; y += prev; return prev; }; }()); console.log(fibonacci3.take(9).reverse().first(1).toArray());// Output: [34] www.it-ebooks.info Fundamentals of Functional Programming [ 14 ] The second example is clearly more mathematically sound. It relies on the Lazy. js library of JavaScript. There are other libraries that can help here as well, such as Sloth.js and wu.js. These will be covered in Chapter 3, Setting Up the Functional Programming Environment. Functional programming in a nonfunctional world Can functional and nonfunctional programming be mixed together? Although this is the subject of Chapter 7, Functional & Object-oriented Programming in JavaScript, it is important to get a few things straight before we go any further. This book is not intended to teach you how to implement an entire application that strictly adheres to the rigors of pure functional programming. Such applications are rarely appropriate outside Academia. Rather, this book will teach you how to use functional programming design strategies within your applications to complement the necessary imperative code. For example, if you need the first four words that only contain letters out of some text, they could naively be written like this: var words = [], count = 0; text = myString.split(' '); for (i=0; count<4, i
还剩171页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

ppbb

贡献于2016-02-18

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf