Interally the compiler has some kinds of "macros" to support some of the internally implemented operators. How to make these macros hygienic in the sense that they can create new local variables that cannot conflict with local variables from the code they are wrapping has been puzzling me for some time.
One idea I have had recently is to namespace all the identifiers, not unlike how LISP does it. Method names would all have to be in the same namespace, by default.
In this way, a macro can generate some code without fear of creating variable conflicts.
The default namespace for a file could be its filename.
In order to serialize / de-serialize expressions to and from source there would need to be a way to denote the namespace of an identifier for cases where the macro has already been expanded.
I haven't figured out what the syntax for this should be, but I think it shouldn't be too complex. Perhaps if a '/' is embedded in the identifier it would assume that the identifier is fully qualified, otherwise the identifier would be resolved relative to the current namespace, but if there is a /
the namespace is left as-is. When printing source we can strip off anything before the /
if it matches the current namespace prefix.
e.g.
foo == current namespace\/foo
x\/foo --> x\/foo