Introduction to Functional Programming with Scala

30
object IntroductionToFunctionalProgrammingWithScala { val myName = "Daniel Cukier" val twitter = "@danicuki" val email = [email protected]" def main(args: Array[String]) { println(“Hello People!”) } }

description

Scala é uma linguagem funcional que roda na JVM. Ela possui todas as vantagens da programação funcional, com a vantagem de ser facilmente integrada com Java, além de possuir uma stack completa de desenvolvimento e deploy. Nessa palestra, daremos os primeiros passos para quem quer trabalhar com Scala. Falaremos de imutabilidade, Traits, funções e expressões lambda entre outros tópicos

Transcript of Introduction to Functional Programming with Scala

Page 1: Introduction to Functional Programming with Scala

object IntroductionToFunctionalProgrammingWithScala { ! val myName = "Daniel Cukier" val twitter = "@danicuki" val email = “[email protected]" ! def main(args: Array[String]) { println(“Hello People!”) } !

}

Page 2: Introduction to Functional Programming with Scala
Page 3: Introduction to Functional Programming with Scala

object IntroductionToFunctionalProgrammingWithScala { ! val myName = "Daniel Cukier" val twitter = "@danicuki" val email = “[email protected]" ! def main(args: Array[String]) { println(“Hello People!”) } !

}

Page 4: Introduction to Functional Programming with Scala

qsort: @ Takes three parameters: @ a: Pointer to base of array a to be sorted (arrives in r0) @ left: First of the range of indexes to sort (arrives in r1) @ right: One past last of range of indexes to sort (arrives in r2) @ This function destroys: r1, r2, r3, r4, r5, r7 stmfd sp!, {r4, r6, lr} @ Save r4 and r6 for caller mov r6, r2 @ r6 <- right qsort_tailcall_entry: sub r7, r6, r1 @ If right - left <= 1 (already sorted), cmp r7, #1 ldmlefd sp!, {r1, r6, pc} @ Return, moving r4->r1, restoring r6 ldr r7, [r0, r1, asl #2] @ r7 <- a[left], gets pivot element add r2, r1, #1 @ l <- left + 1 mov r4, r6 @ r <- right partition_loop: ldr r3, [r0, r2, asl #2] @ r3 <- a[l] cmp r3, r7 @ If a[l] <= pivot_element, addle r2, r2, #1 @ ... increment l, and ble partition_test @ ... continue to next iteration. sub r4, r4, #1 @ Otherwise, decrement r, ldr r5, [r0, r4, asl #2] @ ... and swap a[l] and a[r]. str r5, [r0, r2, asl #2] str r3, [r0, r4, asl #2] partition_test: cmp r2, r4 @ If l < r, blt partition_loop @ ... continue iterating. partition_finish: sub r2, r2, #1 @ Decrement l ldr r3, [r0, r2, asl #2] @ Swap a[l] and pivot str r3, [r0, r1, asl #2] str r7, [r0, r2, asl #2] bl qsort @ Call self recursively on left part, @ with args a (r0), left (r1), r (r2), @ also preserves r6 and @ moves r4 (l) to 2nd arg register (r1) b qsort_tailcall_entry @ Tail-call self on right part, @ with args a (r0), l (r1), right (r6)

Page 5: Introduction to Functional Programming with Scala

qsort: @ Takes three parameters: @ a: Pointer to base of array a to be sorted (arrives in r0) @ left: First of the range of indexes to sort (arrives in r1) @ right: One past last of range of indexes to sort (arrives in r2) @ This function destroys: r1, r2, r3, r4, r5, r7 stmfd sp!, {r4, r6, lr} @ Save r4 and r6 for caller mov r6, r2 @ r6 <- right qsort_tailcall_entry: sub r7, r6, r1 @ If right - left <= 1 (already sorted), cmp r7, #1 ldmlefd sp!, {r1, r6, pc} @ Return, moving r4->r1, restoring r6 ldr r7, [r0, r1, asl #2] @ r7 <- a[left], gets pivot element add r2, r1, #1 @ l <- left + 1 mov r4, r6 @ r <- right partition_loop: ldr r3, [r0, r2, asl #2] @ r3 <- a[l] cmp r3, r7 @ If a[l] <= pivot_element, addle r2, r2, #1 @ ... increment l, and ble partition_test @ ... continue to next iteration. sub r4, r4, #1 @ Otherwise, decrement r, ldr r5, [r0, r4, asl #2] @ ... and swap a[l] and a[r]. str r5, [r0, r2, asl #2]

Page 6: Introduction to Functional Programming with Scala

void swap(int* a, int* b) { int tmp; tmp = *a; * a = *b; * b = tmp; } !int partition(int vec[], int left, int right) { int i, j; ! i = left; for (j = left + 1; j <= right; ++j) { if (vec[j] < vec[left]) { ++i; swap(&vec[i], &vec[j]); } } swap(&vec[left], &vec[i]); ! return i; } !void quickSort(int vec[], int left, int right) { int r; ! if (right > left) { r = partition(vec, left, right); quickSort(vec, left, r - 1); quickSort(vec, r + 1, right); } }

qsort: @ Takes three parameters: @ a: Pointer to base of array a to be sorted (arrives in r0) @ left: First of the range of indexes to sort (arrives in r1) @ right: One past last of range of indexes to sort (arrives in r2) @ This function destroys: r1, r2, r3, r4, r5, r7 stmfd sp!, {r4, r6, lr} @ Save r4 and r6 for caller mov r6, r2 @ r6 <- right qsort_tailcall_entry: sub r7, r6, r1 @ If right - left <= 1 (already sorted), cmp r7, #1 ldmlefd sp!, {r1, r6, pc} @ Return, moving r4->r1, restoring r6 ldr r7, [r0, r1, asl #2] @ r7 <- a[left], gets pivot element add r2, r1, #1 @ l <- left + 1 mov r4, r6 @ r <- right partition_loop: ldr r3, [r0, r2, asl #2] @ r3 <- a[l] cmp r3, r7 @ If a[l] <= pivot_element, addle r2, r2, #1 @ ... increment l, and ble partition_test @ ... continue to next iteration. sub r4, r4, #1 @ Otherwise, decrement r, ldr r5, [r0, r4, asl #2] @ ... and swap a[l] and a[r]. str r5, [r0, r2, asl #2] str r3, [r0, r4, asl #2] partition_test: cmp r2, r4 @ If l < r, blt partition_loop @ ... continue iterating. partition_finish: sub r2, r2, #1 @ Decrement l ldr r3, [r0, r2, asl #2] @ Swap a[l] and pivot str r3, [r0, r1, asl #2] str r7, [r0, r2, asl #2] bl qsort @ Call self recursively on left part, @ with args a (r0), left (r1), r (r2), @ also preserves r6 and @ moves r4 (l) to 2nd arg register (r1) b qsort_tailcall_entry @ Tail-call self on right part, @ with args a (r0), l (r1), right (r6)

Page 7: Introduction to Functional Programming with Scala

void swap(int* a, int* b) { int tmp; tmp = *a; * a = *b; * b = tmp; } !int partition(int vec[], int left, int right) { int i, j; ! i = left; for (j = left + 1; j <= right; ++j) { if (vec[j] < vec[left]) { ++i; swap(&vec[i], &vec[j]); } } swap(&vec[left], &vec[i]); !

Page 8: Introduction to Functional Programming with Scala

def sort(list: List[Int]): List[Int] = { list match { case Nil => list case _ => sort(list.tail.filter(_ <= list.head)) ::: list.head :: sort(list.tail.filter(_ > list.head)) } }

Page 9: Introduction to Functional Programming with Scala

sort :: (Ord a) => [a] -> [a] sort [] = [] sort (pivot:rest) = (sort [y | y <- rest, y < pivot]) ++ [pivot] ++ (sort [y | y <- rest, y >=pivot])

Page 10: Introduction to Functional Programming with Scala

def sort(list: List[Int]): List[Int] = { list match { case Nil => list case _ => sort(list.tail.filter(_ <= list.head)) ::: list.head :: sort(list.tail.filter(_ > list.head)) } }

sort :: (Ord a) => [a] -> [a] sort [] = [] sort (pivot:rest) = (sort [y | y <- rest, y < pivot]) ++ [pivot] ++ (sort [y | y <- rest, y >=pivot])

Page 11: Introduction to Functional Programming with Scala

void swap(int* a, int* b) { int tmp; tmp = *a; * a = *b; * b = tmp; } !int partition(int vec[], int left, int right) { int i, j; ! i = left; for (j = left + 1; j <= right; ++j) { if (vec[j] < vec[left]) { ++i; swap(&vec[i], &vec[j]); } } swap(&vec[left], &vec[i]); ! return i; } !void quickSort(int vec[], int left, int right) { int r; ! if (right > left) { r = partition(vec, left, right); quickSort(vec, left, r - 1); quickSort(vec, r + 1, right); } }

qsort: @ Takes three parameters: @ a: Pointer to base of array a to be sorted (arrives in r0) @ left: First of the range of indexes to sort (arrives in r1) @ right: One past last of range of indexes to sort (arrives in r2) @ This function destroys: r1, r2, r3, r4, r5, r7 stmfd sp!, {r4, r6, lr} @ Save r4 and r6 for caller mov r6, r2 @ r6 <- right qsort_tailcall_entry: sub r7, r6, r1 @ If right - left <= 1 (already sorted), cmp r7, #1 ldmlefd sp!, {r1, r6, pc} @ Return, moving r4->r1, restoring r6 ldr r7, [r0, r1, asl #2] @ r7 <- a[left], gets pivot element add r2, r1, #1 @ l <- left + 1 mov r4, r6 @ r <- right partition_loop: ldr r3, [r0, r2, asl #2] @ r3 <- a[l] cmp r3, r7 @ If a[l] <= pivot_element, addle r2, r2, #1 @ ... increment l, and ble partition_test @ ... continue to next iteration. sub r4, r4, #1 @ Otherwise, decrement r, ldr r5, [r0, r4, asl #2] @ ... and swap a[l] and a[r]. str r5, [r0, r2, asl #2] str r3, [r0, r4, asl #2] partition_test: cmp r2, r4 @ If l < r, blt partition_loop @ ... continue iterating. partition_finish: sub r2, r2, #1 @ Decrement l ldr r3, [r0, r2, asl #2] @ Swap a[l] and pivot str r3, [r0, r1, asl #2] str r7, [r0, r2, asl #2] bl qsort @ Call self recursively on left part, @ with args a (r0), left (r1), r (r2), @ also preserves r6 and @ moves r4 (l) to 2nd arg register (r1) b qsort_tailcall_entry @ Tail-call self on right part, @ with args a (r0), l (r1), right (r6)

def sort(list: List[Int]): List[Int] = { list match { case Nil => list case _ => sort(list.tail.filter(_ <= list.head)) ::: list.head :: sort(list.tail.filter(_ > list.head)) } }

asm

C

Scala

Page 12: Introduction to Functional Programming with Scala

Functional Programming

Page 13: Introduction to Functional Programming with Scala

object Benefits { !!! def FunctionalProgrammingBenefits = Seq(LessCode, Immutability, ConcurrencyAndDistribution, PatternMatching, HigherOrderFunctions ) !

!

}

Page 14: Introduction to Functional Programming with Scala

object Lesscode { !

!

!

!

!

!

!

!

!

!

}

def fact1(n: Int) = { var i = n var result = 1 while (i > 1) { result = result * i i -= 1 } result } ! def fact2(n: Int) = (1 to n).foldLeft(1)(_ * _) ! def fact3(n: Int): Int = if (n == 1) 1 else n * fact3(n - 1)

Page 15: Introduction to Functional Programming with Scala

object ConcurrencyAndDistribution { !

def factorial(n: Int) = Range(1, n+1).foldLeft(1D)(_ * _) ! def main(args: Array[String]) { val x = future { factorial(100) } val y = future { factorial(200) } val z = for (a <- x; b <- y) yield a * b for (c <- z) println("Result: " + c) println("Meanwhile, the main thread goes on!") } !

}

Page 16: Introduction to Functional Programming with Scala

object PatternMatching { !

!

!

!

!

!

!

!

!

!

}

def extract = { val tup = ("hello world", 42) tup match { case (s, i) => println("the string was " + s) println("the number was " + i) } ! val p = Person("John Doe", 42) p match { case Person(name, 42) => println(name) } }

http://goo.gl/bB1TiM

Page 17: Introduction to Functional Programming with Scala

object PatternMatching { !

!

!

!

!

!

!

!

}

def valueAssignment { !

val tup = (19, 73) val (a, b) = tup for ((a, b) <- tup) yield a + b !

}

Page 18: Introduction to Functional Programming with Scala

def checkCases { val tup = (19, 73) ! val result = tup match { case (a, b) => a + b case (19, a) => a } }

object PatternMatching { !

!

!

!

!

!

!

!

!

!

}

//unreachable code

Page 19: Introduction to Functional Programming with Scala

object HigherOrderAndFirstClassFunctions {

!!!!!!!!!

}

!def add(i: Int, j: Int) = i + j !def addTen = add(_: Int, 10) //addTen(20) = 30 : Int !def powerTwo(x: Int => Int)(y: Int): Int = x(y) * x(y) def addTenPowerTwo(x: Int): Int = powerTwo(addTen)(x) !val myFunc = PartialFunction(sum10power2) // myFunc(20) = addTenPowerTwo(20) = // (20 + 10) * (20 + 10) = // 30 * 30 = 900 : Int //vai dar nó no cérebro

Page 20: Introduction to Functional Programming with Scala

object HigherOrderAndFirstClassFunctions {

!!!!!!!!!

}

val root: PartialFunction[Double, Double] = { case d if (d >= 0) => math.sqrt(d) } ! root(3) //Double = 1.7320508075688772 List(0.5, -0.2, 4).collect(root) //List[Double] = List(0.7071067811865476, 2.0)

//vai dar nó no cérebro

Page 21: Introduction to Functional Programming with Scala

Scala

Page 22: Introduction to Functional Programming with Scala
Page 23: Introduction to Functional Programming with Scala

$ mkdir hello $ cd hello $ echo 'object Hi { def main(args: Array[String]) = println("Hi!") }' > hw.scala $ sbt run Hi! !$ mkdir project $ echo 'addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0")' > project/plugins.sbt $ sbt eclipse [info] Successfully created Eclipse project files for project(s): hello

http://www.scala-sbt.org/

Page 24: Introduction to Functional Programming with Scala

object Benefits { !

def ScalaBenefits = Seq(FunctionalProgrammingBenefits, ScalaPlusJava, TypeInference, Traits, Actors) }

Page 25: Introduction to Functional Programming with Scala

object ScalaPlusJava { !!!!!!!!!!!!!}

List<Person> people = ………; List<Person> minors = new ArrayList<Person>(people.size()); List<Person> adults = new ArrayList<Person>(people.size()); public void populate() { for (Person person : people) { if (person.age() < 150) minors.add(person); else adults.add(person); } }

Java

case class Person(val name: String, val age: Int) !val people = List(Person("Dani", 34), Person("Matusalém", 912)) val (minors, adults) = people partition (_.age < 150)

Page 26: Introduction to Functional Programming with Scala

case class Person(val name: String, val age: Int)

def underagePeopleNames(persons: List[Person]) = { for (person <- persons; if person.age < 18) yield person.name } ! def createRandomPeople() = { val names = List("Alice", "Bob", "Carol", “Dave”) for (name <- names) yield { val age = (Random.nextGaussian() * 8 + 20).toInt new Person(name, age) } }

object TypeInference { !

!

!

!

!

!

!

!

!

!

}

val people = createRandomPeople() //people: List[Person] = List(Alice (16),…)) underagePeopleNames(people) //res1: List[String] = List(Alice, Bob, Frank)

Page 27: Introduction to Functional Programming with Scala

object Traits { !

!

!

!

!

!

!

!

!

!

}

abstract class Animal { def eat(): Unit } ! trait HasWings { def fly() { goUp(); goDown() } } ! trait Mammal { def suck() { ... } } ! trait Bird extends Animal with HasWings class Own extends Bird class Bat extends Mammal with HasWings

Page 28: Introduction to Functional Programming with Scala

object Actors {

!!!!!!!!!!

}

class HelloActor extends Actor { def act() { loop { receive { case "hello" => println("hello back at you") case _ => println("huh?") } } } } ! def main(args: Array[String]) { val helloActor = new Actors.HelloActor helloActor.start helloActor ! "hello" helloActor ! “good bye" }

Page 29: Introduction to Functional Programming with Scala

C F C Programação Funcional C G C É um negócio legal G F C Haskel, Erlang ou Scala Am Am/G Não importa a linguagem F C (G7) Se for funcional

C F C Muita recursividade C F C Com imutabilidade C G/B Am Como esse troço é difícil

Bb C Sei programar tão bonito C Bb Que os irmãos vão ficar Bb C Com inveja de mim Bb C Programador de função C Bb Casador de padrão C F Eu uso modelo de ator

Am/G Am Mas também poderoso Am/G Am E um código limpo F C G7 É bem mais gostoso

Page 30: Introduction to Functional Programming with Scala

object IntroductionToFunctionalProgrammingWithScala { ! val myName = "Daniel Cukier" val twitter = "@danicuki" val email = “[email protected]" ! val references = Seq( “https://github.com/danicuki/IntroductionToScala”, “https://www.slideshare.net/danicuki”) ! println(“Thanks!”) !!

}