在defun中使用cond进行Lisp评估

时间:2014-12-01 16:29:49

标签: lisp common-lisp

Lisp noob在这里。

CL-USER> (defun my-if (a b c)
           (cond (a b)
                 (t c)))

CL-USER> (my-if t (print 1) (print 2))
1
2
1

我没有期望获得2,因为如果第一个是真的,cond中的第二个句子不应该被评估:

CL-USER> (cond (t (print 1))
               (t (print 2)))
1
1

这就是为什么我们需要宏,还是我犯了其他错误?

2 个答案:

答案 0 :(得分:9)

Common Lisp中的函数参数在进入函数之前进行评估。评估(print 1)时,会打印1并返回1。评估(print 2)时,会打印2并返回212进入该功能。并返回1作为答案。

要做你想做的事,你需要写一个宏:

CL-USER> (defmacro my-if (a b c)
           `(cond (,a ,b)
                  (t  ,c)))
MY-IF
CL-USER> (my-if t (print 1) (print 2))

1 
1

答案 1 :(得分:7)

由于函数的参数都得到了评估,你需要延迟/强制评估:

CL-USER 35 > (defun my-if (condition then-thunk else-thunk)
               (cond (condition (funcall then-thunk))
                     (t         (funcall else-thunk))))
MY-IF

CL-USER 36 > (my-if t
                    (lambda () (print 1))
                    (lambda () (print 2)))

1
1

CL-USER 37 > (my-if nil
                    (lambda () (print 1))
                    (lambda () (print 2)))

2
2