Linguagens de Programação Programação Funcional (Haskell) Andrei Rimsa Álvares
Sumário Introdução Programação funcional Linguagens funcionais Haskell Casamento de padrões Funções de ordem superior Avaliação preguiçosa (lazy evalua)on) Resumo
INTRODUÇÃO Linguagens de Programação
Introdução Programação funcional é baseada no conceito de funções matemáfcas Uma função matemáfca é um mapeamento de membros de um conjunto (domínio) em outro conjunto (imagem) A ordem de avaliação é controlada por recursões e expressões condicionais, ao invés de sequenciamento e iterações Não possuem efeito colateral
Uma Simples Função Exemplo: função cubo cubo(x) = x * x * x Domínio: conjunto dos números reais = : a função é definida como x: pode representar qualquer elemento do domínio, mas é fixo para representar apenas um elemento na avaliação São diferentes de variáveis no paradigma imperafvo
Formas Funcionais Forma funcional ou função de ordem superior Aceita funções como parâmetros Aceita funções como retorno Composição de funções (h = f g) Exemplo: f(x) = x + 2 g(x) = 3 * x h(x) = f(g(x)) = (3 * x) + 2
PROGRAMAÇÃO FUNCIONAL Linguagens de Programação
Programação Funcional Um programa no paradigma funcional é uma função, o qual pode ser uma composição de outras funções P f (x 1, x 2,..., x n ) f 1 f 2... f n (x 1, x 2,..., x n ) O objefvo da programação é imitar uma função matemáfca Programação funcional é baseada no modelo computacional Lambda Calculus (Church, 1941) Exemplo: ((λ x. (λ y. x)) (λ z. z)) (λ a. a)
Programação Funcional vs. ImperaFva Exemplo de avaliação de (x + y) / (a b) Alan Turing Programação imperamva Avalia (x + y) e armazena resultado na memória Avalia (a b) e armazena resultado na memória Carrega ambos valores da memória e faz a divisão Alonzo Church Programação funcional Não usam variáveis como endereços de memória Usam recursão ao invés de iterações Não possuem efeitos colaterais dados os mesmos parâmetros sempre dará o mesmo resultado (transparência referencial)
Exemplo Algoritmo de Euclides para cálculo do máximo divisor comum (MDC)!# mdc(m, n) = " $# n mdc(n mod m, m) Escrito como um programa em Haskell, se m = 0, se m > 0 mdc :: Int -> Int -> Int -- declaração da função mdc mdc m n -- definição da função m == 0 = n m > 0 = mdc (n `mod` m) m : hbp://haskell.org
LINGUAGENS FUNCIONAIS Linguagens de Programação
Linguagens Funcionais Algumas linguagens funcionais famosas LISP (John McCarthy, 1960) Escopo dinâmico e coleta de lixo Diversas extensões: CLOS, Scheme, etc Principal uso: inteligência arfficial APL (Kenneth Iverson, 1962) Não é puramente funcional (possui atribuição) Principal Fpo de dados: matrizes Principal uso: avaliação de expressões
Linguagens Funcionais Algumas linguagens funcionais famosas ML (Robin Milner, 1979) Polimorfismo e sistema de Fpos forte Modularização e suporte a TAD Não é puramente funcional Miranda (David Turner, 1986) Similar a ML, porém com avaliação lazy Haskell (S. Peyton Jones & P. Wadler, 1992) Puramente funcional Avaliação lazy
Principais Aplicações LISP Diversas aplicações em IA Emacs (editor de textos) Macsyma (cálculos simbólicos) Haskell Compilador GHC ML Servidor Web, provadores de teorema
HASKELL Linguagens de Programação
Haskell Algumas propriedades de Haskell Sintaxe similar a ML EstaFcamente e fortemente Fpada Puramente funcional Não possui variáveis Nem outras caracterísfcas imperafvas Possui avaliação preguiçosa (lazy evaluafon) Permite definir listas infinitas
Exemplo Exemplo de função fatorial fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Mesmo exemplo escrito com uma sintaxe alternafva fact :: Integer -> Integer fact n n == 0 = 1 n > 0 = n * fact (n-1) Int: precisão fixa (32 ou 64 bits) Integer: precisão arbitrária
Conceitos Fundamentais Conceitos fundamentais de Haskell Casamento de Padrões Avaliação Preguiçosa Funções de ordem superior
Casamento de Padrões Função definida por várias equações, cada uma com um padrão no seu lado esquerdo fib :: Int -> Int fib 0 = 0 -- equação aplicada ao caso 0 fib 1 = 1 -- equação aplicada ao caso 1 fib n = fib (n-1) + fib (n-2) -- equação aplicada nos outros casos Vantagens Concisão e clareza Mais próxima de uma definição matemáfca
Casamento de Padrões Forma tradicional para definição de funções via uma única equação (possivelmente condicional) soma :: Int -> Int soma n n <= 0 = 0 -- se n menor ou igual a zero n > 0 = n + soma (n-1) -- se n maior que zero
Cláusula otherwise Casamento de padrão com opção padrão (otherwise) fun :: Int -> Int fun n n < 10 = 0 n > 10 = 2 otherwise = 1
Cláusula where Cálculo das raízes de uma equação de segundo grau Implementado em Haskell x = b ± b2 4ac 2a raizeq :: Float -> Float -> Float -> [Float] raizeq a b c = [ menos_b_sobre_2a - delta_sqrt, menos_b_sobre_2a + delta_sqrt ] where menos_b_sobre_2a = -b / (2.0 * a) delta_sqrt = (sqrt (b*b - 4.0*a*c)) / (2.0 * a)
Listas Declaração de listas entre colchetes Operadores Concatenação (++) Infixo de lista (:) colors :: [String] colors = [ "blue", "green", "red" ] [1, 3, 5] ++ [2, 4, 6] [1, 3, 5, 2, 4, 6] 5:[2, 7, 9] [5, 2, 7, 9] Séries aritméfcas (..) [1, 3..11] [1, 3, 5, 7, 9, 11] Tamanho de lista (length) length [2, 4, 6] 3
Exemplos Operações com lista Soma de todos os elementos de uma lista de inteiros somatorio :: [Int] -> Int somatorio [] = 0 somatorio (a:x) = a + somatorio x Produto de todos os elementos de uma lista de inteiros produtorio :: [Int] -> Int produtorio [] = 1 produtorio (a:x) = a * produtorio x Fatorial de um número inteiro fact :: Int -> Int fact n = produtorio [1..n]
Compreensão de Listas Descrição de listas que representam conjuntos Exemplos Cubo dos números de 1 a 50 [corpo qualificadores ] cubo :: [Int] cubo = [ n * n * n n <- [1..50] ] Fatores de um número inteiro fatores :: Int -> [Int] fatores 0 = [] fatores n = [ i i <- [1..n `div` 2], n `mod` i == 0 ] ++ [n]
Simplicidade Exemplo do algoritmo Quicksort em Haskell qsort :: [Int] -> [Int] qsort [] = [] qsort (a:x) = qsort [ b b <- x, b <= a ] ++ [a] ++ qsort [ b b <- x, b > a ]
Funções de Ordem Superior Formas funcionais Funções de primeira ordem Parâmetros e resultado não são funções Funções de ordem superior Possui parâmetros e/ou retornos que são funções Linguagens funcionais Funções são valores de primeira classe Conceito comum na matemáfca (derivada, integral,...)
Exemplo Funções de primeira ordem impar :: Int -> Bool impar x (x `mod` 2) == 1 = True otherwise = False quad :: Int -> Int quad x = x ^ 2 Função de ordem superior nmap :: (t -> u) -> [t] -> [u] nmap f [] = [] nmap f (a:x) = f a : nmap f x > nmap quad [1,2,3,4] [1,4,9,16] > nmap impar [1,2,3,4] [True,False,True,False] >
Avaliação Preguiçosa Avaliação preguiçosa ou avaliação tardia: argumentos somente são avaliados quando são uflizados Permite que uma função retorne resultados parcialmente avaliados Conceito úfl para construir listas infinitas positivos :: [Integer] positivos = [0..] pares :: [Integer] pares = [2, 4..] quadrados :: [Integer] quadrados = [n * n n <- [0..]]
Exemplo Verificar se um elemento existe na lista quadrado membro :: [Integer] -> Integer -> Bool membro [] b = False membro (a:x) b = (a == b) membro x b > membro quadrados 16 True > Qual o problema desse programa?
Exemplo Reescrevendo o exemplo anterior para consertar o problema membro2 :: [Integer] -> Integer -> Bool membro2 [] n = False membro2 (m:x) n m < n = membro2 x n m == n = True otherwise = False > membro quadrados 16 True > membro quadrados 15 False >
Avaliação Preguiçosa Vantagens Maior poder de expressividade Desvantagens SemânFca complicada Execução mais lenta
RESUMO Linguagens de Programação
Comparação Funcional vs. ImperaFvo Linguagens imperafvas são mais eficientes Modelo computacional de von Neumann: mesmo modelo das atuais arquiteturas de computadores Linguagens funcionais possuem construções com um nível de abstração maior ÚFl para protofpação Linguagens funcionais viabilizam provas formais de propriedades de programas
ISSO É TUDO PESSOAL! Linguagens de Programação