[swift-evolution] [Pitch] `let` in protocols

David Moore mooredev at me.com
Fri Jun 23 17:15:10 CDT 2017


I think there might be some merit to this pitch, since you brought up a particular weak spot. I’d have to see what other people say about this, but it would seem that having the ability to explicitly mark something as constant for a given protocol implementation.

However, I would propose a change to the syntax you gave as an example, since it isn’t quite clear when it comes to the implementation. I think just a simple `let foo: Bar` would suffice, unless I’m missing some particular component of your concept.

This would allow extensions to operate on known constant values, perhaps improving performance maybe.

On Jun 23, 2017, 5:49 PM -0400, Robert Bennett via swift-evolution <swift-evolution at swift.org>, wrote:
> Hello Swift Evolution,
>
> I’m bumping into an annoying problem with protocols. In a class or struct it is common to have a `let` instance variable and assign it in `init`. Unfortunately there is no way to translate this into a protocol with init in an extension. If attempting to set the variable in init in an extension, it must be of type { get set }, which means it cannot be a `let` constant in the conforming type. AFAIK there is no way around this — if you want to set an instance variable in an initializer in a protocol extension, it must be marked as { get set }. The alternative is to write the initializer separately for each adopting type, but this violates DRY.
>
> Hence, I am proposing a third option to go along with `get` and `set` in a protocol. This would indicate that the variable can be a constant, but is settable in an initializer. In this case, the conforming type *must* use `let` to declare the variable.
>
> Option 1: the keyword `let`. If present, it would need to be the only thing in the curly brackets because it simultaneously implies `get` and not `set`.
>
> protocol P {
> var x: Int { let }
> init(_ x: Int)
> func modifyX()
> }
> extension P {
> init(_ x: Int) {
> self.x = x // This is ok; would not be ok if x were marked { get }
> }
>
> func modifyX() {
> self.x += 1 // Not allowed
> }
> }
>
> struct S: P {
> let x: Int // This is ok; would not be ok if x were marked { get set }
> }
>
> Option 2: `set(init)`. Can (and often will) coexist with `get`.
>
> protocol P {
> var x: Int { get set(init) }
> init(_ x: Int)
> func modifyX()
> }
> extension P {
> init(_ x: Int) {
> self.x = x // This is ok; would not be ok if x were marked { get }
> }
>
> func modifyX() {
> self.x += 1 // Not allowed
> }
> }
>
> struct S: P {
> let x: Int // This is ok; would not be ok if x were marked { get set }
> }
>
>
> I’d like to hear all of your thoughts on this.
>
> Best,
> Robert
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170623/8349c7e2/attachment.html>


More information about the swift-evolution mailing list