<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 22, 2015, at 11:26 AM, David Owens II <<a href="mailto:david@owensd.io" class="">david@owensd.io</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">How are you going to deal with public properties creating a breaking change in the memberwise init()?</div><div class=""><br class=""></div><div class="">Example:</div><div class=""><br class=""></div><div class="">v1.0 of the API ships:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">struct Person {</font></div><div class=""><font face="Menlo" class=""> let name: String</font></div><div class=""><font face="Menlo" class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">v1.1 of the API ships:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">struct Person {</font></div><div class=""><font face="Menlo" class=""> let name: String</font></div><div class=""><font face="Menlo" class=""> let age: Int</font></div><div class=""><font face="Menlo" class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">When you use the implicit memberwise init(), the above change is now a breaking change. There are ways around it, but all seem fragile to me - for example, requiring a default value for new properties on the declaration site.</div></div></div></blockquote><div><br class=""></div><div>Adding a new member to a struct is itself a breaking change. I don’t see how memberwise initialization makes this worse.</div><div><br class=""></div><div>You could even use memberwise initialization in v1.0 of your API and then update your implementation to be manual in v2.0 if necessary. Nothing in the proposal prohibits you from taking full manual control if resilient API evolution requires that.</div><div><br class=""></div><div>One option I considered and think is still worth considering is requiring an @memberwise attribute on properties to explicitly opt-in to memberwise initialization. This is discussed in the proposal under alternatives considered. You can find the rationale for my decision there. I do think it is valid to debate which is a better default.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Similarly, the order of the members <i class="">must</i> remain the same now, changing them is a breaking change. This is ok for structs today because the generated init() is only available within a module so all of the places that use it are limited within your own codebase.</div></div></div></blockquote><div><br class=""></div><div>The concern about order does have some validity. If declaration order does not provide sufficient control the proposal could include something which allows a different order to be explicitly specified for memberwise initialization.</div><div><br class=""></div><div>Also, keep in mind that nothing in this proposal is *required*. You can always decline to use the feature. </div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">This is why I do not like like the implicit behavior and the @nomemberwise attribute on the declaration of the property; it tightly couples together things that are inherently fragile.</div></div></div></blockquote><div><br class=""></div><div>Do you have any suggestions on how to improve the proposal without giving up on its underlying goal of solving the M x N complexity problem (M members x N initializers)? </div><div><br class=""></div><div>If you haven’t taken a look at the updated proposal please do so. I’m sure there will still be things you are not totally comfortable with but you might like it better than yesterday's draft.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">-David</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 22, 2015, at 8:46 AM, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi Chris,</div><div class=""><br class=""></div><div class="">I have given your feedback a lot of thought and have taken another run at this proposal from a slightly different angle. I believe it is a significant improvement. </div><div class=""><br class=""></div><div class="">I believe the programmer model is now very clear straightforward:</div><div class=""><br class=""></div><div class="">The set of properties that receive memberwise initialization parameters is determined by considering only the initializer declaration and the declarations for all properties that are at least as visible as the initializer (including any behaviors attached to the properties). The rules are as follows:<br class=""><br class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Their access level is at least as visible as the memberwise initializer.<br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• They do not have a behavior which prohibits memberwise initialization.<br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• The property is not annotated with the @nomemberwise attribute.<br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• The property is not included in the @nomemberwise attribute list attached of the initializer. If super is included in the @nomemberwise<br class=""></div><div class=""><br class=""></div>The parameters are synthesized in the parameter list in the location of the ... placeholder. They are ordered as follows:<br class=""><br class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• All properties without default values precede properties with default values.<br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Within each group, superclass properties precede subclass properties.<br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>• Finally, follow declaration order</div></div><div class=""><br class=""></div><div class="">The new model has also dramatically simplified the implementation details. No more need for the compiler to scan the initializer body!</div><div class=""><br class=""></div><div class="">There are still some details present that you provided feedback on. My reply from last night is still valid discussion around those issues. Please reply inline to that message if possible. </div><div class=""><br class=""></div><div class="">I’m sure there are still plenty of details to discuss and work through, but I hope you will agree that these changes are a step in the right direction.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/anandabits/swift-evolution/blob/flexible-memberwise-initialization/proposals/NNNN-flexible-memberwise-initialization.md" class="">https://github.com/anandabits/swift-evolution/blob/flexible-memberwise-initialization/proposals/NNNN-flexible-memberwise-initialization.md</a></div><div class=""><br class=""></div><div class="">Matthew</div></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></body></html>