[Pitch] `Enum`-like cases within protocols

Enum-like cases within Protocols

Swift already supports using enum-like syntax in protocols, for example:

import SwiftUI

extension PrimitiveButtonStyle where Self == BorderlessButtonStyle {
  public static var borderless: BorderlessButtonStyle {
    BorderlessButtonStyle()
  }
}

Button("Log In") {
  // Implementation Hidden
}
.buttonStyle(.borderless)

I propose a simpler syntatic sugar that reduces boilerplate and builds off our understanding of how these static properties function.

extension PrimitiveButtonStyle {
  case borderless: BorderlessButtonStyle
}

Solved Problems

While nice, the existing implementation is verbose and redundant.

The new syntax removes the confusing where clause and it fits into the Swift language because the property is already treated like an enum case is. It's also easier to write and avoids the redundancy of writing the struct name in three places. Under the hood, it would be expanded into the original, retaining the same functionality.

2 Likes

What about func? Use case with associated value syntax?

extension ShapeStyle {
  case innerShadow(radius: Double)

// call site:
Logo()
  .foregroundStyle(.innerShadow(radius: 3))

Like this?

Cases also allow pattern-matching and deconstruction (if .innerShadow(let radius) = style). I see the analogy, but I don't think it goes so far as to justify this shorthand syntax. Meanwhile, what you call "enum-like" syntax has long worked on structs and classes as well (.white for UIColor.white, for example).

Aside, on pattern-matching

(Could you make pattern-matching work on protocols this way? Probably! But extending pattern-matching beyond enums is a big topic that deserves more attention than just a proposal to add syntactic sugar—your proposal would rapidly become about that, rather than the little thing you wanted to add.)

5 Likes