SlideShare uma empresa Scribd logo
1 de 75
Baixar para ler offline
Programação funcional tipada
Uma introdução
meu nome é Arthur Xavier
Oi,
Sou estudante de Ciência da Computação
e apaixonado por Programação Funcional
@arthurxavierx
@arthur-xavier
Maior previsibilidade.
Melhor testabilidade.
Facilidade de raciocínio.
Simplicidade.
Ajuda a evitar uma grande classe de bugs.
Por quê programação funcional?
Não é somente programar com funções.
É um paradigma de programação declarativo.
Modela computações como o resultado da avaliação e composição de funções.
Evita dados mutáveis e efeitos colaterais.
Mas o que é programação funcional?
function squareArrayImperative(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
result.push(arr[i] ** 2);
}
return result;
}
Programação imperativa
const squareArrayDeclarative = arr => arr.map(x => x ** 2);
Programação declarativa
squareList : List Int -> List Int
squareList xs = List.map (x -> x^2) xs
(Elm) Programação declarativa
Linguagem de programação para a criação de interfaces web declarativas.
Foco na usabilidade do desenvolvedor, performance e resiliência.
Elm
Fortemente tipada e funcional pura.
Na prática, aplicações escritas em Elm não produzem exceções de runtime.
Elm
Uma função é uma expressão.
Mapeia elementos de um domínio em elementos de um contradomínio.
Funções
Função
Função
f : ℤ → ℕ = x ↦ |x|
(Elm) Função
f : Int -> Int
f x = abs x
Funções
Seja um conjunto tal que:
ε ∈ ,
∀ x ∈ ℤ, ∀ α ∈ , x • α ∈ .
Então
squareL : → = α ↦
ε se α = ε
x² • squareL(β) se α = x • β
sumL : → ℤ = α ↦
0 se α = ε
x + sumL(β) se α = x • β
(Elm) Funções
squareList : List Int -> List Int
squareList l =
case l of
[] -> []
x :: xs -> x^2 :: squareList xs
sumList : List Int -> Int
sumList l =
case l of
[] -> 0
x :: xs -> x + sumList xs
Toda função é pura.
Funções impuras são chamadas de procedimentos, rotinasou subrotinas.
Funções puras
Uma função pura é uma função que sempre produz o mesmo resultado quando são
passados os mesmos argumentos, e que não produz efeitos colaterais observáveis.
Funções puras
Efeitos colaterais
“Uma função ou expressão produz efeitos colaterais se ela modifica algum estado
fora de seu escopo ou realiza alguma interação observável com as funções que a
chamaram ou com o mundo externo.”
– Wikipedia
Função impura
function append(x) {
this.array.push(x);
}
Função impura
function appendToArray(array, x) {
array.push(x);
}
Função pura
function appendToArray(array, x) {
return [ ...array, x ];
}
(Elm) Função pura
appendToList : List Int -> Int -> List Int
appendToList list x = list ++ [x]
Função impura
function sumOfSquares(array) {
let result = 0;
for (let x in array) {
result += x*x;
}
console.log(result);
};
Função pura
const square = x => x*x;
const add = (a, b) => a + b;
function sumOfSquares(array) {
return array
.map(square)
.reduce(add, 0);
}
console.log(sumOfSquares([2, 3, 5]));
(Elm) Função pura
sumOfSquares : List Int -> Int
sumOfSquares list =
let
square x = x*x
in
List.foldl (+) 0 (List.map square list)
-- cadê o console.log??
Como
programação funcional pura
pode ser útil
se não tem efeitos colaterais?
Abestado,
tem efeitos colaterais sim,
mas são.
representados de forma diferente.
Linguagens funcionais implementam funções de primeira classe.
Funções em linguagens funcionais são valores.
Funções podem ser passadas como argumentos para outras funções.
Funções podem ser valores de retorno de outras funções.
Funções de primeira classe
São funções que recebem outras funções como argumento.
map
reduce / fold
filter
Funções de alta ordem
Funções de alta ordem
sumOfSquares : List Int -> List Int
sumOfSquares list =
let
square x = x*x
in
List.foldl (+) 0 (List.map square list)
Função de alta ordem
map : (a -> b) -> List a -> List b
map f l =
case l of
[] -> []
x :: xs -> f x :: map f xs
Lambda
sumOfSquares : List Int -> List Int
sumOfSquares list = List.foldl (+) 0 (List.map (x -> x*x) list)
Função de primeira classe
mkAdjectifier : String -> String -> String
mkAdjectifier adjective noun = adjective ++ " " ++ noun
coolifier : String -> String
coolifier = mkAdjectifier "cool"
-- coolifier "meetup" == "cool meetup"
Transforma a avaliação de uma função de vários argumentos na avaliação de uma
sequênciade funções de um argumento.
Facilita o uso de funções de vários argumentos e a aplicação parcial de funções.
Currying
f : ℤ × ℤ → ℤ ~ f : ℤ → ℤ → ℤ
Currying
addT : (Int, Int) -> Int
addT (a, b) = a + b
add : Int -> Int -> Int
add a b = a + b
-- add2 :: Int -> Int
add2 = add 2
-- five :: Int
five = add2 3 -- == 5
Mecanismo que combina funções simples para construir outras mais complexas.
Encoraja a fatoração de funções para melhor manutenção e reuso de código.
Composição de funções
( f ∘ g)(x) = f (g(x))
Operador de composição de funções
compose : (a -> b) -> (b -> c) -> (a -> c)
compose f g = a -> f (g a)
(point free) Composição de funções
squareList : List Int -> List Int
squareList = List.map (x -> x*x)
sumList : List Int -> List Int
sumList = List.foldl (+) 0
sumOfSquares : List Int -> List Int
sumOfSquares = sumList << squareList
Composição de funções
squareList : List Int -> List Int
squareList xs = List.map (x -> x*x) xs
sumList : List Int -> List Int
sumList xs = List.foldl (+) 0 xs
sumOfSquares : List Int -> List Int
sumOfSquares xs = (sumList << squareList) xs
Conjuntos de valores(não são classes).
Podem ser compostos.
Seus valores construídos e desestruturados(com pattern matching).
Garantem segurança.
Tipos
Construídos como operações algébricas sobre conjuntos.
Permitem a definição de tipos mais complexos.
Permitem a composição de tipos.
Tipos algébricos
Tipo soma e função com pattern matching
type PrimaryColor = Red | Blue | Yellow
nextColor : PrimaryColor -> PrimaryColor
nextColor color =
case color of
Red -> Blue
Blue -> Yellow
Yellow -> Red
Tipo produto e função com desestruturação
type Point = Point Int Int -- mkPoint : Int -> Int -> Point
addPoints : Point -> Point -> Point
addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2)
(Elm) Records
type alias User = { name : String, email : String }
maria : User
maria = { name = "Maria", email = "maria@email.com" }
type User = User { name : String, email : String } type User = User String String~
Tipos recursivos
type List = Nil | Cons Int List
type NonEmptyList = Single Int | Cons Int List
type Tree = Tree String (List Tree)
type BTree = Empty | NodeLeft String BTree | NodeRight String BTree
Pattern matching em tipos recursivos
mapList : (Int -> Int) -> List -> List
mapList f l =
case l of
Nil -> Nil
Cons x xs -> Cons (f x) (mapList f xs)
mapList : (Int -> Int) -> List -> List
mapList f Nil = Nil
mapList f Cons x xs = Cons (f x) (mapList f xs)
mapTree : (String -> String) -> Tree -> Tree
mapTree f t =
case t of
Empty -> Empty
NodeLeft x xs -> NodeLeft (f x) (mapTree f xs)
NodeRight x xs -> NodeRight (f x) (mapTree f xs)
Tipos paramétricos
type Point a = Point a a
type Tuple a b = Tuple a b
p : Point Int
p = Point 1 3
p2 : Point Float
p2 = Point 1.2 3.4
user : Tuple Int String
user = Tuple 1 "Maria"
Tipos recursivos paramétricos
type List a = Nil | Cons a List -- mkCons : a -> List -> List
type NonEmptyList a = Single a | Cons a List
type Tree a = Tree a (List Tree)
type BTree a = Empty | NodeLeft a BTree | NodeRight a BTree
Tipos paramétricos e funções
type Maybe a = Nothing | Just a
type Either a b = Left a | Right b
head : List a -> Maybe a
head = …
parseMarkdown : String -> Either Error Markdown
parseMarkdown = …
Tipo soma e função parcial
type SecondaryColor = Orange | Green | Purple
addPrimaryColors : PrimaryColor -> PrimaryColor -> SecondaryColor
addPrimaryColors c1 c2 =
case (c1, c2) of
(Red, Blue) -> Purple
(Red, Yellow) -> Orange
(Blue, Red) -> Purple
(Blue, Yellow) -> Green
(Yellow, Red) -> Orange
(Yellow, Blue) -> Green
Tipo soma e função
type SecondaryColor = Orange | Green | Purple
addPrimaryColors : PrimaryColor -> PrimaryColor -> Either PrimaryColor SecondaryColor
addPrimaryColors c1 c2 =
case (c1, c2) of
(Red, Blue) -> Right Purple
(Red, Yellow) -> Right Orange
(Blue, Red) -> Right Purple
(Blue, Yellow) -> Right Green
(Yellow, Red) -> Right Orange
(Yellow, Blue) -> Right Green
_ -> Left c1
Tipo inseguro
type Permission = BlockUser | BanUser | RemovePosts
type UserType = Guest | User | Admin
type alias User =
{ name : Maybe String
, email : Maybe Email
, permissions : List Permission
, userType : UserType
}
Tipo seguro
type Permission = BlockUser | BanUser | RemovePosts
type User
= Guest
| User
{ name : String
, email : Email
}
| Admin
{ name : String
, email : Email
, permissions : List Permission
}
Tipo seguro++
type Permission = BlockUser | BanUser | RemovePosts
type User p
= Guest
| User
{ name : String
, email : Email
}
| Admin
{ name : String
, email : Email
, permissions : p
}
Ter de tratar todos os valores possíveis de um tipo ajuda a entender o domínio.
Quando uma função é parcial pode-se restringir sua entrada ou sua saída.
“Ah,vocênãosabiaqueessalistanãopodiaservazia?Culpasua!
ArrayOutOfBoundsException!!”
— Java Enterprise Edition
Totalidade
Funções totais
head : List a -> Maybe a
head = …
head : NonEmptyList a -> a
head = …~
Resolve problemas causados por estados mutáveis:
Condições de corrida, complexidade, imprevisibilidade…
Linguagens funcionais puras representam mutabilidade como efeito colateral.
Elm nem mesmo permitem mutabilidade.
Imutabilidade
Coleções como listas ou árvores são úteis para representar iterações sobre dados.
Mais do que isso elas permitem transformar múltiplos valores em outro tipo.
Coleções
Funções úteis do tipo List
head : List a -> Maybe a
tail : List a -> Maybe (List a)
range : Int -> Int -> List Int
(::) : a -> List a -> List a
append : List a -> List a -> List a
sort : List comparable -> List comparable
map : (a -> b) -> List a -> List b
map2 : (a -> b -> c) -> List a -> List b -> List c
foldr : (a -> b -> b) -> b -> List a -> b
foldl : (a -> b -> b) -> b -> List a -> b
filter : (a -> Bool) -> List a -> List a
Estruturas algébricas que implementam a operação map e seguem as leis:
map : (a -> b) -> f a -> f b
map id = id
map (f << g) = map f << map g
Functores
São contêineres que representam resultados de computações sobre outros tipos.
As computações representadas pelo functor são definidas pela forma do functor e
pelo comportamento da operação map.
Functores
Maybe
type Maybe a = Nothing | Just a
map : (a -> b) -> Maybe a -> Maybe b
map f maybe =
case maybe of
Nothing -> Nothing
Just a -> Just (f a)
Either
type Either a = Left a | Right a
map : (a -> b) -> Either a -> Either b
map f either =
case either of
Left a -> Left a
Right a -> Right (f a)
Tuple
map : (a -> b) -> (t, a) -> (t, b)
map f (tag, a) = (tag, f a)
List
map : (a -> b) -> List a -> List b
map f list =
case list of
[] -> []
x :: xs -> f x :: map f list
Maior previsibilidade.
Melhor testabilidade.
Facilidade de raciocínio.
Simplicidade.
Corretude.
Por quê programação funcional?*
Hands-on
TodoMVC++
Nesta primeira parte vamos apenas inserir notas no modelo e mostrá-las como
elementos Html na tela.
Vamos também inserir novas notas no modelo ao clicar em um botão.
Parte 1
Nesta segunda parte vamos tratar a edição de notas.
Quando o usuário clicar em uma nota deveremos poder editá-la. Ao pressionar
Enter, as modificações devem ser salvas no modelo.
Será necessário modificar o modelo para que seja possível identificar qual nota está
sendo editada no momento.
Parte 2
Nesta terceira parte veremos como Elm trata efeitos colaterais através de ports.
Faremos com que nossa aplicação salve o modelo quando ele for alterado no local
storage do browser.
Parte 3
Uma port em Elm é um valor ou função definido com a keyword port que deve
produzir um valor do tipo Cmd, um comando.
Precisaremos definir uma port que envia o modelo a ser salvo para o mundo externo.
Por conveniência já foi feito no arquivo index.html o tratamento dos comandos
recebidos pela port que iremos definir.
Parte 3
Nesta quarta parte veremos os benefícios dos tipos paramétricos.
Parametrizaremos o tipo Noteem relação a um tipo i que representa o campo de
identificação de uma nota.
Parte 4
Nesta quinta e última parte parametrizaremos o tipo Note em relação ao conteúdo.
Para que possamos usar tipos que não sejam String para representar o tipo de uma
nota, mas mantendo o tipo String como conteúdo das notas serializadas, devemos
parametrizar o tipo Note em relação ao conteúdo e tornar as funções que operam
sobre ele polimórficas sobre o conteúdo.
Parte 5
Recursos
An Introduction to Elm
http://guide.elm-lang.org/
Elm Examples
http://elm-lang.org/examples
Elm Search
https://klaftertief.github.io/elm-search/
Elm Packages
http://package.elm-lang.org/
https://github.com/arthur-xavier/workshop-intro-fp-elm

Mais conteúdo relacionado

Mais procurados

Palestra python
Palestra pythonPalestra python
Palestra pythonRony Cruch
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Luciano Ramalho
 
Evolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScriptEvolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScriptJean Carlo Emer
 
Iteraveis e geradores em Python
Iteraveis e geradores em PythonIteraveis e geradores em Python
Iteraveis e geradores em PythonLuciano Ramalho
 
Python em (mais de) 10 minutinhos
Python em (mais de) 10 minutinhosPython em (mais de) 10 minutinhos
Python em (mais de) 10 minutinhosRudá Moura
 
Linguagem C - Vetores, Matrizes e Funções
Linguagem C - Vetores, Matrizes e FunçõesLinguagem C - Vetores, Matrizes e Funções
Linguagem C - Vetores, Matrizes e FunçõesElaine Cecília Gatto
 
Objetos Pythonicos - compacto
Objetos Pythonicos - compactoObjetos Pythonicos - compacto
Objetos Pythonicos - compactoLuciano Ramalho
 
Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Elaine Cecília Gatto
 
Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Elaine Cecília Gatto
 
Iteráveis e geradores (versão RuPy)
Iteráveis e geradores (versão RuPy)Iteráveis e geradores (versão RuPy)
Iteráveis e geradores (versão RuPy)Luciano Ramalho
 
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...Manuel Menezes de Sequeira
 
Orientação a Objetos em Python
Orientação a Objetos em PythonOrientação a Objetos em Python
Orientação a Objetos em PythonLuciano Ramalho
 

Mais procurados (19)

Palestra python
Palestra pythonPalestra python
Palestra python
 
Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)Orientação a objetos em Python (compacto)
Orientação a objetos em Python (compacto)
 
Evolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScriptEvolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScript
 
PHP Básico - Parte 3
PHP Básico - Parte 3PHP Básico - Parte 3
PHP Básico - Parte 3
 
App scala
App scalaApp scala
App scala
 
Iteraveis e geradores em Python
Iteraveis e geradores em PythonIteraveis e geradores em Python
Iteraveis e geradores em Python
 
Python em (mais de) 10 minutinhos
Python em (mais de) 10 minutinhosPython em (mais de) 10 minutinhos
Python em (mais de) 10 minutinhos
 
Linguagem C - Vetores, Matrizes e Funções
Linguagem C - Vetores, Matrizes e FunçõesLinguagem C - Vetores, Matrizes e Funções
Linguagem C - Vetores, Matrizes e Funções
 
Objetos Pythonicos - compacto
Objetos Pythonicos - compactoObjetos Pythonicos - compacto
Objetos Pythonicos - compacto
 
ESTRUTURA DE DADOS (JAVA) AULA 09
ESTRUTURA DE DADOS (JAVA) AULA 09ESTRUTURA DE DADOS (JAVA) AULA 09
ESTRUTURA DE DADOS (JAVA) AULA 09
 
Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1Vetores, Matrizes e Strings em C Parte 1
Vetores, Matrizes e Strings em C Parte 1
 
Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3Vetores, Matrizes e Strings em C Parte 3
Vetores, Matrizes e Strings em C Parte 3
 
Iteraveis e geradores
Iteraveis e geradoresIteraveis e geradores
Iteraveis e geradores
 
Iteráveis e geradores (versão RuPy)
Iteráveis e geradores (versão RuPy)Iteráveis e geradores (versão RuPy)
Iteráveis e geradores (versão RuPy)
 
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
 
Orientação a Objetos em Python
Orientação a Objetos em PythonOrientação a Objetos em Python
Orientação a Objetos em Python
 
Aula 15
Aula 15Aula 15
Aula 15
 
Linguagem C - Vetores
Linguagem C - VetoresLinguagem C - Vetores
Linguagem C - Vetores
 
Introdução à Linguagem Ruby
Introdução à Linguagem RubyIntrodução à Linguagem Ruby
Introdução à Linguagem Ruby
 

Semelhante a Programação funcional tipada: Uma introdução

Haskell aula5 f.ordem-sup_modulos-cifra_cesar
Haskell aula5 f.ordem-sup_modulos-cifra_cesarHaskell aula5 f.ordem-sup_modulos-cifra_cesar
Haskell aula5 f.ordem-sup_modulos-cifra_cesarCRISLANIO MACEDO
 
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonIEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonDiogo Gomes
 
Python Funcional
Python FuncionalPython Funcional
Python Funcionalpugpe
 
Técnicas de Programação Funcional
Técnicas de Programação FuncionalTécnicas de Programação Funcional
Técnicas de Programação FuncionalLambda 3
 
Paradigma Funcional - Caso de Estudo Haskell
Paradigma Funcional - Caso de Estudo HaskellParadigma Funcional - Caso de Estudo Haskell
Paradigma Funcional - Caso de Estudo HaskellSérgio Souza Costa
 
Por que dizemos que Scala é uma linguagem funcional?
Por que dizemos que Scala é uma linguagem funcional?Por que dizemos que Scala é uma linguagem funcional?
Por que dizemos que Scala é uma linguagem funcional?pmatiello
 
Desmistificando Built-in Functions, Lambda e List Comprehension...
Desmistificando Built-in Functions, Lambda e List Comprehension...Desmistificando Built-in Functions, Lambda e List Comprehension...
Desmistificando Built-in Functions, Lambda e List Comprehension...Matheus Pereira
 
Python e django na prática
Python e django na práticaPython e django na prática
Python e django na práticaRafael Cassau
 
F sharp e o paradigma funcional
F sharp e o paradigma funcionalF sharp e o paradigma funcional
F sharp e o paradigma funcionalEvandro Souza
 
Programando em python recursao
Programando em python   recursaoProgramando em python   recursao
Programando em python recursaosamuelthiago
 
Estruturas de dados em Python
Estruturas de dados em PythonEstruturas de dados em Python
Estruturas de dados em PythonRicardo Paiva
 
Lazy Evaluation em Scala
Lazy Evaluation em ScalaLazy Evaluation em Scala
Lazy Evaluation em Scalapmatiello
 

Semelhante a Programação funcional tipada: Uma introdução (20)

Haskell aula5 f.ordem-sup_modulos-cifra_cesar
Haskell aula5 f.ordem-sup_modulos-cifra_cesarHaskell aula5 f.ordem-sup_modulos-cifra_cesar
Haskell aula5 f.ordem-sup_modulos-cifra_cesar
 
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop PythonIEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
 
Introdução ao paradigma funcional com scala
Introdução ao paradigma funcional com scalaIntrodução ao paradigma funcional com scala
Introdução ao paradigma funcional com scala
 
Pythonfuncional
PythonfuncionalPythonfuncional
Pythonfuncional
 
Python Funcional
Python FuncionalPython Funcional
Python Funcional
 
Técnicas de Programação Funcional
Técnicas de Programação FuncionalTécnicas de Programação Funcional
Técnicas de Programação Funcional
 
Paradigma Funcional - Caso de Estudo Haskell
Paradigma Funcional - Caso de Estudo HaskellParadigma Funcional - Caso de Estudo Haskell
Paradigma Funcional - Caso de Estudo Haskell
 
Por que dizemos que Scala é uma linguagem funcional?
Por que dizemos que Scala é uma linguagem funcional?Por que dizemos que Scala é uma linguagem funcional?
Por que dizemos que Scala é uma linguagem funcional?
 
Desmistificando Built-in Functions, Lambda e List Comprehension...
Desmistificando Built-in Functions, Lambda e List Comprehension...Desmistificando Built-in Functions, Lambda e List Comprehension...
Desmistificando Built-in Functions, Lambda e List Comprehension...
 
Python e django na prática
Python e django na práticaPython e django na prática
Python e django na prática
 
F sharp e o paradigma funcional
F sharp e o paradigma funcionalF sharp e o paradigma funcional
F sharp e o paradigma funcional
 
07-lambda.pdf
07-lambda.pdf07-lambda.pdf
07-lambda.pdf
 
Unidade7 1
Unidade7 1Unidade7 1
Unidade7 1
 
Python Emsl2009
Python Emsl2009Python Emsl2009
Python Emsl2009
 
Programando em python recursao
Programando em python   recursaoProgramando em python   recursao
Programando em python recursao
 
Java 8 - New Features
Java 8 - New FeaturesJava 8 - New Features
Java 8 - New Features
 
Funções e procedimentos
Funções e procedimentosFunções e procedimentos
Funções e procedimentos
 
Estruturas de dados em Python
Estruturas de dados em PythonEstruturas de dados em Python
Estruturas de dados em Python
 
Slide_Python.pdf
Slide_Python.pdfSlide_Python.pdf
Slide_Python.pdf
 
Lazy Evaluation em Scala
Lazy Evaluation em ScalaLazy Evaluation em Scala
Lazy Evaluation em Scala
 

Programação funcional tipada: Uma introdução

  • 2. meu nome é Arthur Xavier Oi, Sou estudante de Ciência da Computação e apaixonado por Programação Funcional @arthurxavierx @arthur-xavier
  • 3. Maior previsibilidade. Melhor testabilidade. Facilidade de raciocínio. Simplicidade. Ajuda a evitar uma grande classe de bugs. Por quê programação funcional?
  • 4. Não é somente programar com funções. É um paradigma de programação declarativo. Modela computações como o resultado da avaliação e composição de funções. Evita dados mutáveis e efeitos colaterais. Mas o que é programação funcional?
  • 5. function squareArrayImperative(arr) { let result = []; for (let i = 0; i < arr.length; i++) { result.push(arr[i] ** 2); } return result; } Programação imperativa
  • 6. const squareArrayDeclarative = arr => arr.map(x => x ** 2); Programação declarativa
  • 7. squareList : List Int -> List Int squareList xs = List.map (x -> x^2) xs (Elm) Programação declarativa
  • 8. Linguagem de programação para a criação de interfaces web declarativas. Foco na usabilidade do desenvolvedor, performance e resiliência. Elm
  • 9. Fortemente tipada e funcional pura. Na prática, aplicações escritas em Elm não produzem exceções de runtime. Elm
  • 10. Uma função é uma expressão. Mapeia elementos de um domínio em elementos de um contradomínio. Funções
  • 12. Função f : ℤ → ℕ = x ↦ |x|
  • 13. (Elm) Função f : Int -> Int f x = abs x
  • 14. Funções Seja um conjunto tal que: ε ∈ , ∀ x ∈ ℤ, ∀ α ∈ , x • α ∈ . Então squareL : → = α ↦ ε se α = ε x² • squareL(β) se α = x • β sumL : → ℤ = α ↦ 0 se α = ε x + sumL(β) se α = x • β
  • 15. (Elm) Funções squareList : List Int -> List Int squareList l = case l of [] -> [] x :: xs -> x^2 :: squareList xs sumList : List Int -> Int sumList l = case l of [] -> 0 x :: xs -> x + sumList xs
  • 16. Toda função é pura. Funções impuras são chamadas de procedimentos, rotinasou subrotinas. Funções puras
  • 17. Uma função pura é uma função que sempre produz o mesmo resultado quando são passados os mesmos argumentos, e que não produz efeitos colaterais observáveis. Funções puras
  • 18. Efeitos colaterais “Uma função ou expressão produz efeitos colaterais se ela modifica algum estado fora de seu escopo ou realiza alguma interação observável com as funções que a chamaram ou com o mundo externo.” – Wikipedia
  • 19. Função impura function append(x) { this.array.push(x); }
  • 21. Função pura function appendToArray(array, x) { return [ ...array, x ]; }
  • 22. (Elm) Função pura appendToList : List Int -> Int -> List Int appendToList list x = list ++ [x]
  • 23. Função impura function sumOfSquares(array) { let result = 0; for (let x in array) { result += x*x; } console.log(result); };
  • 24. Função pura const square = x => x*x; const add = (a, b) => a + b; function sumOfSquares(array) { return array .map(square) .reduce(add, 0); } console.log(sumOfSquares([2, 3, 5]));
  • 25. (Elm) Função pura sumOfSquares : List Int -> Int sumOfSquares list = let square x = x*x in List.foldl (+) 0 (List.map square list) -- cadê o console.log??
  • 26. Como programação funcional pura pode ser útil se não tem efeitos colaterais?
  • 27. Abestado, tem efeitos colaterais sim, mas são. representados de forma diferente.
  • 28. Linguagens funcionais implementam funções de primeira classe. Funções em linguagens funcionais são valores. Funções podem ser passadas como argumentos para outras funções. Funções podem ser valores de retorno de outras funções. Funções de primeira classe
  • 29. São funções que recebem outras funções como argumento. map reduce / fold filter Funções de alta ordem
  • 30. Funções de alta ordem sumOfSquares : List Int -> List Int sumOfSquares list = let square x = x*x in List.foldl (+) 0 (List.map square list)
  • 31. Função de alta ordem map : (a -> b) -> List a -> List b map f l = case l of [] -> [] x :: xs -> f x :: map f xs
  • 32. Lambda sumOfSquares : List Int -> List Int sumOfSquares list = List.foldl (+) 0 (List.map (x -> x*x) list)
  • 33. Função de primeira classe mkAdjectifier : String -> String -> String mkAdjectifier adjective noun = adjective ++ " " ++ noun coolifier : String -> String coolifier = mkAdjectifier "cool" -- coolifier "meetup" == "cool meetup"
  • 34. Transforma a avaliação de uma função de vários argumentos na avaliação de uma sequênciade funções de um argumento. Facilita o uso de funções de vários argumentos e a aplicação parcial de funções. Currying f : ℤ × ℤ → ℤ ~ f : ℤ → ℤ → ℤ
  • 35. Currying addT : (Int, Int) -> Int addT (a, b) = a + b add : Int -> Int -> Int add a b = a + b -- add2 :: Int -> Int add2 = add 2 -- five :: Int five = add2 3 -- == 5
  • 36. Mecanismo que combina funções simples para construir outras mais complexas. Encoraja a fatoração de funções para melhor manutenção e reuso de código. Composição de funções ( f ∘ g)(x) = f (g(x))
  • 37. Operador de composição de funções compose : (a -> b) -> (b -> c) -> (a -> c) compose f g = a -> f (g a)
  • 38. (point free) Composição de funções squareList : List Int -> List Int squareList = List.map (x -> x*x) sumList : List Int -> List Int sumList = List.foldl (+) 0 sumOfSquares : List Int -> List Int sumOfSquares = sumList << squareList
  • 39. Composição de funções squareList : List Int -> List Int squareList xs = List.map (x -> x*x) xs sumList : List Int -> List Int sumList xs = List.foldl (+) 0 xs sumOfSquares : List Int -> List Int sumOfSquares xs = (sumList << squareList) xs
  • 40. Conjuntos de valores(não são classes). Podem ser compostos. Seus valores construídos e desestruturados(com pattern matching). Garantem segurança. Tipos
  • 41. Construídos como operações algébricas sobre conjuntos. Permitem a definição de tipos mais complexos. Permitem a composição de tipos. Tipos algébricos
  • 42. Tipo soma e função com pattern matching type PrimaryColor = Red | Blue | Yellow nextColor : PrimaryColor -> PrimaryColor nextColor color = case color of Red -> Blue Blue -> Yellow Yellow -> Red
  • 43. Tipo produto e função com desestruturação type Point = Point Int Int -- mkPoint : Int -> Int -> Point addPoints : Point -> Point -> Point addPoints (Point x1 y1) (Point x2 y2) = Point (x1 + x2) (y1 + y2)
  • 44. (Elm) Records type alias User = { name : String, email : String } maria : User maria = { name = "Maria", email = "maria@email.com" } type User = User { name : String, email : String } type User = User String String~
  • 45. Tipos recursivos type List = Nil | Cons Int List type NonEmptyList = Single Int | Cons Int List type Tree = Tree String (List Tree) type BTree = Empty | NodeLeft String BTree | NodeRight String BTree
  • 46. Pattern matching em tipos recursivos mapList : (Int -> Int) -> List -> List mapList f l = case l of Nil -> Nil Cons x xs -> Cons (f x) (mapList f xs) mapList : (Int -> Int) -> List -> List mapList f Nil = Nil mapList f Cons x xs = Cons (f x) (mapList f xs) mapTree : (String -> String) -> Tree -> Tree mapTree f t = case t of Empty -> Empty NodeLeft x xs -> NodeLeft (f x) (mapTree f xs) NodeRight x xs -> NodeRight (f x) (mapTree f xs)
  • 47. Tipos paramétricos type Point a = Point a a type Tuple a b = Tuple a b p : Point Int p = Point 1 3 p2 : Point Float p2 = Point 1.2 3.4 user : Tuple Int String user = Tuple 1 "Maria"
  • 48. Tipos recursivos paramétricos type List a = Nil | Cons a List -- mkCons : a -> List -> List type NonEmptyList a = Single a | Cons a List type Tree a = Tree a (List Tree) type BTree a = Empty | NodeLeft a BTree | NodeRight a BTree
  • 49. Tipos paramétricos e funções type Maybe a = Nothing | Just a type Either a b = Left a | Right b head : List a -> Maybe a head = … parseMarkdown : String -> Either Error Markdown parseMarkdown = …
  • 50. Tipo soma e função parcial type SecondaryColor = Orange | Green | Purple addPrimaryColors : PrimaryColor -> PrimaryColor -> SecondaryColor addPrimaryColors c1 c2 = case (c1, c2) of (Red, Blue) -> Purple (Red, Yellow) -> Orange (Blue, Red) -> Purple (Blue, Yellow) -> Green (Yellow, Red) -> Orange (Yellow, Blue) -> Green
  • 51. Tipo soma e função type SecondaryColor = Orange | Green | Purple addPrimaryColors : PrimaryColor -> PrimaryColor -> Either PrimaryColor SecondaryColor addPrimaryColors c1 c2 = case (c1, c2) of (Red, Blue) -> Right Purple (Red, Yellow) -> Right Orange (Blue, Red) -> Right Purple (Blue, Yellow) -> Right Green (Yellow, Red) -> Right Orange (Yellow, Blue) -> Right Green _ -> Left c1
  • 52. Tipo inseguro type Permission = BlockUser | BanUser | RemovePosts type UserType = Guest | User | Admin type alias User = { name : Maybe String , email : Maybe Email , permissions : List Permission , userType : UserType }
  • 53. Tipo seguro type Permission = BlockUser | BanUser | RemovePosts type User = Guest | User { name : String , email : Email } | Admin { name : String , email : Email , permissions : List Permission }
  • 54. Tipo seguro++ type Permission = BlockUser | BanUser | RemovePosts type User p = Guest | User { name : String , email : Email } | Admin { name : String , email : Email , permissions : p }
  • 55. Ter de tratar todos os valores possíveis de um tipo ajuda a entender o domínio. Quando uma função é parcial pode-se restringir sua entrada ou sua saída. “Ah,vocênãosabiaqueessalistanãopodiaservazia?Culpasua! ArrayOutOfBoundsException!!” — Java Enterprise Edition Totalidade
  • 56. Funções totais head : List a -> Maybe a head = … head : NonEmptyList a -> a head = …~
  • 57. Resolve problemas causados por estados mutáveis: Condições de corrida, complexidade, imprevisibilidade… Linguagens funcionais puras representam mutabilidade como efeito colateral. Elm nem mesmo permitem mutabilidade. Imutabilidade
  • 58. Coleções como listas ou árvores são úteis para representar iterações sobre dados. Mais do que isso elas permitem transformar múltiplos valores em outro tipo. Coleções
  • 59. Funções úteis do tipo List head : List a -> Maybe a tail : List a -> Maybe (List a) range : Int -> Int -> List Int (::) : a -> List a -> List a append : List a -> List a -> List a sort : List comparable -> List comparable map : (a -> b) -> List a -> List b map2 : (a -> b -> c) -> List a -> List b -> List c foldr : (a -> b -> b) -> b -> List a -> b foldl : (a -> b -> b) -> b -> List a -> b filter : (a -> Bool) -> List a -> List a
  • 60. Estruturas algébricas que implementam a operação map e seguem as leis: map : (a -> b) -> f a -> f b map id = id map (f << g) = map f << map g Functores
  • 61. São contêineres que representam resultados de computações sobre outros tipos. As computações representadas pelo functor são definidas pela forma do functor e pelo comportamento da operação map. Functores
  • 62. Maybe type Maybe a = Nothing | Just a map : (a -> b) -> Maybe a -> Maybe b map f maybe = case maybe of Nothing -> Nothing Just a -> Just (f a)
  • 63. Either type Either a = Left a | Right a map : (a -> b) -> Either a -> Either b map f either = case either of Left a -> Left a Right a -> Right (f a)
  • 64. Tuple map : (a -> b) -> (t, a) -> (t, b) map f (tag, a) = (tag, f a)
  • 65. List map : (a -> b) -> List a -> List b map f list = case list of [] -> [] x :: xs -> f x :: map f list
  • 66. Maior previsibilidade. Melhor testabilidade. Facilidade de raciocínio. Simplicidade. Corretude. Por quê programação funcional?*
  • 68.
  • 69. Nesta primeira parte vamos apenas inserir notas no modelo e mostrá-las como elementos Html na tela. Vamos também inserir novas notas no modelo ao clicar em um botão. Parte 1
  • 70. Nesta segunda parte vamos tratar a edição de notas. Quando o usuário clicar em uma nota deveremos poder editá-la. Ao pressionar Enter, as modificações devem ser salvas no modelo. Será necessário modificar o modelo para que seja possível identificar qual nota está sendo editada no momento. Parte 2
  • 71. Nesta terceira parte veremos como Elm trata efeitos colaterais através de ports. Faremos com que nossa aplicação salve o modelo quando ele for alterado no local storage do browser. Parte 3
  • 72. Uma port em Elm é um valor ou função definido com a keyword port que deve produzir um valor do tipo Cmd, um comando. Precisaremos definir uma port que envia o modelo a ser salvo para o mundo externo. Por conveniência já foi feito no arquivo index.html o tratamento dos comandos recebidos pela port que iremos definir. Parte 3
  • 73. Nesta quarta parte veremos os benefícios dos tipos paramétricos. Parametrizaremos o tipo Noteem relação a um tipo i que representa o campo de identificação de uma nota. Parte 4
  • 74. Nesta quinta e última parte parametrizaremos o tipo Note em relação ao conteúdo. Para que possamos usar tipos que não sejam String para representar o tipo de uma nota, mas mantendo o tipo String como conteúdo das notas serializadas, devemos parametrizar o tipo Note em relação ao conteúdo e tornar as funções que operam sobre ele polimórficas sobre o conteúdo. Parte 5
  • 75. Recursos An Introduction to Elm http://guide.elm-lang.org/ Elm Examples http://elm-lang.org/examples Elm Search https://klaftertief.github.io/elm-search/ Elm Packages http://package.elm-lang.org/ https://github.com/arthur-xavier/workshop-intro-fp-elm