Sent from my iPad

> On Jan 6, 2016, at 7:57 PM, Joe Groff <[email protected]> wrote:
> 
> 
>> On Jan 6, 2016, at 3:39 PM, Matthew Johnson <[email protected]> wrote:
>> 
>> 
>>> On Jan 6, 2016, at 5:08 PM, Joe Groff <[email protected]> wrote:
>>> 
>>> I find it surprising that you key the initialization of 'var's based on 
>>> whether their setter is visible or not. Initialization is not the same as 
>>> setting, and memberwise initializers within the definition have private 
>>> access to the member anyway; this is why `let` properties can be 
>>> initialized, after all. `private(set)` is also a way for an API to 
>>> communicate that a property is read-only without promising that it is or 
>>> will always be immutable, so I think it's important that a 'private(set) 
>>> var' be as capable as a 'let' to the maximum degree possible.
>>> 
>>> -Joe
>> 
>> Hi Joe,
>> 
>> Thanks for bringing this topic up and moving the discussion to the list 
>> (it’s hard to get into details on Twitter).
>> 
>> I am definitely sympathetic to the points you raise.  The problem is that 
>> there is no good solution to this without involving at least one of the 
>> future enhancements.  Chris feels strongly that we need to focus on the core 
>> functionality for the initial proposal so we must choose a solution without 
>> them.
>> 
>> Using the `var` setter visibility is the least bad option in my mind.  There 
>> are many times when a var might represent internal state that a user is 
>> allowed to read, but should never be allowed to specify, whether via 
>> initialization or otherwise.  These will have `private(set)` visibility.  
>> 
>> If we allow memberwise initialization to expose them it will be a useless 
>> feature for types that contain a var like this.  There will not be any way 
>> to specify that they should not participate in memberwise initialization 
>> without at least one of the future enhancements.  On the other hand, if you 
>> do wish to expose them via the initializer it is easy to add a parameter and 
>> initialize the `var` manually.
>> 
>> This is also a safer solution.  The author of the type has specifically 
>> stated that users should not be setting the value of the `var`.  Maybe that 
>> doesn’t apply to initialization, but it is not the right decision to assume 
>> that IMO, at least without the ability to specify `init` visibility 
>> independently if desired.
>> 
>> In the case of `let`, if we do not use the only access control modifier they 
>> are allowed to have they would not be able to participate in memberwise 
>> initialization at all.
>> 
>> I think the proposal makes the least bad choice we can make without 
>> expanding it to include the ability to specify init visibility (which I 
>> would support if the core team was willing to do that).
> 
> 
> I'm not sure what you mean by init visibility.

The proposal suggests a possible future enhancement for specifying access 
control for init distinct from get and set like: 'private public(init)'.  This 
would be available to both 'let' and 'var' properties and would allow a single 
memberwise initialization rule to be used for all properties.

> I feel like all these arguments could also be made for 'let'; what makes a 
> get-only var different from the initializer's perspective?

This is true in some sense.  The difference is that 'let' properties only have 
access control for a getter making it the only option we have if they are 
allowed to participate in memberwise initialization.  

Here's an example.  Think of a progress property.  That will be a far with a 
public getter but a private setter.  It would clearly be wrong if that were 
exposed by an initializer.  If we use the getter for a 'var' in memberwise 
initialization it would be exposed to all memberwise initializers under the 
current proposal (without any of the enhancements).  

Types with properties like this are not uncommon.  Memberwise initialization 
would be useless with these types if the getter visibility was used.  

There are several ways to solve this but Chris did not want to include any of 
them in the initial proposal.  I went with what I feel is the least bad option 
remaining, which is to use the setter visibility for 'var' properties.  

It is least bad because it will actually be the right thing a lot of the time 
and because you can still use memberwise initialization for other properties 
when it doesn't do what you need.  Using the getter would be right some of the 
time (less often I think, but that's just a guess) but when it isn't you would 
have to avoid memberwise initialization for the entire type.

It is different than 'let' properties because it has to be if we want to do the 
least bad thing for 'var' properties and we also want to allow 'let' properties 
to participate in memberwise initialization.

Matthew

> 
> -Joe
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to