October 24, 2015

Introduction

I recently finished the Functional Programming Principles in Scala course on Coursera. Having primarily programmed in an imperative language (Java), I enjoyed all the goodies that provided by a functional language. Overall, I enjoyed the class very much, and I recommend it to anyone looking for an introduction to functional programming. In this post, I will go through some of the favorite features of Scala, many of which are missing from Java.

Pattern Matching

Pattern matching is a powerful feature in Scala with no easy equivalent in Java. Java has a switch statement to choose an execution paths based on some equality condition. Conventionally, it is used mostly to improve readability as a replacement for many if/else branches. The Java switch is limited to a few primitive types (int, byte, char, short) and String (in Java 7). Scala overcomes this limitation with a new match keyword that allows matches on complex types. These includes matching on types, collections and even specific objects.

Type Matching

Here’s an example that shows pattern matching on types.

def printType(x: Any): String = x match {
  case x:Integer => "I'm an integer: " + x.toString
  case y:Double => "I'm a double: " + y.toString
  case z:String => "I'm a String: " + z
  case _ => "IDK!"
}

Collection Matching

Pattern matching also works with Scala’s collections library. In this next snippet, we match on Lists of size 0, 1, 2, and more than 2.

def describeList(list: List[Any]): String = list match {
  case Nil => "Empty"
  case elem :: Nil => "One element"
  case elem1 :: elem2 :: Nil => "Two Elements"
  case _ => "More than Two elements"
}

Case class matching

Scala also provides a construct called a Case Class. Case classes can be used in pattern matching like so:

case class Team(city: String, teamName: String)

val teams = List(Team("Washington", "Wizards"), Team("New York", "Giants"))

for (team <- teams) {
  team match {
    case Team("Washington", "Wizards") => println("GO WIZ")
    case _ => println("Meh")
  }
}

:muscle:-typing

Scala features a strong type system. Types are checked at compile time, the compiler infers types and functions are types (first-class functions).

Similar to Java Generics, Scala supports classes parameterized with types. But unlike Java, Scala provides the ability for more complex types bounding. For example, the type List[A <: B] requires that the list be made up of types that are subtypes of B. Similarly, List[A >: B] requires that A is a supertype of B.

The type system gets quite complicated. More details can be found here.

Syntactic Goodies

Scala provides many utilites that allows for more expressive code. While these features can be implemented in Java, Scala provides these out of the box. Here are a few goodies that I think are cool:

Tuples

Scala uses a tuple type for representing an unstructured group of data together. Scala provides the ability for a tuple to hold up to 22 elements. Here is an example of the syntax:

val tuple = ("A", 1, 342.1)
tuple._1 // use ._# to access element # of a tuple
tuple.getClass // tuple is of type Tuple3

Ranges

Scala provides a Range class to represent a range of integer values starting at from going up to or including to. until is used to exclude the end value of a range. to is used to include the end value of a range. A step value can be used to define the incrementing value between the from and to. Here’s an example:

val range = 0 until 5 // [0, 1, 2, 3, 4]
val range1 = 10 to 0 by -2  // [10, 8, 6, 4, 2, 0]

for-comprehension

Scala also provides a pseudo-DSL for manipulating collections. Similar to list comprehensions in Python, Scala provides a more readable method of calling map/flatMap/filter on collections. Here is a canonical example of this feature:

case class Book(author: String, title: String)

for {
  book <- books
  if book.author startsWith "bob" 
} yield book.title

//the above is equivalent to the following:

books.withFilter(book => book.author startsWith "bob").map(book => book.title)

Conclusion

After spending the last few weeks working with Scala, I have developed a fondness for the simplicity and expressiveness of functional languages. I am still a little overwhelmed at the number of features available in the Scala language. There are quite a few “Good Parts” and this post glosses over a small number of them. I am looking forward to exploring the new functional features of Java 8 with the new perspective I gained from studying Scala!

Design Patterns in Real Life

Real world metaphors for Design Patterns Continue reading

Introduction to ZooKeeper

Published on August 16, 2014