Title: Paradigma Funcional
1Paradigma Funcional
2Paradigma Funcional modelo computacional
Mapeamento (função) de valores de entrada em
valores de saída
Entrada
Saída
Programa
Ausência de estado e comandos (atribuição
controle)
Relação clara e explícita entre entrada e saída
3Características gerais
- Um programa consiste essencialmente de funções
- Composição e decomposição suportados
- Modularidade
- Manipulado como uma expressão matemática
- Transformação de programas facilitada por
transparência referencial - Estilo declarativo
- Conceitos sofisticados como polimorfismo, funções
de alta ordem e avaliação sob demanda
4A Linguagem Funcional 1
5Linguagem Funcional 1 - LF1
- Estende LE2 com funções parametrizadas e
recursivas (mas de primeira ordem) - O corpo de uma função é uma expressão e a
aplicação da função a um argumento retorna um
valor (aplicação também é uma expressão) - O contexto inclui dois componentes
- mapeamento de identificadores em valores
- mapeamento de identificadores (nomes de função)
em definições de função - Um programa é uma expressão
6Apresentação da Linguagem Funcional 1 - LF1
- http//www.cin.ufpe.br/in1007
7Explorando conceitos na LF1
8LF1 é uma linguagem de programação!
- Sintaxe
- Valores, expressões e funções
- Semântica (operacional) e implementação
- Reescrita de termos (avaliação de expressões)
- Universalidade
- Funções recursivas
9Estratégias de Avaliação
- Considere as seguintes funções
- let fun prod x y if x 0 then 0
- else y
prod(x-1,y) in let fun square x prod(x,x) - Como ocorre a avaliação de
- square(34) ?
10Estratégias de Avaliação
- square (3 4) gt square (7)
() - innermost gt prod(7, 7)
(square) - gt 49 (prod)
- square (3 4) gt prod((3 4),(3 4))
(square) - outermost gt prod(7,(3 4)) ()
- gt prod(7,7) ()
- gt 49 (prod)
- Qual estratégia adotar?
- Produzem o mesmo resultado? Considere a
expressão - let fun f x f(x) in let fun first y z y in
first(2,f(3)) - Qual o resultado produzido neste caso?
11Innermost versus Outermost Reduction
- Propriedade de Church-Rosser
- Se um termo possuir uma forma normal, esta será
sempre obtida através de uma outermost reduction. - Se a redução usando a estratégia eager (ou
qualquer outra combinação de avaliação entre
eager e outermost) produzir um resultado, este
será o mesmo produzido usando uma redução
outermost.
12Innermost versus Outermost Reduction
- Outermost Reduction --- Também denominada
- Normal Order Reduction
- Lazy Evaluation (Avaliação Preguiçosa)
- Especialização de Outermost
- O argumento é avaliado uma única vez
- Referências subseqüentes ao argumento são
substituídas pelo valor (evitando reavaliação)
13Innermost versus Outermost Reduction
- Innermost Reduction --- Também denominada
- Applicative Order Reduction
- Eager Evaluation
- Em geral, avaliação Innermost é mais eficiente,
mas a Outermost evita avaliar argumentos não
utilizados - O mecanismo de avaliação de LF1 é innermost!
14Exemplos de Projetos Realizados
15Estender/modificar LF1
- Escopo estático sem renomear variáveis (usando
Display em vez de Stack nos contextos) - Introdução de tipos explícitos e verificação
- Tipos recursivos (datatypes)
- Listas e verificação de tipos de listas (LF3)
- Casamento de padrão com equações condicionais
(LF3) - Overloading
- Avaliação preguiçosa (Lazy)
- Aplicação parcial (LF2)
16Escopo Estático
- O resultado da expressão
- Let var z 2, fun f(x) x 1
- in Let fun g(y) f(y) z
- in Let var z 0, fun f(x) x
- in g(1)
- depende do bind de f e z usados na definição
de g. Se o bind for com f e z (estático ou
léxico) o resultado é 4, mas se for com f e z
(dinâmico) o resultado é 1 - Os interpretadores atuais das linguagens
implementam escopo dinâmico - Referência Acess links e displays em livros de
compiladores
17Introdução de Tipos Explícitos
- As BNFs das linguagens não incluem declaração de
variáveis com tipos - Os tipos são inferidos a partir do uso das
variáveis - O objetivo deste projeto é adicionar declaração
explícita de tipos e modificar o checaTipo() para
LF1
18Introdução de Tipos Explícitos
- A sintaxe para introdução de tipos pode ser a
usual - Let var z Int 2, fun f Int -gt Int . f x x
1 - ...
- Inicialmente o escopo não inclui polimorfismo.
Dependendo da complexidade poderá ser adicionado
19Tipos Recursivos
- O objetivo é implementar os tipos livres, ou
datatypes, comuns em programação funcional. - O caso mais simples permite a definição de tipos
enumerados - Exemplo Type Cor amarelo azul preto ...
- Uma facilidade um pouco mais elaborada é a união
(disjunção de tipos) - Exemplo Type IntBool inteiro (Int)
booleano (Bool)
20Tipos Recursivos
- Em geral, os tipos podem ser recursivos
- Exemplo Type Lista vazia cons (Int x
Lista) - Há ainda a possibilidade de parametrização, mas
não faz parte do escopo do projeto
21Listas e Typecheck de Listas
- Implementar a estrutura de dados listas em LF1.
- A BNF deve ser estendida com ValorLista. Com
relação à sintaxe, usar para representar a
lista vazia e e1,e2,...,en para uma lista de n
elementos. - Incluir as seguintes operações sobre listas
- cons(e,L) recebe um elemento (e), uma lista (L) e
retorna uma lista com o elemento e acrescido no
início de L
22Listas e Typecheck de Listas
- head(L) recebe uma lista L e retorna o elemento
que está na cabeça (elemento mais à esquerda) de
L - Tail(L) recebe uma lista L e retorna uma lista
com todos os elementos de L exceto o head - Concat(L1,L2) concatena (combina) os elementos de
L1 e de L2 preservando a ordem (os de L1
aparecem primeiro) - Referência Seções 2.4.1 e 13.1.2 do livro texto
23Casamento de Padrão
- Implementar casamento de padrão em LF1.
- A BNF deve ser estendida de forma a permitir que
declarações de funções possam ser escritas da
seguinte forma - onde padrao_i é uma constante ou identificador,
exp_i - é uma expressão e cond_i é uma expressão
booleana
fun f padrao_1 exp_1, if cond_1 ...
f padrao_n exp_n, if cond_n
24Casamento de Padrão
- Sugestão converter as definições expressas em
termos de padrões em expressões IfThenElse - Referência Seção 13.1.1 do livro texto
25Avaliação Preguiçosa
- Já explicado na transparência sobre reduções
innermost e outermost. - O único operador lazy no interpretador atual de
LF1 é o if_then_else - O objetivo do projeto é tornar toda avaliação
lazy - Referência Seção 13.1.4 do livro texto
26Aplicação Parcial (LF2)
- Aplicação parcial é permitir a aplicação de uma
função a alguns (não necessariamente a todos os)
argumentos. - Isto é permitido naturalmente em LF2 para funções
definidas de forma currificada (curried) como
será mostrado em sala. - O objetivo do projeto eestender esta facilidade
para funções não currificadas (uncurried)
27Avaliação Parcial (LF2)
- A idéia é permitir que uma função como
- add(x,y) x y
- possa ser aplicada a apenas um argumento. Ex.
add 2 - ReferênciaFunções Curry e Uncurry em livros de
programação funcional
28Outros projetos realizados
- Provador de teoremas para LF1
- Concorrência (linguagem imperativa e OO) via
compartilhamento de variáveis - Concorrência via passagem de mensagens
- Implementação de parte das linguagens usando
outros padrões/plataforma (prog. funcional, prog.
lógica, .net, ...)
29 Outros projetos realizados
- Programação orientada a aspectos (extensão de
projetos existentes) - Características de Java 1.5
30Mais projetos sugeridos
31 Projetos
- Programação lógica
- Mobilidade para LI2 (Extensão de trabalho
anterior já realizado para concorrência) - Linguagem para modelagem de agentes
(possivelmente com construtores de programação em
lógica para modelar aprendizado) continuação de
trabalho anterior - Implementação de Técnicas de I/O para LF1/LF2
32Projetos
- Integração de paradigmas (exemplo, funcional e
imperativo) com base em linguagens
multi-paradigmas existentes - Comparação da abordagem do curso com outras
propostas existentes
33Leitura
- Programming Language Concepts and Paradigms
- Capítulo 5 (5.1.1)
- Capítulo 13 (13.1.1, 13.1.2 e 13.1.4)
- Introduction to Functional Programming
- Seção 6.2