[swift-evolution] [Review] SE-0018 Flexible Memberwise Initialization

Jordan Rose jordan_rose at apple.com
Mon Jan 11 13:44:09 CST 2016

Sorry to leave this over the weekend before getting back to you! Planning to respond here, then go catch up on the thread—a possibly questionable ordering of tasks, but one that ensures I will actually respond at all.

>> - Given that these initializers are based on access control, is "public memberwise init(...)" different from "internal memberwise init(...)"? Can I put both in the same type?
> If you have at least one internal property they would result in different signatures so would not be a duplicate declaration.  The public memberwise init would obviously need to initialize the internal property somehow.

That's what I expected, just wanted to have it spelled out. Thanks.

>>  It seems like a big, complicated feature that "does what you mean" only when it's first added and then becomes an impediment to any later change.
> I can certainly sympathize with this.  It is the big drawback of the automatic model.  At the same time, this proposal builds on the existing memberwise init for structs and doesn’t really make the rules that much more complex.  But it does make the feature more prevalent and visible, thus making it more important to understand the rules.  And of course it could be argued that the current memberwise init is too complex as it is.
> For the record, here is a concise list of how this proposal expands the current memberwise init:
> 1. Allow the memberwise initializer to be used in classes
> 2. Allow default parameter values for `var` properties
> 3. Fix the problem the current memberwise initializer has with lazy properties
> 4. Use the `set` rather than `get` visibility for `var` properties
> 5. Allow you to request the memberwise initializer, including:
> 	i. Add additional parameters
> 	ii. include an initializer body
> 	iii. Specify access level, which will result in omission of memberwise parameters for more-private properties (it would be reasonable to limit this to private and internal if concerns about allowing it to be public are a significant factor)
> I am curious to hear your thoughts on which of these points are not desirable, and what your opinion is about the existing rules for the implicit memberwise init for structs.

I'm happy with 1, 2, and 3 as a separate proposal, or several separate proposals. (For 1 in particular, the restriction predates the access control model, but making it implicit would also interfere with inheriting designated initializers.) I'm not sure 4 is interesting enough, but sure.

The particular concern I have with 5 is that the most interesting use case to me is for 'public' (indeed, that's by far the majority of the requests for this we've seen in Radar, rdar://problem/18065955), but that's also the most dangerous one if you have anything unusual going on: different access control, library evolution, etc. (i) and (ii) are mostly just extra features, but (iii) is where it gets weird.

(The next most common request related to this proposal is 1, memberwise inits for classes, mostly in simple cases. rdar://problem/16704095)

For public memberwise inits, I think my discomfort ultimately comes down to "the order of stored properties in a class is not usually part of the class's ABI", and this makes it too easy to opt into that, and then too hard to explain which members and why. There's also the problem of wanting to tweak one parameter's behavior, and being unable to do that; having to build more features on top of this one to fix that seems like it's going in the wrong direction.

>> I'm motivated to solve the tiny value struct case, the public C-like struct case, but I don't think I want this creeping into the interface of a public class. I'd rather go with the "annotation on parameters" solution (which would be a separate proposal, of course).
>> public struct Point {
>>   public var x: Double
>>   public var y: Double
>>   public init(self x: Double, self y: Double) {}
>> }
>> or
>>   public init(@assigned x: Double, @assigned y: Double) {}
>>   public init(self.x: Double, self.y: Double) {}
>>   // something else
> I’ll ask you the same question I asked David about this approach: if the parameter must be explicitly related to a property for assignment, why should we repeat the type information (and default value information if it is a var)?  Doesn’t it seem reasonable to omit the type?

I'm happy to come up with a syntax to omit the type and default value; I do still think the listing of parameters should be explicit. (And it should be obvious where it gets any type and default value from.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/b86b6a5a/attachment.html>

More information about the swift-evolution mailing list