2010-09-20 3 views
3

Маленькая помощь здесь пожалуйста. Я пытаюсь создать этот макрос lisp, который принимает список (чисел) в качестве входных данных и возвращает сумму этих чисел. КодBasic Lisp Macro Question

(setf g (list 1 2 3 4)) 



(defmacro add-test(var) 

    `(+ ,@var)) 

(добавить тест г) дает эту ошибку

***** значение G не типа LIST. [Состояние типа TYPE-ERROR] *****

В то же время (добавить-тест (1 2 3 4)) дает правильный результат, 10.

Можете ли вы объяснить, почему он не работает, когда переменная передается функции?

Другие детали -

Lispbox - SBCL

Ubuntu Linux

Заранее спасибо

ответ

8

Это легко и одной из наиболее распространенных макро вопросов.

(add-test g) 

Сейчас на макроподстановкам, макрос ADD-TEST вызывается с параметром VAR получать значение G, символ.

Затем вы попробуете операцию с списком. Выражение кавычки

`(+ ,@var) 

Значение VAR является G, и вы пытаетесь склеить, что в список (+ ...). Теперь возвращаемое выражение равно (+ . G).

CL-USER 12 > (macroexpand '(add-test g)) 
(+ . G) 
T 

(+ . G) не является действительной формой Лиспа. Это недопустимый исходный код.

Помните, что параметры макроса - это необоснованные исходные выражения.

Сравните это со следующим:

CL-USER 13 > (macroexpand '(add-test (1 2 3 4))) 
(+ 1 2 3 4) 
T 

Вы сказали: "Можете ли вы объяснить, почему это не работает, когда переменная передается в функцию?

Помните, ADD-TEST НЕ является функцией, это макрос. Макрос передается исходный код и возвращает новую форму - эта форма затем оценивается.

+0

Благодарим Райнера за подробный ответ. Это очень помогло. – bdev

+0

Из любопытства, скажем, мы принимаем идею Бдева дальше. Предположим, у меня есть какое-то оптимизируемое выражение (список целых чисел!), И я хочу оптимизировать выражение до «run-time». Как мне это сделать? (хотя я полагаю, что (eval G) может работать ...). –

+2

@Paul Nathan: вы можете ЭВОЛЮТ его, СОСТАВЛЯЙТЕ его, ФУНКУЛИРУЙТЕ его, ПРИМЕНЯЙТЕ его - ограничений почти нет. См. Также DEFINE-COMPILER-MACRO, который позволяет писать оптимизации. –