Buscar

Paradigmas de Linguagens de Programação - Aula 4

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Paradigmas de Linguagens de Programação
Programação Funcional com linguagem Scheme
PPGCOMP – UNIFACS
Prof. Sergio Martins Fernandes
sergio.fernandes@unifacs.br
71 99958-0897
Tópicos
• Introdução
• Funções matemáticas
• Fundamentos das linguagens de programação funcional 
• A primeira linguagem de programação funcional: LISP
• Uma introdução a Scheme
• Aplicações de linguagens funcionais
• Uma comparação entre linguagens funcionais e imperativas
Introdução
• O projeto das linguagens imperativas é baseado diretamente na 
arquitetura de computadores von Neumann
– Eficiência	é	a	principal	preocupação,	em	vez	da	adequação	da	linguagem	para	
desenvolvimento	de	software
• O projeto das linguagens funcionais é baseado em funções 
matemáticas
– Uma	sólida	base	teórica,	também	próxima	do	usuário,	mas	relativamente	
despreocupada	com	a	arquitetura	das	máquinas	em	que	os	programas	serão	
executados
Paradigma funcional versus imperativo
• John Backus, criador do Fortran e de uma linguagem funcional 
– Linguagens	funcionais	são	superiores	às	imperativas,	porque
• São	mais	fáceis	de	entender	durante	e	após	o	desenvolvimento
– Porque	cada	função	pode	ser	compreendida	independentemente	do	contexto
» Não	há	estado,	efeitos	colaterais	da	execução	de	funções
• Característica fundamental do paradigma imperativo
– Linguagens	tem	estado,	representado	pelas	variáveis	do	programa
– Autor	do	programa	e	leitores	devem	entender	os	usos	das	variáveis	e	como	o	
estado	do	programa	muda	ao	longo	da	execução
• Num	programa	complexo,	isso	pode	ser	muito	desafiador
• Linguagens funcionais não têm variáveis nem, 
consequentemente, estado
Algumas linguagens funcionais
• LISP
– Começou	como	uma	linguagem	puramente	funcional
– Ao	longo	dos	anos,	adquiriu	características	imperativas	que	aumentaram	a	eficiência	de	sua	
execução
– Única	linguagem	funcional	que	atingiu	maior	número	de	usuários
– Usada	para
• Representação	de	conhecimento
• Aprendizado	por	máquinas
• Modelagem	da	fala
• COMMON LISP
– Amálgama	de	vários	dialetos	de	LISP	criados	nos	anos	80
• SCHEME
– Pequeno	dialeto	de	LISP,	usada	para	ensino	de	programação	funcional
• ML, Haskell, OCaml, e F#
– Linguagens	funcionais	tipadas
– Geraram	significativa	expansão	das	áreas	em	que	programação	funcional	é	utilizada
• Processamento	de	BDs,	modelagem	financeira,	análise	estatística,	bio informática
Funções matemáticas
• Uma função matemática é um 
mapeamento de membros de um 
conjunto, chamado de conjunto 
domínio, para outro conjunto, 
chamado de conjunto imagem
• O mapeamento é descrito por uma 
expressão ou por uma tabela
• A função aplicada a um elemento 
do conjunto domínio, passado 
como parâmetro para a função, e 
produz um elemento do conjunto 
imagem
Funções matemáticas
• O conjunto domínio pode ser obtido pelo cruzamento de diversos 
conjuntos
• Neste caso haverá vários parâmetros
• Como não têm efeitos colaterais nem dependem de parâmetros 
externos, sempre mapeiam um determinado elemento do conjunto 
domínio no mesmo elemento do conjunto imagem
Funções simples
• Como definir uma função:
– Nome	da	função
– Seguido	de	uma	lista	de	parâmetros	entre	parêntesis
– Seguido	da	expressão	de	mapeamento
– Exemplo:
Cubo(x) = x * x * x
– O	parâmetro	x		representa	qualquer	membro	do	conjunto	domínio,	mas	é	fixo	e	
representa	um	elemento	específico	durante	a	avaliação	da	expressão	da	função.	
– Exemplo
Cubo (2) = 2 * 2 * 2 = 8
Expressões lambda
• Teoria de funções separa o trabalho de definir a função do trabalho de 
nomeá-la
• Uma expressão lambda especifica o parâmetro e o mapeamento de 
uma função com a seguinte forma
l(x) x * x * x
para a função cubo (x) = x * x * x
• Expressões lambda descrevem funções sem nome
• São aplicadas aos parâmetros colocando-se os parâmetros depois da 
expressão
por exemplo, (l(x) x * x * x)(2)
que resulta no valor 8
• Expressões lambda, como outras definições de função, podem ter mais 
de um parâmetro
Formas funcionais
• Uma função de ordem superior, ou forma funcional, é uma 
função que recebe funções como parâmetros ou uma que leva a 
uma função como resultado, ou ambos
Composição de funções
• É uma forma funcional que tem duas ou mais funções como 
parâmetros ou leva a uma função cujo valor é o primeiro 
parâmetro de função real aplicado ao resultado do segundo
Forma: h º f ° g
que significa h (x) º f ( g ( x))
Para f (x) º x + 2 e g (x) º 3 * x,
h º f ° g resulta (3 * x)+ 2
Aplicar-para-todos
• É uma forma funcional que recebe uma única função como um 
parâmetro e produz uma lista de valores obtidos pela aplicação da 
função de cada elemento de uma lista de parâmetros
Forma: a
Para h (x) º x * x
a( h, (2, 3, 4)) resulta (4, 9, 16)
Fundamentos das linguagens de 
programação funcional
• O objetivo do projeto de uma linguagem de programação 
funcional é mimetizar funções matemáticas ao máximo possível
• A abordagem para a solução de problemas é fundamentalmente 
diferente de abordagens usadas com linguagens imperativas
– Em uma linguagem imperativa, as operações são realizadas e os 
resultados são armazenados em variáveis para uso posterior
– Gestão das variáveis é uma preocupação constante e uma fonte de 
complexidade para a programação imperativa
• Em uma linguagem de programação funcional, variáveis não são 
necessárias, e não há comandos de atribuição
Fundamentos das linguagens de 
programação funcional (continuação)
• Por não ter variáveis, construções iterativas não são possíveis 
nas linguagens funcionais
– Pois	as	iterações	são	controladas	por	variáveis
• Repetições devem ser especificadas com recursão, em vez de 
iterações
• Programas são definições de funções e especificações de 
aplicações de funções
• Execuções de programas consistem em avaliar aplicações de 
funções
• Como não há variáveis, a execução de um programa puramente 
funcional não tem estado
Fundamentos das linguagens de 
programação funcional (continuação)
• Transparência referencial – Em uma linguagem de programação 
funcional, a avaliação de uma função sempre produz o mesmo 
resultado, dados os mesmos parâmetros
Linguagem LISP
• Desenvolvida por John McCarthy no MIT em 1959
• Estudar programação funcional via LISP é o mesmo que estudar 
programação imperativa usando FORTRAN
• LISP evoluiu ao longo de meio século, mas não representa os 
conceitos mais recentes de programação funcional
• Exceto a primeira versão, todos os dialetos de LISP incluem 
recursos imperativos, tais como variáveis, comandos de 
atribuição, e iterações
• Apesar disso tudo, os descendentes do LISP original representam 
conceitos bem fundamentados de programação funcional
Tipos de dados e estruturas LISP
• Tipos de objetos de dados: originalmente, apenas átomos e listas
• Lista: coleção de sublistas e/ou átomos, entre parênteses
por exemplo, 
(a b c d)- lista simples
(a (b c) d (e (f g)))– listas aninhadas
lista de 4 elementos: o primeiro é o átomo a, o segundo é a 
sub-lista (b c), o terceiro é o átomo d, e o quarto é a sublista(e 
(f g))
• Originalmente, LISP era desprovida de tipos
• Internamente, as listas são armazenadas como estruturas de lista 
encadeadas, nas quais cada nó possui dois ponteiros e 
representa um elemento
Representação interna de listas em LISP
Interpretador LISP
• A notação lambda é usada para especificar funções e definições 
de funções, mas modificada para permitir nomear funções
por exemplo, se a lista (a b c) é interpretada como dados, é uma simples 
lista de três átomos, a, b e c
Se é interpretada como uma aplicação de função,
significa que a função chamada A é aplicada aos 
dois parâmetros, b e c
Linguagem Scheme
• Scheme é a linguagem que utlizaremos para praticaro paradigma 
funconal, porque:
– É	relativamente	simples
– É	popular	no	ambiente	acadêmico	
– Interpretadores	Scheme	livres	de	custo	são	amplamente	disponíveis
• Apenas será coberta uma pequena parte da linguagem Scheme
– Que	não	inclui	nenhum	recurso	imperativo	da	linguagem
• Aqui será apresentada a versão 4 da linguagem Scheme
Origens de Scheme
• Scheme é um dialeto de LISP que emergiu no meio dos anos 1970, 
projetado para ser mais claro, moderno e simples do que outros dialetos 
de LISP
• Usa apenas escopo estático
• Funções são entidades de primeira classe
– Eles podem ser 
• Valores de expressões
• Elementos de listas
• Passadas como parâmetros
• Retornadas de funções
• Linguagem não tipada, com sintaxe simples
• Código Scheme precisa de poucas modificações para ser transformado 
em LISP
O intepretador Scheme
• Em modo interativo, é um loop infinito de leitura-avaliação-
impressão
• Valores literais são avaliados para eles próprios
• Os parâmetros são avaliados, em nenhuma ordem especial
• Os valores dos parâmetros são substituídos no corpo da função
• O corpo da função é avaliado
• O valor da última expressão no corpo é o valor da função
Funções numéricas primitivas
• Aritmética: +, -, *, /, ABS, SQRT, REMAINDER, MIN, 
MAX
exemplo
Expressão valor
42 42
(* 3 7) 21
(+ 5 7 8) 20
(− 5 6) −1
(− 15 7 2) 6
(− 24 (* 4 3)) 12
Funções numéricas primitivas
• Outras funções:
– MODULO,	ROUND,	MAX,	MIN,	LOG,	SIN,	and SQRT.
• Usa-se letras minúsculas para todas as palavras reservadas e 
funções pré-definidas
– ISSO	DEPENDE	DO	INTERPRETADOR
• Se uma função requer um número fixo de parâmetros, e um 
número distinto desse for fornecido, haverá uma mensagem de 
erro
Definição de função
• Em Scheme, um programa é uma coleção de definições de 
funções. 
• Consequentemente, saber definir essas funções é pré-requisito 
para escrever mesmo os programas mais simples
Definição de função: lambda
• Em Scheme, uma função sem nome inclui a palavra Lambda, e é 
denominada expressão lambda
• Expressões lambda
– Usadas	para	definir	funções	não	nomeadas
– Forma é baseada na notação l
– Utilizam a palavra chave lambda 
por exemplo, (LAMBDA (x) (* x x)
x é chamada de variável vinculada
Definição de função: lambda
• Expressões lambda podem ser aplicadas da mesma maneira que 
as funções nomeadas, ao colocá-las no início de uma lista que 
contenha os parâmetros reais
por exemplo, ((lambda (x) (* x x)) 7)
• No exemplo acima, x é a variável vinculada. Durante a avaliação 
da função, x é vinculada à constante 7
• Expressões lambda podem ter quaisquer número de parâmetros, como no 
exemplo a seguir:
((lambda(a b c x) (+ (* a x x) (* b x) c)) 1 2 3 4)
Nomes em Scheme
• Nomes em Scheme podem consistir de letras, dígitos e caracteres 
especiais, exceto parêntesis
• Não há distinção entre maiúsculos e minúsculos
– Depende	do	interpretador
• Nos	intepretadores que	usamos,	usar	nomes	minúsculos	para	as	funções
• Não devem começar com um dígito
Função de forma especial: define
• A função de forma especial define em Scheme serve a duas 
necessidades fundamentais:
1. Vincular um nome a um valor
por exemplo, (define pi 3.141593)
(define two_pi (* 2 pi))
2. Vincular um nome a uma expressão lambda
por exemplo, (define (square x) (* x x))
(square 5)
– O processo de avaliação para define é diferente! O primeiro parâmetro 
nunca é avaliado. O segundo parâmetro é avaliado e vinculado ao 
primeiro parâmetro. 
Função de forma especial: define
(define pi 3.14159)
(define two_pi (* 2 pi))
• Se as duas expressões acima foram digitadas num interpretador Scheme, e 
depois PI for digitado, será exibido o valor 3.14159
• Caso o valor two_pi seja digitado, será exibido o valor 6.28318
Funções de predicado numéricas
• Uma função de predicado é aquela que retorna uma valor booleano 
((verdadeiro ou falso).
• #T é verdadeiro (true) e #F é falso (false) (às vezes, (), que é uma lista vazia, é 
usado para falso)
• Scheme inclui uma coleção de funções predicado para valores numéricos. 
Algumas delas abaixo
Função Significado
= Igual
(not (= x y)) Náo igual
> Maior que
< Menor que
>= Maior que ou igual a
<= Menor que ou igual a
even? Número é par?
odd? Número é ímpar?
zero? Valor é zero?
Funções de predicado numéricas
• Quando uma lista é interpretada como um booleano, qualquer 
lista vazia é avaliada como falso, e qualquer lista não vazia é 
avaliada como verdadeiro.
Controle de fluxo: if
• A chamada ao seletor de dois caminhos de Scheme, IF, tem a 
forma
(if predicado expressão_então expressão_senão)
por exemplo, 
(if (not (= count 0))
(/ sum count)
0)
Outro exemplo:
(define (factorial n)
(if (<= n 1)
1
(* n (factorial (− n 1)))
))
Controle de fluxo: cond
• O seletor multiplo de Scheme é uma forma especial chamada 
COND
Forma geral:
(COND
(predicado_1 expressão1)
(predicado_2 expressão2)
...
(predicado_n expressão_n)
[(ELSE expressão)]
)
• Retorna o valor da última expressão no primeiro par cujo 
predicado avaliar para true
• Os colchetes indicam que a cláusula ELSE é opcional
Exemplo de cond
(define (compare x y)
(cond
((> x y) “x é maior que y”)
((< x y) “y é maior que x”)
(else “x ey são iguais”)
)
)
Funções de lista
• Um dos usos mais frequentes de linguagens baseadas em LISP é 
o processamento de listas
• Programas SCHEME são interpretados pela função EVAL, que é 
uma função para aplicação de funções
• Quando aplicada a uma função primitiva, EVAL avalia os 
parâmetros da referida função
– Essa	ação	é	necessária	se	os	parâmetros	da	função	forem	eles	próprios	funções
– Se,	por	outro	lado,	um	parâmetro	for	um	elemento	de	dados,	ele	não	deve	ser	
avaliado
– Para	evitar	avaliar	um	parâmetro,	ele	é	atribuído	à	função	QUOTE
– QUOTE	é	necessária	porque,	nas	linguagens	derivadas	de	LISP,	dados	e	código	
têm	a	mesma	forma
(próximo	slide)
Funções de lista: quote
• quote – um parâmetro é passado à função, que simplesmente o 
retorna sem modificações 
– quote é necessário por que o interpretador de scheme, chamado eval, 
sempre avalia parâmetros para aplicações de funções antes de aplicar a 
função. quote é usado para evitar a avaliação de parâmetros quando 
não é apropriado
(quote a) returns a
(quote (a b c)) returns (a b c)
– quote pode ser abreviada precedendo a expressão a ser citada por um 
apóstrofo
'(a b) é equivalente a (quote (a b))
Funções de lista: cons e list
• cons é um construtor de lista primitivo. Ele constrói uma lista a 
partir de seus dois argumentos, o primeiro deles pode ser um 
átomo ou uma lista; o segundo é normalmente uma lista. 
por exemplo, (cons 'A '(B C)) retorna (A B C)
• list é uma função que constrói uma lista a partir de um número 
variável de parâmetros
Funções de lista: cons e list
• Exemplo de funções cons e list
(cons 'a '()) retorna (a)
(cons 'a '(b c)) retorna (a b c)
(cons '() '(a b)) retorna (() a b)
(cons '(a b) '(c d)) retorna ((a b) c d)
(list 'apple 'orange 'grape) retorna (apple orange grape)
Funções de lista: car e cdr
• car retorna o primeiro elemento de uma dada lista de parâmetros
por exemplo, (car '(a b c)) retorna a
(car '((a b) c d)) retorna (a b)
• cdr retorna o restante de uma dada lista após seu car ter sido 
removido
por exemplo, (cdr '(a b c)) retorna (b c)
(cdr '((a b) c d)) retorna (c d)
Funções de lista: car e cdr
• Exemplos de CAR e CDR
(car '(a b c)) retorna a
(car '((a b) c d)) retorna (a b)
(car 'a) gera um erro porque a não é uma lista
(car '(a)) retorna a
(car '()) gera um erro
(cdr '(a b c)) retorna (b c)
(cdr '((a b) c d)) retorna (c d)
(cdr 'a) gera um erro
(cdr '(a)) retorna ()
(cdr '()) é um erro
Funções de lista: car e cdr
• Schemetem variações e combinações dessas duas funções, que são denominadas por
composições das letras A e D no nome da função
• Exemplo:
(caar x)	é	equivalente	a	(car(car x))
(cadr x)	é	equivalente	a	(car (cdr x))
(caddar x)	é	equivalente	a	(car (cdr (cdr (car x))))
(caddar '((a	b (c)	d)	e))	=
(car (cdr (cdr (car '((a	b	(c)	d)	e)))))	=
(car (cdr (cdr '(a	b	(c)	d))))	=
(car (cdr '(b	(c)	d)))	=
(car	'((c)	d))	=
(c)
Funções de predicado de listas e átomos simbólicos
• Scheme tem três funções de predicado fundamentais para átomos e listas 
simbólicos
eq?
null?
list?
Funções de predicado: eq?
• eq? recebe dois átomos simbólicos como parâmetros; retorna #T se 
ambos os parâmetros forem átomos e ambos forem o mesmo; caso 
contrário, retorna #F
por exemplo, (eq? 'A 'A) retorna #T
(eq? 'A 'B) retorna #F
– Nota que, se EQ? é chamada com lista de parâmetros, o resultado não é 
confiável
– eq? também não funciona para átomos numéricos
(eq? 'a 'a) retorna #t
(eq? 'a 'b) retorna #f
(eq? 'a '(a b)) retorna #f
(eq? '(a b) '(a b)) retorna #f ou #t
(eq? 3.4 (+ 3 0.4)) retorna #f ou #t
Funções de predicado: list? e null?
• list? retorna #t se seu único parâmetro é uma lista; caso contrário, 
retorna #f
(list? '(x y)) retorna #t
(list? 'x) retorna #f
(list? '()) retorna #t
• null? testa seu parâmetro para determinar se ela é a lista vazia e 
retorna #t caso seja
– note que null? retorna #t se o parâmetro é ()
(null? '(a b)) retorna #f
(null? '()) retorna #t
(null? 'a) retorna #f
(null? '(())) retorna #f
Exemplos de funções em Scheme: member
• member pega um átomo e uma lista simples; retorna #T se o 
átomo estiver na lista
(define (member atomo lista)
(cond
((null? lista) #F)
((eq? atomo (car lista)) #T)
(else (member atomo (cdr lista)))
))
Usando a função
(member 'B '(A B C)) retorna #T
(member 'B '(A C D E)) retorna #F
Exemplos de funções Scheme: equalsimp
• equalsimp é uma função de predicados para comparar listas 
simples; retorna #T se as duas listas são iguais
(define (equalsimp lis1 lis2)
(cond
((null? lis1) (null? lis2))
((null? lis2) #f)
((eq? (car lis1) (car lis2))
(equalsimp(cdr lis1)(cdr lis2)))
(else #f)
))
Exemplos de funções em Scheme: equal
• equal funciona em qualquer par de expressões, não apenas 
listas
(define (equal lis1 lis2)
(cond
((not (list? lis1))(eq? lis1 lis2))
((not (list? lis2)) #f)
((null? lis1) (null? lis2))
((null? lis2) #f)
((equal (car lis1) (car lis2))
(equal (cdr lis1) (cdr lis2)))
(else #f)
))
Exemplos de funções em Scheme: append
• append pega duas listas como parâmetros; retorna a primeira 
com os elementos da segunda no final
(define (append lis1 lis2)
(cond
((null? lis1) lis2)
(else (cons (car lis1)
(append (cdr lis1) lis2)))
))
Formas funcionais
• Uma forma funcional é a implementação em LISP e seus dialetos 
do conceito matemático de forma funcional, já apresentado aqui
• Scheme permite a aplicação de duas formas funcionais
– Composição	funcional
– Aplicar-para-todos
Formas funcionais – composição
• Exemplo de composição em Scheme
(define (g x) (* 3 x))
(define (f x) (+ 2 x))
• A forma funcional de f e g pode ser escrita como
(define (h x) (+ 2 (* 3 x)))
• Em Scheme, a função de composição funcional compose pode ser escrita da 
seguinte forma:
(define (compose f g) (lambda (x)(f (g x))))
• A aplicação da função composta seria
((compose f g) 5)
Formas funcionais – composição
• Outro exemplo
(define (compose car cdr) (lambda (x) (car (cdr x))))
• Um exemplo de aplicação da função composta seria
((compose car cdr) '((a b) c d))
• Cujo resultado é c
Formas funcionais – aplicar-a-todos
• Aplicar-a-todos – uma forma em Scheme é map
– Aplica uma função dada a todos os elementos de uma lista
(DEFINE (map fun lis)
(COND
((NULL? lis) ())
(ELSE (CONS (fun (CAR lis))
(map fun (CDR lis))))
))
• Um exemplo de aplicação de map é:
(map (LAMBDA (num) (* num num num)) '(3 4 2 6))
• E o resultado seria (27 64 8 216)
Funções que constroem código
• É possível, em Scheme, definir uma função que cria código 
Scheme e solicita a sua interpretação
• Isso é possível com a função eval
Somando uma lista de números
((define (adder lis)
(cond
((null? lis) 0)
(else (eval (cons '+ lis)))
))
• O parâmetro é uma lista de números a ser adicionada; adder
insere um operador + e avalia a lista resultante
– Use cons para inserir o átomo + na lista de números
– Note que o nome da função + é colocado com uma aspa para prevenir 
que eval o avaliasse
– Submeta a nova lista a eval para avaliação
COMMON LISP
• Uma combinação de diversos recursos de dialetos populares de 
LISP dos anos 1980
• Linguagem grande e complexa, o oposto de Scheme
• Recursos incluem:
– registros 
– matrizes 
– números complexos
– cadeias de caracteres
– operações de entrata e saída poderosas
– pacotes para controle de acesso
ML
• Uma linguagem de programação funcional com escopo estático, 
que se difere de LISP e seus dialetos, incluindo Scheme, de 
maneiras significativas
• Usa declarações de tipo, mas também inferências de tipos para 
determinar os tipos de variáveis não declaradas
• É fortemente tipada (Scheme é essencialmente desprovida de 
tipos)
• Inclui tratamento de exceções e um recurso de módulo para 
implementar tipos de dados abstratos
• Inclui listas e operações de listas
ML
• Forma das declarações de funções:
fun nome_da_função (parâmetros_formais) = 
expressão_corpo_da_função;
por exemplo, fun cube (x : int) = x * x * x;
– O tipo do valor de retorno pode ser especificado após a lista de 
parâmetros, como em
fun cube (x) : int = x * x * x;
– O tipo do valor de retorno não precisa ser explicitamente especificado
– Funções definidas pelo usuário sobrecarregadas não são permitidas; se 
quisermos uma função cube para valores de tipo real, precisamos defini-
la com outro nome
ML
• Seleção em ML
if expressão then expressão_então
else expressão_senão
onde a primeira expressão deve avaliar para um valor booleano
• Usando casamento de padrões, a função fatorial poderia ser 
escrita como 
fun fact(0) = 1
| fact(n : int) : int = 
n * fact(n – 1)
ML
• Listas
Listas são especificadas entre colchetes
[3, 5, 7]
[] é uma lista vazia
CONS é um operador infixo binário, ::
4 :: [3, 5, 7], que avalia para [4, 3, 5, 7]
CAR é o operador unário hd
CDR é o operador unário tl
fun length([]) = 0
| length(h :: t) = 1 + length(t);
fun append([], lis2) = lis2
| append(h :: t, lis2) = h :: append(t, lis2);
ML
• A sentença val vincula um nome a um valor (similar a DEFINE
em Scheme)
val distance = time * speed;
– Assim como DEFINE, val é completamente diferente de uma sentença de 
atribuição em uma linguagem imperativa
Haskell
• Similar a ML (usa uma sintaxe similar, tem escopo estático, é 
fortemente tipada e usa o mesmo método de inferência)
• Diferente de ML (e outras linguagens funcionais) no que é 
puramente funcional
Diferenças de sintaxe
fact 0 = 1
fact n = n * fact (n – 1)
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1) + fib n
Listas
• Notação de lista: coloca os elementos entre colchetes
por exemplo, directions = ["north", 
"south", "east", "west"]
• Comprimento: #
por exemplo, #directions é 4
• Séries aritméticas com o operador .. 
por exemplo, [2, 4..10] is [2, 4, 6, 8, 10]
• Concatenação é com ++
por exemplo, [1, 3] ++ [5, 7] resulta [1, 3, 5, 7]
• CONS, CAR, CDR com o operador dois pontos (como em 
Prolog)
por exemplo, 1:[3, 5, 7] resulta [1, 3, 5, 7]
Função fatorial
product [] = 1
product (a:x) = a * product x
fact n = product [1..n]
Aplicações das linguagens funcionais
• APL é usada para programas “descartáveis”
•LISP é usada para inteligência artificial
– Representação do conhecimento
– Aprendizado de máquina
– Processamento de linguagem natural
– Modelo de fala e visão
• Scheme é usada para ensinar programação introdutória em 
algumas universidades
Exercício 
O Que faz a função abaixo?
(define (y s lis)
(cond
((null? lis) '() )
((equal? s (car lis)) lis)
(else (y s (cdr lis)))
))
Exercício 
O Que faz a função abaixo?
(DEFINE (d atm lst)
(COND
((NULL? lst) '())
((EQ? atm (CAR lst)) (d atm (CDR lst)))
(ELSE (CONS (CAR lst) (d atm (CDR lst)))
))
)
Exercício 
O Que faz a função abaixo?
(DEFINE (r lis)
(COND 
((NULL? lis) '())
(ELSE (APPEND (r (CDR lis)) (CONS (CAR lis) '() )))
))
Comparando linguagens funcionais 
e imperativas
• Linguagens imperativas:
– Execução eficiente
– Semântica complexa
– Sintaxe complexa
– Concorrência é projetada pelo programador
• Linguagens funcionais:
– Semântica simples
– Sintaxe simples
– Execução ineficiente
– Programas podem ter concorrência automaticamente
Resumo
• Funções matemáticas são mapeamentos nomeados ou não nomeados que usam 
apenas expressões condicionais e recursão para controlar suas avaliações
• LISP iniciou como uma linguagem puramente funcional, mas logo teve adicionados 
recursos de linguagens imperativas
• Scheme é um dialeto relativamente simples de LISP que usa exclusivamente 
escopo estático
• COMMON LISP é uma grande linguagem baseada em LISP
• ML é uma linguagem de programação funcional de escopo estático e fortemente tipada
que usa uma sintaxe que é mais fortemente relacionada à de uma linguagem imperativa 
do que à de LISP
• Haskell é similar a ML, exceto que todas as expressões em Haskell são avaliadas 
usando um método preguiçoso, que permite que os programas lidem com listas infinitas
• Apesar de poderem existir vantagens nas linguagens funcionais puras sobre as 
imperativas, sua velocidade de execução mais lenta em máquinas von Neumann 
preveniu que fossem consideradas por muitos como substitutas das imperativas

Outros materiais