SE-0280: Enum cases as protocol witnesses

The review of SE-0280: Enum cases as protocol witnesses begins now and runs through March 17th, 2020.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager (via email or direct message on the Swift forums).

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

  • What is your evaluation of the proposal?

  • Is the problem being addressed significant enough to warrant a change to Swift?

  • Does this proposal fit well with the feel and direction of Swift?

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
John McCall
Review Manager

25 Likes

What is your evaluation of the proposal?

I support the proposal as it fixes a very old and annoying gap in the language I run into myself multiple times. This would finally allow for more fluency.

Is the problem being addressed significant enough to warrant a change to Swift?

Definitely, the issue was reported several times on bugs.swift.com. Personally I had to check it at least one time a year if it was addressed in any of the major Swift releases.

Does this proposal fit well with the feel and direction of Swift?

Yes, as mentioned before it allows for more natural fluency and expressiveness.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Followed and participated in the pitch thread. Read the proposal again.

8 Likes

I’m in favor of basically any proposal that makes enums and structs more equivalent. Making case constructors more static-method-like is part of that, so I like this proposal.

23 Likes

I'm in favor of the proposal; however, I'm unsure how the resilience part works. Renaming a case is not a binary-compatible change because enum cases have a different run-time representation from methods and properties, not to mention a different symbol name (mangling). It's not even a source-compatible change if a client is matching on cases. It'd probably be simpler to say something like this:

There is no change to library evolution; while cases can now satisfy protocol requirements, they still can't be swapped out for methods/properties without breaking binary compatibility—or for that matter, source compatibility.

This isn't great because you can change the implementations of all other publicly-exposed declarations, but here you're stuck with the enum case. But I don't think it should block the proposal; I think it just means we should move towards more indirection for enum cases, and/or a standardization of @_implements for overriding protocol witnesses that would otherwise match cases.

18 Likes

Jordan’s Point are probably well worth consideration, and well beyond my comprehension of the underlying implementation details.

However, I’ve wanted this for so long. And from a language user’s point-of-view, this would make the language semantics more coherent, and simpler. It aligns well with the case constructors as functions.

+1

3 Likes
  • What is your evaluation of the proposal?

+1

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes

  • Does this proposal fit well with the feel and direction of Swift?

Yes

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading eand superficially followed the discussions on the forum.

1 Like
  • What is your evaluation of the proposal?

I like it! Feels very swifty

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes, especially because it doesn't disturb existing code, and makes future code more intuitive, not less

  • Does this proposal fit well with the feel and direction of Swift?

Yes! Already you can use class instead of static, and let instead of var when implementing protocols. It feels natural to me to use case for that too.

example
protocol Proto {
    static func a()
    var b: Int { get }
}
class Foo: Proto {
    class func a() {}
    let b: Int = 123
}
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

no

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I've read pitch thread, and the proposal itself

1 Like

What is your evaluation of the proposal?

+1

Is the problem being addressed significant enough to warrant a change to Swift?

Yes. I can see some sensible use-cases being allowed by this change. From the top of my head:

  • Emptyable and Zeroable protocols
  • constraints on Codable's CodingKeys

Does this proposal fit well with the feel and direction of Swift?

Yes. In fact without this proposal I would have assumed this had always been supported.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I read the proposal, and skimmed the pitch thread

2 Likes
  • What is your evaluation of the proposal?

:100: this is a relatively small but extremely useful enhancement. I have wanted it for quite a while and will take advantage of it in library designs where conforming types will often be enums.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes. It is frustrating as a library author to know that conforming enums provided by users will face the compromises described in the proposal. Lack of this feature can also make a library that relies on factory requirements to feel boilerplate-heavy.

  • Does this proposal fit well with the feel and direction of Swift?

Yes

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

n/a

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I have bumped into this limitation countless times over the years. I gave the proposal a thorough review and believe it addresses the issue in exactly the right way.

2 Likes

+1, makes sense to me. Even if @implements existed, as I expect it will at some point, supporting same-name cases for matching protocol declarations would be welcomed as a convenience anyway.

2 Likes

+1. Been wanting this for a while! Thanks @suyashsrijan for pushing it through!

1 Like
  • What is your evaluation of the proposal?
    +1, I can't remember how many times I expected enums to satisfy static vars/funcs in protocols and only too late remind me myself that this wasn't possible. This closes a huge gap in protocol abstraction imho and make enums and structs a bit closer

  • Is the problem being addressed significant enough to warrant a change to Swift?
    Yes! It's not only additive and harmless, but works in favour of Swift consistency as enums already Quack like a Duck and deserve to be called a Duck

  • Does this proposal fit well with the feel and direction of Swift?
    Yes! Swift becomes more consistent thanks to this proposal

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
    N/A

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
    A good reading in the proposal, but not the real implementation

1 Like

+1
I followed the pitch.

1 Like

I agree with Jordan that in general, replacing an enum case with a static computed property or function (or vice versa) is not a resilient change, because the compiler will "devirtualize" uses of protocol requirements on concrete types, and enum cases and properties have a different ABI.

So I would change the phrasing of that section. My understanding is that it refers to resilience concerns with existing code anyway, not new code that uses the feature.

Other than that, this proposal gets a hearty +1 from me.

4 Likes

+1, this is a straightforward addition which makes witness matching focused less on exact syntax and more on the semantics of a declaration.

Yes, the existing restrictions which disallow this are due to implementation limitations rather than deliberate design decisions IMO. This change will allow enums to conform to some protocols in a more natural manner.

Yes. More generally, I think this fits well with the goals of the author's witness matching manifesto in that it loosens syntactic matching requirements and focuses on what makes sense and is practically useful from a semantic perspective.

I followed the pitch and the progress of the witness matching manifesto.


With regard to the resilience issues brought up by @jrose, I don't think the inability to switch between satisfying a requirement with an enum case and other static members should block this proposal. A similar issue came up during the review of SE-0267 (where clauses on contextually generic declarations) where writing equivalent declarations with different syntax results in mangling differences, and it's likely parameterized extensions will run into similar issues. In comparison to those two features, I think it's intuitively clearer that enum cases and static vars have different ABI.

2 Likes

What is your evaluation of the proposal?

+1

Is the problem being addressed significant enough to warrant a change to Swift?

Yes, the proposal's Motivation section was extremely convincing.

Does this proposal fit well with the feel and direction of Swift?

Yes.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read through the proposal and skimmed the replies on the forums.

1 Like
  • What is your evaluation of the proposal?

+ :100:, I think this is a great proposal and feels very natural.

Overall narrowing the gap between structs/classes and enums being able to conform to protocols is fantastic.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes, more uniformity across enums/structs in expressive power and conforming to protocols seems important, esp. since enums are so useful and omni-present :slight_smile:

  • Does this proposal fit well with the feel and direction of Swift?

Yes, I think so -- it feels quite natural.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Nothing quite the same, actually. Even in Scala(3) this can't be expressed as nicely (due to lack of ability to express static functions in traits, as static is not really a thing by itself) as it can be done here, that's pretty nice.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read through proposal twice and played around with some APIs I'm working with to see if this would be helpful (did not find a killer case yet, but it definitely has potential to clean up certain patterns :heart:)

2 Likes

Thank you very much @jrose and @Slava_Pestov for clarifying the resilience part, I have opened a PR to amend that section.

2 Likes

Merged.

4 Likes

I'm in favor of this proposal.

Yes. One of the direct benefits is that, with this proposal, developers don't have to manually add init(from: Decoder) and encode(to: Encoder) in enums for Codable-conformances all the time.

Yes, and it brings better consistency across different types' behaviours.

N/A

A quick read.

1 Like