// value declarations val l1 = List(1,3,5) val l2 = List(6,8,2) // List is a persistent data structure (operations have no side-effects) val l3 = l1 ++ l2 // lambda abstraction val x = l1.foldLeft(0)(_ + _) val x = l1 reduce (_ + _) val x = l1 reduce ((x: Int, y: Int) => x + y) object Sum extends Function2[Int, Int, Int] { def apply(x: Int, y: Int) = x + y } val x = l1 reduce (Sum) // algebraic data types with case classes abstract class Expression { def +(right: Expression) = Plus(this, right) def -(right: Expression) = Minus(this, right) def *(right: Expression) = Mult(this, right) def /(right: Expression) = Div(this, right) } case class Num(value: Int) extends Expression case class Var(name: String) extends Expression case class Plus(left: Expression, right: Expression) extends Expression case class Minus(left: Expression, right: Expression) extends Expression case class Mult(left: Expression, right: Expression) extends Expression case class Div(left: Expression, right: Expression) extends Expression val e = Num(1) + Var("x") * Var("y") // pattern matching def eval(va: Map[String,Int])(e: Expression): Int = { e match { case Num(v) => v case Var(n) => va(n) case Plus(l,r) => eval(va)(l) + eval(va)(r) case Minus(l,r) => eval(va)(l) + eval(va)(r) case Mult(l,r) => eval(va)(l) * eval(va)(r) case Div(l,r) => eval(va)(l) / eval(va)(r) } } // partial function application val ev = eval(Map("x" -> 2, "y" -> 5))_ val res = ev(e) // user-defined control constructs via automatic closure construction class RepeatUntil(body: => Unit) { def until(cond: => Boolean) { body if (!cond) until(cond) } } def repeat(body: => Unit) = new RepeatUntil(body) var x = 0 var i = 0 repeat { i = i + 1 x = i + x } until (i == 10) Console.println(x) // stackable modifications with traits and mix-in composition import scala.collection.mutable.ArrayBuffer abstract class IntQueue { def get(): Int def put(x: Int) } class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) { buf += x } } trait Filtering extends IntQueue { abstract override def put(x: Int) { if (x >= 0) super.put(x) } } trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) } } val queue = new BasicIntQueue with Incrementing with Filtering queue.put(-1) queue.put(10) queue.get()