lisp macro expand with partial eval -
i have following code confuse me now, hope can tell me difference , how fix this.
(defmacro tm(a) `(concat ,(symbol-name a))) (defun tf(a) (list (quote concat) (symbol-name a)))
i think should same effect, seem not.
try following call:
cl-user> (tf 'foo) (concat "foo") cl-user> (tm 'foo) value 'foo not of expected type symbol. [condition of type type-error]
so, what's problem?
what want is:
(tm 'foo) ==> (concat "foo")
first, note that
`(concat ,(symbol-name a))
and
(list (quote concat) (symbol-name a))
do exact same thing. equivalent pieces of code (backquote syntax isn't restricted macro bodies!): both construct list first element symbol concat
, second element symbol name of whatever variable a
refers to.
clearly, makes sense if a
refers symbol, which, svante has pointed out, isn't case in macro call example.
you could, of course, extract symbol list (quote foo)
, prevents calling macro this:
(let ((x 'foo)) (tm x))
which raises question of why event want force user of macro explicitly quote symbol needs literal constant anyway.
second, way macros work this: take pieces of code (such (quote foo)
) arguments , produce new piece of code that, upon macroexpansion, (more or less) replaces macro call in source code. useful reuse macro arguments within generated code putting them going evaluated later, such in
(defmacro tm2 (a) `(print (symbol-name ,a)))
think piece of code , whether or not let
example above works now. should on right track.
finally, piece of advice: avoid macros when function do. make life easier both implementer , user.
Comments
Post a Comment