2011-09-11 9 views
14

¿Hay alguna ventaja a la definición de una función como (defun hi() "Hi!") y ser capaz de llamar usando (hi) o (HI) o (Hi), o para (setf a-number 5) y ser capaz de acceder a ese número mediante a-number, A-NUMBER, o A-Number?¿Por qué Common Blip es insensible?

Si existe tal ventaja, ¿por qué la mayoría de los otros idiomas distingue entre mayúsculas y minúsculas?

Respuesta

26

Usar mayúsculas y minúsculas en el código dentro de una sesión interactiva es simplemente más propenso a errores.

Common Lisp distingue entre mayúsculas y minúsculas. Es solo que la funcionalidad del lector de Common Lisp convierte de manera predeterminada todos los caracteres de caracteres sin escindir en mayúsculas. Esto también se define en el estándar Common Lisp. Los símbolos predefinidos de Common Lisp también son mayúsculas internamente.

El uso de mayúsculas era común en las máquinas antiguas. Recuerde, el diseño de Common Lisp comenzó a principios de los años ochenta (1982) y un objetivo era la compatibilidad con Maclisp anterior y cuando había más tipos de computadoras para admitir (como los llamados Mini Computers y Mainframes). Otros lenguajes de programación utilizados en computadoras más antiguas también usan identificadores en mayúsculas, como COBOL o PL/1.

También tenga en cuenta que Lisp a menudo se usa de forma interactiva, por lo que durante una sesión de programación interactiva obtener el caso de los nombres correctos es más difícil. Es un poco más fácil cuando el lector Lisp utiliza un caso predeterminado (aquí en mayúsculas) y convierte todas las entradas en este caso.

Common Lisp admite otros modos de lector y también puede escapar de los símbolos: |This is a Symbol with mixed CASE and spaces|.

Hoy en día, una gran cantidad de software es en minúsculas o incluso mayúsculas y minúsculas preferido. Algunos proveedores de Lisp proporcionan una variante no estándar de Common Lisp, donde todos los símbolos por defecto son minúsculos y el lector preserva el caso. Pero esto lo hace incompatible con Common Lisp estándar, donde la expectativa es que (symbol-name 'cl:defun) esté "DEFUN" y no "defun".

3

De forma predeterminada, el lector en CL está convirtiendo mayúsculas y minúsculas, todos los caracteres escapados se convierten en mayúsculas. Puede personalizar este comportamiento con readtable-case. Esto se debe a que es fácil interactuar con otros lenguajes que siguen las mismas convenciones.

+0

Hm, ¿Con qué idiomas se relaciona CL? – wrongusername

+2

En ese momento? Probablemente Fortran. Recuerde que Common Lisp y sus predecesores fueron diseñados hace mucho tiempo en una galaxia muy, muy lejana. –

+3

No fue especialmente Fortran, era que a menudo el härdware (el Teletipo) estaba en mayúscula y el SO estaba usando mayúsculas. Así, los lenguajes de programación también usaron mayúsculas: PL/1, Cobol, Fortran, Lisp, ... Fue un poco doloroso editar comandos sensibles a mayúsculas y minúsculas en un terminal conectado a través de conexiones lentas en modos de edición de línea, ... –

8

(Como otros han señalado, en realidad es mayúsculas y minúsculas, pero el comportamiento estándar de lector es upcase todo.)

En cuanto a las ventajas:

  • Está seguro de querer Hashtable y HashTable para nombrar cosas diferentes?
  • Dado que Common Lisp proporciona diferentes espacios de nombres, tampoco necesita mayúsculas para distinguir los nombres de clases, variables y funciones (entre otros). Puede tener una clase name y una función name sin ambigüedad. Name incluso puede ser el nombre de una variable, además de eso.
  • Como se ve en la última oración, puede poner en mayúscula los nombres de los símbolos en prosa como cualquier otra palabra.
+1

¡Buenos puntos! Pero si 'Hashtable' y' HashTable' apuntan inequívocamente a lo mismo, ¿no debería 'name' apuntar inequívocamente a una función, clase o variable? – wrongusername

+3

@wrongusername: no es ambiguo. Cuando tiene un formulario evaluado '(nombre foo)', es inequívocamente una función 'nombre'; cuando tienes '(defmethod bar ((nombre baz)) ...)', es inequívocamente un 'nombre' de clase (o más bien tipo ...); cuando ve una forma evaluada '(nombre de quux)', es inequívocamente una variable. Es lo mismo que puedes usar "nombre" como verbo y sustantivo en inglés sin confusión. – Svante

+0

Eso tiene sentido. Gracias Svante! – wrongusername

12

Para sesiones interactivas, la falta de sensibilidad de mayúsculas solía ser la predeterminada cuando se definió el estándar Common Lisp.

Pero, lo que realmente sucede es que el lector de Common Lisp convierte todos los símbolos en upcase antes de internarlos y evaluarlos. Ese es el valor predeterminado, pero siempre puede cambiarlo si lo desea.

Objetos *readtable* tiene un atributo, readtable-case, que controla cómo el lector interna y evalúa los símbolos leídos. puede setf readtable-case a :upcase (predeterminado), :downcase, :preserve, :invert.

De forma predeterminada, el readtable-case se establece en :upcase, lo que hace que todos los símbolos se conviertan en upcase.

Si desea mayúsculas y minúsculas, que debe hacer

(setf (readtable-case *readtable*) :invert) 
=> :invert 

A primera vista, se podría pensar que sería mejor elegir la opción: conservar, pero tiene algún problema de menor importancia: todos los símbolos , tal como se define en la norma, debe estar al revés. Por lo tanto, tendría mayúsculas y minúsculas a los símbolos definidos por sólo usted, y que tendría que hacer escritura:

* (DEFUN hi() "Hi!") 
=> hi 
* (SETF a-number 5) 
=> a-number 
* (HI) 
=> ;error: the stored function is #'HI in the *readtable*, but by 
    ;  calling (HI) you try to acces a function named #'hi(downcase), which 
    ;  gives an error 
* A-NUMBER 
=> ;error: same for the variable 
* (hi) 
=> "Hi!" 
* a-number 
=> 5 

La opción :downcase es lo contrario de la opción predeterminada, la conversión de todo para downcase, que le da ninguna sensibilidad caso.

Pero con :invert, los símbolos se escriben en el código fuente, como defun, setf la función hi, se convierten a upcase, y cualquier símbolo en CamelCase se conserva como es originalmente:

* (setf (readtable-case *readtable*) :invert) 
=> :invert 
* (defun Hi() "Hi!") 
=> Hi 
* (Hi) 
=> "Hi!" 
* (eq 'Hi 'hi) 
=> nil 
* (eq 'HI 'hi) 
=> nil 
* (eq 'Hi 'Hi) 
=> t 
+1

[Este] (http://www.cliki.net/case%20sensitivity) aclara todo un poco más. '(setf (readtable-case * readtable *): invert)' invierte todas las letras mayúsculas a minúsculas y todas mayúsculas a minúsculas porque todas las funciones originales están escritas en mayúsculas por defecto. – William

Cuestiones relacionadas