Scalafunctional programming demystified @_denisftw_ http://appliedscala.com
Roadmap 1. Introduction 2. Language fundamentals 3. Functional programming
Users Twitter (Ruby) Foursquare (Java/.NET) Tumblr (PHP) Guardian (Java) Klout (PHP) Coursera (PHP) LinkedIn* Netflix* (JVM)
History 2003 - Released in EPFL 2008 - ‘Programming in Scala’ 2010 - Version 2.8 2011 - Typesafe Inc. founded 2012 - First course on Coursera 2013 - Version 2.10
Recipe ● Take Java-like syntax ● Remove specifics and unnecessary limitations ● Mix in functional features*
Complexity ● About 40 reserved words ● Only 2 namespaces vs. 4 in Java (fields, methods, packages, types) ● Methods instead of operators ● No primitives (AnyVal)
Hierarchy scala Double scala Unit scala AnyVal scala Any scala AnyRef java.lang String scala.collection.immutable List scala Null scala Nothing scala Int
Collections s.c Seq s.c Set scala.collection Iterable scala.collection Traversable s.c Map s.c List s.c Buffer s.c IndexedSeq ● Redesigned in 2.8 ● 100500+ methods ● Immutable by default ● Easy conversions ● Buffers
Basics val a = 123 var b: Int = 124 def increment = (a: Int) => a + 1
Basics val list = new List[Int](1, 2, 3, 4) val first = list(0)
Classes class User (var id: Int, val name: String) { }
Classes class User (var id: Int, val name: String) { override def toString = { id + ". " + name } } scala> new User(1, "Simon")
Objects object User { }
Objects object User { def apply(id: Int, name: String) = new User(id, name) } scala> User.apply(2, "Bob")
Objects object User { def apply(id: Int, name: String) = new User(id, name) } scala> User.apply(2, "Bob") scala> User(3, "Chris")
Language tricks val arr = Array[String]("a", "b") val el = arr(1) // arr.apply(1)
Language tricks def abs(a: Int) = if (a >= 0) a else -a abs(12) abs{-13}
Language tricks def greet(implicit name: String) = "Hello" + name implicit val n = "Joe" greet
Functional features ● Functional data types ● Tail recursion ● Immutability ● Higher-order functions ● Currying ● Pattern matching ● Lazy evaluation
Functional data types val l = 1 :: 2 :: 3 :: Nil // List(1, 2, 3) l.head // 1 l.tail // List(2, 3) l.isEmpty // false s.c.i Nil s.c.i ::[T] scala.collection.immutable List[+T]
Functional data types val l = 1 :: 2 :: 3 :: Nil val l2 = 0 :: l 1 2 3 Nil 0
Imperative example def concat(list: List[Any]): String = { }
Imperative example def concat(list: List[Any]): String = { val iter = list.iterator var result = "" while (iter.hasNext) { result += iter.next } result }
Tail recursion def concat(l: List[Any]): String = if (l.isEmpty) else
Tail recursion def concat(l: List[Any]): String = if (l.isEmpty) "" else l.head + concat(l.tail)
Tail recursion def concatT(s: String, list: List[Any]): String = if (list.isEmpty) s else concatT(s + list.head, list.tail)
Tail recursion def concat(l: List[Any]): String = { @tailrec def concatT(s: String, list: List[Any]): String = if (list.isEmpty) s else concatT(s + list.head, list.tail) concatT("", l) }
Pattern matching def concat(l: List[Any]): String = l match { case Nil => case head :: tail => }
Pattern matching def concat(l: List[Any]): String = l match { case Nil => "" case head :: tail => head + concat(tail) }
Lazy evaluation lazy val now = new Date // 13:52:24 now // 13:55:05
Lazy evaluation def debug(on: Boolean, msg:=> String) = { if (on) { doSomething(msg) } }
Lazy evaluation val numbers = Stream.from(0) numbers.take(5).toArray // Array[Int](0, 1, 2, 3, 4)
Higher-order functions val l = List(1, 2, 3, 4, 5) l.map(el => el + 1) // List(2, 3, 4, 5, 6)
Higher-order functions val l = List(1, 2, 3, 4, 5) l.filter(el => el % 2 == 0) // List(2, 4)
Higher-order functions val l = List(1, 2, 3, 4, 5) l.foreach{ el => print(el) } // 12345
Currying def sum(x: Int)(y: Int) = x + y sum(4)(5)
Currying val l = List(1, 2, 3, 4, 5) list.fold(0) { (a, b) => a + b }
Currying def tx[A](block: Session => A) (implicit ctx: Context)
Currying import scalikejdbc._ val statement = … DB.tx { session => SQL(statement).execute }
flatMap class C[T] def map[R](block: T => R): C[R] = … def flatMap[R](block: T => C[R]): C[R] = …
flatMap val l1 = List(1, 2, 3) val l2 = List("a", "b") l1.flatMap{ el1 => l2.map{ el2 => el1 + el2 } } // 1a, 1b, 2a, 2b, 3a, 3b
Monads A monad is just a monoid in the category of endofunctors What's the problem?
for expressions ● map ● flatMap ● filter ● foreach*
for expressions l1.flatMap { el1 => l2.map { el2 => el1 + el2 } }
for expressions l1.flatMap { el1 => l2.map { el2 => el1 + el2 } } for { el1 <- l1 el2 <- l2 } yield el1 + el2
Stream val numbers = Stream.from(0) scala.collection.immutable Stream[+T] scala.collection Traversable[+T]
Stream val numbers = Stream.from(0) val even = for { num <- numbers if num % 2 == 0 } yield num
Option isDefined: Boolean get: T getOrElse[T](default: T): T scala None scala Some[+T] scala Option[+T]
Option def lookup(login: String, password: String): Option[User] val maybeUser: Option[User] = …
Option maybeUser.map { user => user.name }.map { name => "Welcome back," + name }.getOrElse("Hi") Option[User] Option[String] Option[String] String map map getOrElse
Option for { user <- maybeUser name <- Some(user.name) } yield "Welcome back," + name
Try def parse(json: Js): String try { parse(js) } catch { case e: Exception => … }
Try def parse(js: Js): String val nameT = Try { parse(js) } val maybeName = nameT.toOption scala.util Failure[+T] scala.util Success[+T] scala.util Try[+T]
Try def parse(js: Js): String def store(name: String): Int for { name <- Try(parse(json)) id <- Try(store(name)) } yield id scala.util Failure[+T] scala.util Success[+T] scala.util Try[+T]
Future def query(q: String): List[String] val resF = Future { query(q) } resF.onSuccess { case list => … } resF.onFailure { case ex => … } scala.concurrent Future[+T]
Future def query(q: String): List[String] def store(l: List[String]): Int queryF.onSuccess { case list => { val storeF = Future { store(list) } storeF.onSuccess { case id => … } } } scala.concurrent Future[+T]
Future val resultsF = Future{ query("WTF") } for { results <- resultsF id <- Future{ store(results) } } yield id scala.concurrent Future[+T]
Wait... there’s more! ● object-oriented programming ● arcane things ● actors ● ecosystem ● tools and frameworks
The book ● Suited for people with no prior experience in Scala ● Includes functional programming tutorial ● Focuses on Play 2.5 ● ScalikeJDBC, MacWire, Akka ● Webpack, Sass, React, EcmaScript 6
Questions?

Demystifying functional programming with Scala