Functional Programming in JavaScript Luis Atencio Copyright 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. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Development editor: Marina Michaels Technical development editor: Dean Iverson Review editor: Aleksandar Dragosavljevic 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 1 2 3 4 5 6 7 8 9 10 – EBM – 21 20 19 18 17 16 To my wonderful wife, Ana. Thank you for your unconditional support and for being the source of passion and inspiration in my life. Brief Table of Contents Copyright Brief Table of Contents Table of Contents Preface Acknowledgments About this Book 1. Think functionally Chapter 1. Becoming functional Chapter 2. Higher-order JavaScript 2. Get functional Chapter 3. Few data structures, many operations Chapter 4. Toward modular, reusable code Chapter 5. Design patterns against complexity 3. Enhancing your functional skills Chapter 6. Bulletproofing your code Chapter 7. Functional optimizations Chapter 8. Managing asynchronous events and data JavaScript libraries used in this book Index List of Figures List of Tables List of Listings Table of Contents Copyright Brief Table of Contents Table of Contents Preface Acknowledgments About this Book 1. Think functionally Chapter 1. Becoming functional 1.1. Can functional programming help? 1.2. What is functional programming? 1.2.1. Functional programming is declarative 1.2.2. Pure functions and the problem with side effects 1.2.3. Referential transparency and substitutability 1.2.4. Preserving immutable data 1.3. Benefits of functional programming 1.3.1. Encouraging the decomposition of complex tasks 1.3.2. Processing data using fluent chains 1.3.3. Reacting to the complexity of asynchronous applications 1.4. Summary Chapter 2. Higher-order JavaScript 2.1. Why JavaScript? 2.2. Functional vs. object-oriented programming 2.2.1. Managing the state of JavaScript objects 2.2.2. Treating objects as values 2.2.3. Deep-freezing moving parts 2.2.4. Navigating and modifying object graphs with lenses 2.3. Functions 2.3.1. Functions as first-class citizens 2.3.2. Higher-order functions 2.3.3. Types of function invocation 2.3.4. Function methods 2.4. Closures and scopes 2.4.1. Problems with the global scope 2.4.2. JavaScript’s function scope 2.4.3. A pseudo-block scope 2.4.4. Practical applications of closures 2.5. Summary 2. Get functional Chapter 3. Few data structures, many operations 3.1. Understanding your application’s control flow 3.2. Method chaining 3.3. Function chaining 3.3.1. Understanding lambda expressions 3.3.2. Transforming data with _.map 3.3.3. Gathering results with _.reduce 3.3.4. Removing unwanted elements with _.filter 3.4. Reasoning about your code 3.4.1. Declarative and lazy function chains 3.4.2. SQL-like data: functions as data 3.5. Learning to think recursively 3.5.1. What is recursion? 3.5.2. Learning to think recursively 3.5.3. Recursively defined data structures 3.6. Summary Chapter 4. Toward modular, reusable code 4.1. Method chains vs. function pipelines 4.1.1. Chaining methods together 4.1.2. Arranging functions in a pipeline 4.2. Requirements for compatible functions 4.2.1. Type-compatible functions 4.2.2. Functions and arity: the case for tuples 4.3. Curried function evaluation 4.3.1. Emulating function factories 4.3.2. Implementing reusable function templates 4.4. Partial application and parameter binding 4.4.1. Extending the core language 4.4.2. Binding into delayed functions 4.5. Composing function pipelines 4.5.1. Understanding composition with HTML widgets 4.5.2. Functional composition: separating description from evaluation 4.5.3. Composition with functional libraries 4.5.4. Coping with pure and impure code 4.5.5. Introducing point-free programming 4.6. Managing control flow with functional combinators 4.6.1. Identity (I-combinator) 4.6.2. Tap (K-combinator) 4.6.3. Alternation (OR-combinator) 4.6.4. Sequence (S-combinator) 4.6.5. Fork (join) combinator 4.7. Summary Chapter 5. Design patterns against complexity 5.1. Shortfalls of imperative error handling 5.1.1. Error handling with try-catch 5.1.2. Reasons not to throw exceptions in functional programs 5.1.3. Problems with null-checking 5.2. Building a better solution: functors 5.2.1. Wrapping unsafe values 5.2.2. Functors explained 5.3. Functional error handling using monads 5.3.1. Monads: from control flow to data flow 5.3.2. Error handling with Maybe and Either monads 5.3.3. Interacting with external resources using the IO monad 5.4. Monadic chains and compositions 5.5. Summary 3. Enhancing your functional skills Chapter 6. Bulletproofing your code 6.1. Functional programming’s influence on unit tests 6.2. Challenges of testing imperative programs 6.2.1. Difficulty identifying and decomposing tasks 6.2.2. Dependency on shared resources leads to inconsistent results 6.2.3. Predefined order of execution 6.3. Testing functional code 6.3.1. Treating a function as a black box 6.3.2. Focusing on business logic instead of control flow 6.3.3. Separating the pure from the impure with monadic isolation 6.3.4. Mocking external dependencies 6.4. Capturing specifications with property-based testing 6.5. Measuring effectiveness through code coverage 6.5.1. Measuring the effectiveness of testing functional code 6.5.2. Measuring the complexity of functional code 6.6. Summary Chapter 7. Functional optimizations 7.1. Under the hood of function execution 7.1.1. Currying and the function context stack 7.1.2. Challenges of recursive code 7.2. Deferring execution using lazy evaluation 7.2.1. Avoiding computations with the alternation functional combinator 7.2.2. Taking advantage of shortcut fusion 7.3. Implementing a call-when-needed strategy 7.3.1. Understanding memoization 7.3.2. Memoizing computationally intensive functions
Description: