Michał Płachta Learn functional programming in the most practical way possible! Hundreds of code snippets... Like this one All executable from your computer! def parseShows(rawShows: List[String]): List[TvShow] = { rawShows // List( T h e W i r e ( 2 0 0 2 - 2 0 0 8 ) , C h e r n o b y l ( ) ) .map(parseShow) // List(So m e ( T v S h o w ( T h e W i r e , 2 0 0 2 , 2 0 0 8 ) ), None) .map(_.toList) // List(Li s t ( T v S h o w ( T h e W i r e , 2 0 0 2 , 2 0 0 8 ) ), List()) .flatten // List( T v S h o w ( T h e W i r e , 2 0 0 2 , 2 0 0 8 ) ) } ...and accompanying illustrations Like this one flatten goes through each of the lists in this list and adds all their elements into the resulting list in the same order. List[List[A]].flatten: List[A] List(List( ), List(), List( ), List( )).flatten → List( ) Twelve chapters, each including a different real-world scenario You will implement a travel guide, a planner, a meeting scheduler, a TV show parser, a music artists search engine, a currency exchange, and many more applications! (Continued on inside back cover) grokking functional programming Michał Płachta MANNING S I helter Sland 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] ©2022 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. The author and publisher have made every effort to ensure that the information in this book was correct at press time. The author and publisher do not assume and hereby disclaim any liability to any party for any loss, damage, or disruption caused by errors or omissions, whether such errors or omissions result from negligence, accident, or any other cause, or from any usage of the information herein. Manning Publications Co. Development editor: Jennifer Stout 20 Baldwin Road Technical development editor: Josh White Shelter Island, NY 11964 Review editor: Aleksandar Dragosavljevic´ Production editor: Keri Hales Copy editor: Christian Berk Proofreader: Katie Tennant Technical proofreader: Ubaldo Pescatore Typesetter: Dennis Dalinnik Cover designer: Leslie Haimes ISBN: 9781617291838 Printed in the United States of America To my dear family: Marta, Wojtek, and Ola, for all the good vibes and inspiration. To my parents: Renia and Leszek, for all the opportunities you’ve given me. contents preface xix acknowledgments xxi about this book xxiii about the author xxvii P 1 t . . . . . . . . . . . . . . . . . . .1 art he functional toolkit 1 Learning functional programming 3 Perhaps you picked up this book because... 4 What do you need to know before we start? 5 What do functions look like? 6 Meet the function 7 When the code lies... 8 Imperative vs. declarative 9 Coffee break: Imperative vs. declarative 10 Coffee break explained: Imperative vs. declarative 11 How useful is learning functional programming? 12 Leaping into Scala 13 Practicing functions in Scala 14 Getting your tools ready 15 v vi contents Getting to know the REPL 16 Writing your first functions! 17 How to use this book 18 2 Pure functions 21 Why do we need pure functions? 22 Coding imperatively 23 Breaking the code 24 Passing copies of the data 25 Breaking the code . . . again 26 Recalculating instead of storing 27 Focusing on the logic by passing the state 28 Where did the state go? 29 The difference between impure and pure functions 30 Coffee break: Refactoring to a pure function 31 Coffee break explained: Refactoring to a pure function 32 In pure functions we trust 34 Pure functions in programming languages 35 Difficulty of staying pure... 36 Pure functions and clean code 37 Coffee break: Pure or impure? 38 Coffee break explained: Pure or impure? 39 Using Scala to write pure functions 40 Practicing pure functions in Scala 41 Testing pure functions 42 Coffee break: Testing pure functions 43 Coffee break explained: Testing pure functions 44 3 Immutable values 47 The fuel for the engine 48 Another case for immutability 49 Can you trust this function? 50 contents vii Mutability is dangerous 51 Functions that lie... again 52 Fighting mutability by working with copies 53 Coffee break: Getting burned by mutability 54 Coffee break explained: Getting burned by mutability 55 Introducing shared mutable state 58 State’s impact on programming abilities 59 Dealing with the moving parts 60 Dealing with the moving parts using FP 61 Immutable values in Scala 62 Building our intuition about immutability 63 Coffee break: The immutable API 64 String Coffee break explained: The immutable API 65 String Hold on . . . Isn’t this bad? 66 Purely functional approach to shared mutable state 67 Practicing immutable slicing and appending 69 4 Functions as values 71 Implementing requirements as functions 72 Impure functions and mutable values strike back 73 Using Java Streams to sort the list 74 Function signatures should tell the whole story 75 Changing requirements 76 We just pass the code around! 77 Using Java’s values 78 Function Using the syntax to deal with code duplication 79 Function Passing user-defined functions as arguments 80 Coffee break: Functions as parameters 81 Coffee break explained: Functions as parameters 82 Problems with reading functional Java 83 Passing functions in Scala 84 Deep dive into sortBy 85 Signatures with function parameters in Scala 86 viii contents Passing functions as arguments in Scala 87 Practicing function passing 88 Embracing declarative programming 89 Passing functions to custom-made functions 90 Small functions and their responsibilities 91 Passing functions inline 92 Coffee break: Passing functions in Scala 93 Coffee break explained: Passing functions in Scala 94 What else can we achieve just by passing functions? 95 Applying a function to each element of a list 96 Applying a function to each element of a list using 97 map Getting to know 98 map Practicing 99 map Learn once, use everywhere 100 Returning parts of the list based on a condition 101 Returning parts of the list using 102 filter Getting to know 103 filter Practicing 104 filter Our journey so far... 105 Don’t repeat yourself? 106 Is my API easy to use? 107 Adding a new parameter is not enough 108 Functions can return functions 109 Using functions that can return functions 110 Functions are values 111 Coffee break: Returning functions 112 Coffee break explained: Returning functions 113 Designing functional APIs 114 Iterative design of functional APIs 115 Returning functions from returned functions 116 How to return functions from returned functions 117 Using the flexible API built with returned functions 118 Using multiple parameter lists in functions 119 We have been currying! 120 Practicing currying 121