Вызов функций по имени во время выполнения - PullRequest
1 голос
/ 08 февраля 2011

Я понимаю, что на функцию можно ссылаться с помощью # 'PRINT для ссылки на функцию PRINT. Если у нас есть список S, где первым элементом является «PRINT», можем ли мы ссылаться на него с помощью # (car S)?

Скажем, я смотрю на список, где элементы в списке - это атомы, которые являются названиями некоторых функций. В настоящее время я могу сделать это:

(defun aritheval (S)
    (funcall
        (cond
            ((eq '+ (car S)) #'+)
            ((eq '- (car S)) #'-)
            ((eq '* (car S)) #'*)
            ((eq '/ (car S)) #'/)
        )
        '2
        '3
    )
)

Эта функция будет вычислять 2 + 3, 2-3, 2 * 3 или 2/3 в зависимости от первого элемента в списке S. S содержит имена этих функций.

1 Ответ

6 голосов
/ 08 февраля 2011

# (машина S) не имеет смысла.Синтаксис существует, но означает вектор с символами CAR и S.

use

(funcall (first somelist) someargument)

или

(apply (first somelist) a-list-of-arguments)

Ваша функция не отформатирована.

Завершающие скобки не используются в правильном коде Lisp.Вам также не нужно указывать цифры.Числа самооценки, они оценивают для себя.Кроме того, теперь мы можем предпочесть ПЕРВОЕ, чем АВТО, и ОТДЫХ, а не CDR.Функции делают то же самое, но имена лучше.Всякий раз, когда мы имеем дело с простыми списками, используются FIRST, SECOND, THIRD, ... и REST.

(defun aritheval (S)
  (funcall (cond ((eq '+ (car S)) #'+)
                 ((eq '- (car S)) #'-)
                 ((eq '* (car S)) #'*)
                 ((eq '/ (car S)) #'/))
            2 3)))

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

Эта функция ниже делает то же самое, учитывая, что отображение символа на функцию одинаково.

(defun aritheval (s)
  (funcall (first s) 2 3)))
...