Removing var keyword in protocol property reqirements


(Vinnie Hesener) #1

The var keyword in protocol property requirements is misleading.

From the docs:

*If a protocol requires a property to be gettable and settable, that
property requirement cannot be fulfilled by a constant stored property or a
read-only computed property. If the protocol only requires a property to be
gettable, the requirement can be satisfied by any kind of property, and it
is valid for the property to be also settable if this is useful for your
own code.*

I feel this is slightly confusing. To conform, I can use let for { get }. I
can't use var for { get set } if it's computed. This leads me to believe
that the keyword var has no actual instructional meaning here. It seems
misplaced to represent "property".

I think it should be something else, or maybe removed entirely? Isn't { get
set } enough to describe what this protocol needs? Maybe we can put the {
get set } in front of the property name?

I can think of a couple other small benefits of this, but I don't know if
it will distract from the main discussion. One of them being that it may
discourage using lets for those new to the language, as most people will
just lazily copy/paste the declaration.


(Jeremy Pereira) #2

The var keyword in protocol property requirements is misleading.

From the docs:
*If a protocol requires a property to be gettable and settable, that property requirement cannot be fulfilled by a constant stored property or a read-only computed property. If the protocol only requires a property to be gettable, the requirement can be satisfied by any kind of property, and it is valid for the property to be also settable if this is useful for your own code.*

I feel this is slightly confusing. To conform, I can use let for { get }. I can't use var for { get set } if it's computed. This leads me to believe that the keyword var has no actual instructional meaning here. It seems misplaced to represent "property".

I think it should be something else, or maybe removed entirely? Isn't { get set } enough to describe what this protocol needs? Maybe we can put the { get set } in front of the property name?

-1 from me

I’d rather keep the syntax for protocols as similar as possible to the syntax for classes and structs.

There might be an argument for `let` in a protocol as well as `var` although that would really be allowing protocol designers to dictate implementation details to designers of structs and classes that implement the protocol.

···

On 18 Jan 2017, at 05:38, Vinnie Hesener via swift-evolution <swift-evolution@swift.org> wrote:

I can think of a couple other small benefits of this, but I don't know if it will distract from the main discussion. One of them being that it may discourage using lets for those new to the language, as most people will just lazily copy/paste the declaration.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tony Allevato) #3

Personally, I don't feel that the problem is big enough to warrant a
breaking change here.

`var` is the general property declaration keyword in Swift for read-write
stored properties and read-only/read-write computed properties. The fact
that you can use `let` in place of `var` under one specific circumstance (a
read-only property backed by a stored variable) doesn't necessarily make
the entire keyword meaningless, IMO. `let` is just a shortcut for a
read-only stored property, and I think dropping it or moving `{ get set }`
elsewhere would be more confusing, since it would be syntactically
inconsistent with how the property is implemented. (Protocol members look
the same as class/struct members with the body removed.)

In general, I'm skeptical of ideas that just aim to protect new or bad
developers from themselves, especially at the expense of consistency.

···

On Tue, Jan 17, 2017 at 9:39 PM Vinnie Hesener via swift-evolution < swift-evolution@swift.org> wrote:

The var keyword in protocol property requirements is misleading.

From the docs:
*If a protocol requires a property to be gettable and settable, that
property requirement cannot be fulfilled by a constant stored property or a
read-only computed property. If the protocol only requires a property to be
gettable, the requirement can be satisfied by any kind of property, and it
is valid for the property to be also settable if this is useful for your
own code.*

I feel this is slightly confusing. To conform, I can use let for { get }.
I can't use var for { get set } if it's computed. This leads me to believe
that the keyword var has no actual instructional meaning here. It seems
misplaced to represent "property".

I think it should be something else, or maybe removed entirely? Isn't {
get set } enough to describe what this protocol needs? Maybe we can put the
{ get set } in front of the property name?

I can think of a couple other small benefits of this, but I don't know if
it will distract from the main discussion. One of them being that it may
discourage using lets for those new to the language, as most people will
just lazily copy/paste the declaration.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Joe Groff) #4

`let` more strongly guarantees **immutability**, not just "read-only". var { get } indicates that the protocol's interface only lets you read, but provides no guarantee that the implementation can't change the value you get. The language doesn't have the ability to reason about immutability for anything other than stored properties yet, but we want to leave syntactic space for that possibility without muddying the strong guarantee of `let`. For that reason, protocols only support `var { get }` requirements today. `let` properties naturally model the requirement since you can read them; their interface is a superset of the protocol requirement.

-Joe

···

On Jan 18, 2017, at 8:41 AM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

Personally, I don't feel that the problem is big enough to warrant a breaking change here.

`var` is the general property declaration keyword in Swift for read-write stored properties and read-only/read-write computed properties. The fact that you can use `let` in place of `var` under one specific circumstance (a read-only property backed by a stored variable) doesn't necessarily make the entire keyword meaningless, IMO. `let` is just a shortcut for a read-only stored property, and I think dropping it or moving `{ get set }` elsewhere would be more confusing, since it would be syntactically inconsistent with how the property is implemented. (Protocol members look the same as class/struct members with the body removed.)

In general, I'm skeptical of ideas that just aim to protect new or bad developers from themselves, especially at the expense of consistency.


(Tony Allevato) #5

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to
indicate a value that must be immutable after initialization, such that a
computed `var { get }` wouldn't satisfy it?

···

On Wed, Jan 18, 2017 at 8:48 AM Joe Groff <jgroff@apple.com> wrote:

> On Jan 18, 2017, at 8:41 AM, Tony Allevato via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Personally, I don't feel that the problem is big enough to warrant a
breaking change here.
>
> `var` is the general property declaration keyword in Swift for
read-write stored properties and read-only/read-write computed properties.
The fact that you can use `let` in place of `var` under one specific
circumstance (a read-only property backed by a stored variable) doesn't
necessarily make the entire keyword meaningless, IMO. `let` is just a
shortcut for a read-only stored property, and I think dropping it or moving
`{ get set }` elsewhere would be more confusing, since it would be
syntactically inconsistent with how the property is implemented. (Protocol
members look the same as class/struct members with the body removed.)
>
> In general, I'm skeptical of ideas that just aim to protect new or bad
developers from themselves, especially at the expense of consistency.

`let` more strongly guarantees **immutability**, not just "read-only". var
{ get } indicates that the protocol's interface only lets you read, but
provides no guarantee that the implementation can't change the value you
get. The language doesn't have the ability to reason about immutability for
anything other than stored properties yet, but we want to leave syntactic
space for that possibility without muddying the strong guarantee of `let`.
For that reason, protocols only support `var { get }` requirements today.
`let` properties naturally model the requirement since you can read them;
their interface is a superset of the protocol requirement.

-Joe


(Joe Groff) #6

It's conceivable that even computed `let` properties could be supported, if the getter implementation is a pure function of `self`.

-Joe

···

On Jan 18, 2017, at 8:50 AM, Tony Allevato <tony.allevato@gmail.com> wrote:

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to indicate a value that must be immutable after initialization, such that a computed `var { get }` wouldn't satisfy it?


(Joe Groff) #7

The exact meaning of "pure" and "immutable" would have to be designed. To a first approximation, you could say a pure method would only be able to read immutable global or class data (which is itself `let` or `pure func`, not anything that's potentially mutable) in addition to its own arguments.

-Joe

···

On Jan 18, 2017, at 8:57 AM, Matthew Johnson <matthew@anandabits.com> wrote:

On Jan 18, 2017, at 10:54 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 18, 2017, at 8:50 AM, Tony Allevato <tony.allevato@gmail.com> wrote:

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to indicate a value that must be immutable after initialization, such that a computed `var { get }` wouldn't satisfy it?

It's conceivable that even computed `let` properties could be supported, if the getter implementation is a pure function of `self`.

How would that work when `self` is mutable?


(Matthew Johnson) #8

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to indicate a value that must be immutable after initialization, such that a computed `var { get }` wouldn't satisfy it?

It's conceivable that even computed `let` properties could be supported, if the getter implementation is a pure function of `self`.

How would that work when `self` is mutable?

···

On Jan 18, 2017, at 10:54 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 18, 2017, at 8:50 AM, Tony Allevato <tony.allevato@gmail.com> wrote:

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #9

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to indicate a value that must be immutable after initialization, such that a computed `var { get }` wouldn't satisfy it?

It's conceivable that even computed `let` properties could be supported, if the getter implementation is a pure function of `self`.

How would that work when `self` is mutable?

The exact meaning of "pure" and "immutable" would have to be designed. To a first approximation, you could say a pure method would only be able to read immutable global or class data (which is itself `let` or `pure func`, not anything that's potentially mutable) in addition to its own arguments.

Got it. That makes sense. Looking forward to the expanded pure / immutable model someday!

···

On Jan 18, 2017, at 11:00 AM, Joe Groff <jgroff@apple.com> wrote:

On Jan 18, 2017, at 8:57 AM, Matthew Johnson <matthew@anandabits.com> wrote:

On Jan 18, 2017, at 10:54 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 18, 2017, at 8:50 AM, Tony Allevato <tony.allevato@gmail.com> wrote:

-Joe


(Adrian Zubarev) #10

Yeah I’m looking for that day too. :slight_smile:

class ImmutableThing : AnyValue { … }

···

--
Adrian Zubarev
Sent with Airmail

Am 18. Januar 2017 um 18:03:59, Matthew Johnson via swift-evolution (swift-evolution@swift.org) schrieb:

On Jan 18, 2017, at 11:00 AM, Joe Groff <jgroff@apple.com> wrote:

On Jan 18, 2017, at 8:57 AM, Matthew Johnson <matthew@anandabits.com> wrote:

On Jan 18, 2017, at 10:54 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 18, 2017, at 8:50 AM, Tony Allevato <tony.allevato@gmail.com> wrote:

Good point—I hadn't considered the distinction.

Does that mean a future version of Swift might allow `let` in a protocol to indicate a value that must be immutable after initialization, such that a computed `var { get }` wouldn't satisfy it?

It's conceivable that even computed `let` properties could be supported, if the getter implementation is a pure function of `self`.

How would that work when `self` is mutable?

The exact meaning of "pure" and "immutable" would have to be designed. To a first approximation, you could say a pure method would only be able to read immutable global or class data (which is itself `let` or `pure func`, not anything that's potentially mutable) in addition to its own arguments.

Got it. That makes sense. Looking forward to the expanded pure / immutable model someday!

-Joe

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution