Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Demystifying functional programming with Scala

Avatar for denisftw denisftw
September 28, 2014

Demystifying functional programming with Scala

An overview of Scala, a brief look at its functional features including higher order functions, monads, currying etc.

Avatar for denisftw

denisftw

September 28, 2014
Tweet

More Decks by denisftw

Other Decks in Programming

Transcript

  1. History 2003 - Released in EPFL 2008 - ‘Programming in

    Scala’ 2010 - Version 2.8 2011 - Typesafe Inc. founded 2012 - Play 2.0 2013 - Version 2.10
  2. Recipe • Take Java-like syntax • Remove specifics and unnecessary

    limitations • Mix in functional features*
  3. Complexity • About 40 reserved words • Only 2 namespaces

    vs. 4 in Java (fields, methods, packages, types) • Methods instead of operators • No primitives (AnyVal)
  4. Hierarchy scala Double scala Unit scala AnyVal scala Any scala

    AnyRef java.lang String scala.collection.immutable List scala Null scala Nothing scala Int
  5. 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
  6. Basics val a = 123 var b: Int = 124

    def increment = (a: Int) => a + 1
  7. Classes class User (var id: Int, val name: String) {

    override def toString: String = { id + ". " + name } } scala> new User(1, "Simon")
  8. Objects object User { def apply(id: Int, name: String): User

    = new User(id, name) } scala> User.apply(2, "Bob")
  9. Objects object User { def apply(id: Int, name: String): User

    = new User(id, name) } scala> User.apply(2, "Bob") scala> User(3, "Chris")
  10. Functional features • Functional data types • Tail recursion •

    Immutability • Higher-order functions • Currying • Pattern matching • Lazy evaluation
  11. 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]
  12. Functional data types val l = 1 :: 2 ::

    3 :: Nil val l2 = 0 :: l 1 2 3 Nil 0
  13. Imperative example def concat(list: List[Any]): String = { val iter

    = list.iterator var result = "" while (iter.hasNext) { result += iter.next } result }
  14. Tail recursion def concatT(s: String, list: List[Any]): String = if

    (list.isEmpty) s else concatT(s + list.head, list.tail)
  15. 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) }
  16. Pattern matching def concat(l: List[Any]): String = l match {

    case Nil => "" case head :: tail => head + concat(tail) }
  17. Higher-order functions val l = List(1, 2, 3, 4, 5)

    l.map(el => el + 1) // List(2, 3, 4, 5, 6)
  18. Higher-order functions val l = List(1, 2, 3, 4, 5)

    l.filter(el => el % 2 == 0) // List(2, 4)
  19. Higher-order functions val l = List(1, 2, 3, 4, 5)

    l.foreach { el => print(el) } // 12345
  20. flatMap class C[T] def map[R](block: T => R): C[R] =

    … def flatMap[R](block: T => C[R]): C[R] = …
  21. 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
  22. Monads A monad is just a monoid in the category

    of endofunctors What's the problem?
  23. for expressions l1.flatMap { el1 => l2.map { el2 =>

    el1 + el2 } } for { el1 <- l1 el2 <- l2 } yield el1 + el2
  24. Stream val numbers = Stream.from(0) val even = for {

    num <- numbers if num % 2 == 0 } yield num
  25. Option maybeUser.map { user => user.name }.map { name =>

    "Welcome back," + name }.getOrElse("Hi") Option[User] Option[String] Option[String] String map map getOrElse
  26. 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]
  27. Try def parse(js: Js): Try[String] def store(name: String): Try[Int] for

    { name <- parse(json) id <- store(name) } yield id scala.util Failure[+T] scala.util Success[+T] scala.util Try[+T]
  28. Future def query(q: String): List[String] val resF = Future {

    query(q) } resF.onComplete { case Success(list) => … case Failure(th) => … } scala.concurrent Future[+T]
  29. Future def query(q: String): Future[List[String]] def store(l: List[String]): Future[Int] def

    notify(i: Int): Future[Unit] queryF.flatMap { list => store(list).flatMap { index => notify(index) } } scala.concurrent Future[+T]
  30. Future val googleF = Future { query("WTF") } Val bingF

    = Future { query("WTF") } for { google <- googleF bing <- bingF } yield process(Seq(google, bing)) scala.concurrent Future[+T]
  31. The book • Suited for people with no prior experience

    in Scala • Includes functional programming tutorial • Focuses on Play 2.7 • ScalikeJDBC, MacWire, Akka • Webpack, Sass, React, EcmaScript 6