Rules for Programming (Scala 3 Video)
Alright, that’s enough of the “preface” material, let’s get on with the book!
As I wrote earlier, I want to spare you the route I took of, “You Have to Learn Haskell to Learn Scala/FP,” but, I need to say that I did learn a valuable lesson by taking that route:
It’s extremely helpful to completely forget about several pieces of the Scala programming language as you learn FP in Scala.
Assuming that you come from an “imperative” and OOP background as I did, your attempts to learn Scala/FP will be hindered because it is possible to write both imperative code and FP code in Scala. Because you can write in both styles, what happens is that when things in FP start to get more difficult, it’s easy for an OOP developer to turn back to what they already know, rather than to try to navigate the “FP Learning Cliff.”
To learn Scala/FP the best thing you can do is forget that the imperative options even exist. I promise you, Scout’s Honor, this will accelerate your Scala/FP learning process.
Therefore, to help accelerate your understanding of how to write FP code in Scala, this book uses only the following subset of the Scala programming language.
The rules
To accelerate your Scala/FP learning process, this book uses the following programming “rules”:
- There will be no
null
values in this book. We’ll intentionally forget that there is even anull
keyword in Scala. - Only pure functions will be used in this book. I’ll define pure functions more thoroughly soon, but simply stated, (a) a pure function must always return the same output given the same input, and (b) calling the function must not have any side effects, including reading input, writing output, or modifying any sort of hidden state.
- This book will only use immutable values (
val
) for all fields. There are novar
fields in pure FP code, so I won’t use any variables (var
) in this book, unless I’m trying to explain a point. - Whenever you use an
if
, you must always also use anelse
. Functional programming uses only expressions, not statements. - We won’t create “classes” that encapsulate data and behavior. Instead we’ll create data structures and write pure functions that operate on those data structures.
The rules are for your benefit (really)
These rules are inspired by what I learned from working with Haskell. In Haskell the only way you can possibly write code is by writing pure functions and using immutable values, and when those really are your only choices, your brain quits fighting the system. Instead of going back to things you’re already comfortable with, you think, “Hmm, somehow other people have solved this problem using only immutable values. How can I solve this problem using pure FP?” When your thinking gets to that point, your understanding of FP will rapidly progress.
If you’re new to FP those rules may feel limiting — and you may be wondering how you can possibly get anything done — but if you follow these rules you’ll find that they lead you to a different way of thinking about programming problems. Because of these rules your mind will naturally gravitate towards FP solutions to problems.
For instance, because you can’t use a var
field to initialize a mutable variable before a for
loop, your mind will naturally think, “Hmm, what can I do here? Ah, yes, I can use recursion, or maybe a built-in collections method to solve this problem.” By contrast, if you let yourself reach for that var
field, you’ll never come to this other way of thinking.
Not a rule, but a note: using ???
While I’m writing about what aspects of the Scala language I won’t use in this book, it’s also worth noting that I will often use the Scala ???
syntax when I first sketch a function’s signature. For example, when I first start writing a function named createWorldPeace
, I’ll start to sketch the signature like this:
def createWorldPeace = ???
I mention this because if you haven’t seen this syntax before you may wonder why I’m using it. The reason I use it is because it’s perfectly legal Scala code; that line of code will compile just fine. Go ahead and paste that code into the REPL and you’ll see that it compiles just like this:
scala> def createWorldPeace = ???
createWorldPeace: Nothing
However, while that code does compile, you’ll see a long error message that begins like this if you try to call the createWorldPeace
function:
scala.NotImplementedError: an implementation is missing
I wrote about the ???
syntax in a blog post titled, What does ‘???’ mean in Scala?, but in short, Martin Odersky, creator of the Scala language, added it to Scala for teaching cases just like this. The ???
syntax just means, “The definition of this function is TBD.”
Summary
In summary, the rules we’ll follow in this book are:
- There will be no
null
values. - Only pure functions will be used.
- Immutable values will be used for all fields.
- Whenever you use an
if
, you must always also use anelse
. - We won’t create “classes” that encapsulate data and behavior.
What’s next
Given these rules, let’s jump into a formal definition of “functional programming.”