Functional Programming in Scala

Posted Sun 03 November 2013

Tagged: Scala

Functional Programming in Scala is a Coursera course taught by Martin Odersky. Odersky contributed substantially to Java's generics and built the current incarnation of the Java compiler; you could say he knows his Javas. It seems that was too easy for him, so he created Scala.

My experience with Massively Open Online Courses ("MOOC"s) is that they're slow and highly theoretical, with just the odd quiz thrown in to keep you from falling asleep. I was hesitant to sign up for it.

I'm glad I did, because I ended up learning a great deal.

The course structure is about 1-2 hours of lectures (depending on whether you watch at 2x speed or not - I recommend it), followed by a homework assignment.

The assignments are almost always completely solvable using only the techniques covered in the lectures so far. They're great for forcing you to put the theory into practice, but there's a lot of variance in how much time it takes to finish them, because they often rely on "aha" moments. On the other hand, that's part of what makes them so valuable.

That Functional Programming Thing

I work in Java fulltime, so I've been exposed to a tiny amount of programming in functional style through Google's excellent Guava library. However, Java's lack of lambdas / anonymous functions left some things to be desired:

List<String> myList = ImmutableList.of("dog", "cat", "dingo", "leopard");
List<String> dAnimals = Collections2.filter(myList, new Predicate<String>() {}
    public boolean apply(String animalName) {
        return animalName.startsWith("d");

It's a little hard to appreciate functional programming when it's so verbose; even the Guava documentation reads (paraphrasing) "if you think you need these functional constructs, consider first if you can do the same in a tenth of the lines of code by using a for-each loop". Ouch.

The same thing in Javascript or Python is a lot more concise; here's the python equivalent:

animals = ["dog", "cat", "dingo", "leopard"]
dAnimals = filter(lambda x: x.startswith("d"), animals)
# or using a list comprehension:
dAnimals = [animal for animal in animals if animal.startswith("d")]

First class functions are relatively common in Python (and are a requirement for getting anything done in Javascript these days), so I'm familiar with passing functions around as arguments.

And I had the obligatory course on Haskell way back at uni, where I learnt about function currying and partially applied functions.

What about Scala?

You're expecting Scala to be the savior, bringing functional conciseness to Java's world of verbosity. Surely I wouldn't have typed out those other code examples if it wasn't? Well, I'd hate to disappoint:

val animals = List("dog", "cat", "dingo", "leopard")
val dAnimals = animals.filter(animal => animal.startsWith("d"))
// or using the underscore shortcut
val dAnimals = animals.filter(_.startsWith("d"))

It looks like Python, but it's statically typed, runs on the JVM, and is actually transparently compiled to Java first!

I'll just wait here for you to finish clapping.

Done? Good, now let's talk a little about some neat features of Scala which are demo'd here.

  • val is an immutable reference, like a final variabl in Java.
  • Scala does its best to infer the type of variables. I could have written List[String]("dog", "cat", "dingo", "leopard"), but there was no need to, and I also didn't need to declare animals as a val animals: List[String].
  • List has a filter() method, which returns a new list (because a list created with List() is immutable) which contains only elements for which the given function returns true. You can map (transform), reduce, and fold out of the box as well.
  • Very concise syntax for functions: animal: String => animal.startsWith("d") is a function which takes a String and returns a boolean. (In the example, we didn't need to declare that animal has a type of String because it can be inferred from the context.)

And that doesn't even touch on the many other parts of Scala which are much nicer than Java: free standing functions, inline/nested functions (with closures), pairs/tuples, pattern matching (a way to avoid the mass of if else that regularly happens in Java), interfaces (traits) which can specify implementations too (which enables class mixins), support for lazy evaluation (i.e. a variable's value is only evaluated as it's required), support for call by name evaluation (e.g. you can write a logging function which only evaluates its arguments inside the function, rather than at the call site), and way more.

Scala in Practice

In practice, Scala is a cross between "what Java should have been if it hadn't taken a 5 year-long tea break" and "wouldn't it be neat if we could X in a type-safe way?".

Unfortunately, the enthusiasm of the latter camp seems to have led to a lot of scary features; for example, you can write code that writes that writes code that is statically checked at compile time for type safety. There's also a tendency to invent cryptic new operators (try and guess what /: does? It's not a right-associative division operator).

This seems familiar.

Still, I think it's very much worth using today; in my opinion, the benefits (conciseness & safety) outweigh the downsides (namely, that it's still a bit of an academic dumping ground). Right now, I believe much of the scary stuff can be worked around by having strong style guidelines.

Look for a more complete verdict after I've spent some time writing production code. I have some personal project ideas, and Atlassian is starting to use Scala in production, so that will probably be sooner rather than later.

Anyway, I highly recommend Odersky's Functional Programming Principles in Scala. I've already signed up for the next course in the series, Principles of Reactive Programming.

(With apologies to any functional programming or Scala guru readers for any inaccuracies; please feel free to contact me with corrections)