Aula 22 LISP

Historia de (algumas) linguagens de programação

https://en.wikipedia.org/wiki/History_of_programming_languages

Listas

Entre pareteses, heterogenea, separa por brancos

(5  6 9.8e-3 abobora ())

abobora é um simbolo/atomo, como em prolog.

comandos e operadores

numa lista, sempre o comando ou operador é o primeiro elemento da lista

  (if teste then else)
  
  (setf x 4)
  
  (+ x (* 3 4))

  (if (> x (+ 6 5)) 
      (setf x (+ x 1)) 
      (print x))

Definindo funções

(defun soma (a b) 
    (+ a b)
    )

Listas e outros comandos

class X
 pass
 
a = X()
a.nome = "jose" 
a.dado = a

b = X()
b.nome = "jose" 
b.dado = b

a==b

Exemplos

(defun reverte (lista)
    (if (null lista) NIL
        (append (reverte (rest lista)) (list (head lista)))
        ))
(defun revacc (lista acc)
    (if (null lista) acc
        (revacc (rest lista) (cons (head lista) acc))
        ))

Quote - desligando o avaliador

Como criar a lista (if (< a b) 3 4)

(list if (list < a b) 3 4)

nao funciona porque o list como toda funçao avalia seus argumentos. Qual é o valor da variavel if? E das variáveis <, a e b?

O que voce quer é desligar o avaliador, para que o list de fora use o símbolo if sem avalia-lo.

O quote ' faz isso

(list 'if (list '< 'a 'b) 3 4)

nao precisa colocar o quote no 3 e no 4 pois a avaliaçao do 3 é o proprio 3.

Isso vai gerar um lista que é um programa/expressão em Lisp, sintaticamente correta e que pode ou nao rodar/ser avaliada, se a e b tem valor no momento de execução.

Diferença de função e comando (special form)

Em outras linguagens de programação uma diferença é a sintaxe

 if (a<b) then a else b 

 if(a<b,a,b)
 

mas em lisp nao há diferença sintática

     (if (> a b) a b)
          
     (func (> a b) a b)

A diferença central é que funções sempre avaliam seus argumentos e comandos podem nao avaliar todos

(if (> a b) a (/ 1 0))

ok - se a > b. (/ 1 0) não é avaliado e nao da problema. Se fosse uma funçao (que avalia seus argumentos antes de rodar) isso daria problema.

Criando novos comandos

defmacro não avalia nenhum dos seus argumentos, monta uma lista e avalia/executa ela.

(defmacro when1 (teste &rest corpo)
    (list 'if teste (cons 'progn corpo))
    )
    
(macroexpand '(when (eq 1 b) (print b) (setf b (+ 1 b))))

==> (IF (EQ 1 B) (PROGN (PRINT B) (SETF B (+ 1 B)))) 

curiosamente macroexpand é uma função e dai o “novo programa” esta em quote.

Esse foi um exemplo simples de macro. a macro é um programa (em lisp) que pode processar os varios argumentos (que sao expressoes em lisp e portanto listas) e montar uma expressão/lista complexa, que é então executada.

Static & Dynamic scope

variavies livres em funções.

(setf x 8)
(defun f1 (a) (+ x a))
   
(let ((x 100)) 
        (f1 4))
        
==> 12

em python

x = 8
def f1 (a):
    return x+a
    
def f2():
    x = 100
    f1(4)

f2()
==> 12

que é o comum em outras linguagens de programação. A variavel “livre” x de f1 vem do contexto sintatico onde a definição de f1esta. Nesse caso a variavel global.

Isto é o escopoestatico

(defvar x 8)
(defun f1 (a) 
    (+ x a))

(let ((x 100)) (f1 4))

==> 104

no segundo caso, o escopo de x é dinamico, e o valor usado será o último disponível na pilha de execuçao.