Por que dizemos que Scala é uma linguagem funcional?

Post on 05-Jul-2015

293 views 1 download

description

Presented at: VII Scaladores, June/2012.

Transcript of Por que dizemos que Scala é uma linguagem funcional?

POR QUE DIZEMOS QUE SCALA É UMA LINGUAGEM

FUNCIONAL?

Pedro Matiellopmatiello@gmail.com

@pmatiello

POR QUE DIZEMOS QUE SCALA É UMA LINGUAGEM

FUNCIONAL?

SCALA

•Tipagem estática

•Programação orientada a objetos

•Programação funcional

PROGRAMAÇÃO FUNCIONAL

•Hughes, John.: Why Functional Programming Matters. The Computer Journal (1984)

•A operação fundamental é a aplicação de funções

•Um programa é uma função

•Normalmente composta de outras funções

•A entrada são os argumentos

•A saída é o valor devolvido

��

��

��

f(x) = x²

•Transparência referencial (referential transparency)

•A aplicação de uma função não produz efeitos colaterais

•Funções de ordem superior (higher-order functions)

•Avaliação atrasada (lazy evaluation)

FUNÇÕES DE ORDEM SUPERIOR

•Uma função de ordem superior satisfaz ao menos uma das propriedades abaixo:

•Aceita ao menos uma função como argumento

•Devolve uma função

scala> def square(i:Int) = i*isquare: (i: Int)Int

scala> val list = (1 to 10).toListlist: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> def square(i:Int) = i*isquare: (i: Int)Int

scala> val list = (1 to 10).toListlist: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.map(square)res0: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

scala> def square(i:Int) = i*isquare: (i: Int)Int

scala> val list = (1 to 10).toListlist: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.map(square)res0: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

AVALIAÇÃO ATRASADA

•Estratégia de avaliação que satisfaz ambas as propriedades abaixo:

•A avaliação da expressão é atrasada até que o valor seja necessário (non-strict evaluation)

•Avaliações repetidas são evitadas (sharing)

def loop(condition: => Boolean)(expression: => Unit) { if (condition) { expression loop(condition)(expression) }}

CALL BY NAME

def loop(condition: => Boolean)(expression: => Unit) { if (condition) { expression loop(condition)(expression) }}

CALL BY NAME

def loop(condition: => Boolean)(expression: => Unit) { if (condition) { expression loop(condition)(expression) }}

var i = 0;loop(i < 5) { println(i); i=i+1 }

CALL BY NAME

def loop(condition: => Boolean)(expression: => Unit) { if (condition) { expression loop(condition)(expression) }}

var i = 0;loop(i < 5) { println(i); i=i+1 }01234

CALL BY NAME

def loop(condition: => Boolean)(expression: => Unit) { if (condition) { expression loop(condition)(expression) }}

var i = 0;loop(i < 5) { println(i); i=i+1 }01234

CALL BY NAME

(apenas non-strict evaluation)

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

LAZY VALS

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

LAZY VALS

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

scala> if (true) x else y

LAZY VALS

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

scala> if (true) x else yavaliou xres0: java.lang.String = XXX

LAZY VALS

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

scala> if (true) x else yavaliou xres0: java.lang.String = XXX

scala> if (true) x else y

LAZY VALS

scala> lazy val x = { println("avaliou x"); "XXX" }x: java.lang.String = <lazy>

scala> lazy val y = { println("avaliou y"); "YYY" }y: java.lang.String = <lazy>

scala> if (true) x else yavaliou xres0: java.lang.String = XXX

scala> if (true) x else yres1: java.lang.String = XXX

LAZY VALS

scala> lazy val eagerNaturals:List[Int] =0 :: eagerNaturals.map(_+1)

eagerNaturals: List[Int] = <lazy>

STREAMS

scala> lazy val eagerNaturals:List[Int] =0 :: eagerNaturals.map(_+1)

eagerNaturals: List[Int] = <lazy>

scala> eagerNaturals.take(20)java.lang.StackOverflowError! at .eagerNaturals(<console>:7)! at .eagerNaturals(<console>:7)! ...

STREAMS

scala> lazy val lazyNaturals:Stream[Int] =0 #:: lazyNaturals.map(_+1)

lazyNaturals: Stream[Int] = <lazy>

STREAMS

scala> lazy val lazyNaturals:Stream[Int] =0 #:: lazyNaturals.map(_+1)

lazyNaturals: Stream[Int] = <lazy>

scala> lazyNaturals.take(20)res0: scala.collection.immutable.Stream[Int] = Stream(0, ?)

STREAMS

scala> lazy val lazyNaturals:Stream[Int] =0 #:: lazyNaturals.map(_+1)

lazyNaturals: Stream[Int] = <lazy>

scala> lazyNaturals.take(20).toListres1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

STREAMS

POR QUE DIZEMOS QUE SCALA É UMA LINGUAGEM FUNCIONAL?

Pedro Matiellopmatiello@gmail.com

@pmatiello