Universidade Estadual de Santa Cruz
Conceitos de Linguagens de Programação
Linguagens Imperativas e Funcionais
Prof. Dr. Rogério Vargas
Ilhéus-Ba, 16 de Maio de 2013.
Roteiro Linguagens Imperativas
Linguagens Funcionais
Atividade
Linguagens Imperativas
Roteiro 1- Introdução
Paradigmas de Programação
2- Paradigma Imperativo
Modelo Computacional • Arquitetura de Von Neumann
Características Centrais
3- Efeitos Colaterais
4- Exemplos Linguagens Imperativas
5- Linguagens Imperativas não Estruturadas
6- Linguagens Imperativas Estruturada
4
Introdução Na Ciência da Computação, programação imperativa é
um paradigma de programação que descreve a computação como ações, enunciados ou comandos que mudam o estado(variáveis) de um programa.
5
Paradigmas de Programação Fornece e determina a visão que o
programador possui sobre a estruturação e execução do programa.
Assim como diferentes grupos em engenharia de software propõem diferentes metodologias, diferentes linguagens de programação propõem diferentes paradigmas de programação.
6
Paradigmas de Programação
Um paradigma específico: • SmallTalk e Java- Orientações a objetos • Haskell- Funcional
Múltiplos paradigmas: • LISP, Perl, Python, C++, Oz
7
Paradigmas de programação Os paradigmas de programação são
muitas vezes diferenciados pelas técnicas de programação que proíbem ou permitem. Por exemplo, a programação estruturada não permite o uso de goto.
O relacionamento entre paradigmas de programação e linguagens de programação pode ser complexo.
8
Quanto ao paradigma
Se dividem em dois grandes grupos:
• Imperativo
• Declarativo
9
Paradigma Imperativo Os paradigmas imperativos são aqueles
que facilitam a computação por meio de mudanças de estado. Se dividem em:
• O paradigma procedural: Fortran e o Basic.
• O paradigma de estrutura de blocos: Algol 60, Pascal e C.
• O paradigma de orientação a objetos: C++, Java, Python e Ruby.
• O paradigma da computação distribuída: Ada.
10
Modelo Computacional A arquitetura dos computadores exerceu um efeito
crucial sobre o projeto das linguagens de programação.
Arquitetura de Von Neumann. Se caracteriza pela possibilidade de uma máquina digital armazenar seus programas no mesmo espaço de memória que os dados, podendo assim manipular tais programas.
11
Modelo Computacional Arquitetura de Von Neumann
12
Modelo Computacional O modelo imperativo de programação
baseia-se no modo de funcionamento do computador.
O paradigma imperativo é predominante nas LPs, pois tais linguagens são mais fáceis de traduzir para uma forma adequada para execução na máquina.
13
Modelo Computacional Linguagens imperativas são caracterizadas por três
conceitos: variáveis, atribuições e sequências.
O estado de um programa imperativo é mantido em variáveis de programa que são associados com localizações de memória que correspondem a um endereço e um valor de armazenamento.
O valor da variável pode ser acessado direta e indiretamente, e pode ser alterado através de um comando de atribuição. O comando de atribuição introduz uma dependência de ordem no programa: o valor de uma variável é diferente antes e depois de um comando de atribuição.
14
Modelo Computacional Já as funções de linguagem de programação
imperativas são descritas como algoritmos que especificam como processar um intervalo de valores, a partir de um valor de domínio, com uma série de passos prescritos.
A repetição, ou laço, é usada extensivamente para processar os valores desejados. Laços são usados para varrer uma sequência de localizações de memória tal como vetores, ou para acumular um valor em uma variável específica.
15
Características centrais As características centrais das linguagens
imperativas são:
• as variáveis, que modelam as células de memória;
• comandos de atribuição, que são baseados nas operações de transferência dos dados e instruções;
• a execução sequencial de instruções;
• e a forma iterativa de repetição, que é o método mais eficiente desta arquitetura.
16
Características Centrais Ex.: O valor da variável é modificado através de
atribuições. Por exemplo, em Pascal: X := 5; O termo à esquerda do operador de atribuição
(:=) é a variável cujo valor está sendo modificado e à direita está o novo valor. X tem valores diferentes antes e depois da atribuição. Portanto o significado (efeito) de um programa depende da ordem em que as atribuições são escritas e executadas.
17
Características Centrais Uma última característica importante é que
a repetição (laços) é utilizada extensivamente para computar valores desejados. Laços são usados para varrer um vetor ou acumular valores numa variável.
Por causa dessas características, as linguagens imperativas têm sido chamadas de orientadas a estado ou orientadas à atribuição.
18
Efeitos Colaterais Vantagens
• Eficiência (embute o modelo de Von Neumann)
• Mais fácil de traduzir para a linguagem de máquina
• Paradigma dominante e bem estabelecido
• Modelagem “Natural” de aplicações do mundo real
• Também é muito flexível
Desvantagens
• Descrições demasiadamente operacionais
• Focaliza o “como” e não o “quê”
• Relacionamento indireto com a E/S (indução a erros/estados) 19
Exemplos de Linguagens Imperativas
Alguns exemplos de linguagens de programação que baseiam-se no modelo imperativo:
• Ada
• Algol
• Basic
• C
• PHP
• Java
• Cobol
• Fortran
• Pascal
• Python
• Lua
• Mathematica
20
Linguagens Imperativas Não Estruturadas
São linguagens caracterizadas pela utilização da expressão goto.
Necessária para determinar a repetição e a seleção de execução de instruções.
Uso de goto geralmente leva ao que chamam na literatura de código spaguetti.
21
Linguagens Imperativas Não Estruturadas
Exemplo de código com o uso de instrução goto, baseado na sintaxe do Pascal: read(x); 2: if x = 0 then goto 8; writeln(x); 4: read(next); if next = x then goto 4; x := next; goto 2;
8: ...;
22
Linguagens Imperativas Não Estruturadas
Fortran, Assembly e Basic são algumas das linguagens imperativas que possuem o conceito de goto.
23
Linguagens Imperativas Estruturadas
Linguagens estruturadas surgiram com o objetivo de facilitar a leitura e acompanhamento da execução de algoritmos.
Normalmente linguagens estruturadas não fazem uso de comando goto.
Instruções são agrupadas em blocos, os quais podem ser considerados como unidades de programa, abstraindo-se das suas estruturas internas.
24
Linguagens Imperativas Estruturadas
Blocos de instruções podem ser selecionados para execução através de declarações de seleção como if...else, ou repetidamente executados através de declarações de repetição como while.
Procedurais e Modulares.
25
Linguagens Imperativas Estruturadas
Exemplo de código estruturado, baseado na sintaxe do Pascal, correspondente ao mesmo exemplo da seção anterior: read(x); while x <> 0 do begin writeln(x); repeat read(next); until next <> x; x := next; end;
26
Linguagens Funcionais
Linguagens Funcionais Introdução
Algumas características
Antecedentes históricos
(Lambda) λ-Cálculo
Operações básicas λ
Estratégias de redução
Formas funcionais
Trabalhando com linguagens funcionais
Exemplos
Vantages e Desvantagens
Introdução 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 l inguagens de p r o g r a m a ç ã o A P L e L i s p , e m a i s recentemente ML, Haskell e F#
Algumas Características 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 sub-expressões que as constituem;
Não permite efeito colateral em funções, a linguagem oferece transparência referencial.
Antecedentes Históricos Década de 1930:
Alonzo Church desenvolve o cálculo lambda, uma teoria de funções simples, mas poderosa
Antecedentes Históricos 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.
Antecedentes Históricos Década de 1960:
Peter Landin desenvolve ISWIM, a primeira linguagem funcional pura, baseada fortemente no cálculo lambda, sem atribuições.
Antecedentes Históricos 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.
Antecedentes Históricos 1987: Um comitê internacional de pesquisadores inicia
o desenvolvimento de Haskell, uma linguagem funcional lazy padrão.
Antecedentes Históricos 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.
(Lambda) λ-Cálculo 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 função e um elemento do domínio
A redução de um programa consiste em substituir uma parte da expressao original, obedecendo a certas regras de reescrita;
Operações Básicas λ 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;
Operações Básicas λ 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;
Nessa expressão, a variável X não está mais livre para assumir um valor arbitrário;
Aplicação: Um sistema de reduções deve permitir que se produza a
sequencia de expressões λX.(X + 5) 4 => 4 + 5 => 9;
Estratégias de redução 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);
Estratégias de redução De fora pra dentro(a priori)
Estratégias de redução De fora para dentro (sob demanda)
Estratégias de redução 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;
Trabalhando com programação funcional
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.
Trabalhando com programação funcional
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.
Linguagens imperativas x Linguagens funcionais
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 imperativas x Linguagens funcionais
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.
Vantagens – Linguagens Funcionais
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.
Desvantagens – Linguagens Funcionais
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.
Top Related