2008-10-17 15 views

Respuesta

31

Aquí hay una función make-keyword que empaqueta el proceso de creación de palabras clave (intern ing de un nombre en el paquete KEYWORD). :-)

(defun make-keyword (name) (values (intern name "KEYWORD"))) 
+0

Casi, pero no del todo. Cuando crea una palabra clave, también debe asegurarse de establecer su enlace de valor a sí mismo. – Vatine

+0

@Vatine Solo tengo SBCL para probar, y en SBCL, '(symbol-value (intern" FOO "" KEYWORD ")' ya tiene el valor correcto. Además, Alexandria lo implementa usando el mismo enfoque también. –

+9

@Vatine [11.1.2.3.1 Interning a Symbol en el paquete KEYWORD] (http://www.lispworks.com/documentation/HyperSpec/Body/11_abca.htm) dice (énfasis agregado), * "El paquete KEYWORD es se trata de manera diferente a otros paquetes en el sentido de que se toman acciones especiales cuando se interpone un símbolo. En particular, cuando un símbolo se interna en el paquete KEYWORD, se convierte automáticamente en un símbolo externo y ** se convierte automáticamente en un variable constante consigo misma como valor. ** "* –

-5
(intern "foo" "KEYWORD") -> :foo 

Véase el Strings section del Common Lisp Cookbook para otras conversiones cadena/de símbolos y una discusión detallada de los símbolos y los paquetes.

+3

El nombre tiene que ser internados en el paquete "PALABRA CLAVE" a ser una palabra clave. por ejemplo, (interno "FOO" "KEYWORD") –

+0

ah sí. El (interno "foo" "KEYWORD") funciona bastante bien. Gracias. – nathan

+0

En mi respuesta, lo he empaquetado en una pequeña función ordenada, que puede disfrutar. :-) –

35

Las respuestas dadas al tiempo que más o menos correcta, no producen una solución correcta a la pregunta de ejemplo.

considerar:

CL-USER(4): (intern "foo" :keyword) 

:|foo| 
NIL 
CL-USER(5): (eq * :foo) 

NIL 

Por lo general, desea aplicar CADENA-upcase a la cadena antes de la internación que, por lo tanto:

(defun make-keyword (name) (values (intern (string-upcase name) "KEYWORD"))) 
+1

Podría ser, por supuesto, que OP acabara de tener la caja de impresión configurada en': downcase' ... –

2

hay una función make-keyword en la biblioteca Alexandria, aunque sí preservar el estuche para obtener exactamente lo que desea, primero tendrá que guardar la cadena.

+0

O configure 'print-case' en': downcase'. 'intern' no hace ninguna modificación de caso, por lo que la solución aquí probablemente tampoco debería. (Aunque el ejemplo en la pregunta dice '(palabra clave" foo ") =>: foo', probablemente sea mejor tener' (... "foo") =>: | foo | 'o' (... " FOO ") =>: FOO'.) –

1

En este ejemplo también se ocupa de las cadenas con espacios (sustituyéndolos por puntos):

(defun make-keyword (name) (values (intern (substitute #\. #\space (string-upcase name)) :keyword))) 
+1

¿Hay algún motivo por el que desee reemplazar espacios con puntos? Si internan '" foo bar "' obtienes un símbolo con el nombre '" foo bar "', y no hay problema con eso. 'intern' tampoco reemplaza los espacios con puntos. –