Как вызвать конкретную функцию в зависимости от переданной переменной?

Я новичок, чтобы шепелявить, но я играл с этим. У меня есть несколько проблем, которые мне нужно прояснить. Ниже мой небольшой макрос, который я определил.

(defmacro transform (query)
 '(lambda (row)
   (eq (nth 1 query) (nth 0 (nth 0 row)))
  )
)

Мне просто интересно, как я могу указать функцию для динамического использования в теле? Скажите, хочу ли я использовать функцию «+» или «-» вместо «eq» или даже другую функцию, которую я определил? Как я и думал, можно передать имя функции в качестве параметра, но это явно не работает. Я также получаю переменные несвязанные ошибки при изменении переданного списка (запроса).


person John Jiang    schedule 01.09.2009    source источник
comment
ты хоть представляешь, почему это должен быть макрос, а не функция?   -  person Rainer Joswig    schedule 01.09.2009
comment
Я снова превратил его в функцию, и, похоже, он работает нормально.   -  person John Jiang    schedule 01.09.2009


Ответы (2)


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

(defmacro transform (query &key (test 'eq))
   (let ((row-var (gensym)))
     `(lambda (,row-var) 
        (,test (nth 1 ,query) (nth 0 (nth 0 ,row-var))))))

В этой версии вместо простого апострофа используется обратная кавычка, что позволяет «убирать кавычки» форм в теле, что позволяет включать сгенерированные формы в результат.

Вы можете использовать этот макрос, как и исходную версию:

(transform (...))

или (передача явной тестовой функции):

(transform (...) :test equal)

Обратите внимание, что вы не должны использовать простые символы в качестве имен переменных в расширениях макросов (в качестве аргумента row для сгенерированного лямбда выражения), так как это может случайно помешать использованию этого символ на месте использования вашего макроса. При написании макроса вы просто не знаете, будет ли где-то переменная с именем row при использовании вашего макроса и не используется ли она уже в запросе форма / выражение. Ваше исходное определение будет «захватывать» переменную, возможно, изменяя значение того, что делает запрос.

person Dirk    schedule 01.09.2009

funcall - это ответ! Решил просто передать его и использовать funcall для оценки функции.

person John Jiang    schedule 01.09.2009