#### Archived

This topic is now archived and is closed to further replies.

# Lisp macros

This topic is 5006 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I know that Lisp macros are useful in extending the language. However the problem with most implementation of Lisp macros is that the issue of name conflicts. I know that various means have been proposed to solve the problem. In Common Lisp, I think it is done by generating a unique symbol, in Scheme, a total different mechanism is used, in Emacs Lisp, it is done by creating a symbol but does not intern it. Now I am going to propose another one, but I am not sure if anyone has ever come up with this idea before. What we want is in fact to evaluate expressions in the environment where the macro is invoked. Why don''t we just pass the environment, then when evaluate an expression, do it in that environment. Say to write ''if''
(defmacro if (p y n)
(cond ((eval p pre-env) (eval y pre-env))
(t (eval n pre-env))))

where pre-env gives the environment where the macro is invoked, and (eval a e) means evaluate a in the environment e. In this way, there is no way the name conflicts could have occured because you control exactly which environment is used. If the macro is somehow recursive, pre-env cannot be used directly in the macro, instead pre-env should be passed as local variable to the recursive part of the macro. I am by no means very proficient in Lisp, so the above code may not be correct syntax, but I hope I can get across the idea. I think a more appropriate way to call this is ''user defined special form'' instead of macro. Also, I think this suits an interpreter more, but the same idea can be applied to compiler. What do you think of this idea? Do you think it will work?

##### Share on other sites
You seem to misunderstand the way macros work: they are macroexpanded at compile-time, not run-time. The macroexpansion is inserted, literally, into the code.

so for example, "PUSH" is a macro. This code:

(let ((a NIL))
(push 1 a)
(push 2 a))

Might be translated into this code by the macroexpander:

(let ((a 1))
(setq a (cons 1 a))
(setq a (cons 2 a)))

Your strategy would require that we do the macro processing at run-time, and it would require that we manipulate environments explicitly. That would make it very hard to compile the code into efficient assembly language.

[edited by - Nekhmet on June 8, 2004 1:37:57 PM]

##### Share on other sites
That''s why I call it ''user-defined special form'' and I mentioned that it is more suitable to an interpreter than a compiler.

I know how macros work, but I just want to see if another way can solve the same problem.