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

Vision for macros in Swift #1927

Merged
merged 9 commits into from
Mar 22, 2023
Merged

Conversation

DougGregor
Copy link
Member

@DougGregor DougGregor commented Jan 25, 2023

Updated and revised from the gist initially posted to the forums back in October (https://forums.swift.org/t/a-possible-vision-for-macros-in-swift/60900), reflecting improvements to the design.

@DougGregor DougGregor marked this pull request as draft January 25, 2023 06:24
@DougGregor DougGregor marked this pull request as ready for review January 25, 2023 06:25
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
Thank you @benrimmington

Co-authored-by: Ben Rimmington <me@benrimmington.com>
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
visions/macros.md Outdated Show resolved Hide resolved
Co-authored-by: Ben Rimmington <me@benrimmington.com>
@beccadax
Copy link
Contributor

beccadax commented Feb 7, 2023

General thoughts:

  • When you discuss conformance macros, you allude to it being possible to have a single macro declaration with multiple roles. How does this work? Is the macro only valid to apply in a place where all of its declared roles make sense? (Can a macro declaration be overloaded on role to support a disjunction of roles under the same name?) Do all of the roles have to be implemented in the same #externalMacro type, or can different roles be implemented by different types?
  • Some of the role names use compiler jargon, like codeItem and witness, that I dearly hope we don’t end up using in the actual feature.
  • Nit: I hope @attached(peer) gets workshopped a little more—it’s kinda strange to have it have the same name but a very different function. Or maybe there’s a unity here that I don’t understand?

@DougGregor
Copy link
Member Author

@beccadax the "attached macros" proposal has a lot more detail about macro roles and what it means to inhabit several different roles. Does that address your questions/concerns? Do you feel that the discussion needs to be lifted up into the vision document?

I'm happy to workshop names like "codeItem" and "witness" a bit more.

@beccadax
Copy link
Contributor

the "attached macros" proposal has a lot more detail about macro roles and what it means to inhabit several different roles. Does that address your questions/concerns?

Maybe it's subtle enough that I overlooked it, but I don't quite see the answer to my question there; you mention that a macro can have multiple roles and that the compiler expands each of them, but I don't think you talk about what happens when only some of those roles are applicable.

Let me make the question more concrete. Consider the Clamping macro described in that document:

@attached(peer, prefixed(_))
@attached(accessor)
macro Clamping<T: Comparable>(min: T, max: T) = #externalMacro(module: "MyMacros", type: "ClampingMacro")

What happens if I do this?

struct MyStruct {
    @Clamping(min: 0, max: 255) func fn() { ... }
}

Clamping has both an @attached(peer) role, which is perfectly valid to use on a method, and an @attached(accessor) role, which is only valid on a property (or subscript, I suppose). Does the Swift compiler expand the @attached(peer) role but not the @attached(accessor) role? Or does it diagnose an error because you tried to apply Clamping in a place where the @attached(accessor) role is not valid?

(ClampingMacro.expansion(of:providingPeersOf:in:) could, of course, diagnose an attempt to use it on anything but a var. For the sake of argument, assume that it doesn't. Maybe its designer wants it to apply a postcondition to the return value when it's used on a method.)

Do you feel that the discussion needs to be lifted up into the vision document?

Probably not the whole discussion, but a brief mention of what it means when a macro has multiple roles might help readers understand how different roles are supposed to be used in concert.

@DougGregor
Copy link
Member Author

@beccadax we should move this discussion elsewhere. Attached macros has a pitch

Maybe it's subtle enough that I overlooked it, but I don't quite see the answer to my question there; you mention that a macro can have multiple roles and that the compiler expands each of them, but I don't think you talk about what happens when only some of those roles are applicable.

I've added a paragraph to this effect in the attached macros proposal (7add644), but I think further discussion should occur on the forums, not here.

Probably not the whole discussion, but a brief mention of what it means when a macro has multiple roles might help readers understand how different roles are supposed to be used in concert.

We have the Clamping example where a single macro inhabits multiple roles, and they are used in concert to achieve the property-wrapper effect. This seems sufficient to me. Again, I think we should continue this discussion on the forums.

@rjmccall rjmccall added the vision Prospective vision document label Feb 20, 2023
@@ -406,14 +440,14 @@ The `@freestanding` and `@attached` attributes for macro declarations specify th
* **Body**: A body macro would allow one to create or replace the body of a function, initializer, or closure through syntactic manipulation. Body macros are attached to one of these entities, e.g.,

```swift
@traced(logLevel: 2)
@Traced(logLevel: 2)
func myFunction(a: Int, b: Int) { ... }
```

where the `traced` macro is declared as something like:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Traced

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@DougGregor
Copy link
Member Author

The Language Workgroup has approved this vision document. Merging!

@DougGregor DougGregor merged commit ad28322 into swiftlang:main Mar 22, 2023
@DougGregor DougGregor deleted the macros-vision branch March 22, 2023 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vision Prospective vision document
Projects
None yet
5 participants