2008-11-17 10 views
9

Tengo una gran lista de variables globales que cada una tiene su propia función de configuración. Mi objetivo es revisar esta lista, llamar a la función de configuración de cada elemento y generar algunas estadísticas sobre los datos cargados en la variable correspondiente. Sin embargo, lo que estoy intentando ahora no funciona y necesito ayuda para que mi programa llame a las funciones de configuración.Nombres de funciones como cadenas en Lisp?

Las variables globales y sus funciones de configuración distinguen entre mayúsculas y minúsculas ya que provienen de XML y son necesarias para la exclusividad.

Los datos se ve algo como esto:

'(ABCD ABC\d AB\c\d ...) 

y las funciones de configuración de este aspecto:

(defun setup_ABCD... 
(defun setup_ABC\d... 

He intentado concatenar juntos y girando la cadena resultante en una función, pero esto interfiere con el espacio de nombres de la función de configuración previamente cargada. Así es como he tratado de poner en práctica lo siguiente:

(make-symbol (concatenate 'string "setup_" (symbol-name(first '(abc\d))))) 

Pero el uso de funcall en esto no funciona. ¿Cómo puedo obtener una función invocable de esto?

+0

Si la respuesta de Nowhere man funcionó, sería bueno marcarla como aceptada haciendo clic en el tic. – Pablo

+0

El estándar de nombre de Lisp es usar guiones, no guiones bajos. Además, el lector domina todos los símbolos internamente, y el estándar es escribirlos en minúsculas, por lo que la forma estándar de llamar a su función de configuración es 'setup-abcd'. – Svante

+0

¡Disculpa por el tic con retraso! También los fns de configuración fueron escritos por un non-lisper. Desde entonces le he prestado mi copia del libro Norvigs Lisp/AI. – ktdh

Respuesta

12

Es porque MAKE-SYMBOL devuelve un símbolo no identificado. Deberías usar INTERN en su lugar.

+0

BINGO! Esperaba que fuera así de simple, ¡muchas gracias! – ktdh

+0

Bueno, Chet, siguiente paso: acepta la respuesta. – Svante

+0

puede dar un ejemplo para cementar esto para mí, todavía estoy un poco confundido :( – ajivani

0

Utilizaría INTERN o (posiblemente, debería tener perfil para estar 100% seguro de que es útil) una función auxiliar que realiza la concatenación de cadenas y el hallazgo inicial, luego almacena el resultado en una tabla hash (clave fuera del símbolo original). Eso puede ser más rápido que una solución de INTERNO/CONCATENATO pura, potencialmente generaría menos basura transitoria, pero probablemente terminaría usando más almacenamiento a largo plazo.

Algo a lo largo de las líneas de:

 
(defvar *symbol-function-map* (make-hash-table)) 

(defun lookup-symbol (symbol) 
    (or (gethash symbol *symbol-function-map*) 
     (let ((function-name (intern (concatenate 'string "setup_" (symbol-name symbol))))) 
     (setf (gethash symbol *symbol-function-map*) (symbol-function function-name))))) 

Si necesita el nombre de la función, en lugar de la propia función, dejar de lado la llamada a symbol-function.

0
(funcall (read-from-string (concatenate 'string "setup_" (symbol-name(first '(abc\d)))))) 

funciona también.

Cuestiones relacionadas