Upload
vinicius-hana-scardazzi
View
222
Download
3
Embed Size (px)
Citation preview
Técnicas de Programação
Funcional
Em F# e Scala
Vinícius Hana e Juliano Alves
@vinicius_hana e @vonjuliano
Apresentação
Primeiro de tudo: não são paradigmas excludentes!
Programação funcional considera que todas as operações são funções
Todas as operações são funções
def f(x: Int, g: (Int) => Int) = g(x) + 3def g(x: Int) = x * 2
val resultado = f(4, g) // isso dá 11
5
Isso tem nome: funções de alta ordem
Perceberam que se parece com matemática?
Todas as operações são funções
f(x) = x + 3
g(x) = x * 2
(f o g) = f(g(x)) = g(x) + 3
g(4) = 4 * 2 = 8 f(g(4)) = 8 +3 = 11
8
Funções de alta ordem permitem algumas coisas bem legais!
Funções de alta ordem
let funcao = let lista = [0;1;2;3;4]List.map (fun x -> x * 2) lista
10
Agora, uma outra ideia:Dado f(x) = x + 1, se eu passar sempre 1, sempre vai dar 2?
Sim!E isso tem nome: transparência referencial
Dada a mesma entrada, obteremos sempre a mesma saídaOu seja, ausência de efeitos colaterais
Dá pra fazer isso em programação?Sim, usando imutabilidade!
Mutabilidade
public int Resultado { get; set; }
public void Dobrar(int numero){
Resultado *= 2;}
15
Imutabilidade
DateTime.Now.AddDays(1);// retorna novo datetime com a adição feita
16
Dada a mesma entrada, obteremos sempre a mesma saída
Ou seja, ausência de efeitos colaterais – mais confiabilidade no código
F# e Scala suportam mutabilidade e imutabilidade
Imutabilidade em Scala e F#
let x = 1 // imutavellet mutable x = 1 // mutavel
val x = 1 // imutavelvar y = 1 // mutavel
20
Isso ajuda demais em concorrência
Certo, mas como eu manipulo e altero os itens de uma lista, então? Ela não é imutável?
Simples: gere outra com nossa velha amiga recursão!
Com recursão, podemos compor e decompor listas
Recursão em listaslet rec reverse lista =
match lista with| head :: tail -> (reverse tail) @ [head]| [] -> []
def reverse[T](list: List[T]): List[T] = list match { case head :: tail => reverse(tail) ++ List(head) case Nil => Nil}
Percebeu uma estrutura diferente para compor a lista?
Essa estrutura se chama pattern matching
Ela lembra switch-case, porém com muito mais funcionalidade
Pattern matching
match coisa with| 1 | 3 -> …| head :: tail -> …| [] -> …| _ -> …
lista match {case 1 => …case head :: tail => …case Nil => …case _ => …
29
E se eu iterar em uma lista gigantesca, ou mesmo infinita?
Lista infinita? Isso não arrebentaria a memória?
Não se você tiver lazy evaluation!
Lazy evaluation
let x = 10let resultado = lazy (x + 10)
val x = { println("x"); 1 }lazy val y = { println("y"); 2 }
33
Vamos juntar tudo isso em uma implementação de Fibonacci?
Fibonacci
let rec fib n = match n with
| x when n > 2 -> 1| _ -> fib (n - 1) + fib (n - 2)
val seq: Stream[BigInt] = 0 #:: 1 #:: (seq zip seq.tail).map { case (a, b) => a + b }
def elemento(posicao: Int): BigInt = seq(posicao - 1)
35
Referências
Obrigado!
Vinícius Hana e Juliano Alves
@vinicius_hana e @vonjuliano
www.lambda3.com.br