lisp - ¿Por qué Clojure tiene "palabras clave" además de "símbolos"?
scheme keyword (5)
Aquí está la documentación de Clojure para palabras clave y símbolos.
Las palabras clave son identificadores simbólicos que se evalúan a sí mismos. Proporcionan pruebas de igualdad muy rápidas ...
Los símbolos son identificadores que normalmente se utilizan para referirse a otra cosa. Se pueden usar en formularios de programa para referirse a parámetros de funciones, dejar enlaces, nombres de clases y variables globales ...
Las palabras clave se usan generalmente como "cadenas constantes" livianas, por ejemplo, para las claves de un hash-map o los valores de envío de un multimétodo. Los símbolos se usan generalmente para nombrar variables y funciones, y es menos común manipularlos como objetos directamente, excepto en macros y demás. Pero no hay nada que te impida usar un símbolo en cualquier lugar donde uses una palabra clave (si no te importa citarlos todo el tiempo).
La forma más fácil de ver la diferencia es leer Keyword.java
y Symbol.java
en la fuente de Clojure. Hay algunas diferencias de implementación obvias. Por ejemplo, un Símbolo en Clojure puede tener metadatos y una Palabra clave no puede.
Además de la sintaxis de un solo punto, puede usar dos puntos para crear una palabra clave calificada para el espacio de nombres.
user> :foo
:foo
user> ::foo
:user/foo
Common Lisp tiene palabras clave, al igual que Ruby y otros idiomas. Son ligeramente diferentes en esos idiomas, por supuesto. Algunas diferencias entre las palabras clave Common Lisp y las palabras clave Clojure:
Las palabras clave en Clojure no son símbolos.
user> (symbol? :foo) false
Las palabras clave no pertenecen a ningún espacio de nombres a menos que los califique específicamente:
user> (namespace :foo) nil user> (namespace ::foo) "user"
(Gracias Rainer Joswig por darme ideas de cosas para mirar).
Tengo un conocimiento pasajero de otros Lisps (especialmente Scheme) desde hace mucho tiempo. Recientemente he estado leyendo sobre Clojure . Veo que tiene tanto "símbolos" como "palabras clave". Símbolos con los que estoy familiarizado, pero no con palabras clave.
¿Tienen otros Lisp palabras clave? ¿En qué se diferencian las palabras clave de los símbolos, además de tener una notación diferente (es decir, dos puntos)?
Las palabras clave son símbolos que se evalúan a sí mismos, por lo que no tiene que recordar citarlos.
Las palabras clave también son tratadas especialmente por muchas de las colecciones, lo que permite una sintaxis muy conveniente.
(:user-id (get-users-map))
es lo mismo que
((get-users-map) :user-id)
esto hace las cosas un poco más flexibles
Para las palabras clave, los valores hash se calculan y almacenan en caché cuando se crea la palabra clave por primera vez. Al buscar una palabra clave como una clave hash, simplemente devuelve el valor hash precalculado. Para cadenas y símbolos, el hash se vuelve a calcular en cada búsqueda.
La razón por la cual las mismas palabras clave siempre son idénticas, contienen sus propios valores hash. Como la búsqueda en mapas y conjuntos se realiza a partir de claves hash, esto implica una mejor eficacia de búsqueda en caso de numerosas búsquedas, no en la búsqueda en sí.
Common Lisp tiene símbolos de palabras clave.
Las palabras clave son símbolos, también.
(symbolp '':foo) -> T
Qué hace que las palabras clave sean especiales:
- : foo es analizado por el lector de Common Lisp como la palabra clave de símbolo :: foo
- palabras clave evaluar a sí mismos:: foo ->: foo
- el paquete principal de símbolos de palabras clave es el paquete KEYWORD: palabra clave: foo ->: foo
- las palabras clave se exportan desde el paquete KEYWORD
- las palabras clave son constantes, no está permitido asignar un valor diferente
De lo contrario, las palabras clave son símbolos ordinarios. Por lo tanto, las palabras clave pueden nombrar funciones o tener listas de propiedades.
Recuerde: en Common Lisp los símbolos pertenecen a un paquete. Esto se puede escribir como:
- foo, cuando el símbolo es accesible en el paquete actual
- foo: bar, cuando el símbolo FOO se exporta desde el paquete BAR
- foo :: bar, cuando el símbolo FOO está en el paquete BAR
Para los símbolos de palabras clave eso significa que: foo, palabra clave: foo y palabra clave :: foo son todos el mismo símbolo. Por lo tanto, las dos últimas notaciones generalmente no se usan.
Por lo tanto: foo simplemente se analiza para que esté en el paquete KEYWORD, suponiendo que no dar el nombre del paquete antes del nombre del símbolo significa por defecto el paquete KEYWORD.