En Lisp(Clojure, Emacs Lisp), ¿cuál es la diferencia entre listar y cotizar?
elisp quote (3)
Después de leer material introductorio sobre Lisp, ahora considero que lo siguiente es idéntico:
(list 1 2 3)
''(1 2 3)
Sin embargo, a juzgar por los problemas que enfrento al usar la forma citada tanto en Clojure como en Emacs Lisp, no son lo mismo. ¿Puedes decirme cuál es la diferencia?
En Common Lisp, los objetos citados son datos literales constantes. No debe modificar estos datos, ya que las consecuencias no están definidas. Las posibles consecuencias son: la modificación de los datos compartidos, el intento de modificar los datos de solo lectura, un error podría ser señalado, podría funcionar, ...
Para listas:
''(1 2 3)
Arriba hay una lista constante, que será construida por el lector y evaluándose a sí misma, porque está citada. Si aparece en el código Lisp, un compilador incrustará estos datos de alguna manera en el código FASL.
(quote (1 2 3))
es otra forma de escribirlo.
(list 1 2 3)
esta es una llamada de la función Common Lisp LIST
con tres argumentos 1
, 2
y 3
. Cuando se evalúa, el resultado es una nueva lista nueva (1 2 3)
.
Similar:
''(1 . 2) and (cons 1 2)
''#(1 2 3) and (vector 1 2 3)
Uno es los datos literales y el otro es una llamada a la función que construye dicha estructura de datos.
La principal diferencia es que la quote
impide la evaluación de los elementos, mientras que la list
no:
user=> ''(1 2 (+ 1 2)) (1 2 (+ 1 2)) user=> (list 1 2 (+ 1 2)) (1 2 3)
Por esta razón (entre otras), es un error idiomático utilizar un vector al describir una colección literal:
user=> [1 2 (+ 1 2)] [1 2 3]
Las listas citadas (por ejemplo, ''(1 2 3)
] deben tratarse con cuidado (generalmente como de solo lectura). (vea las respuestas de SO cuando usar ''cita en Lisp y cuándo usar'' cita en Lisp ).
(list 1 2 3)
hará "contras" en una lista nueva, independiente de todas las demás.
Puede ver un ejemplo de una trampa en el uso de listas citadas en el manual de nconc
.
Y, como probablemente sepa, cuando llame a ''list
: los argumentos obviamente se evaluarán frente al contenido de una lista citada. Y ''quote
toma un solo argumento, versus ''list
el número variable de argumentos de la lista.
(list (+ 1 2) 3) --> (3 3)
(quote ((+ 1 2) 3)) --> ((+ 1 2) 3)