portacle instalar LISP localmente
https://en.wikipedia.org/wiki/History_of_programming_languages
Entre pareteses, heterogenea, separa por brancos
(5 6 9.8e-3 abobora ())
abobora
é um simbolo/atomo, como em prolog.
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))
setf
é atribuiçãoif
é como no haskel, retorna um valorDefinindo funções
(defun soma (a b)
(+ a b)
)
cons
gruda na frente de uma lista (:
do haskell)
car
first
a cabeça da lista
cdr
rest
o resto da lista
null
testa se a lista é vazia
NIL
ou ()
lista vazia
append
gruda 2 ou mais listas
list
cria uma lista de seus argumentos
progn
mais de um comando (braces)
eq
eql
equal
equalp
=
testes de igualdade https://eli.thegreenplace.net/2004/08/08/equality-in-lisp
igualdades rapidas/atomicas O(1) eq
eql
=
e igualdades lógicas O(n) listas, etc
há o problema do caso infinito para igualdades lógicas
class X
pass
a = X()
a.nome = "jose"
a.dado = a
b = X()
b.nome = "jose"
b.dado = b
a==b
(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))
))
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.
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.
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.
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 f1
esta. 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.