Functional Programming: a Pragpub Anthology
Total Page:16
File Type:pdf, Size:1020Kb
Prepared exclusively for Shohei Tanaka Prepared exclusively for Shohei Tanaka Early Praise for Functional Programming: A PragPub Anthology If you’ve been wondering what all the functional hubbub is about, Functional Programming: A PragPub Anthology will satisfy. You can wet your whistle with several languages, get a feel for how to think functionally, and do so without overcommitting to one language or school of thought. ➤ Ben Vandgrift Chief architect, Oryx Systems Inc. Programming’s last sea change was in the 1990s when object orientation went mainstream. It’s happening again, but this time it’s functional programming that’s sweeping through our profession. Read this book to understand why and to learn how to ride the wave. ➤ Paul Butcher Founder and CTO, writeandimprove.com I really enjoyed the structure and flow of the book. The chapters stand on their own as essays but when put together make a strong argument for functional programming, regardless of the language. It’s also a treat to see all these different familiar writers write about diverse languages. ➤ Ben Marx Lead engineer, Bleacher Report Prepared exclusively for Shohei Tanaka You’re sure to find a way functional programming resonates with you with the wealth of approaches and languages covered. The treatment of Scala collection is superb: everything a beginner needs to know from the get-go! ➤ Jeff Heon Research software developer, CRIM Prepared exclusively for Shohei Tanaka Functional Programming: A PragPub Anthology Exploring Clojure, Elixir, Haskell, Scala, and Swift Michael Swaine and the PragPub writers The Pragmatic Bookshelf Raleigh, North Carolina Prepared exclusively for Shohei Tanaka Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and The Pragmatic Programmers, LLC was aware of a trademark claim, the designations have been printed in initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer, Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade- marks of The Pragmatic Programmers, LLC. Every precaution was taken in the preparation of this book. However, the publisher assumes no responsibility for errors or omissions, or for damages that may result from the use of information (including program listings) contained herein. Our Pragmatic books, screencasts, and audio books can help you and your team create better software and have more fun. Visit us at https://pragprog.com. The team that produced this book includes: Publisher: Andy Hunt VP of Operations: Janet Furlow Executive Editor: Susannah Davidson Pfalzer Indexing: Potomac Indexing, LLC Copy Editor: Nicole Abramowitz Layout: Gilson Graphics For sales, volume licensing, and support, please contact [email protected]. For international rights, please contact [email protected]. Copyright © 2017 The Pragmatic Programmers, LLC. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent of the publisher. Printed in the United States of America. ISBN-13: 978-1-68050-233-6 Encoded using the finest acid-free high-entropy binary digits. Book version: P1.0—July 2017 Prepared exclusively for Shohei Tanaka Contents Introduction . xi Acknowledgements . xiii Part I — The Functional Paradigm 1. Functional Programming Is Big Again . 3 We’ve Seen This Movie Before 3 New Arguments for Functional Programming 5 2. Functional Thinking for the Imperative Mind . 7 It’s About Functions 7 It’s About Immutability 8 It’s a Way of Thinking 9 Part II — Scala: A Hybrid Language 3. Scala and Functional Style . 15 Functional Purity 15 Higher-Order Functions 15 A Simple Example 16 A Practical Example 18 What About Debugging and Performance? 21 4. Working with Scala Collections . 23 Immutable Collections 23 Mutable Collections 27 Lazy Collections 27 Prepared exclusively for Shohei Tanaka Contents • vi 5. Creating Higher-Order Functions in Scala . 31 Creating a Higher-Order Function 31 Multiple Parameter Lists 34 Function Values and the Loan Pattern 35 Part III — Clojure: The New Lisp 6. An Interview with Rich Hickey . 41 Why Clojure? 41 The Infrastructure 42 Compared to What? 43 7. Getting Clojure: Why Lisp Still Matters . 45 The REPL 45 Vectors and Keywords 47 Macros 49 8. Identity, Value, and State in Clojure . 51 The Object-Oriented Model 51 The Clojure Model 54 9. Concurrent Programming in Clojure . 59 A "Simple" Concurrent Programming Problem 59 Clojure’s Solution 61 Part IV — Elixir: Making Programming Fun Again 10. Patterns and Transformations in Elixir . 69 Pattern Matching 70 Pattern Matching Structured Data 71 Pattern Matching and Functions 72 Transformation Is Job #1 73 11. Getting Functional with Elixir . 75 Anonymous Functions 75 Named Functions 76 A Practical Example 78 Refactor to Functional Style 80 What’s Different About This Code 83 12. Getting Parallel with Elixir . 85 The Actor Model 85 Prepared exclusively for Shohei Tanaka Contents • vii Actors and Elixir 86 Messages 87 Monitoring Your Processes 91 A Final Example 92 Concurrency Is the Core of Elixir 94 Part V — Haskell: The Researcher’s Playground 13. Functional Thinking and Haskell . 97 What It’s All About 97 A Quick Exercise 98 Data Types Are Cheap 99 Pattern Matching 102 Recursion, Control, and Higher-Order Functions 103 Further Features 105 14. Haskell Hands-On . 109 One Step at a Time 110 Generating Candidates 113 Dictionary Filtering 116 Breadth-First Searching 117 Using the Search 120 Performance and Optimization 121 Part VI — Swift: Functional Programming for Mobile Apps 15. Swift: What You Need to Know . 125 Hello, Swift! 126 Functional Swift 127 16. Functional Thinking in Swift . 133 Avoid Nil, Unless You Mean It 133 Avoid Mutable State 135 Use Higher-Order Functions 136 Prepared exclusively for Shohei Tanaka Contents • viii Part VII — Going Deeper 17. Protocols in Swift vs. Ruby and Elixir . 143 The Problem with Extensions 144 The Case for Protocols 145 Protocols and Extensions 147 18. Pattern Matching in Scala . 149 Counting Coins 149 Matching All the Things 152 Using Extractions 153 19. Concurrency in Scala . 157 Using Parallel Collections 157 Knowing When to Use Concurrency 159 Revisiting an Earlier Example 161 20. Clojure’s Exceptional Handling of Exceptions . 163 A Simple Example 164 The Problem with Exceptions 165 A Solution: Conditions 165 Make Life Simple for Your Callers 166 Laziness and Errors 167 21. A Testing Framework for Elixir . 169 Investing in Testing 169 One Experiment, Several Measurements 170 Optimizing Setup with TrueStory 171 Condense and Combine the Measurements 172 Controlling Setup Repetition with Nested Contexts 173 Controlling Setup Repetition with Story Pipes 174 22. Building Test Data with Elixir . 177 The Typical Approaches 177 Beautiful Data for Beautiful Tests 178 Registering Templates and Prototypes with Forge 179 Instantiating Template Entries 180 Mutual Attributes and Having 180 Creating Structs 181 Creating Custom Entities 181 Customizing Persistence 182 Prepared exclusively for Shohei Tanaka Contents • ix 23. Haskell’s Type System . 185 TL;DR 185 What Are Types For? 186 A Concrete Example: Sorting 187 The Language of Haskell’s Type System 189 Type Inference and Type Checking 190 Some Examples 191 Comfort Break 194 Interfaces and Type Classes 195 Some Real-World Examples with Interfaces 200 Pros and Cons—the 80/20 Rule 202 Beyond Haskell: Dependent Types 203 Propositions Are Types, and Proofs Are Programs 204 Another Look at Sorting 205 Back to Earth 207 24. A Haskell Project: Testing Native Code . 211 Our Native Code 212 Our Model 212 A Brief Introduction to Haskell’s FFI 213 Wrapping Our Native Code in Haskell 213 Experimenting with GHCi 214 A Brief Introduction to QuickCheck 215 Writing an Equivalence Property 215 Defect Smashing 218 25. The Many Faces of Swift Functions . 221 Anatomy of Swift Functions 222 Calling All Functions 222 Calling on Methods 223 Instance Methods Are Curried Functions 224 Init: A Special Note 225 Fancy Parameters 227 Access Controls 233 Fancy Return Types 234 Nested Functions 237 26. A Functional Approach to Lua . 239 First-Class Functions in Lua 239 Recursion in Lua 241 Prepared exclusively for Shohei Tanaka Contents • x Building with Functional Primitives 242 A Simple Game Animation 243 A1. Meet the Authors . 247 Bibliography . 251 Index . 253 Prepared exclusively for Shohei Tanaka Introduction by Michael Swaine This book shows how five different languages approach the paradigm of functional programming. The chapters were written by experts in the different languages and first appeared as articles in PragPub magazine. After publishing nearly one hundred issues of the magazine, it became clear that we were in possession of a wealth of information about functional programming, and we decided that some of the best articles would make an interesting book. Functional programming is one of the major paradigms of programming. In functional programming, we approach computation as the evaluation of mathematical functions, and as much as possible we avoid changing state and mutable data. Certain concepts and issues are sure to come up in any discussion of func- tional programming. Recursion. Lazy evaluation. Referential transparency. Eliminating side effects. Functions as first-class objects. Higher-level functions. Currying. Immutable data. Type systems. Pattern matching. The authors touch on all these concepts, looking at them from the perspective of different languages. But functional programming is not an all-or-none thing. It is perfectly reason- able to write imperative code that uses functional techniques and practices and data structures. It is fine to mix and match styles, and some programming languages are designed as hybrids, allowing you to use the style that best fits your needs of the moment. Scala, for example, or Mathematica, or Swift. Our authors explore these different approaches in this book, and you can decide which works best for you.