Immutable Things

JIT: Immutable Things

As a first “Just In Time” lesson, the first important concept I need to cover is what I call “immutable things”:

  • Immutable variables (immutable algebraic variables)
  • Immutable data structures

1) Immutable variables (algebraic variables)

The term immutable variable sounds like a contradiction, but it just means that we’ll be creating variables in the algebraic sense. For instance, in algebra you write an equation like this:

x = a + b + c

In that equation it’s assumed that all of those variables are immutable — they can’t be changed. That is, you would NOT write algebra like this:

x = a + b + c

a = 42    // error
x = 11    // error

As shown, those last two lines are errors: variables in algebra are never reassigned. The Scala equivalent of this is that you create algebraic variables using the val keyword:

val x = a + b + c

When you create a variable using val, it’s like final in Java; it can never be reassigned. You can see this in the Scala REPL:

scala> val x = 1
val x: Int = 1

scala> x = 2
-- [E052] Type Error: --
1 |x = 2
  |Reassignment to val x

Attempting to reassign x to a new value generates that “Reassignment” error. So that’s how we’ll create variables in this book: as algebraic variables, with the val keyword.

NOTE: In Scala/OOP you can create mutable variables using the var keyword, but this book will not use those.

2) Immutable data structures

This book also uses only immutable data structures, such as the String, List, and Seq classes, and the default Map class, which is also immutable. When you use an immutable data structure, you cannot modify it.

TIP: Java developers know that the Java String is immutable. So just think of all these other data types as working the same way as String: you never modify a String; instead, you call its methods to create a new String. These are like the immutable collections classes that were introduced in Java 9, such as using List.of() in Java 9+.

Because you can’t mutate Scala collections classes like List, Seq, and Map, once you create a sequence like this:

val xs = Seq(1, 2, 3)

the only way to create a new Seq from it is to reassign its result to a new variable:

// create a sequence:
val a = Seq(1, 2, 3)

// create new sequences based on that initial sequence:
val b = a ++ Seq(4, 5)     // b: List(1, 2, 3, 4, 5)
val c = b.filter(_ > 2)    // c: List(3, 4, 5)

If this seems limiting — fear not! — FPers write code like this every day. Immutability is a key concept that makes your code easier to maintain, and safe for parallel programming.