<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 Jan 8, 2016, at 5:41 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; 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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 8, 2016, at 4:14 PM, Paul Cantrell &lt;<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>&gt; 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=""><blockquote type="cite" class=""><div class=""><span style="font-family: HelveticaNeue;" class="">Would you propose removing the current implicit memberwise initializer for structs on the same grounds?</span></div></blockquote><div class=""><br class=""></div><div class="">No, it’s a much smaller feature surface. I would proposed promoting it from a simple, situational feature to something very generic — much like what Joe Groff is doing with “lazy.”</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">How exactly would you do this? &nbsp;I don’t understand what you think that would look like.</div></div></div></div></blockquote><div><br class=""></div><div>It would like what I sketched out in remainder of my previous message.</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=""><div class="">Making it more capable is what my proposal is attempting to do so I am confused by this statement.</div></div></div></div></blockquote><div><br class=""></div><div><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="">Making it more capable is not what I’m talking about. Making it more generic and more flexible it is what I’m talking about.&nbsp;</div><div class=""><br class=""></div><div class="">The property behaviors proposal, at least as I understand it, could change “lazy” from being a <i class="">language</i> feature to being a <i class="">library</i> feature. In the language, lazy is replaced with something more flexible and generic, something that could give rise to other new features totally unrelated to laziness, but built from the same new building blocks.</div><div class=""><br class=""></div><div class="">The “memberwise” proposal, on the other hand, would be analogous to expanding the “lazy” feature at the language level, adding a bunch of new rules and behavior to it.</div><div class=""><br class=""></div><div class="">• • •</div><div class=""><br class=""></div><div class="">Based on your feedback, I’m not sure the central point of my review came across. I don’t think I can explain it better than I did in the review, but maybe others can find the words.</div></div></div></div><div><br class=""></div><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=""><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=""><div class="">Here’s a sketch of that — not a proposal, total BS syntax, totally hypothetical:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">struct</span> S {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> s0, s1, s2: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">private</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> i: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">init</span>(anInt: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>, anotherInt: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>, otherArgs: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Members.</span>except(<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">i</span>)) {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; members =&nbsp;otherArgs&nbsp;&nbsp;<span style="color: rgb(102, 139, 73); font-size: 10.5px;" class="">// assigned members inferred from tuple item names</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = anInt &gt; anotherInt ? anInt : anotherInt</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div></div><div class="">I’d be happy — happier! — with a solution like that, despite the modest additional keystrokes, because (1)&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">members</span>&nbsp;and&nbsp;<span style="color: rgb(88, 126, 168); font-family: Menlo; font-size: 11px;" class="">Members</span>&nbsp;would presumably have a more predictable behavior that’s easier to remember and to understand by reading, and (2) they’d be usable in other contexts:</div><div class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> updateFrom(other: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">S</span>) {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">self</span>.members = other<span style="font-size: 10.5px;" class="">.except(i)</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; i = anInt &gt; anotherInt ? anInt : anotherInt</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">…or heck, even this:</div><div class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> updateTwoStrings(s0: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span>, s1: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span>) {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; members = arguments</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> updateTwoStrings(s0: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span>, s1: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span>, message: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span>) {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">print</span>(message)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; members = arguments.except(message)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">OK, I concede I'm now brainstorming quite a feature list here:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class=""><span style="font-family: Menlo; font-size: 11px;" class="">members</span>&nbsp;property that turns all (stored?) properties into a tuple,</li><li class=""><span style="color: rgb(88, 126, 168); font-family: Menlo; font-size: 11px;" class="">Members</span>&nbsp;property that returns the type of the above,</li><li class=""><span style="font-family: Menlo; font-size: 11px;" class="">select<span style="font-family: 'Helvetica Neue'; font-size: 13px;" class="">&nbsp;/&nbsp;</span>except</span>&nbsp;operations on any tuple that create a new tuple by filtering keys,</li><li class="">assignment of a tuple to&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">members</span>&nbsp;that matches by tuple key (and the tuple can contain a subset of all properties),</li><li class=""><span style="font-family: Menlo; font-size: 11px;" class=""><span style="font-family: 'Helvetica Neue'; font-size: 13px;" class="">some way of variadically expanding a tuple type in an arg list, and</span></span></li><li class=""><span style="font-family: Menlo; font-size: 11px;" class="">arguments</span>&nbsp;implicit variable that gives all func args as a tuple. (That last one’s not necessary to replace this proposal; just threw it in there because I’m brainstorming.)</li></ul></div><div class=""><br class=""></div><div class="">That’s a lot! But all these feature are more independent, flexible, and transparent than the ones in the proposal. They (1) need not all be understood all at once, (2) have less implicit behavior and rules about corner cases, (3) thus have a simpler mental model and are easier to understand just by reading, and (4) provide more capabilities in a broader range of contexts.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I really don’t think the “members” computed tuple property is a workable solution for initializing `let` properties.</div></div></div></div></blockquote><div><br class=""></div><div>What not? All the static type information is there for the compiler to apply the same checks it does right now.</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=""><div class="">Any such property that was allowed to do so would not work outside an initializer anyway as it would try to mutate a `let` when you used it.</div></div></div></div></blockquote><div><br class=""></div><div>Well, yes, because instead of invisible magic, the “members = tuple” initialization behaves exactly like any other assignment.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">I have also been thinking a lot about approaches that would be similar in some sense and build on a general purpose parameter forwarding mechanism. &nbsp;I have some ideas that I am going to work on fleshing out tonight.</div></div></div></blockquote><br class=""></div><div>That’s the sort of thing I’d be interested in seeing.</div><div><br class=""></div><div>Cheers,</div><div><br class=""></div><div>Paul</div><br class=""><div class=""><br class=""></div></body></html>