Yoo
Yoo

Reputation: 18336

eval during emacs lisp macro expansion

How can I fix the simple macro foo in (elisp)Eval During Expansion?

None of the followings work:

(defmacro foo1 (a)
  `(setq (eval ,a) t))

(defmacro foo2 (a)
  `(setq ,(eval a) t))

(defmacro foo3 (a)
  `(setq ,a t))

I really don't get what's said in (elisp)Eval During Expansion. I think if I got it, I'd have been able to fix the macro.

Update: huaiyuan's solution works:

(defmacro foo7 (a)
  `(set ,a t))

(setq x 'b 
      a 'c)

(foo7 x)
(assert (eq b t))
(assert (eq x 'b))

(foo7 a)
(assert (eq a 'c))
(assert (eq c t))

(macroexpand '(foo7 x)) ; ==> (set x t)
(macroexpand '(foo7 a)) ; ==> (set a t)

Upvotes: 2

Views: 1467

Answers (3)

huaiyuan
huaiyuan

Reputation: 26529

Try

(defmacro foo7 (a)
  `(set ,a t))

The semantics of elisp is often accidental to the implementation. For an example of well thought out, clearly specified macro systems, I recommend Common Lisp's.

Upvotes: 2

Vatine
Vatine

Reputation: 21258

The "right" fix is to not require evaluation of user-supplied parameters within the macro expansion function.

(defmacro foo4 (a) `(setq ,a t))

Though this does NOT do the same thing as either of foo1, foo2 or foo3. What is the problem you are trying to solve?

Upvotes: 0

Bahbar
Bahbar

Reputation: 18015

What do you mean, "fix" ?

The page you are referring to shows that the macro works only if you call it with a name that is not the same name as the macro parameter. To fix the issue in question, either modify the macro to reduce the conflict opportunities, or the usages so that it does not conflict.

 (defmacro foo (aVeryLongAndImprobablyConflictingName)
   (list 'setq (eval aVeryLongAndImprobablyConflictingName) t))

Upvotes: 0

Related Questions