Lisp & Common Lisp Carlos Cunha Joabe Jesus {ceac, jbjj}@cin.ufpe.br

Preview:

Citation preview

Lisp & Common Lisp

Carlos CunhaJoabe Jesus

{ceac, jbjj}@cin.ufpe.br

Roteiro

Motivação Histórico Common Lisp

Linguagem CLOS Aplicações

Motivação

Poder de Abstração de Linguagens Funcionais

Relacionada ao projeto de pesquisa - Linguagem da implementação do núcleo do Z-EVES (provador de teoremas)

Histórico

Concebida por John McCarthy no MIT em 1959

Influenciado pelo Cálculo Lambda de Alonzo Church Manipulação formal de funções

matemáticas

Acrônimo para List Processing

Histórico - Lisp e seus dialétos

Existiam vários dialetos: MacLisp Common Lisp Scheme ...

Hoje LISP está padronizado e referenciado como COMMON LISP

O que é o Common Lisp?

Uma das implementações de Lisp Um “SDK” de domínio público

Interpretador Compilador para executáveis até 5

vezes mais rápidos Conjunto de funções padrões

Common Lisp - Modularidade

Lisp permite: O empacotamento (packaging) de

programas em módulos Sistema de objetos, funções genéricas

com a possibilidade de combinação de métodos

Definição de Macros

Common Lisp

Tipos de dados

Common Lisp - Tipos de dados

números, caracteres, strings, arrays, listas, símbolos, estruturas, streams, ...

Todos com tamanho ilimitado (a precisão e o tamanho de uma variável não necessita de ser declarado, o tamanho de listas e arrays altera-se dinamicamente)

Integers de precisão arbitrária, precisão de ponto flutuante ilimitada

Common Lisp - “API”

Funções genéricas: 88 funções aritméticas para todos os

tipos de número (integers, ratios, floating point numbers, complex numbers)

44 funções de busca/filtro/ordenação para listas, arrays e strings

Common Lisp - Características

Tipagem em tempo de execução O programador geralmente não precisa

se preocupar com declarações de tipo, mas ele recebe mensagens de erro caso haja violações de tipo (operações ilegais)

Gerenciamento automático de memória (garbage collection)

Common Lisp - Tipos de Dados

Booleano LISP utiliza t e nil para representar

verdadeiro e falso Lisp tem funções booleanas-padrão,

como and, or e not. Sendo os conetivos and e or são curto-circuitantes

Common Lisp - Tipos de Dados

Símbolos Um símbolo é somente um string de

caracteresabc1foobar

Qualquer símbolo cujo nome inicia com dois pontos (:_) é uma palavra-chave

Exemplo - Símbolos

Ex:> (setq a 5) ; store a number as the value of a symbol5> a ; take the value of a symbol5> (let ((a 6)) a) ;bind the value of a symbol temporarily to 66> a ; the value returns to 5 once the let is finished5> (+ a 6) ; use the value of a symbol as an argument11> b ; try to take the value of a symbol which has no valueError: Attempt to take the value of the unbound symbol b.

Common Lisp - Tipos de Dados

Números Um inteiro é um string de dígitos

opcionalmente precedido de um + ou -. Um real parece com um inteiro, só que possui

um ponto decimal e pode opcionalmente ser escrito em notação científica.

Um racional se parece com dois inteiros com um / entre eles.

LISP suporta números complexos que são escritos como: #c(r i)

Common Lisp - Tipos de Dados

Conses – Associações Produto Cartesiano -> Dupla Os campos são chamados de "car" e

"cdr", ao invés de first e second> (cons 4 5) ; Aloca uma dupla, car = 4 e cdr = 5(4 . 5)> (car (cons 4 5))4> (cdr (cons 4 5))5

Common Lisp - Tipos de Dados

Listas (encadeadas) Construídas a partir de conses

O car de cada cons aponta para um dos elementos da lista e

O cdr aponta ou para outro cons ou para nil. Ex:

> (list 4 5 6)(4 5 6)

OBS: LISP imprime listas de uma forma especial, omitindo os pontos e parênteses internos dos conses

Common Lisp - Tipos de Dados

Listas (encadeadas) nil corresponde à lista vazia

O car e cdr de nil são definidos como nil. O car de um átomo é o próprio átomo. O cdr de um átomo é nil.

Se o cdr de um cons é nil, Lisp não se preocupa em imprimir o ponto ou o nil

Se o cdr de cons A é cons B, então lisp não se preocupa em imprimir o ponto para A nem o parênteses para B

Common Lisp - Tipos de Dados

Listas (encadeadas) e Conses Ex:> (cons 4 nil)(4)> (cons 4 (cons 5 6))(4 5 . 6)> (cons 4 (cons 5 (cons 6 nil)))(4 5 6)

Common Lisp - Tipos de Dados

Ordenação de Listas LISP provê duas primitivas para ordenação:

sort e stable-sort. O primeiro argumento para sort é uma lista, o segundo é a função de comparação. Ex:

> (sort '(2 1 5 4 6) #'<)(1 2 4 5 6)> (sort '(2 1 5 4 6) #'>)(6 5 4 2 1) OBS: A função de comparação não garante

estabilidade: se há dois elementos a e b tais que (and (not (< a b)) (not (< b a))), sort vai arranjá-los de qualquer maneira

Common Lisp - Tipos de Dados

A função stable-sort é exatamento como sort, só que ela garante que dois elementos equivalentes vão aparecer na lista ordenada exatamente na mesma ordem em que aparecem lista original

Common Lisp - Tipos de Dados

Funções de Lista Úteis> (append '(1 2 3) '(4 5 6)) ;concatena listas (1 2 3 4 5 6)> (reverse '(1 2 3)) ;reverte os elementos(3 2 1)> (member 'a '(b d a c)) ;pertinência a conjunto ;retorna

primeira cauda cujo car é o elemento desejado(A C)> (find 'a '(b d a c)) ;outro set membershipA> (find '(a b) '((a d) (a d e) (a b d e) ()) :test #'subsetp)(A B D E) ;find é mais flexível

Common Lisp - Tipos de Dados

Funções de Lista Úteis> (subsetp '(a b) '(a d e)) ;set containmentNIL> (intersection '(a b c) '(b)) ;set intersection(B)> (union '(a) '(b)) ;set union(A B)> (set-difference '(a b) '(a)) ;diferença de conjuntos(B)

Common Lisp

Igualdade

Common Lisp - Igualdade

LISP tem muitos conceitos diferentes de igualdade. Igualdade numérica é denotada por =

Como em Smalltalk ou em Prolog, existem os conceitos de identidade (mesmo objeto) e igualdade (objetos distintos, porém iguais)

Common Lisp - Igualdade

Dois símbolos são eq se e somente se eles forem idênticos (identidade). Duas cópias da mesma lista não são eq (são dois objetos diferentes) mas são equal (iguais)> (eq 'a 'a)T> (eq 'a 'b)NIL> (= 3 4)T> (eq '(a b c) '(a b c))NIL> (equal '(a b c) '(a b c))T> (eql 'a 'a)T> (eql 3 3)T

Common Lisp - Igualdade

O predicado eql é equivalente a eq para símbolos e a = para números. É a identidade que serve tanto para números como para símbolos.

O predicado equal é equivalente eql para símbolos e números. Ele é verdadeiro para dois conses, se e somente se,

seus cars são equal e seus cdrs são equal. Ele é verdadeiro para duas estruturas se e somente

se as estruturas forem do mesmo tipo e seus campos correspondentes forem equal.

Common Lisp

Funções

Common Lisp - Funções

Definindo uma função:> (defun foo (x y) (+ x y 5))FOO> (foo 5 0) ;chamando a função10> (defun HELLO-WORLD () (print (list 'HELLO 'WORLD))) HELLO WORLD

Common Lisp - Funções

Funcall, Apply, e Mapcar São funções que pedem como

argumento uma função:> (funcall #'+ 3 4)7> (apply #'+ 3 4 '(3 4))14> (mapcar #'not '(t nil t nil t nil))(NIL T NIL T NIL T)

Common Lisp - Funções

Funcall chama seu primeiro argumento com os argumentos restantes como argumentos deste.

Apply é semelhante a Funcall, exceto que seu argumento final deverá ser uma lista. Os elementos desta lista são tratados como se fossem argumentos adicionais ao Funcall.

O primeiro argumento a mapcar deve ser uma função de um argumento. mapcar aplica esta função a cada elemento de uma lista dada e coleta os resulatdos em uma outra lista.

Utilidade de Funcall, apply e Mapcar

Funcall e apply são principalmente úteis quando o seu primeiro argumento é uma variável. Por exemplo, uma máquina de inferência

poderia tomar uma função heurística e utilizar funcall ou apply para chamar esta função sobre uma descrição de um estado.

As funções de ordenação de listas utilizam funcall para chamar as suas funções de comparação

Mapcar, juntamente com funções sem nome (lambda) pode substituir muitos laços

Common Lisp - Funções Lambda

É uma função temporária e não nomeada> #'(lambda (x) (+ x 3))(LAMBDA (X) (+ X 3))> (funcall * 5)8

Common Lisp - Funções Lambda

O poder de Lambda Ex:> (do ((x '(1 2 3 4 5) (cdr x)) (y nil)) ((null x) (reverse y)) (push (+ (car x) 2) y))(3 4 5 6 7)

> (mapcar #'(lambda (x) (+ x 2)) '(1 2 3 4 5))(3 4 5 6 7)

Common Lisp

Forms

Common Lisp - Forms

Forms e o Laço Top-Level Um Form é qualquer trecho digitado

pelo usuário para o interpretador

read-eval-print loop

Lisp salva os três últimos resultados de forms previamente digitados. Ele os armazena sob os símbolos *, ** e ***.

Common Lisp - Forms

Forms e o Laço Top-Level Em geral, um form é ou um átomo (p.ex.: um

símbolo, um inteiro ou um string) ou uma lista. Se o form for um átomo, LISP o avalia

imediatamente. Símbolos avaliam para seu valor, inteiros e strings avaliam para si mesmos.

Se o form for uma lista, LISP trata o seu primeiro elemento como o nome da função, avaliando os elementos restantes de forma recursiva. Então chama a função com com os valores dos elementos restantes como argumentos.

Common Lisp - Forms especiais

quote ‘ e function parecem chamadas a funções mas não são! Ex. quote:

> (setq a 3)3> a3> (quote a)A> 'a ; 'a is an abbreviation for (quote a)A

Common Lisp

Forms especiais Ex. function:

> (setq + 3)3> +3> '++> (function +)#<Function + @ #x-fbef9de>> #'+ ; #'+ is an abbreviation for (function +)#<Function + @ #x-fbef9de>

Common Lisp

Binding

Common Lisp - Binding

Binding é uma atribuição escopada lexicamente

Forms especiais let e let*: (let ((var1 val1) (var2 val2) ... ) body)

Let “atribui” val1 a var1, ..., e então executa os comandos de seu corpo

Let* permite que sejam referenciadas variáveis definidas anteriormente

Common Lisp - Dynamic Scoping

No escopo dinâmico se você atribui um valor a uma variável, TODA menção desta variável vai retornar aquele valor até que você atribua outro valor à mesma variável

Usa o form defvar

Common Lisp - Dynamic Scoping

Ex:> (defvar *special* 5)*SPECIAL*> (defun check-special () *special*)CHECK-SPECIAL> (check-special)5> (let ((*special* 6)) (check-special))6

Common Lisp

Fluxo de controle

Common Lisp - Fluxo de controle

Execução seqüencial em Lisp O form progn permite blocos de

comandos em seu corpo, que são executados sequencialmente e retornando o valor do último

Permite também declaração explícita de variáveis locais, além de retorno explícito

Common Lisp - Fluxo de controle

Ex:(defun F2.17a nil (prog (i j) ;define i e j como variáveis locais inic. com nil (setq i (read)) (setq j (read) (return (print (- i j))) ))

Common Lisp - Condicionais

Lisp possui um função para representar condicionais:> (if t 5 6)5> (if nil 5 6)6> (if 4 5 6)5

OBS: nil significa falso e qualquer outra coisa verdadeiro.

Common Lisp - Condicionais

If’s sem then ou sem else podem ser escritos utilizando-se when ou unless, respectivamente:> (when t 3)3> (when nil 3)NIL> (unless t 3)NIL> (unless nil 3)3

Common Lisp - Condicionais

Else If’s são descritos usando o form cond: Um cond consiste de símbolo con

seguido por um número de cláusulas-cond, cada qual é uma lista. O primeiro elemento de uma cláusula-cond é a condição, os lementos restantes são a ação.

Common Lisp - Condicionais

Ex:> (setq a 3)3> (cond ((evenp a) a) ; if a is even return a ((> a 7) (/ a 2)) ; else if a > 7 return a/2 ((< a 5) (- a 1)) ; else if a < 5 return a-1 (t 17) ; else return 17 )2

OBS: Se não há nenhuma ação na cláusula cond selecionada, cond retorna o valor verdadeiro

Common Lisp - Condicionais

Form case Ex:> (setq x 'b)B> (case x (a 5) ((d e) 7) ((b f) 3) (otherwise 9) )3

Common Lisp - Iteração

Lisp permite a utilização da função loop:> (setq a 4)4> (loop (setq a (+ a 1)) (when (> a 7) (return a)) )8> (loop (setq a (- a 1)) (when (< a 3) (return)) )NIL

Common Lisp - Iteração

dolist - ata uma variável aos elementos de uma lista na sua ordem e termina quando encontra o fim da lista: > (dolist (x '(a b c)) (print x))ABCNIL

Common Lisp - Iteração

Iteração com do e do*:> (do ((x 1 (+ x 1)) ;variável x, com valor inicial 1 (y 1 (* y 2)) ; variável y, com valor inicial 1 ) ((> x 5) y) ;retorna valor de y quando x > 5 (print y) ; corpo (print 'working) ; corpo )1WORKING 2 WORKING4WORKING 8WORKING16WORKING32

Common Lisp - Sáidas Não-Locais

O form especial return na seção de iteração é um exemplo de um return não-local. Outro exemplo é o form return-from, o qual retorna um valor da função que o envolve:> (defun foo (x) (return-from foo 3) x )FOO> (foo 17)3

Common Lisp - Blocos nomeados

Ex:> (block foo (return-from foo 7) 3 )7

Common Lisp - Gerando Erros

Ex:> (error "This is an error")Error: This is an error

Common Lisp - Extensões

Dados Avançados

Common Lisp - Dados Avançados

Estruturas: análogas a structs em "C" ou records em

PASCAL O exemplo abaixo define um tipo de dado

chamado FOO contendo 2 campos:> (defstruct foo bar quux )FOO

Define também 3 funções que operam neste tipo de dado:

make-foo, foo-bar e foo-quux

Common Lisp - Dados Avançados

Estruturas: make-foo - cria um novo objeto FOO. As outras acessam os campos de um

objeto do tipo FOO> (make-foo)#s(FOO :BAR NIL :QUUX NIL)> (make-foo :baa 3)#s(FOO :BAR 3 :QUUX NIL) > (foo-bar *)3> (foo-quux **)NIL

Common Lisp - “Atribuição”

O form especial setf usa seu primeiro argumento para definir um lugar na memória, avalia o seu segundo argumento e armazena o valor resultante na locação de memória resultante

Setf é a única maneira de se setar os valores de um array ou os campos de uma estrutura

Common Lisp - “Atribuição”

Ex:> (setf a (make-array 1)) ; setf on a variable is equivalent to

setq#(NIL)> (push 5 (aref a 1)) ;push can act like setf(5)> (pop (aref a 1)) ; so can pop5> (setf (aref a 1) 5) 5> (incf (aref a 1)) ; incf reads from a place, increments, and

writes back6> (aref a 1)6

Common Lisp

A extensão CLOS

CLOS

Extensão do Common Lisp para Orientação a Objetos

Características: Herança múltipla Funções genéricas Meta-classe e meta-objeto Técnica de criação e iniciação de

objetos que permite controle do processo por parte do usuário

Classes CLOS

Definida usando o form DEFCLASS Ex:

(DEFCLASS nodeDeClasse (nomeDeSuperclasse*) (slot*) opções*)

Se nomeDeSuperclasse* for vazio a superclasse padrão é STANDARD-OBJECT

Slots em CLOS

Um slot tem a forma:

(nomeDoSlot slotOption*)

As opções mais úteis são: :ACCESSOR function-name :INITFORM expression :INITARG symbol

Exemplo DEFCLASS

Um DEFCLASS:(defclass person () ((name :accessor person-name :initform 'bill :initarg :name) (age :accessor person-age :initform 10 :initarg :age)))

DEFCLASS DEFSTRUCT

Sintaxe um pouco diferente Considere o DEFSTRUCT:

(defstruct person (name 'bill) (age 10))

DEFCLASS DEFSTRUCT

DEFSTRUCT definiria automaticamente campos com expressões para: computar valores iniciais default funções de acesso (get e set) como

PERSON-NAME e uma função de inicialização (MAKE-

PERSON) que pegaria argumentos com palavras-chave como abaixo:

(make-person :name 'george :age 12)

DEFCLASS DEFSTRUCT

DEFCLASS dá maior controle sobre quais coisas são chamadas, pois: Permite especificar quais funções

auxiliares queremos, sendo mais flexível que o DEFSTRUCT

Objetos em CLOS

Instâncias são criadas através da função MAKE-INSTANCE Similar às funções MAKE-x definidas por

DEFSTRUCT Permite que você passe a classe a ser

instanciada como argumento EX:

(MAKE-INSTANCE class {initarg value}*)

Objetos de Classe (“static”)

Uma classe, uma vez definida, também é um objeto

Para obter um objeto-classe a partir de seu nome, usa-se:

(FIND-CLASS name)

Métodos em CLOS

Um DEFMETHOD(DEFMETHOD generic-function-name

specialized-lambda-list

form*)

Métodos em CLOS

Ex.:(defmethod test ((x number) (y number)) '(num num))(defmethod test ((i integer) (y number)) '(int num)) (defmethod test ((x number) (j integer)) '(num int))

(test 1 1) => (int num), not (num int) (test 1 1/2) => (int num) (test 1/2 1) => (num int) (test 1/2 1/2) => (num num)

Combinação de Métodos

:before methods are all called before the primary

method, with the most specific :before method called first

:after methods are all called after the primary method,

with the most specific :after method called last. :around

methods run before the other methods. As with primary methods, only the most specific is called and call-next-method calls the next most specific

Combinação de Métodos - Ex.

(defclass food () ()) (defmethod cook :before ((f food)) (print "A food is about to be

cooked."))(defmethod cook :after ((f food)) (print "A food has been cooked."))

(defclass pie (food) ((filling :accessor pie-filling :initarg :filling :initform 'apple)))

(defmethod cook ((p pie)) (print "Cooking a pie.") (setf (pie-filling p) (list 'cooked (pie-filling p))))

(defmethod cook :before ((p pie)) (print "A pie is about to be cooked."))

(defmethod cook :after ((p pie)) (print "A pie has been cooked."))

(setq pie-1 (make-instance 'pie :filling 'apple))

Combinação de Métodos – Ex.

Saída> (cook pie-1) "A pie is about to be cooked." "A food is about to be cooked." "Cooking a pie.“ "A food has been cooked." "A pie has been cooked." (cooked apple)

Lisp & Common Lisp

Aplicações

Aplicações

Utilizado para desenvolver o primeiro sistema computacional de matématica simbólica, o MACSYMA.

Linguagem de extensão do software do AutoCAD, desenvolvido pela AutoDesk; e do editor de textos Emacs

Estudos de semântica formal das línguas naturais e de programação

Aplicações

Sistema de reserva de passagens Orbitz da ITA. Utilizado por diversas companhias aérias

A Simbolics criou um sistema de modelagem 3D, adquirido pela IZWare e renomeado para Mirai, que foi utilizado nos efeitos de Senhor dos Anéis

Sistema de e-commerce da viaweb (por Paul Graham) que posteriormente foi vendida para o Yahoo por US$ 40 milhões, na época da bolha da internet

Referências

Introdução à Linguagem Lisp http://www.inf.ufsc.br/~awangenh/Funcional/

Funcional.html http://www.gia.ist.utl.pt/Lisp9596/Lisp9596.html http://pt.wikipedia.org/wiki/Lisp

Common Lisp http://www.dca.ufrn.br/~adelardo/lisp/ http://pt.wikipedia.org/wiki/Common_Lisp

CLOS http://www.aiai.ed.ac.uk/~jeff/clos-guide.html

Lisp & Common Lisp

Dúvidas?

Recommended