2009-10-06 15 views
111

Tengo un conocimiento pasajero de otros Lisps (especialmente Scheme) de mucho tiempo atrás. 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.¿Por qué Clojure tiene "palabras clave" además de "símbolos"?

¿Hay otros Lisp que tengan 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)?

+0

Ver también: [en Clojure, ¿por qué tienen cadenas, palabras clave y símbolos?] (Http://stackoverflow.com/q/11655080/405550) – Zaz

Respuesta

119

Aquí está el Clojure documentation 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 hacer referencia a parámetros de funciones, dejar enlaces, nombres de clases y variables globales ...

Las palabras clave se utilizan generalmente como "cadenas constantes" livianas, p. 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 manera más fácil de ver la diferencia es leer Keyword.java y Symbol.java en la fuente 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 como espacio de nombre.

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 de Common Lisp y Clojure:

  1. Las palabras clave en Clojure no son Símbolos.

    user> (symbol? :foo) 
    false 
    
  2. Palabras clave no pertenecen a ningún espacio de nombres a menos que califique de manera específica: (. Gracias Rainer Joswig por darme ideas de cosas para mirar)

    user> (namespace :foo) 
    nil 
    user> (namespace ::foo) 
    "user" 
    

+9

Esto explica _qué_ son las diferencias, pero no por qué se necesitan dos construcciones diferentes. ¿No pudo Clojure haber creado algo con la unión de las capacidades de Palabra clave y Símbolo? – mtnygard

+20

Las palabras clave son livianas y tienen una sintaxis conveniente, creo que eso es todo lo que hay que hacer. El lenguaje funcionaría bien sin ellos, pero son agradables de tener y son muy utilizados. No puede tener una unión de sus habilidades porque las palabras clave son siempre autoevaluativas (es decir, no puede usarlas como nombres de variables o funciones) y los símbolos en general no siempre se pueden autoevaluar. –

+1

Parece que las palabras clave son más útiles como claves en hashmaps, etc. ya que no cambian una vez evaluadas: '(eval (eval ': a))' vs '(eval (eval' 'a))'. ¿Hay otras ventajas? En cuanto al rendimiento, ¿son idénticos? – kristianlm

5

Las palabras clave son símbolos que se evalúan a sí mismos, por lo que no tiene que recordar citarlos.

+5

¿Eso es todo? Escribir: en lugar de 'no parece una gran ganancia, especialmente porque: es una pulsación de tecla adicional en la mayoría de los teclados. –

+8

Bueno, es más que solo el personaje, realmente. Las palabras clave siguen siendo palabras clave después de la evaluación, mientras que los símbolos se evalúan a lo que sea que se vinculen. Es más como una diferencia semántica, ya que normalmente se utilizan para diferentes propósitos. –

+12

Las palabras clave no son símbolos en Clojure –

26

Common Lisp tiene símbolos de palabra clave.

Las palabras clave son símbolos, también.

(symbolp ':foo) -> T 

Lo que hace especiales palabras clave:

  • : foo es analizada por el lector de Common Lisp como símbolo de la palabra clave :: foo
  • palabras clave se evalúan a sí mismos: foo: ->: foo
  • el paquete principal de símbolos de palabras clave es el paquete KEYWORD: palabra clave: foo ->: foo
  • palabras clave se exportan desde el paquete KEYWORD
  • palabras clave son constantes, no está permitido asignar un valor diferente

De lo contrario, las palabras clave son símbolos normales. 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 la barra de paquete
  • foo :: bar, cuando el El símbolo FOO está en el paquete BAR

Para los símbolos de palabras clave que 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.

Así que: foo se acaba de analizar 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.

2

: 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 Flexable

+19

Esto también es cierto para los símbolos, ('a {' a 1 'b 2}) => 1 y ({' a 1 'b 2}' b) => 2. – Jonas

3

Para las palabras clave, los valores hash se calculan y almacenan en caché cuando la palabra clave es primera construida. Al buscar una palabra clave como una clave hash, simplemente devuelve el valor hash precalculado. Para cadenas y símbolos, el hash es recalculado en cada búsqueda.

La razón por la cual las mismas palabras clave son siempre 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í.

Cuestiones relacionadas