我编写的大多数函数都非常小,并且其中很少有递归函数。 Common Lisp是否通过“解除绑定”函数体内的名称来提供防止递归的方法。另外,它是否提供一种解除符号功能值绑定的方法,以便我可以滚动自己的显式非递归defun
?
我希望能够执行以下操作,可能隐藏在宏后面。
(defun non-recursive-func (arg)
(unflet (non-recursive-func)
(+ (first arg) (second arg))))
我今天不小心写了一些错误的代码,其中有一个包装函数委托给自己而不是未包装的函数,这使我意识到,使用某些编译时机制防止递归可能会有用。
(defun fcompose-2 (f g)
(lambda (x) (funcall f (funcall g x))
(defun fcompose (&rest args)
(reduce #'fcompose-2 args))
除了我不小心为fcompose
编写了以下内容。
(defun fcompose (&rest args)
(reduce #'fcompose args))
自然导致堆栈溢出。
答案 0 :(得分:5)
怎么样:
(defmacro defun* (name (&rest args) &body body)
`(defun ,name ,args
(flet ((,name ,args
(declare (ignore ,@args))
(error "~a is defined with defun* and cannot be called from itself" ',name)))
,@body)))
这会在函数范围中添加一个内部绑定,如果在主体中使用它,则仅表示错误,并且您可以将defun*
定义替换为defun
进行生产。