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

Xiaodi Wu xiaodi.wu at gmail.com
Fri Jun 23 18:02:03 CDT 2017


On Fri, Jun 23, 2017 at 17:19 David Moore via swift-evolution <
swift-evolution at swift.org> wrote:

> 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,
>

The way to express such a requirement is `var x { get }`. By contrast, what
Robert is asking for is a property that can be set exactly once
specifically during initialization.

For his proposed idea to work, `let x = 42` must in fact *not* satisfy the
requirement that Robert spells `var x { let }`, since the initializer could
not then set the value one more time. However, as I demonstrated in my
previous email, his idea also cannot work because initializers can be
chained (and, in protocol extension implementations, *must* be chained),
and the implementation of the chainer may be opaque to the chainee or vice
versa. Therefore, neither the compiler nor the author can guarantee that
the property is set once and not more or less.

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
>
> _______________________________________________
> 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/31d85576/attachment.html>


More information about the swift-evolution mailing list