> On Dec 22, 2015, at 12:08 AM, David Owens II <da...@owensd.io> wrote:
> 
> I really like the idea and it’s something that’s extremely annoying to deal 
> with today in Swift. My biggest concern is that the proposal, in its 
> entirety, seems to really complicate the initialization rules.

Hi David.  I’m glad that you like the basic idea.  Thanks for taking the time 
to respond and offer feedback.

The proposal as written was only intended to be a place to start a 
conversation.  I expected it to be revised and am already in the process of 
doing that.  Chris had some great feedback that I am taking into account.  I 
hope both of you see the changes as improvements to the current draft.

I looked at the approach you are suggesting and discussed something similar to 
it in the alternatives section.  The problem with this approach is that it 
doesn’t address the fundamental problem I am trying to solve - namely that 
trivial code grows with MxN complexity (M memberwise initializable properties 
and N initializers).  

Your approach reduces the trivial code by about 50% but it does not address the 
scaling problem.  Scaling isn’t really significant in small struct examples but 
it would be quite non-trivial in something like a Swift UIKit.

You mentioned how your approach addresses private properties.  I did consider 
allowing parameters to be synthesized for lower access level members.  The 
property wouldn’t be visible, but a parameter could still be synthesized to 
initialize the member.  I decided against this approach because I believe it is 
probably relatively uncommon to want to initialize a member not visible to the 
caller with a value provided directly by the caller.  I will update the 
alternatives considered section to address this.

I would also like to point out:
1) Nothing in my proposal prevents you from taking full control of the 
signature for your initializer.  You just need to write the assignments 
manually.
2) What you are proposing and what I am proposing are not mutually exclusive.  
It would be possible for them to exist side-by-side in the language.  

Matthew

> 
> Also, I don’t think it generates good API signatures. Take this example:
> 
> struct S {
>       let s: String
>       let i: Int
> 
>       // user declares:
>       memberwise init() {}
>       // compiler synthesizes:
>       init(s: String, i: Int) {
>               self.s = s
>               self.i = i
>       }
> }
> 
> That is not a very descriptive API. It’s also not necessarily the case that 
> your internal names are what you want exposed.
> 
> I would actually prefer the rule to simply be this: when an init() is 
> modified by memberwise, the labelled parameters will be set. This lookup will 
> try both the argument name and the parameter name, in that order, for reasons 
> that become more clear with convenience inits described later.
> 
> So you would have this:
> 
> memberwise init(name s: String, value i: Int) {
>     // autogenerated: self.s = s; self.i = i
> }
> 
> This provides you all of the freedom that you may need:
> Order of the APIs is explicitly controlled
> API names of the members are not exposed if not desired, especially helpful 
> for non-public members
> Default values are handled naturally
> 
> Optionally, you could keep the default simply with this:
> 
> memberwise init {}
> 
> This would use the property names as the argument labels.
> 
> Another example:
> 
> memberwise init(name s: String, value i: Int = 12) {
>     // autogenerated: self.s = s; self.i = i
> }
> 
> And the usage is much nicer:
> 
> let s = S(name: "Happy")
> 
> Here’s a subclassing example:
> 
> class Animal {
>     let type: String
>     let numberOfLegs: Int
>     
>     memberwise init(type: String, numberOfLegs: Int) {
>         /* generated */ self.type = type
>         /* generated */ self.numberOfLegs = numberOfLegs
>     }
> }
> 
> class Dog: Animal {
>     let name: String
>     
>     memberwise private init(type: String = "dog", numberOfLegs: Int = 4, n 
> name: String) {
>         /* generated */ self.name = name
>         /* generated */ super.init(type: type, numberOfLegs: numberOfLegs);
>     }
>     
>     memberwise convenience init(name: String) {
>         /* generated */ self.init(type: "dog", numberOfLegs: 4, n: name)
>     }
> }
> 
> let d = Dog(name: "Fido")
> 
> The biggest thing about convenience inits is that the generation of the init 
> needs to pull the defaults from the designated init. Also, for super.init(), 
> it’s a straight label/name lookup for the designated init() only. Anything 
> more fancy must be written by the user.
> 
> You also disallow private init, but that doesn’t need to happen with explicit 
> members. That’s the beauty of giving the public API a real contract with 
> names.
> 
> struct S {
>     let s: String
>     private let i: Int
>     
>     memberwise init(name s: String, value i: Int = 12) {
>         /* generated */ self.s = s
>         /* generated */ self.i = i
>     }
> }
> 
> Also, partial initialization could be possible, much like you proposed 
> originally:
> 
> struct S {
>     let s: String
>     private let i: Int
>     
>     memberwise init(name s: String) {
>         /* generated */ self.s = s
>         self.i = s.utf8.count
>     }
> }
> 
> My concern is that this starts to be more complicated and magical. I’d 
> actually cut this from the proposal.
> 
> The last change I would make is that if any property has an assignment in the 
> declaration, it cannot be memberwise initialized.
> 
> struct S {
>     let s: String
>     let i: Int = 10
>     
>     memberwise init(name s: String) {
>         /* generated */ self.s = s
>     }
> }
> 
> In the above, i will always be 10.
> 
> -David
> 
>> On Dec 21, 2015, at 11:32 AM, Matthew Johnson via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I have completed a draft of the proposal I have been working on for flexible 
>> memberwise initialization.  I am really looking forward to your input and 
>> will be refining the proposal based on our discussion.
>> 
>> I am including a current snapshot of the proposal in this message.  I will 
>> keep the proposal up to date on Github at this link:
>> 
>> https://github.com/anandabits/swift-evolution/blob/flexible-memberwise-initialization/proposals/NNNN-flexible-memberwise-initialization.md
>>  
>> <https://github.com/anandabits/swift-evolution/blob/flexible-memberwise-initialization/proposals/NNNN-flexible-memberwise-initialization.md>

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

Reply via email to