Universidade Estadual de Santa Cruz Conceitos de Linguagens de Programação Aluno: Pedro Arthur M. Nascimento Ilhéus-Ba, 05 de Novembro de 2012 O projeto de linguagens funcionais é baseado em funções matemáticas Programação com alto nível de abstração Forte fundamentação teórica, o que permite mais facilmente provas de propriedades sobre os programas Linguagens funcionais, especialmente as puramente funcionais, tem sido mais usadas academicamente que no desenvolvimento comercial de software Importantes influências na programação funcional foram o cálculo lambda, as linguagens de programação APL e Lisp, e mais recentemente ML, Haskell e F# As expressões são a representação exata da informação; As expressões podem ser associadas a nomes; Todos os nomes que de uma expressão tem um valor único e imutável; Os valores dependem dos valores das subexpressões que as constituem; Não permite efeito colateral em funções, a linguagem oferece transparência referencial. Década de 1930: Alonzo Church desenvolve o cálculo lambda, uma teoria de funções simples, mas poderosa Década de 1950: John McCarthy desenvolve Lisp, a primeira linguagem funcional,com algumas influências do cálculo lambda, mas mantendo as atribuições de variáveis. Década de 1960: Peter Landin desenvolve ISWIM, a primeira linguagem funcional pura, baseada fortemente no cálculo lambda, sem atribuições. Década de 1970: John Backus desenvolve FP, uma linguagem funcional que enfatiza funções de ordem superior e raciocínio sobre programas. Robin Milner e outros desenvolvem ML, a primeira linguagem funcional moderna, que introduziu a inferência de tipos e tipos polimórficos. 1987: Um comitê internacional de pesquisadores inicia o desenvolvimento de Haskell, uma linguagem funcional lazy padrão. 2003: O comitê publica o relatório Haskell 98, a definição de uma versão estável da linguagem Haskell. 2009: O comitê publica o relatório Haskell 2010, uma revisão da definição da linguagem Haskell. O cálculo lambda pode ser considerado a primeira linguagem de programação funcional, embora nunca tenha sido projetada para ser realmente executada em um computador Um programa funcional e composto por uma única expressão Essa expressão deve descrever detalhadamente uma funcao e um elemento do dominio daquela funcão A reducão de um programa consiste em substituir uma parte da expressao original, obedecendo a certas regras de reescrita; Expressões lambda são aplicadas aos parâmetros colocando os parâmetros após a expressão(λ(x) x * x * x)(2),que é avaliado como sendo 8. Outro exemplo: seja F a expressão X + 5, sendo X uma variável; ▪ Essa expressão é indeterminada, no sentido que a variável X está livre para assumir qualquer valor arbitrário; Substituição: [ X ← 4 ] resulta na expressão 4 + 5; Abstração: A abstração λX.F, ou seja, λX.(X + 5), denota a função matemática que, para cada valor de X, associa o valor X + 5; Aplicação: Nessa expressão, a variável X não está mais livre para assumir um valor arbitrário; Um sistema de reduções deve permitir que se produza a sequencia de expressões λX.(X + 5) 4 => 4 + 5 => 9; As propriedades de confluência e terminação garantem que qualquer sequencia de reduções deve levar ao mesmo resultado final; Diferentes estratégias para organizar essas sequencias, entretanto, podem levar a sequencias menores para λtermos específicos; Duas estratégias fundamentais: De dentro para fora (a priori); Do inglês Eager (gananciosa); De fora para dentro (sob demanda); Do inglês Lazy (sossegada); De fora pra dentro(a priori) De fora para dentro (sob demanda) Características: De dentro para fora (a priori): Implementação mais simples; Pode ocorrer de tentativas infinitas de reduções; Interpretadores e compiladores mais compactos; De fora para dentro (sob demanda): Resultados intermediários; Função, durante a redução, computacionalmente difícil ou demorada; Função: Regra para mapear elementos de um conjunto (conjunto domínio) em outro conjunto (conjunto imagem / contradomínio) – cubo(x) ≡ x * x * x, em que x é um número real • O símbolo “≡”, indica “definido como”. • O parâmetro x pode representar qualquer elemento do conjunto domínio. Forma funcional ou função de ordem superior: toma funções como parâmetros, produz uma função como seu resultado, ou ambos. Formas Funcionais: – Composição de funções – Construção – Apply-To-All Composição de funções, onde uma função mais complexa é composta de funções mais simples. • h ≡ f °g (indica que h é função composta de f e g) • f(x) ≡ x + 2 • g(x) ≡ 3 * x • h(x) ≡ f ( g (x))), ou h (x) ≡ (3 * x) + 2 Construção, forma funcional que toma lista de funções como parâmetros e aplica esta a um determinado argumento. • g(x) ≡ x * x • h(x) ≡ 2 * x • i(x) ≡ x / 2 • [g,h,i](4) produz (16,8,2) É uma forma funcional que toma uma única função como parâmetro e se aplica a uma lista de argumentos, gerando uma lista como saída Forma: α Para h (x) ≡ x * x α( h, (2, 3, 4)) produz (4, 9, 16) Uma caracteristica muito importante da programação funcional é a construção de definições. Uma lista de definições chama-se script. Exemplo de script: square x = x * x somaEmult x y = 3 * (x + y) No script acima duas funções, square e somaEmult foram definidas. A função square toma um valor x e o multiplica por ele mesmo. A função somaEmult devolve a soma de seus argumentos multiplicada por 3. Nota-se que as funções foram definidas através de equações e que uma definição pode ser considerada como uma definição lógica de como a função se comporta. Em outras palavras, uma definição funcional pode ser vista como uma especificação do problema. Tendo criado scripts pode-se usá-los em uma avaliação no computador. Exemplos: > square (2 + 3) 25 > somaEmult 1 2 9 > square (somaEmult 2 4) 324 O objetivo de uma definição é ligar um nome a um valor. No script anterior, por exemplo, o nome square é associado a uma função que eleva um valor ao quadrado. Família de linguagens de programação concebida por John McCarthy em 1958. A mais antiga e mais amplamente usada. LISP – List Processing (a lista é a estrutura de dados fundamental desta linguagem). Com exceção da primeira versão, todos os dialetos incluem algumas características de linguagens imperativas:Variáveis,instruções de atribuição,iteração. LISP é versátil e poderosa. LISP foi desenvolvida para computação simbólica e aplicações de processamento de listas. Editor de texto escrito em LISP: EMACS Cálculos simbólicos: MACSYMA Ensino introdutório de programação. LISP na Inteligência Artificial: ● Sistemas Especialistas. ● Representação do conhecimento. ● Aprendizado de máquina. ● Processamento de linguagem natural. ● Sistemas de treinamento inteligente. ● Modelagem da fala e visão. Funções como: QUOTE (evita a avaliação de um parâmetro) CAR (retorna o primeiro elemento de uma lista) CRD (Retorna o restante da lista depois que o seu CAR é removido). Scheme: Dialeto do LISP, surgiu no MIT na década de 70. – Interpretador scheme é um laço infinito de leitura-avaliação-escrita. – Outras funções: • CONS e LIST (construtores de lista) • EQ?, NULL? e LIST?, avaliam e retornam valores booleanos (#T e #F). APL: Muitos aspectos funcionais FP: semelhante a APL Common LISP: junção de recursos de LISP e Scheme Permite o uso da função PROG, para sequenciar instruções, como em uma linguagem imperativa Possui rótulos e funções GO e RETURN para controle de iteração. Linguagem Imperativas Execução eficiente Semântica Complexa Sintaxe complexa Concorrência é formulada pelo programador Na programação imperativa o programador deve fazer uma divisão estática do programa em suas partes concorrentes, e escrever estas partes como novas tarefas. Entender programas concorrentes em linguagens imperativas é muito mais difícil. Linguagens Funcionais Semântica simples Sintaxe simples Execução ineficiente Programas podem ser feitos concorrentes de maneira automática A recursão é a forma das linguagens funcionais para representar iterações. A recursão não é característica de algumas linguagens imperativas. Programas funcionais podem ser convertidos em grafos e então executados por um processo de redução de grafos • Na programação funcional a regra é definir funções em função deoutras funções. Na definição procedural, as regras são definidas por passos a serem executados. Um alto nível de abstração, especialmente quando as funções são utilizadas, suprimindo muitos detalhes da programação e minimizando a probabilidade da ocorrência de muitas classes de erros. A não dependência das operações de atribuição permite aos programas avaliações nas mais diferentes ordens. Esta característica de avaliação independente da ordem torna as linguagens funcionais as mais indicadas para a programação de computadores massissamente paralelos. A ausência de operações de atribuição torna os programas funcionais muito mais simples para provas e análises matemáticas do que os programas procedurais. Menor eficiência. Problemas que envolvam muitas variáveis (ex. contas de banco) ou muitas atividades seqüenciais são muitas vezes mais fáceis de se trabalhar com programas procedurais ou programas orientados a objeto. –[SEB00] SEBESTA, R. Conceitos de Linguagens de Programação . 4. ed. Bookman, 2000. Flavio Miguel Varejao; Linguagens de Programação - Conceitos e Técnicas. Slides do professor Marcelo Honda