2014-12-01 58 views
3

Lisp noob here。在defun使用cond的Lisp評估

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 

這是爲什麼我們需要宏,或我是否犯了一些其他錯誤?

回答

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 
+0

請注意,這與其他可能熟悉的語言的行爲沒有任何區別。例如,在類C或類似Java的語言中,定義如下:void my_if(boolean x,type then,type else){if(x){return then; } else {return else; }},在調用my_if(true,print(1),print(2));'你會看到1和2都打印出來。 – 2014-12-02 02:59:05

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 
+1

謝謝Rainer。宏是我所追求的,但這也是有趣和有啓發性的 – 2014-12-01 16:57:08