Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

macro expansion: to quote the body forms or not?

I'm having a hard time understanding exactly how macro expansion works. What is the difference in how the elisp interpreter handles these two snippets of code?

(defmacro foo (arg)
  (message "arg is: %s" arg))
(foo "bar")

and:

(defmacro foo (arg)
  `(message "arg is: %s" ,arg))
(foo "bar")
like image 639
Richard Hansen Avatar asked Feb 16 '23 06:02

Richard Hansen


1 Answers

You example may be confusing because

  1. message both displays a message and returns it.
  2. strings (like "bar") are self-evaluating.

Instructive Example

(defconst zzz 123)
(defmacro zzz1 (arg)
  `(insert (format "arg is: %s" ,arg)))
(defmacro zzz2 (arg)
  (insert (format "arg is: %s" arg)))

Evaluate the code above using C-x C-e after each of the 3 forms.

Now evaluate these:

First version: (zzz1 zzz)

The interpreter...

  1. calls the macro function of zzz1
  2. the macro function returns the form (insert (format "arg is: %s" zzz))
  3. the interpreter evaluates the form, and inserts "arg is: 123" into the current buffer, and returns nil (seen in the echo area at the bottom)

Second version: (zzz2 zzz)

The interpreter...

  1. calls the macro function of zzz2
  2. the macro function inserts "arg is: zzz" in the current buffer and returns nil
  3. the interpreter evaluates nil to nil (seen in the echo are at the bottom)

The bottom line

The most important "take-away" here is that macros are just functions which operate on code before the interpreter (of compiler) kicks in.

These functions take their arguments unevaluated (i.e., in both zzz1 and zzz2, arg is zzz, not 123).

They are evaluated like any other lisp function (e.g., they can have macro forms in their bodies; the body is wrapped in an implicit progn; &c).

Their return value is evaluated by the interpreter instead of the original form.

like image 128
sds Avatar answered Feb 23 '23 22:02

sds