在defun中使用cond进行Lisp求值

在defun中使用cond进行Lisp求值,lisp,common-lisp,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

我是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

这就是我们需要宏的原因,还是我犯了其他错误?

Common Lisp中函数的参数在进入函数之前进行求值。当计算
(打印1)
时,它打印
1
,并返回
1
。当计算
(打印2)
时,它打印
2
,并返回
2
<代码>1和
2进入该功能。然后返回
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

由于函数的所有参数都得到求值,因此需要延迟/强制求值:

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

谢谢雷纳。宏是我所追求的,但这也是有趣和启发性的注意,这与其他语言中可能熟悉的行为没有任何不同。例如,在C或类似Java的语言中,在调用
my_if(true,print(1),print(2))时,使用类似
void my_if(boolean x,type-then,type-else){if(x){return then;}else{return else;}}
的定义您将看到打印的1和2。