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?

+3


source to share


2 answers


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

      

+9


source


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

      

+7


source







All Articles