Functional Programming in JavaScript Functional Programming in JavaScript LUIS ATENCIO MANNING SHELTER ISLAND For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: [email protected] ©2016 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Development editor: Marina Michaels 20 Baldwin Road Technical development editor: Dean Iverson PO Box 761 Review editor: Aleksandar Dragosavljevic Shelter Island, NY 11964 Project editor: Tiffany Taylor Copy editor: Tiffany Taylor Proofreader: Katie Tennant Technical proofreader: Daniel Lamb Typesetter: Dennis Dalinnik Cover designer: Leslie Haimes ISBN: 9781617292828 Printed in the United States of America 12345678910–EBM–212019181716 To my wonderful wife, Ana. Thank you for your unconditional support and for being the source of passion and inspiration in my life. brief contents PART 1THINK FUNCTIONALLY ..................................................1 1 ■ Becoming functional 3 2 ■ Higher-order JavaScript 23 PART 2GET FUNCTIONAL........................................................55 3 ■ Few data structures, many operations 57 4 ■ Toward modular, reusable code 84 5 ■ Design patterns against complexity 117 PART 3ENHANCING YOUR FUNCTIONAL SKILLS......................151 6 ■ Bulletproofing your code 153 7 ■ Functional optimizations 180 8 ■ Managing asynchronous events and data 205 vii contents preface xv acknowledgments xvii about this book xix PART 1THINK FUNCTIONALLY.......................................1 Becoming functional 3 1 1.1 Can functional programming help? 5 1.2 What is functional programming? 5 Functional programming is declarative 7 ■ Pure functions and the problem with side effects 9 ■ Referential transparency and substitutability 13 ■ Preserving immutable data 15 1.3 Benefits of functional programming 16 Encouraging the decomposition of complex tasks 16 Processing data using fluent chains 18 ■ Reacting to the complexity of asynchronous applications 19 1.4 Summary 22 ix x CONTENTS Higher-order JavaScript 23 2 2.1 Why JavaScript? 24 2.2 Functional vs. object-oriented programming 24 Managing the state of JavaScript objects 31 ■ Treating objects as values 32 ■ Deep-freezing moving parts 34 ■ Navigating and modifying object graphs with lenses 37 2.3 Functions 38 Functions as first-class citizens 39 ■ Higher-order functions 40 Types of function invocation 43 ■ Function methods 44 2.4 Closures and scopes 45 Problems with the global scope 47 ■ JavaScript’s function scope 48 ■ A pseudo-block scope 49 ■ Practical applications of closures 50 2.5 Summary 53 PART 2GET FUNCTIONAL ............................................55 Few data structures, many operations 57 3 3.1 Understanding your application’s control flow 58 3.2 Method chaining 59 3.3 Function chaining 60 Understanding lambda expressions 61 ■ Transforming data with _.map 62 ■ Gathering results with _.reduce 65 Removing unwanted elements with _.filter 68 3.4 Reasoning about your code 70 Declarative and lazy function chains 71 ■ SQL-like data: functions as data 75 3.5 Learning to think recursively 77 What is recursion? 77 ■ Learning to think recursively 77 Recursively defined data structures 79 3.6 Summary 83 Toward modular, reusable code 84 4 4.1 Method chains vs. function pipelines 85 Chaining methods together 86 ■ Arranging functions in a pipeline 87 CONTENTS xi 4.2 Requirements for compatible functions 88 Type-compatible functions 88 ■ Functions and arity: the case for tuples 89 4.3 Curried function evaluation 92 Emulating function factories 95 ■ Implementing reusable function templates 97 4.4 Partial application and parameter binding 98 Extending the core language 100 ■ Binding into delayed functions 101 4.5 Composing function pipelines 102 Understanding composition with HTML widgets 102 Functional composition: separating description from evaluation 104 ■ Composition with functional libraries 107 Coping with pure and impure code 109 ■ Introducing point-free programming 111 4.6 Managing control flow with functional combinators 112 Identity (I-combinator) 112 ■ Tap (K-combinator) 113 Alternation (OR-combinator) 113 ■ Sequence (S-combinator) 114 Fork (join) combinator 115 4.7 Summary 116 Design patterns against complexity 117 5 5.1 Shortfalls of imperative error handling 118 Error handling with try-catch 118 ■ Reasons not to throw exceptions in functional programs 119 ■ Problems with null-checking 121 5.2 Building a better solution: functors 121 Wrapping unsafe values 122 ■ Functors explained 124 5.3 Functional error handling using monads 127 Monads: from control flow to data flow 128 ■ Error handling with Maybe and Either monads 132 ■ Interacting with external resources using the IO monad 141 5.4 Monadic chains and compositions 144 5.5 Summary 150 xii CONTENTS PART 3ENHANCING YOUR FUNCTIONAL SKILLS ..........151 Bulletproofing your code 153 6 6.1 Functional programming’s influence on unit tests 154 6.2 Challenges of testing imperative programs 155 Difficulty identifying and decomposing tasks 155 Dependency on shared resources leads to inconsistent results 157 Predefined order of execution 158 6.3 Testing functional code 159 Treating a function as a black box 159 ■ Focusing on business logic instead of control flow 160 ■ Separating the pure from the impure with monadic isolation 161 ■ Mocking external dependencies 164 6.4 Capturing specifications with property-based testing 166 6.5 Measuring effectiveness through code coverage 172 Measuring the effectiveness of testing functional code 173 Measuring the complexity of functional code 177 6.6 Summary 179 Functional optimizations 180 7 7.1 Under the hood of function execution 181 Currying and the function context stack 183 ■ Challenges of recursive code 186 7.2 Deferring execution using lazy evaluation 188 Avoiding computations with the alternation functional combinator 189 ■ Taking advantage of shortcut fusion 190 7.3 Implementing a call-when-needed strategy 191 Understanding memoization 192 ■ Memoizing computationally intensive functions 192 ■ Taking advantage of currying and memoization 196 ■ Decomposing to maximize memoization 196 Applying memoization to recursive calls 197 7.4 Recursion and tail-call optimization (TCO) 199 Converting non-tail calls to tail calls 201 7.5 Summary 203 CONTENTS xiii Managing asynchronous events and data 205 8 8.1 Challenges of asynchronous code 206 Creating temporal dependencies among functions 207 Falling into a callback pyramid 208 ■ Using continuation- passing style 210 8.2 First-class asynchronous behavior with promises 214 Future method chains 216 ■ Composing synchronous and asynchronous behavior 221 8.3 Lazy data generation 224 Generators and recursion 226 ■ The Iterator protocol 228 8.4 Functional and reactive programming with RxJS 229 Data as observable sequences 229 ■ Functional and reactive programming 230 ■ RxJS and promises 233 8.5 Summary 234 appendix JavaScript libraries used in this book 235 index 239 preface When I was in college and graduate school, my class schedule was focused on object- oriented design as the sole methodology for planning and architecting software sys- tems. And, like many developers, I began my career writing object-oriented code and building entire systems based on this paradigm. Throughout my development career, I’ve learned and followed programming lan- guages closely, not only because I want to learn something cool, but also because I’m intrigued by the design decisions and philosophy that each language fosters. Just as a new language provides a different perspective on how to approach software problems, a new paradigm can achieve the same effect. Although the object-oriented approach continues to be the modus operandi of software design, learning about functional programming will open your eyes to new techniques that you can use on their own or in parallel with any other design paradigm that fits your application. Functional programming has been around for years, but to me it was only a minor distraction. I had heard and read about the benefits of Haskell, Lisp, Scheme, and, more recently, Scala, Clojure, and F# in terms of expressiveness and being highly pro- ductive platforms; even Java, which has traditionally been known as a verbose language, has functional artifacts that make code more succinct. Eventually, the minor distrac- tion became impossible to avoid. And guess what? JavaScript, that object-oriented language everyone uses, can be turned
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages274 Page
-
File Size-