Top Banner
Scala functional programming demystified @_denisftw_ http://appliedscala.com
60

Demystifying functional programming with Scala

Apr 14, 2017

Download

Engineering

denis
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Demystifying functional programming with Scala

Scalafunctional programming demystified

@_denisftw_http://appliedscala.com

Page 2: Demystifying functional programming with Scala

Roadmap

1. Introduction2. Language fundamentals3. Functional programming

Page 3: Demystifying functional programming with Scala

UsersTwitter (Ruby)Foursquare (Java/.NET)Tumblr (PHP)Guardian (Java)

Klout (PHP)Coursera (PHP)LinkedIn* Netflix* (JVM)

Page 4: Demystifying functional programming with Scala

History

2003 - Released in EPFL2008 - ‘Programming in Scala’2010 - Version 2.82011 - Typesafe Inc. founded2012 - First course on Coursera2013 - Version 2.10

Page 5: Demystifying functional programming with Scala

Recipe

● Take Java-like syntax● Remove specifics and

unnecessary limitations● Mix in functional features*

Page 6: Demystifying functional programming with Scala

Complexity

● About 40 reserved words● Only 2 namespaces vs. 4 in Java (fields, methods,

packages, types)● Methods instead of operators● No primitives (AnyVal)

Page 7: Demystifying functional programming with Scala

Hierarchy

scala

Doublescala

Unit

scala

AnyVal

scala

Any

scala

AnyRef

java.lang

Stringscala.collection.immutable

List

scala

Null

scala

Nothing

scala

Int

Page 8: Demystifying functional programming with Scala

Collections

s.c

Seqs.c

Set

scala.collection

Iterable

scala.collection

Traversable

s.c

Map

s.c

Lists.c

Buffers.c

IndexedSeq

● Redesigned in 2.8● 100500+ methods● Immutable by default● Easy conversions● Buffers

Page 9: Demystifying functional programming with Scala

Basics

val a = 123

var b: Int = 124

def increment = (a: Int) => a + 1

Page 10: Demystifying functional programming with Scala

Basics

val list = new List[Int](1, 2, 3, 4)

val first = list(0)

Page 11: Demystifying functional programming with Scala

Classes

class User (var id: Int, val name: String) {

}

Page 12: Demystifying functional programming with Scala

Classes

class User (var id: Int, val name: String) {

override def toString = {

id + ". " + name

}

}

scala> new User(1, "Simon")

Page 13: Demystifying functional programming with Scala

Objects

object User {

}

Page 14: Demystifying functional programming with Scala

Objects

object User {

def apply(id: Int, name: String) =

new User(id, name)

}

scala> User.apply(2, "Bob")

Page 15: Demystifying functional programming with Scala

Objects

object User {

def apply(id: Int, name: String) =

new User(id, name)

}

scala> User.apply(2, "Bob")

scala> User(3, "Chris")

Page 16: Demystifying functional programming with Scala

Language tricksval arr = Array[String]("a", "b")

val el = arr(1)

// arr.apply(1)

Page 17: Demystifying functional programming with Scala

Language tricksdef abs(a: Int) = if (a >= 0) a else -a

abs(12)

abs{-13}

Page 18: Demystifying functional programming with Scala

Language tricksdef greet(implicit name: String) = "Hello" + name

implicit val n = "Joe"

greet

Page 19: Demystifying functional programming with Scala

Functional features● Functional data types● Tail recursion● Immutability● Higher-order functions● Currying● Pattern matching● Lazy evaluation

Page 20: Demystifying functional programming with Scala

Functional data typesval l = 1 :: 2 :: 3 :: Nil

// List(1, 2, 3)

l.head // 1

l.tail // List(2, 3)

l.isEmpty // false s.c.i

Nils.c.i

::[T]

scala.collection.immutable

List[+T]

Page 21: Demystifying functional programming with Scala

Functional data typesval l = 1 :: 2 :: 3 :: Nil

val l2 = 0 :: l

1 2 3 Nil

0

Page 22: Demystifying functional programming with Scala

Imperative example

def concat(list: List[Any]): String = {

}

Page 23: Demystifying functional programming with Scala

Imperative example

def concat(list: List[Any]): String = {

val iter = list.iterator

var result = ""

while (iter.hasNext) {

result += iter.next

}

result

}

Page 24: Demystifying functional programming with Scala

Tail recursion

def concat(l: List[Any]): String =

if (l.isEmpty)

else

Page 25: Demystifying functional programming with Scala

Tail recursion

def concat(l: List[Any]): String =

if (l.isEmpty)

""

else

l.head + concat(l.tail)

Page 26: Demystifying functional programming with Scala

Tail recursion

def concatT(s: String, list: List[Any]): String =

if (list.isEmpty)

s

else

concatT(s + list.head, list.tail)

Page 27: Demystifying functional programming with Scala

Tail recursiondef 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)

}

Page 28: Demystifying functional programming with Scala

Pattern matching

def concat(l: List[Any]): String =

l match {

case Nil =>

case head :: tail =>

}

Page 29: Demystifying functional programming with Scala

Pattern matching

def concat(l: List[Any]): String =

l match {

case Nil => ""

case head :: tail =>

head + concat(tail)

}

Page 30: Demystifying functional programming with Scala

Lazy evaluation

lazy val now = new Date // 13:52:24

now // 13:55:05

Page 31: Demystifying functional programming with Scala

Lazy evaluation

def debug(on: Boolean, msg:=> String) = {

if (on) {

doSomething(msg)

}

}

Page 32: Demystifying functional programming with Scala

Lazy evaluation

val numbers = Stream.from(0)

numbers.take(5).toArray

// Array[Int](0, 1, 2, 3, 4)

Page 33: Demystifying functional programming with Scala

Higher-order functions

val l = List(1, 2, 3, 4, 5)

l.map(el => el + 1)

// List(2, 3, 4, 5, 6)

Page 34: Demystifying functional programming with Scala

Higher-order functions

val l = List(1, 2, 3, 4, 5)

l.filter(el => el % 2 == 0)

// List(2, 4)

Page 35: Demystifying functional programming with Scala

Higher-order functions

val l = List(1, 2, 3, 4, 5)

l.foreach{ el => print(el) }

// 12345

Page 36: Demystifying functional programming with Scala

Currying

def sum(x: Int)(y: Int) = x + y

sum(4)(5)

Page 37: Demystifying functional programming with Scala

Currying

val l = List(1, 2, 3, 4, 5)

list.fold(0) { (a, b) =>

a + b

}

Page 38: Demystifying functional programming with Scala

Currying

def tx[A](block: Session => A)

(implicit ctx: Context)

Page 39: Demystifying functional programming with Scala

Currying

import scalikejdbc._

val statement = …

DB.tx { session =>

SQL(statement).execute

}

Page 40: Demystifying functional programming with Scala

flatMapclass C[T]

def map[R](block: T => R): C[R] = …

def flatMap[R](block: T => C[R]): C[R] = …

Page 41: Demystifying functional programming with Scala

flatMapval l1 = List(1, 2, 3)

val l2 = List("a", "b")

l1.flatMap{ el1 =>

l2.map{ el2 => el1 + el2 }

}

// 1a, 1b, 2a, 2b, 3a, 3b

Page 42: Demystifying functional programming with Scala

Monads

A monad is just a monoid in the category of endofunctors

What's the problem?

Page 43: Demystifying functional programming with Scala

for expressions● map● flatMap● filter● foreach*

Page 44: Demystifying functional programming with Scala

for expressionsl1.flatMap { el1 =>

l2.map { el2 => el1 + el2 }

}

Page 45: Demystifying functional programming with Scala

for expressionsl1.flatMap { el1 =>

l2.map { el2 => el1 + el2 }

}

for {

el1 <- l1

el2 <- l2

} yield el1 + el2

Page 46: Demystifying functional programming with Scala

Stream

val numbers = Stream.from(0)

scala.collection.immutable

Stream[+T]

scala.collection

Traversable[+T]

Page 47: Demystifying functional programming with Scala

Stream

val numbers = Stream.from(0)

val even = for {

num <- numbers if num % 2 == 0

} yield num

Page 48: Demystifying functional programming with Scala

Option

isDefined: Boolean

get: T

getOrElse[T](default: T): T

scala

Nonescala

Some[+T]

scala

Option[+T]

Page 49: Demystifying functional programming with Scala

Option

def lookup(login: String, password: String):

Option[User]

val maybeUser: Option[User] = …

Page 50: Demystifying functional programming with Scala

Option

maybeUser.map { user =>

user.name

}.map { name =>

"Welcome back," + name

}.getOrElse("Hi")

Option[User]

Option[String]

Option[String]

String

map

map

getOrElse

Page 51: Demystifying functional programming with Scala

Option

for {

user <- maybeUser

name <- Some(user.name)

} yield

"Welcome back," + name

Page 52: Demystifying functional programming with Scala

Trydef parse(json: Js): String

try {

parse(js)

}

catch {

case e: Exception => …

}

Page 53: Demystifying functional programming with Scala

Trydef 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]

Page 54: Demystifying functional programming with Scala

Trydef 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]

Page 55: Demystifying functional programming with Scala

Futuredef query(q: String): List[String]

val resF = Future { query(q) }

resF.onSuccess {

case list => …

}

resF.onFailure {

case ex => …

}

scala.concurrent

Future[+T]

Page 56: Demystifying functional programming with Scala

Futuredef 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]

Page 57: Demystifying functional programming with Scala

Futureval resultsF = Future{ query("WTF") }

for {

results <- resultsF

id <- Future{ store(results) }

} yield id

scala.concurrent

Future[+T]

Page 58: Demystifying functional programming with Scala

Wait... there’s more!

● object-oriented programming● arcane things● actors● ecosystem● tools and frameworks

Page 59: Demystifying functional programming with Scala

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

Page 60: Demystifying functional programming with Scala

Questions?