Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are library cycles/compilation units visible to macros? #3713

Open
lrhn opened this issue Apr 18, 2024 · 0 comments
Open

Are library cycles/compilation units visible to macros? #3713

lrhn opened this issue Apr 18, 2024 · 0 comments
Labels
question Further information is requested static-metaprogramming Issues related to static metaprogramming

Comments

@lrhn
Copy link
Member

lrhn commented Apr 18, 2024

Macros are run at a time when not all declarations exist, because some have yet to be introduced by macros.

That means that any identifier that is being resolved by introspection during macro invocation, or prior to that when determining which annotations are macro annotations, may change meaning after macros have introduced new declarations.

The solution I'd propose for this is to have pre-macro resolution use "preliminary" scopes containing only the currently existing declarations of the library, and carry those over into preliminary export and import scopes, before trying to resolve any identifier.
Unlike a complete program, it's possible for an identifier to not resolve to anything in the preliminary scope (or to refer to something different than what it will refer to in the final scope, which should become an error if the macro has ever resolved that identifier).

That's its own issue, but it also makes the order of macro application visible.
If a library cycle/strongly connected component of libraries is compiled and macro-expanded before and independently of things that depend on it, and after things it itself depends on, then whether macro generated declarations are available for introspection depends on whether things are in the same library cycle or not.

Assume we have libraries A and B, with B importing A, and both A and B having macro applications.
In this case, macro application in library B would see the complete library A, after it has had its macro applications executed.

Now add an import of library B to library A, putting them into the same library cycle. This is a change in library A, that library B doesn't know about.
Yet it changes which declarations of library A that library B's macro applications can see during introspection, at least in step 1 (I don't remember if the declarations added in step 1 are visible in step 2 of another macro in the same compilation unit).

That is, adding an import can potentially be breaking for the library that you import.

Does the macro specification need to specify the precise order of macro application, how library cycles are detected and in which order they are macro-executed?

The macro specification will need to specify the preliminary environment that identifiers are resolved in, we can't rely on standard language semantics for doing resolution in a partial program, and language semantics are not modular enough that we can just refer to the "algorithm to build export and import scopes for libraries" for the partial program, and do the same thing again for a complete program later.
If the macro specification specifies preliminary environments, then it needs to be aware that some libraries may be post-macro expansion (because they're strictly earlier in the dependency graph) while other libraries are still pre-macro expansion (because we're looking at them now, to do macro expansion), since that changes which names are available from those preliminary environments.

Alternatively macros can be defined abstractly as a program transformation that applies a number of macros.
It doesn't matter that some libraries are post-macro expansion at this point, because after macro expansion, they're just the libraries of the transformed program, no different from if they'd been written by hand.
What then needs to be defined is which libraries are due for macro application next, which again needs some definition of library cycle/strongly connected dependency component in the specification.

Macro application order on libraries is visible, so whatever the specification states, it needs to be aware that it at least allows the actual behavior that users see.

@lrhn lrhn added question Further information is requested static-metaprogramming Issues related to static metaprogramming labels Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested static-metaprogramming Issues related to static metaprogramming
Projects
None yet
Development

No branches or pull requests

1 participant