如何在lisp中本地定义函数?

时间:2017-01-14 16:29:23

标签: lambda lisp common-lisp

我需要在let中定义一个函数,并能够立即使用它,如下所示:

(let ((test (lambda () (print "ha")))) 
    (test))

但是,由于测试是变量(而不是函数),因此它不起作用。相反,我需要像这样运行它:

(let ((test (lambda () (print "ha")))) 
    (funcall test))

就我而言,这是一个问题。我可以通过制作一个改变(测试)到(funcall测试)的宏来解决这个问题,但是,这不起作用,因为宏的名称将与我的情况中的方法相同(I' m猜测这会导致(测试)成为(funcall test)=>(funcall(funcall test))=> ...?)

有没有办法在lambda中定义一个方法并立即运行它,而不用像funcall这样的东西?

3 个答案:

答案 0 :(得分:9)

Special Operator FLET, LABELS, MACROLET 。请注意FLETLABELS之间的差异。特别是,LABELS可以定义(相互)递归函数,而FLET可以隐藏现有函数,同时能够调用该函数本身:

(defun foo () (flet ((foo () (foo))) (foo)))
       ^1             ^2      ^1      ^2

(defun foo () (labels ((foo () (foo))) (foo)))
       ^1               ^2      ^2      ^2

答案 1 :(得分:6)

  

我可以通过制作一个更改(测试)到(funcall测试)的宏来解决这个问题,但这不起作用

为什么不呢?

CL-USER 4 > (let ((test (lambda () (print "ha"))))
              (macrolet ((test ()
                           `(funcall test)))
                (test)))

"ha" 
"ha"

答案 2 :(得分:3)

您可以使用labels,就像使用let变量一样。即:

(labels ((test ()
             (print "ha")))
    (test))