object IntroductionToFunctionalProgrammingWithScala {
!

val myName = "Daniel Cukier"
val twitter = "@danicuki"
val email = “danicuki@ime.usp.br"
!

def main(args: Array[String]) {
println(“Hello People!”)
}
!

}
object IntroductionToFunctionalProgrammingWithScala {
!

val myName = "Daniel Cukier"
val twitter = "@danicuki"
val email = “danicuki@ime.usp.br"
!

def main(args: Array[String]) {
println(“Hello People!”)
}
!

}
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)
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].
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)

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);
}
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]);
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])
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])
qsort:

asm

@ 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)

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;

!

C
!

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);
}

}
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))
}
}

Scala
Functional
Programming
object Benefits {
!
!
!

def FunctionalProgrammingBenefits =
Seq(LessCode,

Immutability,
ConcurrencyAndDistribution,
PatternMatching,
HigherOrderFunctions
)
!
!

}
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)
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!")
}
!

}
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
object PatternMatching {
!

def valueAssignment {

!
!

!

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

!
!
!
!
!

}

!

}
object PatternMatching {
!
!

def checkCases {
val tup = (19, 73)

!
!

!

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

!
!
!
!
!
!

}

}

//unreachable code
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

!
!
!

}
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
Scala
http://www.scala-sbt.org/

$ 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
object Benefits {
!

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

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)

!
!
!
!
!
!
!
!

}

Java

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);
}
}
object TypeInference {
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)
}
}
val people = createRandomPeople()
//people: List[Person] = List(Alice (16),…))
underagePeopleNames(people)
//res1: List[String] = List(Alice, Bob, Frank)
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
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"
}
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

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

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
object IntroductionToFunctionalProgrammingWithScala {
!

val myName = "Daniel Cukier"
val twitter = "@danicuki"
val email = “danicuki@ime.usp.br"
!

val references = Seq(
“https://github.com/danicuki/IntroductionToScala”,
“https://www.slideshare.net/danicuki”)
!

println(“Thanks!”)
!
!

}

Introduction to Functional Programming with Scala

  • 1.
    object IntroductionToFunctionalProgrammingWithScala { ! valmyName = "Daniel Cukier" val twitter = "@danicuki" val email = “danicuki@ime.usp.br" ! def main(args: Array[String]) { println(“Hello People!”) } ! }
  • 3.
    object IntroductionToFunctionalProgrammingWithScala { ! valmyName = "Daniel Cukier" val twitter = "@danicuki" val email = “danicuki@ime.usp.br" ! def main(args: Array[String]) { println(“Hello People!”) } ! }
  • 4.
    qsort: @ Takes threeparameters: @ 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)
  • 5.
    qsort: @ Takes threeparameters: @ 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].
  • 6.
    qsort: @ Takes threeparameters: @ 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) 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); }
  • 7.
    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]);
  • 8.
    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)) } }
  • 9.
    sort :: (Orda) => [a] -> [a] sort [] = [] sort (pivot:rest) = (sort [y | y <- rest, y < pivot]) ++ [pivot] ++ (sort [y | y <- rest, y >=pivot])
  • 10.
    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])
  • 11.
    qsort: asm @ Takes threeparameters: @ 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) 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; ! C ! 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); } } 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)) } } Scala
  • 12.
  • 13.
    object Benefits { ! ! ! defFunctionalProgrammingBenefits = Seq(LessCode,
 Immutability, ConcurrencyAndDistribution, PatternMatching, HigherOrderFunctions ) ! ! }
  • 14.
    object Lesscode { ! deffact1(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)
  • 15.
    object ConcurrencyAndDistribution { ! deffactorial(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!") } ! }
  • 16.
    object PatternMatching { ! defextract = { 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
  • 17.
    object PatternMatching { ! defvalueAssignment { ! ! ! val tup = (19, 73) val (a, b) = tup for ((a, b) <- tup) yield a + b ! ! ! ! ! } ! }
  • 18.
    object PatternMatching { ! ! defcheckCases { val tup = (19, 73) ! ! ! val result = tup match { case (a, b) => a + b case (19, a) => a } ! ! ! ! ! ! } } //unreachable code
  • 19.
    object HigherOrderAndFirstClassFunctions { ! defadd(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 ! ! ! }
  • 20.
    object HigherOrderAndFirstClassFunctions { 
 valroot: 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
  • 21.
  • 23.
    http://www.scala-sbt.org/ $ 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
  • 24.
    object Benefits { ! defScalaBenefits = Seq(FunctionalProgrammingBenefits, ScalaPlusJava, TypeInference, Traits, Actors) }
  • 25.
    object ScalaPlusJava { ! ! ! ! ! caseclass Person(val name: String, val age: Int) ! val people = List(Person("Dani", 34), Person("Matusalém", 912)) val (minors, adults) = people partition (_.age < 150) ! ! ! ! ! ! ! ! } Java 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); } }
  • 26.
    object TypeInference { caseclass 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) } } val people = createRandomPeople() //people: List[Person] = List(Alice (16),…)) underagePeopleNames(people) //res1: List[String] = List(Alice, Bob, Frank)
  • 27.
    object Traits { abstractclass 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
  • 28.
    object Actors { classHelloActor 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" }
  • 29.
    C F C Programação Funcional C G C É umnegó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 Am/G Am Mas também poderoso Am/G Am E um código limpo F C G7 É bem mais gostoso
 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
  • 30.
    object IntroductionToFunctionalProgrammingWithScala { ! valmyName = "Daniel Cukier" val twitter = "@danicuki" val email = “danicuki@ime.usp.br" ! val references = Seq( “https://github.com/danicuki/IntroductionToScala”, “https://www.slideshare.net/danicuki”) ! println(“Thanks!”) ! ! }