# Protocol Concrete Properties

**URL:** <https://forums.swift.org/t/protocol-concrete-properties/40676>\
**Category:** Pitches\
**Tags:** extensions, protocols\
**Created:** [September 27, 2020, 12:05am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676 "2020-09-27T00:05:43Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mtsrodrigues](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mtsrodrigues/32/34169_2.png) [@mtsrodrigues](https://forums.swift.org/u/mtsrodrigues)\
**Post date:** [September 27, 2020, 12:05am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/1 "2020-09-27T00:05:43Z")

</div>

Protocols are a great tool to define some type of configuration because it gives flexibility. SwiftUI, for example, uses to define styles for interface elements.

```swift
protocol PrimitiveButtonStyle { ... }

protocol PickerStyle { ... }

protocol ListStyle { ... }

```

The use of protocol here, instead of enumerations, allows the definition of platform-specific styles.

```swift
@available(watchOS 6.0, *)
@available(iOS, unavailable)
@available(OSX, unavailable)
@available(tvOS, unavailable)
public struct CarouselListStyle : SwiftUI.ListStyle { ... }

```

It also allows the implementation of styles in addition to the predefined ones.

```swift
struct CustomButtonStyle: PrimitiveButtonStyle {

    func makeBody(configuration: PrimitiveButtonStyle.Configuration) -> some View {
        ...
    }

}

```

A downside of this approach is that we lose the use of dot syntax to access the existing styles that the use of enumeration would allow. This is particularly problematic in frameworks because it leaves the user completely clueless. This type of styling ends up having a poor usability dependent on documentation, not always as good as it could be, or tips from a text editor, who does not always suggest the right options.

```swift
Picker(selection: $selectedOption, label: Text("Option")) {
    ...
}
.pickerStyle(???)

```

One may try declare a static property in the protocol only to realize that this is not currently possible.

```swift
extension PickerStyle {
    static var wheels = WheelPickerStyle() // Swift Compiler Error: Static stored properties not supported in protocol extensions
}

```

I propose to introduce a **concrete** keyword that would allow the declaration of a static like property in a protocol extension but constrained to a concrete implementation of it, hence a new keyword instead of use **static**.

```swift
extension PickerStyle {
    concrete var wheels = WheelPickerStyle()
}

```

This would give us the flexibility of protocols and the usability of dot syntax.

```swift
Picker(selection: $selectedOption, label: Text("Option")) {
    ...
}
.pickerStyle(.wheels)

```

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [September 27, 2020, 12:16am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/2 "2020-09-27T00:16:52Z")

</div>

> [@mtsrodrigues](#):
>
> The use of protocol here, instead of enumerations, allows the definition of platform-specific styles.

Why is this not possible with an enum, and what would it take to make it possible?

---

<div class="post-metadata">

**Author:** ![mtsrodrigues](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mtsrodrigues/32/34169_2.png) [@mtsrodrigues](https://forums.swift.org/u/mtsrodrigues)\
**Post date:** [September 27, 2020, 2:22am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/3 "2020-09-27T02:22:05Z")

</div>

Sorry, I actually made a wrong statement. I could swear it was not possible to annotate enumerations cases with **@available** but it is possible.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [September 27, 2020, 3:23am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/4 "2020-09-27T03:23:11Z")

</div>

I'd still say that enum is quite lacking in providing this much configurability. It needs to have a `.custom` case with a protocol payload. At which point we might as well just use said protocol.

---

<div class="post-metadata">

**Author:** ![Palle](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@Palle](https://forums.swift.org/u/Palle)\
**Post date:** [September 27, 2020, 8:08pm UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/5 "2020-09-27T20:08:54Z")

</div>

This has already been discussed in detail in the [protocol metatype extension thread](https://forums.swift.org/t/protocol-metatype-extensions-to-better-support-swiftui/25469)

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [September 28, 2020, 9:06am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/6 "2020-09-28T09:06:41Z")

</div>

I agree about the problem statement, this is a significant hurdle to SwiftUI usability. But I wonder if the solution isn't to be found in XCode instead? It should be able to know which concrete types are allowed at a particular function argument and could suggest them. The only challenge is really what trigger the user should have to supply, since there is no leading dot. Perhaps simply waiting a few seconds? Or pressing space?

---

<div class="post-metadata">

**Author:** ![xAlien95](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xalien95/32/12558_2.png) [@xAlien95](https://forums.swift.org/u/xAlien95)\
**Post date:** [September 28, 2020, 9:19am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/7 "2020-09-28T09:19:34Z")

</div>

> [@GreatApe](#):
>
> The only challenge is really what trigger the user should have to supply, since there is no leading dot. Perhaps simply waiting a few seconds? Or pressing space?

You can press the Esc key to trigger completion suggestions if I recall correctly.

However, I don't think that's the way to go. Even the SwiftUI team wanted to provide dot notation for View styles originally, as explained in the [thread](https://forums.swift.org/t/protocol-metatype-extensions-to-better-support-swiftui/25469) @Palle linked. To achieve that feature they provided a workaround in SwiftUI, using StaticMember ([wayback machine link](https://web.archive.org/web/20190617130815/https://developer.apple.com/documentation/swiftui/staticmember), since it's been removed after a few betas), a concrete wrapper for enabling implicit member expressions and thought to be used in the following way:

```swift
protocol ColorStyle {
    typealias Member = StaticMember<Self>
}

extension StaticMember where Base: ColorStyle {
    static var red: RedStyle.Member { .init(.init()) }
    static var blue: BlueStyle.Member { .init(.init()) }
}

extension View {
    func colorStyle<S: ColorStyle>(_ style: S.Member) -> some View {
        ...
    }
}

MyView().colorStyle(.red)
MyView().colorStyle(.blue)

```

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [September 28, 2020, 9:46am UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/8 "2020-09-28T09:46:53Z")

</div>

To be honest I never quite understood what `StaticMember` was about, and it's still slightly mysterious...

But I'd say the concrete type problem is a general one, there should be a Find -\> Implementers popup menu for protocols, and/or an option under Assistant, along with subclasses, superclasses etc.

---

<div class="post-metadata">

**Author:** ![mtsrodrigues](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mtsrodrigues/32/34169_2.png) [@mtsrodrigues](https://forums.swift.org/u/mtsrodrigues)\
**Post date:** [September 28, 2020, 2:18pm UTC](https://forums.swift.org/t/protocol-concrete-properties/40676/9 "2020-09-28T14:18:28Z")

</div>

`StaticMember` was a workaround to solve this usability problem but in fact it was kind of confusing. I miss it though.
