Lisp macros

Started by
1 comment, last by Peter19852001 19 years, 10 months ago
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?
Q:"Why it doesn''t work?"A:"There is a mistake."Q:"Who made that silly mistake?"A:"The one who write it."
Advertisement
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]
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.
Q:"Why it doesn''t work?"A:"There is a mistake."Q:"Who made that silly mistake?"A:"The one who write it."

This topic is closed to new replies.

Advertisement