Functional Programming in Java: How functional techniques improve your Java programs

Functional Programming in Java: How functional techniques improve your Java programs

by Pierre-Yves Saumont
Functional Programming in Java: How functional techniques improve your Java programs

Functional Programming in Java: How functional techniques improve your Java programs

by Pierre-Yves Saumont

eBook

$38.99 

Available on Compatible NOOK devices, the free NOOK App and in My Digital Library.
WANT A NOOK?  Explore Now

Related collections and offers


Overview

Summary

Functional Programming in Java teaches Java developers how to incorporate the most powerful benefits of functional programming into new and existing Java code. You'll learn to think functionally about coding tasks in Java and use FP to make your applications easier to understand, optimize, maintain, and scale.

Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.

About the Technology

Here's a bold statement: learn functional programming and you'll be a better Java developer. Fortunately, you don't have to master every aspect of FP to get a big payoff. If you take in a few core principles, you'll see an immediate boost in the scalability, readability, and maintainability of your code. And did we mention that you'll have fewer bugs? Let's get started!

About the Book

Functional Programming in Java teaches you how to incorporate the powerful benefits of functional programming into new and existing Java code. This book uses easy-to-grasp examples, exercises, and illustrations to teach core FP principles such as referential transparency, immutability, persistence, and laziness. Along the way, you'll discover which of the new functionally inspired features of Java 8 will help you most.

What's Inside

  • Writing code that's easier to read and reason about
  • Safer concurrent and parallel programming
  • Handling errors without exceptions
  • Java 8 features like lambdas, method references, and functional interfaces

About the Reader

Written for Java developers with no previous FP experience.

About the Author

Pierre-Yves Saumont is a seasoned Java developer with three decades of experience designing and building enterprise software. He is an R&D engineer at Alcatel-Lucent Submarine Networks.

Table of Contents

  1. What is functional programming?
  2. Using functions in Java
  3. Making Java more functional
  4. Recursion, corecursion, and memoization
  5. Data handling with lists
  6. Dealing with optional data
  7. Handling errors and exceptions
  8. Advanced list handling
  9. Working with laziness
  10. More data handling with trees
  11. Solving real problems with advanced trees
  12. Handling state mutation in a functional way
  13. Functional input/output
  14. Sharing mutable state with actors
  15. Solving common problems functionally

Product Details

ISBN-13: 9781638353621
Publisher: Manning
Publication date: 01/18/2017
Sold by: SIMON & SCHUSTER
Format: eBook
Pages: 472
File size: 6 MB

About the Author

Pierre-Yves Saumont is a seasoned Java developer with three decades of experience designing and building enterprise software. He is an R&D engineer at Alcatel-Lucent Submarine Networks.
Pierre-Yves Saumont is a seasoned Java developer with three decades of experience designing and building enterprise software. He is an R&D engineer at Alcatel-Lucent Submarine Networks.

Table of Contents

Preface xiii

Acknowledgments xvi

About this book xvii

1 What is functional programming? 1

1.1 What is functional programming? 2

1.2 Writing useful programs with no side effects 4

1.3 How referential transparency makes programs safer 6

1.4 The benefits of functional programming 7

1.5 Using the substitution model to reason about programs 8

1.6 Applying functional principles to a simple example 9

1.7 Pushing abstraction to the limit 14

1.8 Summary 15

2 Using functions in Java 16

2.1 What is a function? 17

Functions in the real world 17

2.2 Functions in Java 22

Functional methods 23

Java functional interfaces and anonymous classes 28

Composing functions 29

Polymorphic functions 29

Simplifying the code by using lambdas 31

2.3 Advanced function features 33

What about functions of several arguments? 33

Applying curried functions 34

Higher-order functions 35

Polymorphic higher-order functions 36

Using anonymous functions 39

Local functions 41

Closures 42

Partial function application and automatic currying 44

Sxoitching arguments of partially applied functions 48

Recursive functions 49

The identity function 51

2.4 Java 8 functional interfaces 52

2.5 Debugging with lambdas 53

2.6 Summary 56

3 Making Java more functional 57

3.1 Making standard control structures functional 58

3.2 Abstracting control structures 59

Cleaning up the code 63

An alternative to if… else 66

3.3 Abstracting iteration 71

Abstracting an operation on lists with mapping 72

Creating lists 73

Using head and tail, operations 74

Functionally appending to a list 75

Reducing and folding lists 75

Composing mappings and mapping compositions 82

Applying effects to lists 82

Approaching functional output 83

Building corecursive lists 84

3.4 Using the right types 87

Problems with standard types 87

Defining value types 90

The future of value types in Java 93

3.5 Summary 93

4 Recursion, corecursion, and memoization 94

4.1 Understanding corecursion and recursion 95

Exploring corecursive and recursive addition example 95

Implementing recursion in Java 96

Using tail call elimination 96

Using tail recursive methods and functions 97

Abstracting recursion 97

Using a drop-in replacement for stack-based recursive methods 101

4.2 Working with recursive functions 103

Using locally defined functions 104

Making functions tail recursive 104

Doubly recursive functions: the Fibonacci example 105

Making the list methods stack-safe and recursive 108

4.3 Composing a huge number of functions 111

4.4 Using memoization 114

Memoization in imperative programming 114

Memoization in recursive functions 115

Automatic memoization 117

4.5 Summary 123

5 Data handling with lists 124

5.1 How to classify data collections 125

Different types of lists 125

Relative expected list performance 126

Trading time against memory space, and time against complexity 127

In-place mutation 128

Persistent data structures 129

5.2 An immutable, persistent, singly linked list implementation 130

5.3 Data sharing in list operations 133

More list operations 135

5.4 Using recursion to fold lists with higher-order functions 140

Heap-based recursive version of fold-Right 146

Mapping and filtering lists 148

5.5 Summary 150

6 Dealing with optional data 151

6.1 Problems with the null pointer 152

6.2 Alternatives to null references 153

6.3 The Option data type 156

Getting a value from an Option 158

Applying functions to optional values 160

Dealing with Option composition 161

Option use cases 163

Other ways to combine options 167

Composing List with Option 169

6.4 Miscellaneous utilities for Option 171

Testing for Some or None 171

Equals and hashcode 172

6.5 How and when to use Option 172

6.6 Summary 175

7 Handling errors and exceptions 176

7.1 The problems to be solved 177

7.2 The Either type 178

Composing Either 179

7.3 The Result type 181

Adding methods to the Result class 183

7.4 Result patterns 184

7.5 Advanced Result handling 191

Applying predicates 191

Mapping failures 192

Adding factory methods 195

Applying effects 196

Advanced result composition 199

7.6 Summary 202

8 Advanced list handling 203

8.1 The problem with length 204

The performance problem 204

The benefit of memoization 205

The drawbacks of memoization 205

Actual performance 207

8.2 Composing List and Result 207

Methods on List returning Result 208

Converting from List <Result> to Result<List> 209

8.3 Abstracting common List use cases 212

Zipping and unzipping lists 212

Accessing elements by their index 215

Splitting lists 217

Searching for sublists 221

Miscellaneous functions for working with lists 222

8.4 Automatic parallel processing of lists 225

Not all computations can be parallelized 226

Breaking the list into sublists 226

Processing sublists in parallel 227

8.5 Summary 229

9 Working with laziness 230

9.1 Understanding strictness and laziness 230

Java is a strict language 231

The problem with strictness 232

9.2 Implementing laziness 233

9.3 Things you can't do without laziness 234

9.4 Why not use the Java 8 Stream? 235

9.5 Creating a lazy list data structure 236

Memoizing evaluated values 237

Manipulating streams 241

9.6 The true essence of laziness 243

Folding streams 245

9.7 Handling infinite streams 251

9.8 Avoiding null references and mutable fields 253

9.9 Summary 255

10 More data handling with trees 256

10.1 The binary tree 257

Balanced and unbalanced trees 258

Size, height, and depth 258

Leafy trees 259

Ordered binary trees or binary search trees (EST) 259

Insertion ender 260

Tree traversal order 261

10.2 Implementing the binary search tree 263

10.3 Removing elements from trees 268

10.4 Merging arbitrary trees 270

10.5 Folding trees 275

Folding with two functions 276

Folding with a single function 279

Winch fold implementation to choose 279

10.6 Mapping trees 281

10.7 Balancing trees 282

Rotating trees 282

Balancing trees using the Day-Stout-Warren algorithm 285

Automatically balancing trees 287

Solving the right-problem 288

10.8 Summary 288

11 Solving real problems with advanced trees 290

11.1 Better performance and stack safety with self-balancing trees 291

The basic tree, structure 291

Inserting an element into the red-black tree 295

11.2 A use case for the red-black tree: maps 300

Implementing Map 301

Extending maps 303

Using Map with n on comparable keys 304

11.3 Implementing a functional priority queue 307

The priority queue access protocol 307

Priority queue use cases 307

Implementation requirements 308

The leftist heap data structure 308

Implementing the leftist heap 309

Implementing the queue-like interface 313

11.4 A priority queue for noncomparable elements 314

11.5 Summary 319

12 Handling state mutation in a functional way 321

12.1 A functional random number generator 322

The random number generator interface 323

Implementing the random number generator 324

12.2 A generic API for handling state 327

Working with state operations 328

Composing state operations 329

Recursive state operations 331

12.3 Generic state handling 333

State patterns 334

Building a state machine 335

When to use state and the state machine 340

12.4 Summary 341

13 Functional input/output 342

13.1 Applying effects in context 343

What are effects? 343

Implementing effects 344

More-powerful effects for failures 346

13.2 Reading data 349

Reading data from the console 349

Reading from a file 354

Testing with input 355

13.3 Really functional input/output 356

How can input/output be made fully functional 356

Implementing purely functional input/output 357

Combining 10 358

Handling input with 10 359

Extending the 10 type 361

Making the 10 type stack-safe 364

13.4 Summary 369

14 Sharing mutable state with actors 370

14.1 The actor model 371

Asynchronous messaging 372

Handling parallelization 372

Handling actor state mutation 372

14.2 Building the actor framework 373

Limitations of this actor framework 374

Designing the actor framework interfaces 374

The AbstractActor implementation 376

14.3 Putting actors to work 377

Implementing the ping-pong example 378

A more serious example: running a computation in parallel 379

Reordering the results 385

Fixing the performance problem 388

14.4 Summary 393

15 Solving common problems functionally 394

15.1 Using assertions to validate data 395

15.2 Reading properties from file 399

Loading the property file 400

Reading properties as strings 400

Producing better error message 402

Reading properties as lists 405

Reading enum values 406

Reading properties of arbitral types 407

15.3 Converting an imperative program: the XML reader 409

Listing the necessary functions 411

Composing the functions and applying an effect 412

Implementing the functions 412

Making the program even more functional 414

Fixing the argument type problem 417

Making the element-processing function a parameter 418

Handling errors on element names 420

15.4 Summary 421

Appendix A Using Java 8 functional features 422

Appendix B Monads 429

Appendix C Where to go from here 434

Index 440

From the B&N Reads Blog

Customer Reviews