Lisp evaluation using cond in defun
Lisp noob here.
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
I didn't expect to get 2, because the second sentence in cond
shouldn't be evaluated if the first is true:
CL-USER> (cond (t (print 1))
(t (print 2)))
1
1
Is that why we need macros, or am I making some other mistake?
source to share
Common Lisp function arguments are evaluated before entering the function. When (print 1)
evaluated, it prints 1
and returns 1
. When (print 2)
evaluated, it prints 2
and returns 2
. 1
and 2
go to function. And it returns 1
as a response.
To do what you want to do, you need to write a macro:
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
source to share
Since the function arguments are all evaluated, you need to delay / force the evaluation:
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
source to share