Имена функций как строки в Лиспе? - PullRequest
9 голосов
/ 17 ноября 2008

У меня есть большой список глобальных переменных, каждая из которых имеет свою собственную функцию установки. Моя цель - просмотреть этот список, вызвать функцию настройки каждого элемента и сгенерировать некоторую статистику для данных, загруженных в соответствующую переменную. Однако то, что я сейчас пытаюсь, не работает, и мне нужна помощь, чтобы моя программа вызывала функции настройки.

Глобальные переменные и их функции настройки чувствительны к регистру, поскольку они получены из XML и необходимы для уникальности.

Данные выглядят примерно так:

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

и функции настройки выглядят так:

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

Я пытался объединить их вместе и превратить полученную строку в функцию, но это мешает пространству имен ранее загруженной функции установки. Вот как я пытался это реализовать:

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

Но использование funcall на этом не работает. Как я могу получить вызываемую функцию из этого?

Ответы [ 3 ]

12 голосов
/ 17 ноября 2008

Это потому, что MAKE-SYMBOL возвращает неустранимый символ. Вместо этого вы должны использовать INTERN.

0 голосов
/ 22 июля 2011
(funcall (read-from-string (concatenate 'string "setup_" (symbol-name(first '(abc\d))))))  

тоже работает.

0 голосов
/ 17 ноября 2008

Я бы либо использовал INTERN или (возможно, вам нужно было бы профилировать, чтобы быть на 100% уверенным, что это полезно) вспомогательную функцию, которая выполняет конкатенацию строк и первоначальный поиск, а затем кэширует результат в хеш-таблице (отключенной). оригинальный символ). Это может быть быстрее, чем чистое решение INTERN / CONCATENATE, потенциально генерировать меньше временного мусора, но, вероятно, в конечном итоге будет использовать более длительное хранилище.

Что-то вроде:

(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)))))

Если вам требуется имя функции, а не сама функция, пропустите вызов SYMBOL-FUNCTION.

...