[swift-evolution] [Proposal Draft] Flexible memberwise initialization
matthew at anandabits.com
Wed Jan 6 17:39:04 CST 2016
> On Jan 6, 2016, at 5:08 PM, Joe Groff <jgroff at apple.com> 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.
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).
NOTE: The “access control for init” enhancement specifies that `var` init visibility will continue to use the setter visibility if no init visibility was directly specified. It would be very reasonable to change this so that the getter visibility is used if no init visibility is directly specified, thus making `private(set) var` as capable as `let`.
More information about the swift-evolution