and...
are great feedback, thank you. We are looking to improve the SwiftSyntax documentation, as well as providing more examples for folks to start from.
Most of time, removing a @MainActor
or @escaping
will cause type-checking failures. The same is true for @expression
on macros.
Swift is consistent about having introducers (func
, var
, struct
, protocol
, etc.) be followed directly by the name of the thing being introduced. I think that's for good reason---if we put more between the introducer and the name, it's hard to find the name:
macro(expression) stringify(...)
macro(declaration(.peer, namePrefixes: ["_", "$"])) myLazy(...)
it gets hard to scan through the parenthesized bits to get to the name of the macro we're declaring. I think we're also boxed in a bit here by source compatibility---the @
from attributes gives us the ability to add new syntax without breaking existing code, but something like this:
macro(declaration(.peer, namePrefixes: ["_", "$"]))
myLazy(...)
is well-formed code today, and we shouldn't break that.
Yes, that's fair. While many of the built-in expression macros can be declared, they can't be implemented unless we allow the expansion context to access more information.
We're trying to keep macro definitions self-contained so that we can ensure that we understand and minimize their dependencies on other source code in the file/project. This post goes into some detail about the concerns here.
Very nice! If you're up for it, please go ahead and create a pull request to that repository, where we can collect various macro examples.
I agree that the bigger wins will come from other kinds of macros. Expression macros are the first step, and the easiest one because they are the most contained. Once we start generating declarations, issues around compile-time dependencies and incremental builds that we've only touched on with source locations will become a whole lot more interesting.
Doug