Alguna referencia histórica es debida.
Emacs Lisp toma muchas cosas de Common Lisp, pero la similitud solo es superficial. El símbolo de dos puntos en Common Lisp es un calificador de espacio de nombres. Los nombres de símbolos canónicos tienen dos partes: el nombre del paquete y el nombre del símbolo en ese paquete, por lo que, por ejemplo, cl-user:apropos
es un símbolo definido en el paquete cl-user
. También hay un paquete especial de palabras clave importado automáticamente por Common Lisp cuando se inicia. Este paquete se usa para comunicarse entre otros paquetes (de modo que si los paquetes necesitan enviarse información simbólica entre sí, no se pelearán por quién tiene que declararlo). Como habrás adivinado, los símbolos en ese paquete están escritos con los dos puntos iniciales.
Emacs Lisp no tiene un concepto de paquetes, pero los dos puntos siguen siendo especiales porque le indica al lector que interprete la expresión como símbolo de autoevaluación (es decir, es una variable cuyo valor es esa variable en sí misma). Hay varios símbolos incorporados de autoevaluación: t
y nil
son ejemplos sobre los que escribiré más adelante.
El apóstrofe también se toma prestado de Common Lisp, donde es una macro de lector estándar (es decir, es un código que el intérprete de Lisp ejecuta mientras lee en la fuente del programa). Se expande de la siguiente manera:, 'x -> (quote x)
donde (quote ...)
hay una forma especial que impide que el intérprete de Lisp evalúe el contenido de la expresión en su interior. Emacs Lisp tiene tres armarios macros lector: '
, `
y #
, pero no se puede añadir su propia. Los dos primeros se expanden a (quote ...)
, sin embargo, el segundo permite una sintaxis especial para construir la expresión no evaluada. #
se expande para (function ...)
formar, lo que le indica al intérprete que el valor debe buscarse en el espacio de nombres de la función.
Los símbolos en Emacs Lisp deben evaluarse hasta cierto valor (similar a las variables en otros idiomas) de lo contrario es un error. Sin embargo, puede evitar la evaluación utilizando el formulario de cotización.
Finalmente, la diferencia entre:
(search-forward "something" nil 'noerror)
y
(search-forward "something" nil :noerror)
Es que en el primer caso llamó search-forward
con un símbolo sin valor, para el cual solo se conoce el nombre, y en el segundo caso llamó a esta función con un símbolo cuyo valor es este símbolo en sí. Sucede que a esta función no le importa cuál use.
Los tipos son una herramienta de programación importante para la verificación automática de programas. El sistema de tipos Emacs Lisp es similar a Common Lisp en que su tipo universal (escrito como t
) es el tipo del que se derivan todos los demás tipos. Por otro lado, nil
es el tipo del que no se deriva ningún tipo (el complemento de t
). Esto es diferente a muchos lenguajes de programación populares, que pueden no tener un concepto de tipo universal, o tener un tipo booleano distinto.
Una vez más, desafortunadamente, Emacs Lisp no copió esta parte precisamente de Common Lisp, y la type-of
función da resultados confusos para t
y nil
.
Emacs Lisp:
(type-of t) ; symbol
Lisp común
(type-of t) ; BOOLEAN
La extensión común de Lisp de Emacs Lisp tiene una función cl-typep
que, sin embargo, podría ayudar a comprender la relación. Así por ejemplo
(cl-typep 'noerror t) ; t
es decir, lo 'noerror
que sea es de tipo t
.
nil
valores son tratados de la misma manera por la función dada, en mi código paso un símbolo con el mismo nombre o similar al nombre del parámetro utilizado en la descripción de la función, y generalmente en mayúscula. Esto me sirve de recordatorio cuando leo el código. Por ej(search-forward "abc" nil 'NOERROR)
. Es más útil para argumentos opcionales que rara vez se utilizan.