2

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)

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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))

Comments

0

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?

2 Comments

Your foo4 looks the same as foo3.
So it does! I even looked for that!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.