Я пишу рекурсивный макрос Лиспа с номером n и оценивая тело n раз (упражнение от ANSI Lisp). Я пробовал два способа сделать это - сам макро-вызов в своем расширении и макрос расширяется в локальную рекурсивную функцию. Я не работаю так, как хочу.Lisp рекурсивные макро проблемы
Вот первый - у него переполнение стека, но когда я смотрю его расширение с помощью macroexpand-1, это кажется мне прекрасным.
(defmacro n-times (n &rest body)
(let ((i (gensym)))
`(let ((,i ,n))
(if (zerop ,i) nil
(progn
,@body
(n-times (- ,i 1) ,@body))))))
Вот второй один - он делает ошибку, «неопределенная функция #xxxx вызвана с аргументами (г)» где #xxxx это имя GENSYM и г составляет 1 меньше числа я называю его с. Я думаю, что есть проблема с тем, как я использую gensyms и flet вместе, но я не уверен, как это сделать правильно.
(defmacro n-times (n &rest body)
(let ((g (gensym)))
`(flet ((,g (x)
(if (zerop x) nil
(progn
,@body
(,g (- x 1))))))
(,g ,n))))
Спасибо, что заставило его сработать! Почему вы не можете использовать flet для указания рекурсивных функций? – lightlike
'flet' делает привязки видимыми только внутри тела. 'labels 'делает привязки видимыми внутри определений привязки. –
Получил это. Будет ли первый метод в порядке, если я возьму 'if' из backquote для проверки' (zerop n) 'во время компиляции? – lightlike