¿Comprender el lenguaje elisp (valores booleanos frente a argumentos citados)?


7

Tengo algunas preguntas básicas sobre elisp.

A menudo veo algo como

(search-forward "something" nil 'noerror)

Y a veces veo algo como

(search-forward "something" nil :noerror)

¿Cuál es la diferencia y debería preferir una forma sobre la otra?

Hasta donde yo entiendo todo menos la lista vacía se evalúa como verdadera en un contexto booleano. Pero, ¿cómo viene lo siguiente?

Cuando el término de búsqueda "algo" no existe en el búfer, el punto salta al final del búfer cuando 'noerrorse usa en lugar de t. Cuando tse usa, el punto permanece donde está.

Primer caso:

(search-forward "something" nil 'noerror);; 1.Evaluate this

;; end of buffer 2.point jumps here

Segundo caso:

(search-forward "something" nil t);; 1.Evaluate this, 2. Point stays here

;; end of buffer

1
FWIW: Cuando todos los no nilvalores 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.
Dibujó

Respuestas:


12

Los valores booleanos en elisp funcionan de la siguiente manera:

  • nily ()(que, como has observado, son lo mismo) son falsas
  • Absolutamente cualquier otra cosa es verdad.

El tsímbolo existe como un valor 'puro' de verdadero (cuando no hay ningún beneficio al usar otro valor), pero la mayoría de las funciones tratarán de devolver algo que de otro modo podría ser útil, siempre que sea posible.

Ver también C-hig (elisp) nil and t RET

Cuando se trata de usar argumentos de palabras clave u otros símbolos como un no nilvalor cuando el código solo se preocupa nilo no nil, en realidad es solo una cuestión de preferencia personal. No hay diferencia en términos de ejecución.

Una vez pregunté lo mismo y me informaron que el enfoque del argumento de palabras clave es un método más común de Lisp-ish.

(Me decidí a usar argumentos de palabras clave yo mismo, en parte para el resaltado de sintaxis y en parte porque los diferencia mejor de los símbolos de variables y funciones).

En cuanto a su ejemplo específico, la función hace diferenciar entre las distintas no nillos valores, y que el comportamiento está cubierto por su cadena de documentación:

El tercer argumento opcional, if t, significa que si falla, simplemente regrese nil(sin error). Si no niles así t, muévase al límite de búsqueda y regrese nil.

En general, notará que las cadenas de documentos tienden a referirse a "no nulo" en lugar de "verdadero" o "t". Si ve "t", entonces hay una buena posibilidad de que sea un caso especial.


Gracias, eso me lo aclaró! Entonces, todo menos nulo es cierto, pero t como "puro" es diferente de eso.
clemera

2
Bueno, sigue siendo solo un símbolo (aunque sea uno entre comillas, como niles). Por "puro" quiero decir que existe específicamente para ser un valor que significa "verdadero", porque a veces eso es lo que quieres. Sin nilembargo, otros no valores siguen siendo tan "verdaderos" como lo tson.
phils

14

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:aproposes 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: ty nilson 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-forwardcon 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, niles 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-offunción da resultados confusos para ty 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-typepque, sin embargo, podría ayudar a comprender la relación. Así por ejemplo

(cl-typep 'noerror t) ; t

es decir, lo 'noerrorque sea es de tipo t.


Información de fondo adicional interesante, gracias!
clemera

Maravillosa explicación. También aprendí algo sobre Common Lisp. Gracias.
gsl
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.