This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

how do I define this conditional inside a defmacro?

4 posts · 4480 views

When I run this macro as `(bool :true)` I get:

The function COMMON-LISP:T is undefined.

How do I change this macro so I can run `(bool :true)` and get `1` without really changing anything else about that's not necessary. As a defun, the below works btw. Thanks in advance for any help on this:)
      (defmacro bool (&rest args)
         ` (cond ((eq (first ,args) nil) (princ nil))

        	((eq :true (first ,args)) (princ 1))

        	(t nil)))

Re: how do I define this conditional inside a defmacro?

Try to macroexpand your macro:
(macroexpand '(bool :true))
You'll get this:
(IF (EQ (FIRST (:TRUE)) NIL) (PRINC NIL)
  (IF (EQ :TRUE (FIRST (:TRUE))) (PRINC 1) NIL))
:true will be evaluated as a function

you have to write instead of ,args:
',args if you don't want the args to be evaluated, or
(list ,@args) if you want the args to be evaluated.

(and you should define it at the beginning of the macrodefinition, so it has not to be evaluated twice)

For example you could write this:
(defmacro bool (&rest args)
  (let ((x (gensym)))
   `(let ((,x (first ',args)))
      (cond ((eq ,x nil)
             (princ nil))
            ((eq :true ,x)
             (princ 1))
            (t nil)))))

Re: how do I define this conditional inside a defmacro?

Thanks alot ...that's exactly what I was looking for,

Take care

Re: how do I define this conditional inside a defmacro?

Thanks again...just realized what (list ,@args) was for...now thanks to you I finally "get" defmacro