There is certainly a similarity in that macros are a kind of function which
accepts as argument a piece of code and returns a new piece of code. But
there are differences. Consider the following from the CLHS :
3.1.2.1.2.2 Macro Forms
If the operator names a macro, its associated macro function is applied
to the entire form and the result of that application is used in place of
the original form.
Specifically, a symbol names a macro in a given lexical environment if
macro-function is true of the symbol and that environment. The function
returned by macro-function is a function of two arguments, called the
expansion function. The expansion function is invoked by calling the
macroexpand hook with the expansion function as its first argument, the
entire macro form as its second argument, and an environment object
(corresponding to the current lexical environment) as its third argument.
The macroexpand hook, in turn, calls the expansion function with the form
as its first argument and the environment as its second argument. The
value of the expansion function, which is passed through by the
macroexpand hook, is a form. The returned form is evaluated in place of
the original form.
It probably doesn't count as a "deep theoretical reason" but it explains that
macros and ordinary functions get called by different mechanisms and using
different arguments [some of the arguments passed implicitly] so it wouldn't
be practical to make them interchangeable for MAP and friends. Now you might
ask , do they have to be called using so different mechanisms ? The fact that
a macro must also be able to accept a lexical environment certainly adds to
the functionality. For a specific example see
Remembering information during compilation
https://groups.google.com/g/comp.lang.lisp/c/Rg5Ehxk2yZw
, a thread I started in 2009. [ If you're curious as to why I wanted that ,
see the IMPLEMENTATION section in
http://vlaho.ninja/prog/enhanced-do/README.txt ]
I've never had a chance to [explicitly] use the macroexpand hook [ i.e. the
value of the variable *MACROEXPAND-HOOK* ] but I'm sure that it exists in the
specification because some people have a use for this kind of thing.
Perhaps with sufficient effort one could make functions and macros
interchangeable in more contexts but I can't think of any reason to
expend the effort.
--
Being a pianist as well as a cellist, I learned both parts before we met.
When we first played it together, I kept correcting him. "I think that F
natural should be an F#.... The chord isn't C, E-flat, G, it's C, E natural,
G#...." Prokofiev finally said, "Who wrote this, me or you?"
http://www.cello.org/Newsletter/Articles/rostropovich/rostropovich.htm