G
gugamilare
Ah!!! I didn't know that! Now I know why C macros fail. And why this
is so difficult for you to understand
Now you get it. The only difference between macros and functions is
when it is called, and the type of arguments it receives. Believe me,
all the power we are talking about come from such a simple feature.
Whether you believe it or not, this simple feature is already enough
to make all the things we said. Period.
The Lisp compiler always complains about name collisions, whether it
is a macro-macro, function-function or macro-function call. Any other
cases can't be misinterpreted.
No. Every language implements everything in a different way.
This is easily handled in lisp using local variables and gensyms (auto-
generated collision-free symbols). You just bound the arguments you
want to evaluate into variables whenever you want to evaluate anything
(this is mostly, but not always, the case), and then use the
variables. Side-effects and variable-collision safe. Just simple as
that.
Gensyms again.
Do you really think that 50 years of coding and Lisp programmers are
amateurs enough to make such bad mistakes? Again you fail to
understand this.
Nintendo 64 was implemented using Lisp. So was Mario 64. And also
another game made to Playstation 2 that I don't remember the name. ITA
Software is a well known company that uses Common Lisp. There are at
least 2 commercial Lisp implementations that sell CL environments with
many features and charge over a thousand dollars on a single license.
Many really experienced programmers like Paul Graham use Lisp (and not
only Lisp). And you are the first one to ever see these problems. You
must be a genius.
is so difficult for you to understand
C lets you #define all kinds of code fragments. Lisp macros apparently
have to appear to be function calls, and be called in the same places
where one could make function calls.
Now you get it. The only difference between macros and functions is
when it is called, and the type of arguments it receives. Believe me,
all the power we are talking about come from such a simple feature.
Whether you believe it or not, this simple feature is already enough
to make all the things we said. Period.
But Lisp (and C's preprocessor) allow a typo to catastrophically
affect far-away code that isn't even supposed to be interacting
directly with the part of the codebase containing the typo, and in
ways other than by causing an obvious name collision or other compile-
time error.
The Lisp compiler always complains about name collisions, whether it
is a macro-macro, function-function or macro-function call. Any other
cases can't be misinterpreted.
Another hand-wave. Macros are macros are macros.
No. Every language implements everything in a different way.
Macros are a symbol, possibly with formal parameters, that is expanded
where it is called in the code, with the formal parameters in turn
expanded into copies of the actual parameters.
It immediately follows that an actual parameter with side effects may
end up having those side effects multiple times, and that certain
other problems can arise.
This is easily handled in lisp using local variables and gensyms (auto-
generated collision-free symbols). You just bound the arguments you
want to evaluate into variables whenever you want to evaluate anything
(this is mostly, but not always, the case), and then use the
variables. Side-effects and variable-collision safe. Just simple as
that.
Furthermore, the variable capture problems follow automatically as
well.
Gensyms again.
If the macro assigns to a variable in the outermost scope in its
body, it will clobber the value of any variable of the same name
existing at the call site, since when the macro is expanded in place
at that site, the variable name in the macro becomes a reference to
that other variable. Likewise, if the macro contains a structure in
its body that creates a smaller local scope and defines a variable in
that, when expanded at the call site that becomes a nested local scope
at the call site, and the variable will hide any variable of the same
name existing in the scope enclosing the call. If the macro uses a
formal parameter inside that nested scope, and the call site uses that
variable in the corresponding actual parameter, the expansion will use
the macro's local variable instead of the one the coder intended it to
use, because the latter is hidden by the former.
This again causes an encapsulation failure: merely changing the names
of variables internally used in the macro, without altering anything
else, may cause it to behave very differently at some call sites.
And all of the above is extrapolated from the definition of "macro"
without reference to any particular language, implementation, or
anything. The only way for the above not to happen is for the "macro"
involved to violate in some manner the generic, language-independent
definition of a macro, i.e. for it not to be a macro at all but rather
something else, such as a plain-Jane function call.
Do you really think that 50 years of coding and Lisp programmers are
amateurs enough to make such bad mistakes? Again you fail to
understand this.
Nintendo 64 was implemented using Lisp. So was Mario 64. And also
another game made to Playstation 2 that I don't remember the name. ITA
Software is a well known company that uses Common Lisp. There are at
least 2 commercial Lisp implementations that sell CL environments with
many features and charge over a thousand dollars on a single license.
Many really experienced programmers like Paul Graham use Lisp (and not
only Lisp). And you are the first one to ever see these problems. You
must be a genius.