Cheatsheet

About

Thanks to Brendan O’Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O’Connor under a CC-BY-SA 3.0 license.

Variables

variable
var x = 5
constant
GOOD val x = 5
BAD x = 6
explicit type
var x: Double = 5

Functions

define function
GOOD def f(x: Int) = { x*x }
BAD def f(x: Int) { x*x } [1]
define function
GOOD def f(x: Any) = println(x)
BAD def f(x) = println(x) [2]
type alias
type R = Double
call-by-value
def f(x: R)
call-by-name
def f(x: => R)
anonymous function
(x:R) => x*x
anonymous function: underscore is positionally matched arg
(1 to 5).map(_*2)
(1 to 5).reduceLeft( _+_ )
anonymous function: to use an arg twice, have to name it
(1 to 5).map( x => x*x )
anonymous function: bound infix method.
GOOD (1 to 5).map(2*)
BAD (1 to 5).map(*2) [3]
anonymous function: block style returns last expression
(1 to 5).map { val x=_*2; println(x); x }
anonymous functions: pipeline style. (or parens too)
(1 to 5) filter {_%2 == 0} map {_*2}
anonymous functions: to pass in multiple blocks, need outer parens
def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x))
val f = compose({_*2}, {_-1})
currying, obvious syntax
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd
currying, obvious syntax
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd
currying, sugar syntax
def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd
val normer = zscore(7, 0.4)_ need trailing underscore to get the partial, only for the sugar version
generic type
def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g)
infix sugar
5.+(3); 5 + 3
(1 to 5) map (_*2)
varargs
def sum(args: Int*) = args.reduceLeft(_+_)

Packages

wildcard import
import scala.collection._
selective import
import scala.collection.Vector
import scala.collection.{Vector, Sequence}
renaming import
import scala.collection.{Vector => Vec28}
import all from java.util except Date
import java.util.{Date => _, _}
declare a package
package pkg at start of file
package pkg { ... }

Data Structures

tuple literal
(1,2,3)
destructing bind: tuple unpacking via pattern matching
GOOD var (x,y,z) = (1,2,3)
BAD var x,y,z = (1,2,3) [4]
list (immutable)
var xs = List(1,2,3)
paren indexing (slides)
xs(2)
cons
1 :: List(2,3)
range sugar
1 to 5 same as 1 until 6
1 to 10 by 2
sole member of the unit type (like C/Java void)
() (empty parens)

Control Constructs

conditional
if (check) happy else sad
conditional sugar
if (check) happy same as if (check) happy else ()
while loop
while (x < 5) { println(x); x += 1}
do while loop
do { println(x); x += 1} while (x < 5)
break (slides)
import scala.util.control.Breaks._
breakable {
    for (x <- xs) {
        if (Math.random < 0.1) break
    }
}
for comprehension: filter/map
for (x <- xs if x%2 == 0) yield x*10 same as xs.filter(_%2 == 0).map(_*10)
for comprehension: destructing bind
for ((x,y) <- xs zip ys) yield x*y same as (xs zip ys) map { case (x,y) => x*y }
for comprehension: cross product
for (x <- xs; y <- ys) yield x*y same as xs flatMap {x => ys map {y => x*y}}
for comprehension: imperative-ish sprintf-style
for (x <- xs; y <- ys) {
    println("%d/%d = %.1f".format(x,y, x*y))
}
for comprehension: iterate including the upper bound
for (i <- 1 to 5) {
    println(i)
}
for comprehension: iterate omitting the upper bound
for (i <- 1 until 5) {
    println(i)
}

Pattern Matching

use case in function args for pattern matching
GOOD (xs zip ys) map { case (x,y) => x*y }
BAD (xs zip ys) map( (x,y) => x*y )
v42 is interpreted as a name matching any Int value, and “42” is printed

BAD

val v42 = 42
Some(3) match {
    case Some(v42) => println("42")
    case _ => println("Not 42")
}
`v42` with backticks is interpreted as the existing val v42, and “Not 42” is printed

GOOD

val v42 = 42
Some(3) match {
    case Some(`v42`) => println("42")
    case _ => println("Not 42")
}
UppercaseVal is treated as an existing val, rather than a new pattern variable, because it starts with an uppercase letter. Thus, the value contained within UppercaseVal is checked against 3, and “Not 42” is printed.

GOOD

val UppercaseVal = 42
    Some(3) match {
    case Some(UppercaseVal) => println("42")
    case _ => println("Not 42")
}

Object Orientation

constructor params - private
class C(x: R) same as class C(private val x: R)
var c = new C(4)
constructor params - public
class C(val x: R)
var c = new C(4)
c.x
constructor is class body, declare a public member, declare a gettable but not settable member, declare a private member, alternative constructor
class C(var x: R) {
    assert(x > 0, "positive please")
    var y = x
    val readonly = 5
    private var secret = 1
    def this = this(42)
}
anonymous class
new{ ... }
define an abstract class. (non-createable)
abstract class D { ... }
define an inherited class
class C extends D { ... }
inheritance and constructor params. (wishlist: automatically pass-up params by default)
class D(var x: R)
class C(x: R) extends D(x)
define a singleton. (module-like)
object O extends D { ... }
traits [5]
trait T { ... }
class C extends T { ... }
class C extends D with T { ... }
multiple traits
trait T1; trait T2
class C extends T1 with T2
class C extends D with T1 with T2
must declare method overrides
class C extends D { override def f = ...}
create object
new java.io.File("f")
callable factory shadowing the type
GOOD List(1,2,3)
BAD new List[Int] [6]
class literal
classOf[String]
type check (runtime)
x.isInstanceOf[String]
type cast (runtime)
x.asInstanceOf[String]
ascription (compile time)
x: String

Footnotes

[1]Hidden error: without = it’s a unit-returning procedure; causes havoc
[2]Syntax error: need types for every arg
[3]Use 2* for sanity’s sake instead
[4]Hidden error: each assigned to the entire tuple
[5]Interfaces-with-implementation. no constructor params. mixin-able
[6]Type error: abstract type