gpt4 book ai didi

recursion - 是否可以在 lisp 中将递归函数重写为宏?

转载 作者:太空宇宙 更新时间:2023-11-03 18:39:46 26 4
gpt4 key购买 nike

我写了这个快速排序函数:

(defun quicksort (lst)
(if (null lst)
nil
(let ((div (car lst))
(tail (cdr lst)))
(append (quicksort (remove-if-not (lambda (x) (< x div)) tail))
(list div)
(quicksort (remove-if (lambda (x) (< x div)) tail))))))

但我不能将它重写为宏,它不起作用,例如,这个简单的 foo(递归求和 - 我知道,有点傻,但仅作为示例)也不起作用:

(defun Suma (lst)
(if (cdr lst)
(+ (Suma (cdr lst))
(car lst))
(car lst)))

工作正常,但是宏:

(defmacro SumaMacro (lst)
'(if (cdr lst)
'(+ (prog (SUMAMACRO (cdr lst)))
(prog (car lst)))
'(car lst)))

好像是错的。有人对将递归函数重写为宏有什么建议吗?

最佳答案

您正在混合使用宏和运行时;或者换句话说,您正在混合值和语法。这是一个非常简单的例子:

(defmacro while (condition &body body)
`(when ,condition ,@body (while ,condition ,@body)))

这里的坏处是宏不会执行主体,它只是构造一段代码,其中包含给定的主体。所以,当函数中存在这种循环时,它会受到一些条件的保护,例如 if ,这将防止无限循环。但是在这个宏代码中没有这样的条件——你可以看到这个宏展开成精确的原始形式,这意味着它试图展开成一些无限的代码片段。就好像你写过一样

(defun foo (blah)
(cons 1 (foo blah)))

然后将该生成器函数挂接到编译器中。所以要执行这些类型的运行时循环,你必须使用一个真正的函数。 (当需要时,您可以使用 labels 创建一个本地函数来执行递归工作。)

关于recursion - 是否可以在 lisp 中将递归函数重写为宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2104672/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com