While it is generally held that everything in lisp is an expression. Isn't the more pertinant fact that everything is a list? That is, I thought macros hinged on the fact that everything is a list, not that everything is an expression.
Macros hinge on the idea that code is data. Macros are functions that run at "compile-time" [1], that take unevaluated code (i.e. data) and return any valid data, it just happens that returning a list is interpreted as a function call. But I can also define:
(defmacro foo [x] :foo)
which always returns a keyword.
All lisps that I'm aware of only let macros dispatch on list evaluation, i.e. when you see (foo ...), call the function defined in (defmacro foo), but I'm not aware of any limitation preventing you from applying that to other types of data.
[1] technically, they run at macro-expansion time, which is after reading the expression, and before evaluating.
And my point is that everything isn't a list, but it is data. Macros are functions that take data, and return data. Their most common usage is that that they take lists and return lists, but that isn't required.
Makes sense. I was actually coming at it from the "everything is in a list" vantage. And can be destructured as such. (Restructured, as well, of course.)
Often they are but not always, e.g. a value of type other than cell/list can be evaluated at the top-level. How the top-level itself works is an implementation detail.
More fundamentally, being known to something else is not the direction "is a" works in.
Apologies for missing this earlier. At evaluation time, I agree things make a difference. Before that, though, things are merely items in a list. So, yeah, I said it poorly. It is less "everything is a list." And more "everything is in a list." At least at the reasoning level.