Some Scala code examples which are by no means exhaustive but just some things I wanted to write down.

Options

val foo = Option(1) // or None
def bar(a: Int) = a + 1

// The match:
foo match {
  case Some(f) => bar(f)
  case None => -1
}

// ...is equivalent to:
foo map bar getOrElse -1

// ...or since Scala 2.10:
foo.fold(-1)(bar)

foo.isEmpty
// is equivalent to:
foo.fold(true)(_ => false)

Performant Matching

Compiling a match expression to a tableswitch or lookupswitch is much more performant because it results in a branch table rather than a decision tree. Such as in the code:

val i = 1
val x = i match {
  case 1  => "Foo"
  case 2  => "Bar"
  case _  => "Baz"
}

The code with a value rather than an integer literal:

val i = 1
val Two = 2
val x = i match {
  case 1  => "Foo"
  case Two  => "Bar"
  case _  => "Baz"
}

…could not be compiled to a tableswitch. However the code:

import scala.annotation.switch

val i = 1
val Two = 2
val x = (i: @switch) match {
  case 1  => "Foo"
  case Two  => "Bar"
  case _  => "Baz"
}

…yields a warning that a tableswitch is not being created.

Enriching

// add method using 'pimp (enrich) my library pattern':
class SpecialList(list: List[String]) {
  def special = list.filter(_.startsWith("foo"))
}

implicit def listToSpecialList(list: List[String]) = new SpecialList(list)

val list = List("foobar", "bazqux")

list.special

// add method using implicit classes (Scala 2.10 onwards):
implicit class SpecialList(list: List[String]) {
  def special = list.filter(_.startsWith("foo"))
}

val list = List("foobar", "bazqux")

list.special

// 'add' method using composition
case class SpecialList(
  list: List[String]
) {
  def special = list.filter(_.startsWith("foo"))
}

val list = SpecialList(List("foobar", "bazqux"))

list.special

Loops

val items = Array("Hello", ", ", "World!")
val moreitems = Array.apply("Hello", ", ", "World!")

items.foreach(arg => println(arg))
items.foreach((arg: String) => println(arg))

val greetStrings = new Array[String](3)

greetStrings.update(0, "Hello")
greetStrings.update(1, ", ")
greetStrings.update(2, "World!")

// long-hand
for (i <- 0.to(2))
  print(greetStrings.apply(i))
// but equivalent to
for (i <- 0 to 2)
  print(greetStrings(i))

Lists

val emptyList = List()
val otherEmptyList = Nil

val items = List("foo", "bar", "baz")
val consStyleItems = "foo" :: "bar" :: "baz" :: Nil // cons prepend to front of Nil list
val concatStyleItems = List("foo", "bar") ::: List("baz")

items(2) // returns 'baz'
items.count(s => s.length == 3) // counts number of items with length of three chars
items.drop(2) // drops first two elements and returns rest of list
items.dropRight(2) // drops RIGHT MOST two elements and returns rest of list
items.exists(s => s == "bar") // boolean: contains item?
items.forall(s => s.startsWith("b")) // Boolean: all items start with "b"
items.forall(s => s.length == 3) // Boolean: all items three chars long
items.foreach(print)
items.isEmpty // Boolean
items.head // first item
items.init // all but the last item
items.last // the last item
items.tail // list minus first element
items.length // Int

val extraItems = items ::: List("password", "extra")
extraItems.filter(s => s.length == 3) // filters only strings with three chars
extraItems.foreach(s => s.startsWith("b"))
extraItems.map(s => "x" + s + "x")
extraItems.map(s => if (s == "password") { "[redacted]" } else { s })
extraItems.filterNot(s => s.length > 3) // new list without the matching items
extraItems.mkString(", ") // make a String out of the List
extraItems.reverse

extraItems.sortBy(s => s)
def printItemsImperative(items: Array[String]): Unit = {
  var i = 0

  while (i < items.length) {
    println(items(i))
    i += 1
  }
}

def printItemsFunctional(items: Array[String]): Unit = {
  for (item <- items)
    println(item)
}

def printItemsFunctionalShort(items: Array[String]): Unit = {
  items.foreach(println)
}

def printItemsPureFunctional(items: Array[String]) = {
  items.mkString("\n")
}

val items = Array("one", "two", "three")
printItemsImperative(items)
printItemsFunctional(items)
printItemsFunctionalShort(items)
println(printItemsPureFunctional(items))

// makes the pure functional method easy to test:
assert(printItemsPureFunctional(items) == "one\ntwo\nthree")

val lines = Array("This is a line", "and this is another line", "so's this!")

val longestLine = lines.reduceLeft((a, b) => if (a.length > b.length) a else b)

Placeholder Syntax

val l = List(1, 3, 4, 6, 1, 3, 4, 9, 4, 6, 2)

l.filter((x: Int) => x > 4)
l.filter((x) => x > 4)
l.filter(x => x > 4)
l.filter(_ > 4)

Partially-applied functions

// the function
def sum (a: Int, b: Int, c: Int) = a + b + c
sum(1, 2, 3)

// create function value object
val s = sum _
s(1, 2, 3)
// is the short form of
s.apply(1, 2, 3) // which forwards params to sum then returns results

// apply to one of the params with two other new ones
val s2 = sum(1, _: Int, 3)
s2(2)

Parameters

// repeated parameters
def echo(args: String*) = for (arg <- args) println(arg)

val args = Array("one", "two", "three")

// pass each element of array to echo, rather than as an Array
echo(args: _ *)

// named arguments
def speed(distance: Float, time: Float): Float = distance / time

speed(100, 10)
speed(time = 10, distance = 100)

// default parameters
def greet(name: String = "World") = println(s"Hello, $name!")
greet("Beth")
greet()

Tail recursion vs imperative loop

def countFromRecursive(x: Int): Int =
  if(x > 9) x
  else countFromRecursive(x + 1)

def countFromLoop(x: Int): Int = {
  var current = x
  while (current < 10)
    current += 1
  current
}

// new stack frame for each call
def notTailRecursive(x: Int): Int =
  if (x == 0) throw new Exception()
  else notTailRecursive(x - 1) + 1

// single stack frame
def tailRecursive(x: Int): Int =
  if (x == 0) throw new Exception()
  else tailRecursive(x - 1)

// no tail-call optimisation
val funValueObject = nestedFunction _

def nestedFunction(x: Int) {
  if (x != 0) {
     println(x)
     funValueObject(x - 1)
  }
}

String interpolation

// s interpolator
val name = "World"
println(s"Hello, $name!")

// f interpolator, like printf
val population = 7.125d
println(f"Hello all $population%2.2f billion people in the world!")

// escaped string
s"x\ny"

// no formatting
raw"x\ny"

Tuples

// finite ordered list of heterogeneous immutable elements
val t = (4,3,2,1)
val sum = t._1 + t._2 + t._3 + t._4
t.productIterator.foreach(println)

val t = (1, "hello", Console)
// is equal to
val t = new Tuple3(1, "hello", Console)

Case class with trait-implemented function

trait Greeter {
  val name: String
  def render: String = "Hello, " + name + "!"
}
 
object Hello {
  case class greet(name: String) extends Greeter
}
 
Hello.greet("World").render

Futures

import scala.util._
import scala.concurrent._
import ExecutionContext.Implicits.global

val f: Future[List[String]] = future {
     Thread.sleep(200) // do something expensive
     List("Hello, World!", "Goodbye, World!")
}

// then:

f onSuccess {
     case messages => for (message <- messages) println(message)
}

f onFailure {
     case t => println("An error has occured: " + t.getMessage)
}

// or, concisely:

f onComplete {
     case Success(messages) => for (message <- messages) println(message)
     case Failure(t) => println("An error has occured: " + t.getMessage)
}

Serialized Futures using flatMap

import scala.util._
import scala.concurrent._
import ExecutionContext.Implicits.global
 
val f1: Future[String] = Future {
  Thread.sleep(200)
  "done 1..."
}
 
val f2: Future[String] = Future {
  Thread.sleep(200)
  "done 2..."
}
 
val serializedFutures: Future[String] = f1 flatMap(res1 => f2)
 
f1 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}
 
f2 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}
 
serializedFutures onComplete{
  case resTry => println("Both Done: Success=" + resTry.isSuccess)
}

Serialized Futures using for comprehension

import scala.util._
import scala.concurrent._
import ExecutionContext.Implicits.global

val f1: Future[String] = Future {
  Thread.sleep(200)
  "done 1..."
}

val f2: Future[String] = Future {
  Thread.sleep(200)
  "done 2..."
}

def combine(s1: String, s12: String): String = "result"

val serializedFutures = for {
  val1 <- f1
  val2 <- f2
} yield combine(val1, val2)

f1 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

f2 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

serializedFutures onComplete{
 case resTry => println("Both Done: Success=" + resTry.isSuccess)
}

BLOCKING Futures using Awaits

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Success, Failure}
 
val f1: Future[String] = Future {
  Thread.sleep(200)
  "done 1..."
}
 
val f2: Future[String] = Future {
  Thread.sleep(200)
  "done 2..."
}
 
Await.result(f1, 10 seconds)
Await.result(f2, 10 seconds)
 
f1 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}
 
f2 onComplete{
  case Success(result) => println(result)
  case Failure(t) => println("An error has occured: " + t.getMessage)
}

XML

def fromXML(node: scala.xml.Node): TheThingIWant = new TheThingIWant {
  val field   = (node \ "field").text
}