Page 1 of 1

how do I define this conditional inside a defmacro?

Posted: Mon May 05, 2014 2:14 am
by joeish80829
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:)

Code: Select all

      (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?

Posted: Mon May 05, 2014 6:07 am
by porky11
Try to macroexpand your macro:

Code: Select all

(macroexpand '(bool :true))
You'll get this:

Code: Select all

(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:

Code: Select all

(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?

Posted: Tue May 06, 2014 3:18 am
by joeish80829
Thanks alot ...that's exactly what I was looking for,

Take care

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

Posted: Sun May 11, 2014 4:03 am
by joeish80829
Thanks again...just realized what (list ,@args) was for...now thanks to you I finally "get" defmacro