Programação Funcional

Post on 10-Jul-2015

361 views 0 download

description

Programação Funcional FISL 2013

Transcript of Programação Funcional

Programação FuncionalFISL 2013

Juarez Bochi

λSunday, July 14, 13

Juarez Bochi

Sunday, July 14, 13

Juarez Bochi

Sunday, July 14, 13

Juarez Bochi

Sunday, July 14, 13

Juarez Bochi

Sunday, July 14, 13

Juarez Bochi

Sunday, July 14, 13

Agenda

• Motivação

• Conceitos

• Exemplos

• Resumo

Sunday, July 14, 13

Motivação

Sunday, July 14, 13

Ler um arquivo, listar as palavras mais

comuns em ordem decrescente.

Sunday, July 14, 13

Ler um arquivo, listar as palavras mais

comuns em ordem decrescente.

Sunday, July 14, 13

Donald Knuth

X

Sunday, July 14, 13

Donald Knuth Doug McIlroy

X

Sunday, July 14, 13

Donald Knuth Doug McIlroy

X

10+ páginas de Pascal/WEBSunday, July 14, 13

Donald Knuth Doug McIlroy

X

10+ páginas de Pascal/WEB 6 linhas de shellSunday, July 14, 13

tr -cs A-Za-z '\n' |tr A-Z a-z |sort |uniq -c |sort -rn |sed ${1}q

Sunday, July 14, 13

Sunday, July 14, 13

$ cat discurso.txt | tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed 40q 65 e 48 de 42 a 35 o 32 que 18 os 15 para 15 com 14 mais 13 nao 13 do 11 as 10 um 10 dos 10 da 9 das 8 ela 7 todos 7 se 7 pais 7 muito 6 ruas 6 brasil 5 violencia

Sunday, July 14, 13

“Keep it simple, make it general, and make it intelligible.” Doug McIlroy

Sunday, July 14, 13

“Keep it simple, make it general, and make it intelligible.” Doug McIlroy

Sunday, July 14, 13

Conceitos

Sunday, July 14, 13

Paradigmas

• Imperativo

• Lógico

• Funcional

• Orientado a Objetos

Sunday, July 14, 13

Paradigma Imperativo

Linguagem Computador

Variáveis Mutáveis Endereço de memória

Estruturas de controle (if-then-else, loop)

Jumps

Sunday, July 14, 13

“Can Programming Be Liberated from the von. Neumann Style?”John Backus - Turing Award Lecture

Sunday, July 14, 13

Programação Funcional

• Concentrar em teorias, não mutações

• Minimizar mudança de estados

• Sem estruturas de controle imperativas

• Foco em funções

Sunday, July 14, 13

“Programação Funcional é ortogonal à Orientação

a Objetos”

Sunday, July 14, 13

Elementos de Programação

• Expressões Primitivas

• Meios de Combinação

• Meios de Abstração

Sunday, July 14, 13

Exemplos

Sunday, July 14, 13

First Class Functions

Sunday, July 14, 13

First Class Functions

Sunday, July 14, 13

Closure> var inc, dec;undefined> function contador() {... var x = 0;... inc = function() { return ++x; };... dec = function() { return --x; };... }undefined> contador();undefined

Sunday, July 14, 13

Closure> inc();1> inc();2> dec();1> dec();0> inc();1> xReferenceError: x is not defined

Sunday, July 14, 13

> import Control.Applicative> let foo = fmap (+3) (+2)> foo 1015

Sunday, July 14, 13

> import Control.Applicative> let foo = fmap (+3) (+2)> foo 1015

Sunday, July 14, 13

> (defn soma3 [x] (+ x 3))

Sunday, July 14, 13

> (defn soma3 [x] (+ x 3))

> (map soma3 [2 4 6])(5 7 9)

Sunday, July 14, 13

> (defn soma3 [x] (+ x 3))

> (map soma3 [2 4 6])(5 7 9)

Sunday, July 14, 13

> (defn soma3 [x] (+ x 3))

> (map soma3 [2 4 6])(5 7 9)

> (pmap soma3 [2 4 6])(5 7 9)

Sunday, July 14, 13

Higher Order Functionpessoas = [{'nome': 'Adolfo', 'estado': 'MG'}, {'nome': 'Pedro', 'estado': 'RS'}, {'nome': 'Maria', 'estado': 'AC'}]

def por_estado(pessoa1, pessoa2): return cmp(pessoa1['estado'], pessoa2['estado'])

>>> pprint.pprint(sorted(pessoas, cmp=por_estado))[{'estado': 'AC', 'nome': 'Maria'}, {'estado': 'MG', 'nome': 'Adolfo'}, {'estado': 'RS', 'nome': 'Pedro'}]

Sunday, July 14, 13

Recursão

Sunday, July 14, 13

Recursão

(define (fib n) .. (if (< n 2) .. n .. (+ (fib (- n 1)) (fib (- n 2))))) (fib 10)=> 55

Sunday, July 14, 13

Tail Call Optimization1. fib(5)2. fib(4) + fib(3)3. (fib(3) + fib(2)) + (fib(2) + fib(1))4. ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fibb(1) + fib(0)) + fib(1))5. (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) +

fib(1))

Sunday, July 14, 13

Tail Call Optimization

(define (fib n) .. (letrec ((fib-aux (lambda (n a b) .. (if (= n 0) .. a .. (fib-aux (- n 1) b (+ a b)))))) .. (fib-aux n 0 1))) (fib 1000)=> 4.346655768693743e+208

1. fib(5)2. fib(4) + fib(3)3. (fib(3) + fib(2)) + (fib(2) + fib(1))4. ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fibb(1) + fib(0)) + fib(1))5. (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) +

fib(1))

Sunday, July 14, 13

Sunday, July 14, 13

Currying & Partialsdef to_tag(tag, texto): return "<{tag}>{texto}</{tag}>".format(tag=tag, texto=texto)

Sunday, July 14, 13

Currying & Partials

def partial(funcao, argumento): def fn(arg): return funcao(argumento, arg) return fn

def to_tag(tag, texto): return "<{tag}>{texto}</{tag}>".format(tag=tag, texto=texto)

Sunday, July 14, 13

Currying & Partials

def partial(funcao, argumento): def fn(arg): return funcao(argumento, arg) return fn

def to_tag(tag, texto): return "<{tag}>{texto}</{tag}>".format(tag=tag, texto=texto)

negrito = partial(to_tag, 'b')italico = partial(to_tag, 'i')

Sunday, July 14, 13

Currying & Partials

def partial(funcao, argumento): def fn(arg): return funcao(argumento, arg) return fn

def to_tag(tag, texto): return "<{tag}>{texto}</{tag}>".format(tag=tag, texto=texto)

negrito = partial(to_tag, 'b')italico = partial(to_tag, 'i')>>> negrito(italico("Oi, FISL!"))"<b><i>Oi FISL!</i></b>"

Sunday, July 14, 13

Currying & Partials

def partial(funcao, argumento): def fn(arg): return funcao(argumento, arg) return fn

def to_tag(tag, texto): return "<{tag}>{texto}</{tag}>".format(tag=tag, texto=texto)

DSL!!negrito = partial(to_tag, 'b')italico = partial(to_tag, 'i')>>> negrito(italico("Oi, FISL!"))"<b><i>Oi FISL!</i></b>"

Sunday, July 14, 13

Laziness

Sunday, July 14, 13

Laziness

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1)

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) 

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0)

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) 

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] =

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] = s.head #:: sieve(s.tail filter (_ % s.head != 0))

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] = s.head #:: sieve(s.tail filter (_ % s.head != 0)) 

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] = s.head #:: sieve(s.tail filter (_ % s.head != 0)) val primes = sieve(from(2))

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] = s.head #:: sieve(s.tail filter (_ % s.head != 0)) val primes = sieve(from(2)) 

Sunday, July 14, 13

Lazinessdef from(n: Int): Stream[Int] = n #:: from(n+1) val nats = from(0) def sieve(s: Stream[Int]): Stream[Int] = s.head #:: sieve(s.tail filter (_ % s.head != 0)) val primes = sieve(from(2)) (primes take N).toList

Sunday, July 14, 13

Data Abstractionclass Zero(Natural): def __init__(self): pass

def __repr__(self): return "0"

def __add__(self, other): return other

Sunday, July 14, 13

Data Abstractionclass Zero(Natural): def __init__(self): pass

def __repr__(self): return "0"

def __add__(self, other): return other

class Natural(object): def __init__(self, anterior): self.anterior = anterior

def __repr__(self): return repr(self.anterior) + " + 1"

def __add__(self, other): return self.anterior + other.sucessor()

def sucessor(self): return Natural(anterior=self)

Sunday, July 14, 13

Data Abstractionclass Zero(Natural): def __init__(self): pass

def __repr__(self): return "0"

def __add__(self, other): return other

class Natural(object): def __init__(self, anterior): self.anterior = anterior

def __repr__(self): return repr(self.anterior) + " + 1"

def __add__(self, other): return self.anterior + other.sucessor()

def sucessor(self): return Natural(anterior=self)>>> zero = Zero()

>>> um = zero.sucessor()>>> dois = um.sucessor()>>> um0 + 1>>> dois0 + 1 + 1>>> um + dois0 + 1 + 1 + 1

Sunday, July 14, 13

Resumo

Sunday, July 14, 13

Blub Paradox

Sunday, July 14, 13

Resumo

Código fácil de entender

Sunday, July 14, 13

Resumo

Código fácil de manter

Sunday, July 14, 13

Resumo

Código fácil de testar

Sunday, July 14, 13

Resumo

Código fácil de escalar

Sunday, July 14, 13

Obrigado!@jbochi

Sunday, July 14, 13

Referências• http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/

• http://onesixtythree.com/literate/literate2.pdf

• http://mitpress.mit.edu/sicp/

• http://www.paulgraham.com/avg.html

• https://www.coursera.org/course/progfun

• http://www.slideshare.net/jbochi/programao-funcional-em-python

• https://raw.github.com/richhickey/slides/master/simplicitymatters.pdf

• http://pragprog.com/magazines/2013-01/functional-programming-basics

• http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

• http://en.literateprograms.org/Fibonacci_numbers_(Scheme)

• http://norvig.com/21-days.html

• http://www.youtube.com/watch?v=3jg1AheF4n0

• http://www.flickr.com/photos/niceric/74977685/sizes/l/in/

Sunday, July 14, 13