What this Tutorial Is (and Isn't)
This is a short tutorial on Scala, specifically for CS162. It is intended to answer some common questions students often have about the language. This is not intended to be a complete description of the language, only a brief mentioning of the features most relevant to CS162.
Before diving in, here are some frequently asked questions and answers about Scala and it's relationship to CS162:
Question 1: What is Scala?
Scala is an object-oriented, functional language that runs on the Java Virtual Machine (JVM). By "object-oriented", we mean that it encourages programmers to think in terms of objects and method calls. By "functional", we mean that it encourages programmers to think in terms of higher-order functions (more on those later).
Question 2: Why Scala?
There are two main reasons. From a purely pragmatic viewpoint, Scala is a particularly good implementation language for ideas in programming languages. It is very expressive, and often allows for very short and elegant implementations of things like typecheckers and language interpreters. A more education-oriented reason is that certain ideas behind Scala, such as functional programming, are likely new to most students. We feel that these ideas are valuable, especially considering that there is somewhat of an emergent trend towards these ideas. Additionally, we intentionally want you to learn a language which likely differs significantly from what you're used to; this will help expand your programmer's toolbox, and help you learn additional languages down the road.
Question 3: What is "Pure" Code?
In this context, "pure" code is short for "purely functional" code. Purely functional code is marked not by what it does, but what it doesn't do: mutate state. Purely functional code doesn't reassign to any variables or update any data structures in place.
Question 4: Why Write Pure Code?
Pure code is generally much easier to reason about than impure code.
For example, we know that for a pure function foo
, that foo(5)
will always return the same value.
This aids in debugging and testing, since we need not worry about anything besides the definition of foo
and what is passed to foo
.
If foo
were impure, then arbitrary components of the program may influence the result of foo
, making it much more difficult to figure out what foo
does.
We can no longer assume that two calls to foo(5)
will return the same value, and many other parts of the program could be related.
For example, consider the following impure C code:
int global = 0;
int foo(int x) {
return global + x;
}
void bar(int y) {
global = y * 7;
}
With the above example, debugging foo
is complicated by the fact bar
mutates global
.
This means that if foo
gives us an unexpected result, it may very well be because bar
is to blame, not foo
.
In fact, anything that mutates the global
variable is potentially to blame.
Here, if we want to debug foo
, we also have to debug bar
, and anything else that mutates global
.
This may be a nontrivial amount of code.
In fact, the situation could be even worse, since code that mutates global
may also mutate other variables, meaning they enter the mix of things that must be debugged.
Machines also benefit from pure code.
For example, consider the problem of parallelizing some code.
Parallelization tends to be hard, since synchronization is often necessary to ensure the correctness of some result.
This synchronization is around portions that must be done sequentially or otherwise in some specific order.
The only time this sort of ordering matters is when - you guessed it - mutable state is involved.
Without mutable state, there is no chance that thread A
will mutate thread B
's state before B
is done with it, simply because there is no state to mutate.
This makes things like automatic parallelization much easier.
Question 5: Why Must We Write Pure Code For This Class?
This is to force you to think in a different way than you're probably used to. Scala permits both pure and impure code, and it's pretty easy to write very Java-like Scala that mutates state right and left. The problem with doing this is that you're not learning anything more than a different syntax for Java. By restricting you to write pure code, you'll be learning a whole new way to write programs, rather than just a new skin on an old language.
Question 6: How Can I Write Anything Without Mutating State?!?
Ultimately, this is the most common question about Scala in this class, and rightfully so. Most programmers (myself included) learned that state mutation is how you get anything and everything done, so it initially seems downright impossible to make anything work. It is intended that after this tutorial, you'll at least be able to grasp the basics of getting things done in a purely functional way.