¿Hay alguna función en Common Lisp que tome una cadena como argumento y devuelva una palabra clave?Palabra clave programática Common Lisp
Ejemplo: (keyword "foo")
->:foo
¿Hay alguna función en Common Lisp que tome una cadena como argumento y devuelva una palabra clave?Palabra clave programática Common Lisp
Ejemplo: (keyword "foo")
->:foo
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")))
(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.
El nombre tiene que ser internados en el paquete "PALABRA CLAVE" a ser una palabra clave. por ejemplo, (interno "FOO" "KEYWORD") –
ah sí. El (interno "foo" "KEYWORD") funciona bastante bien. Gracias. – nathan
En mi respuesta, lo he empaquetado en una pequeña función ordenada, que puede disfrutar. :-) –
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")))
Podría ser, por supuesto, que OP acabara de tener la caja de impresión configurada en': downcase' ... –
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.
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'.) –
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)))
¿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. –
Casi, pero no del todo. Cuando crea una palabra clave, también debe asegurarse de establecer su enlace de valor a sí mismo. – Vatine
@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. –
@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. ** "* –