<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="">NOTE: this may cross-over with other proposals. I’m totally fine with converging, but just want this idea vetted first.<div class=""><br class=""></div><div class="">The idea is to reduce code duplication and improve maintainability, particularly around the constructing of objects. Objects hold fields which are subject to schema change, and therefore must be maintainable. The goal with this proposal/idea is to avoid replicating field names throughout the code, particularly when objects are being constructed.</div><div class=""><br class=""></div><div class="">One example is with the Builder pattern, which separates configuration of an object from it’s creation.</div><div class=""><br class=""></div><div class="">Here is some sample code. I have made <b class="">bold</b> the suggested changes.</div><div class=""><br class=""></div><div class="">Models:</div><div class=""><br class=""></div><div class=""><font face="Courier" class="">struct&nbsp;Profile&nbsp;&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;user:Person?<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;shippingAddress:Location?<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;billingAddress:Location?<br class="">}<br class=""><br class="">struct&nbsp;Person {<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;givenName:String<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;familyName:String<br class="">}<br class=""><br class="">struct&nbsp;Location {<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;street:String<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;town:String<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;region:String<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;country:String<br class="">&nbsp; &nbsp;&nbsp;init&nbsp;<b class="">custom</b> (street: String, town: String, region: String, country: String) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// ^^ initializer with label. contrived example.<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.street&nbsp;= street<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.town&nbsp;= town<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.region&nbsp;= region<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.country&nbsp;= country<br class="">&nbsp; &nbsp;&nbsp;}<br class="">}<br class=""></font><br class="">Here is a typical builder. Notice the field name <u class="">duplication</u>, in the method signatures, bodies, and the model objects above.&nbsp;This is a code smell. Granted, it can be resolved in other ways, but we tend to see this kind of duplication everywhere surrounding the model layer, and it causes maintenance problems.</div><div class=""><br class=""><font face="Courier" class="">struct&nbsp;TypicalBuilder {<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;profile:Profile&nbsp;=&nbsp;Profile()<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setUser(givenName:&nbsp;String, familyName:&nbsp;String) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.user&nbsp;=&nbsp;Person(givenName: givenName, familyName: familyName)<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setShippingAddress(street:&nbsp;String, town:&nbsp;String, region:&nbsp;String,&nbsp;country:&nbsp;String) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.shippingAddress&nbsp;=&nbsp;Location(street: street, town: town, region: region,&nbsp;country: country)<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setBillingAddress(street:&nbsp;String, town:&nbsp;String, region:&nbsp;String,&nbsp;country:&nbsp;String) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.billingAddress&nbsp;=&nbsp;Location(street: street, town: town, region: region,&nbsp;country: country)<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;func&nbsp;build() -&gt;&nbsp;Profile&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;profile<br class="">&nbsp; &nbsp;&nbsp;}<br class="">}<br class=""></font><br class="">Here’s my idea for&nbsp;<i class="">initializer forwarding</i>.&nbsp;</div><div class=""><br class=""><font face="Courier" class="">struct&nbsp;BetterBuilder {<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;profile:Profile&nbsp;=&nbsp;Profile()<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setUser(<b class="">forward:&nbsp;Person.init</b>) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// .init without label would be equivalent to memberwise initializer<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// "forward”&nbsp;could be an arbitrary label<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.user = Person(<b class="">forward</b>)<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setShippingAddress(<b class="">forward:&nbsp;Location.init{custom}</b>) {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; // .init with label, uses initializer signature with that label<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.shippingAddress = Location(<b class="">forward</b>)<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;mutating&nbsp;func&nbsp;setBillingAddress(<b class="">forward:&nbsp;Location.init{custom}</b>) {<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;profile.billingAddress = Location(<b class="">forward</b>)<br class="">&nbsp; &nbsp;&nbsp;}<b class=""><br class=""></b>&nbsp; &nbsp;&nbsp;func&nbsp;build() -&gt;&nbsp;Profile&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;profile<br class="">&nbsp; &nbsp;&nbsp;}<br class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">let builder = BetterBuilder()</font></div><div class=""><font face="Courier" class="">builder.setUser(</font><span style="font-family: Courier;" class="">givenName:&nbsp;</span><font face="Courier" class="">“David”, familyName:&nbsp;“James”</font><span style="font-family: Courier;" class="">)</span><span style="font-family: Courier;" class="">&nbsp;</span></div><div class=""><font face="Courier" class=""><br class=""></font>It’s important to note, that the <u class="">above two structs are equivalent</u>, code completion would be the same and the call site would be same.&nbsp;</div><div class=""><br class=""></div><div class="">Syntax is up for grabs. Suggestions would be appreciated. Can this be converged with&nbsp;<a href="https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md" class="">Doug Gregor’s function naming proposal</a>&nbsp;or other proposals in the works?</div><div class=""><br class=""></div><div class="">Mainly, is the <u class="">idea</u> interesting? Can we expand it to include plain functions/methods as well (not just initializers).</div><div class=""><br class=""></div><div class=""><div class="">
<div style="color: rgb(0, 0, 0); font-family: Verdana;  font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); font-family: Verdana; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; line-height: normal; border-spacing: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Verdana; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Verdana; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">David James</div></div></span></div></span></div></span></div></div>
</div>
<br class=""></div></body></html>