functional programming with_scala

28
λ-Functional Programming with Scala ©2013 Raymond Tay

Upload: raymond-tay

Post on 15-Jan-2015

1.054 views

Category:

Technology


1 download

DESCRIPTION

Functional Programming with Scala

TRANSCRIPT

Page 1: Functional programming with_scala

λ-Functional Programming

with Scala

©2013 Raymond Tay

Page 2: Functional programming with_scala

About m(e)I write code.

I write books too !

Page 3: Functional programming with_scala
Page 4: Functional programming with_scala

https://github.com/raygit/Introduction_to_Scala

Page 5: Functional programming with_scala

The Whats and Whos

Page 6: Functional programming with_scala

Is Scala a fad?

This is when i first heard of Scala

Page 7: Functional programming with_scala

Mutability

val x = 3

var y = 3

Page 8: Functional programming with_scala

Mutability?scala> val x = mutable.HashMap[String,String]()

x: scala.collection.mutable.HashMap[String,String] = Map()

scala> x += ("a" → "a")

res0: x.type = Map(a -> a)

------

scala> val y = immutable.HashMap[String,String]()

y: scala.collection.immutable.HashMap[String,String] = Map()

scala> y += ("a" → "a")

<console>:9: error: reassignment to val

y += ("a" → "a")

Page 9: Functional programming with_scala

Free of side effects

•Code reuse

•Make better building blocks

•Easier to reason about, optimize and test

Page 10: Functional programming with_scala

Functions are First-classdef multiplyFour : Int ⇒ Int = (4 * )

def addTwo: Int ⇒ Int = (2 + )

def º[A,B,C](f: A ⇒ B, g : B ⇒ C ) = f andThen g // Parametric-polymorphism

def f = º(multiplyFour , addTwo) // We’ll make it look more ‘natural’ in the section: Typeclasses

f(4)

res6: Int = 18

(addTwo compose multiplyFour)(4)

res4: Int = 18

Page 11: Functional programming with_scala

Closureval x = 3 // what if its `var x = 3`?

def λ = (y: Int) ⇒ x + y

Be careful what you `close` over i.e. context-sensitive

val xval x λλ33

var xvar x λλ33

77

Page 12: Functional programming with_scala

Lambdas

def g(λ: Int ⇒ Int) = λ

g((x:Int) ⇒ x * 2) OK

g( (x:Int) ⇒ (y:Int) ⇒ x + y ) FAIL

g( ((x: Int) ⇒ (y: Int) ⇒ x + y)(4) ) OK

Page 13: Functional programming with_scala

Matching// simulate a binary tree

sealed trait Tree

case class Branch(ele: Int, left: Tree: right: Tree) extends Tree

case object Leaf extends Tree

// inOrder aka Depth-First Traversal

def inOrder(t: Tree) : List[Int] = t match {

case Branch(ele, l, r) ⇒ inOrder(l):::List(ele):::inOrder(r)

case Leaf ⇒ Nil

}

Page 14: Functional programming with_scala

Recursiondef string2spaces(ss: List[Char]) = ss match {

case Nil ⇒ Nil

case h :: tail ⇒ ‘ ‘ :: string2spaces(tail)

}

import scala.annotation.tailrec

@tailrec

def string2spaces(ss: List[Char], acc: List[Char]): List[Char] = ss match {

case Nil ⇒ acc

case h :: tail ⇒ string2spaces(tail, ‘ ‘ +: acc)

}

Page 15: Functional programming with_scala

Lazy vs Eager Eval

def IamEager[A](value: A)

def IamLazy[A](value: ⇒ A)

Page 16: Functional programming with_scala

TypeclassesWhat I really want to write is

(addTwo ∘ multiplyFour)(4) and not

(addTwo compose multiplyFour)(4)

typeclasses - create higher kinded types! e.g. List[Int ⇒ Int]

Page 17: Functional programming with_scala

Typeclasses in Scalatrait Fn extends (Int ⇒ Int) {

def apply(x: Int) : Int

def º(f: Fn) = f andThen this

}

def addTwo = new Fn { def apply(x: Int) = 2 + x }

def multiplyFour = new Fn { def apply(x: Int) = 4 * x }

multiplyFour º addTwo

res0: Int => Int = <function1>

(addTwo º multiplyFour)(4)

res1: Int = 18

Page 18: Functional programming with_scala

Typeclasses in Scala

sealed trait MList[+A]

case object Nil extends MList[Nothing]

case class ::[+A](head: A, tail: MList[A]) extends MList[A]

object MList {

def apply[A](xs: A*) : MList[A] = if (xs.isEmpty) Nil else ::(xs.head, apply(xs.tail: _*))

}

Page 19: Functional programming with_scala

Typeclasses in Scala

object Main extends App {

val x = MList(1,2,3,4,5) match {

case ::(x, ::(2, ::(4, _))) => x

case Nil => 42

case ::(x, ::(y, ::(3, ::(4, _)))) => x + y

case ::(h, t) => h

case _ => 101

}

println(s"value of ${x}")

}

Page 20: Functional programming with_scala

Adhoc Polymorphism

scala> (1,2,3) map { 1 + _ }

<console>:8: error: value map is not a member of (Int, Int, Int)

(1,2,3) map { 1 + _ }

scala> implicit def giveMeMap[A](t : Tuple3[A,A,A]) = new Tuple3[A,A,A](t._1, t._2, t._3) { def map[B](f: A => B) = new Tuple3(f(_1), f(_2), f(_3)) }scala> (1,2,3) map { 1 + _ }res1: (Int, Int, Int) = (2,3,4)

Page 21: Functional programming with_scala

Adhoc Concurrency

class Matrix(val repr: Array[Array[Double]])

trait ThreadStrategy {

def execute[A](f: () ⇒ A) : () ⇒ A

}

object SingleThreadStrategy extends ThreadStrategy { // uses a single thread }

object ThreadPoolStrategy extends ThreadStrategy { // uses a thread pool }

Page 22: Functional programming with_scala

Adhoc Concurrencyscala> val m = new Matrix(Array(Array(1.2, 2.2), Array(3.4, 4.5)))

m: Matrix =

Matrix

|1.2 | 2.2|

|3.4 | 4.5|

scala> val n = new Matrix(Array(Array(1.2, 2.2), Array(3.4, 4.5)))

n: Matrix =

Matrix

|1.2 | 2.2|

|3.4 | 4.5|

Page 23: Functional programming with_scala

Adhoc Concurrency

scala> MatrixUtils.multiply(m, n)

res1: Matrix =

Matrix

|8.92 | 12.540000000000001|

|19.38 | 27.73|

scala> MatrixUtils.multiply(m, n)(ThreadPoolStrategy)

Executing function on thread: 38

Executing function on thread: 39

Executing function on thread: 40

Executing function on thread: 41

res2: Matrix = // truncated but result is the same, trust me ;)

Page 24: Functional programming with_scala

Concurrency on Collections!

par

val parList = (1 to 1000000).toList.par

(1 to 1000000).toList.par.partition{ _ % 2 == 0 }

Page 25: Functional programming with_scala

Functional Data Structures - List

def foldRight[A,B](l: List[A], z: B)(f: (A,B) ⇒ B) : B = l match {

case Nil ⇒ z

case ::(h, t) ⇒ f(h, foldRight(t,z)(f))

}

@tailrec

def foldLeft[A,B](l: List[A], z: B)(f: (B, A) ⇒ B) : B = l match {

case Nil ⇒ z

case ::(h, t) => foldLeft(t, f(z,h))(f)

}

Page 26: Functional programming with_scala

Reactive Concurrency

Page 27: Functional programming with_scala

If i had more time...

•Existential Types

•Self Types

•Structural Typing (think Duck Typing)

•Compile-time metaprogramming (macros,quasiquotes)

•Reactive Programming through Akka

•Monoids, Monads, Endos, Corecursive and a whole lot more

Page 28: Functional programming with_scala

Thanks

twitter: @RaymondTayBL