Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Scala Functional Programming Patterns

You're reading from   Scala Functional Programming Patterns Grok and perform effective functional programming in Scala

Arrow left icon
Product type Paperback
Published in Dec 2015
Publisher
ISBN-13 9781783985845
Length 298 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Atul S. Khot Atul S. Khot
Author Profile Icon Atul S. Khot
Atul S. Khot
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Grokking the Functional Way 2. Singletons, Factories, and Builders FREE CHAPTER 3. Recursion and Chasing your Own Tail 4. Lazy Sequences – Being Lazy, Being Good 5. Taming Multiple Inheritance with Traits 6. Currying Favors with Your Code 7. Of Visitors and Chains of Responsibilities 8. Traversals – Mapping/Filtering/Folding/Reducing 9. Higher Order Functions 10. Actors and Message Passing 11. It's a Paradigm Shift Index

Preface

This is a book on functional programming patterns using Scala. Functional programming uses functions as basic building blocks. These are functions that don't have any side effects. This challenges our notions about how to write programs. The order of execution for such functions does not matter. We get to reason about them in a referentially transparent manner. This can be a big help in proving correctness. It feels just like a plain arithmetic problem, where (2+2)*(3+3) always equals 24. You may evaluate the expression as 2+2 first, or as 3+3.

I got to know about the Unix culture early in my career. The Unix philosophy relies on pipelining small programs, each doing functionally one and only one thing. One can connect these processing nuggets together. In addition to these hundreds of ready-made building blocks, you could write your own too. These could be easily connected in the pipeline. These pipes and filters were a deeply influential concept as a whole. When I saw Scala's combinators, options, and for comprehensions, I knew I was looking at pipes and filters again. The nuggets in this case were Scala functions instead of Unix processes. Understanding functional programming gives you a new perspective on your code and programming in general. The other aspect of pipelining is that you tend to reuse them intuitively, and you also write less. Though you iterate lines of a text file in a Unix shell pipeline, you don't write any for loops. These are done for you. You just specify which lines pass your criteria or how to transform these lines or both.

Scala allows you to do just that—albeit in a somewhat different form. You don't need to write a for loop, and you keep away from loop counters. Instead, the language invites you to write for comprehensions. Immutability is an actively advocated rule of thumb. Another is avoiding side effects. Scala advocates both. As you probably know, immutability paves the way for more robust concurrency. Why are these so important? Simple, we need to reason about code. Any strategy that makes this activity controlled and simpler is a godsend! Does going down the immutable route mean we end up doing too much copying? How would this Copy On Write measure up against large data structures? Scala has an answer for this in the form of structural sharing.

One-liners are very popular as they get a lot done in a line of code. Scala features allow you to compose such one-liners. Instead of reiterating the same collection, you can do it in one elegant expression. For example, creating an immutable class with constructor and equality comparison defined that is bestowed with destructuring powers is just a one-liner. We just define a case class. There are many situations where Scala one-liners save a lot of programmer time and result in far less code. Combinators such as map, flatMap, filter, and foreach are composed together to express a lot of logic in a one-liner. How does it all affect a program design and design patterns? Here are a few illustrative cases. The singleton design pattern is used to ensure that only one instance of a class could ever exist. Null Objects are specialized singletons that are used to avoid nulls and null checks. Scala's Options give us a similar functionality. Scala's object keyword gives us ready-made singletons. Singletons are specialized factories. A factory creates objects. Scala's syntactic sugar give us a very succinct way to use the apply factory method.

The command design pattern encapsulates an object as a command. It invokes a method on the object. Scala has parameters by name. These are not evaluated at the call site but instead are evaluated at each use within the function. This feature effectively replaces the command pattern with first-class language support. The strategy pattern encapsulates algorithms and allows us to select one at runtime. In Java, we could express the strategy as an interface and the varying algorithms as concrete implementations. Scala's functions are first-class objects. You can pass functions around as method arguments and return values. Functions can be very effective substitutes for the strategy pattern. The ability to define anonymous functions is really helpful here. The Decorator pattern is needed at times. It can be used to decorate (that is, extend) the functionality of an object without modifying it. Some design plumbing needs to be done though. Scala's stackable traits can express the same design very elegantly. One use of the proxy design pattern is for implementing lazy evaluation. When some computation is expensive, we do it only when needed.

As we are very familiar with eager evaluations, we create a list in memory and think it is fully realized. However, just like eager lists, there are lazy lists too. If we think of a typical OR (||) conditional statement, if the left operand is true, the right is not evaluated. This is a very powerful concept. Scala's streams provide lazy lists.

Chain of responsibility is another handy pattern that is used to decouple the sender of a request from its receiver and allows more than one object (a chain of objects) to handle a request. If any object in the chain is not able to handle the request, it passes the request to its next object in the chain. Scala's partial functions fit this bill nicely. We can chain partial functions with Scala's orElse operator to realize the pattern. When we write code, we need to handle errors. Scala's Try/Success/Failure again allows us to write pipelines, and if any piece of the pipeline is an error, rest of the pipeline processing is skipped.

We will look at all these concepts in greater detail. We will set up a problem, look at the traditional Java solution, and then see how Scala changes the game.

Welcome to the Scala wonderland!

lock icon The rest of the chapter is locked
Next Section arrow right
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image