<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 12:51 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=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Are you suggesting that this attribute would be applied to a specific initializer? &nbsp;Or would this be shared by all memberwise initializers of the type in some way?</div></div></blockquote><div><br class=""></div><div>I meant it as a type-level declaration.</div><div><br class=""></div><div>The mental model here is that in many cases, a type with multiple public initializers winds up (or at least should wind up) like this:</div><div><br class=""></div><div>- there’s a common “package” comprised of:</div><div>&nbsp; - the input parameters (e.g. init args)</div><div>&nbsp; - the boilerplate assignments (in the init)</div><div>- each init has some additional parameters/logic not shared with the other</div><div><br class=""></div><div>For another example, this is lightly-adapted from actual code:</div><div><br class=""></div><div>class PlayerItemWrapper : NSObject {</div><div>&nbsp; let previewInfo: PreviewInfo</div><div>&nbsp; let itemDescriptor: ItemDescriptor</div><div>&nbsp; let metricCollector: MetricCollector</div><div>&nbsp; let playerItem: AVPlayerItem</div><div><br class=""></div><div>&nbsp; // assume trivial assignments followed by observation-setup logic:</div><div>&nbsp; required init(previewInfo: PreviewInfo, itemDescriptor: ItemDescriptor, metricCollector: MetricCollector, playerItem: AVPlayerItem)</div><div><br class=""></div><div>&nbsp; // these exist for convenience only; we have them b/c we don’t want to directly use</div><div>&nbsp; // the corresponding AVPlayerItem convenience methods, since we also want to</div><div>&nbsp; // control some of automatically loaded keys (etc.)</div><div>&nbsp; convenience init(previewInfo: PreviewInfo, itemDescriptor: ItemDescriptor, metricCollector: MetricCollector, asset: AVAsset)</div><div>&nbsp; convenience init(previewInfo: PreviewInfo, itemDescriptor: ItemDescriptor, metricCollector: MetricCollector, assetURL: NSURL)</div><div>&nbsp; convenience init(previewInfo: PreviewInfo, itemDescriptor: ItemDescriptor, metricCollector: MetricCollector, assetDescriptor: AssetDescriptor)</div><div>}</div><div><br class=""></div><div>…where you can easily see these inits have the structure of a “common package” + per-init details.</div><div><br class=""></div><div>Under the organization above, it then makes sense to me to have a type-level declaration that is able to declare that type’s “official” common package, which would let the above be condensed into something like:</div><div><br class=""></div><div><div>class PlayerItemWrapper : NSObject {</div><div>&nbsp; @memberwise(previewInfo, itemDescriptor, metricCollector)</div><div>&nbsp; // ^ need to be explicit here to *omit* playerItem, unless we</div><div>&nbsp; // &nbsp; also plan to immediately have an @nomemberwise declaration</div><div>&nbsp; // &nbsp; we can apply to individual properties</div><div>&nbsp; let previewInfo: PreviewInfo</div><div>&nbsp; let itemDescriptor: ItemDescriptor</div><div>&nbsp; let metricCollector: MetricCollector</div><div>&nbsp; let playerItem: AVPlayerItem</div><div><br class=""></div><div>&nbsp; // assume trivial assignments followed by observation-setup logic:</div><div>&nbsp; memberwise required init(..., playerItem: AVPlayerItem)</div><div><br class=""></div><div>&nbsp; // these exist for convenience only (and would need a way to forward the …&nbsp;</div><div>&nbsp; // to the required init, e.g. `self.init(…, playerItem: _)`, which is seems to be</div><div>&nbsp; // noted as a future direction in the current proposal</div><div>&nbsp; memberwise convenience init(…, asset: AVAsset)</div><div>&nbsp; memberwise convenience init(..., assetURL: NSURL)</div><div>&nbsp; memberwise convenience init(..., assetDescriptor: AssetDescriptor)</div><div>}</div><div class=""><br class=""></div><div class="">…and because writing out such parameter lists explicitly is a bit of a pain, the hope is that it’d also be possible to simply write e.g. @memberwise w/out an explicit list and get some automatically-inferred list synthesized on your behalf wherever possible.</div><div class=""><br class=""></div><div class=""><div class="">Hope this clears up the kind of thing I was trying to sketch earlier. It is at a different point in the flexibility/feature spectrum for sure, and not thought-through too thoroughly either.</div></div><div class=""><br class=""></div></div><div>I also made a significant earlier error: it shouldn’t be an error if some @memberwise’s $parameterList was *incomplete*, the only error is if it contains invalid/unrecognized names.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">I don’t think applying this to a specific initializer gains enough over just writing the initializer manually to be worthwhile. &nbsp;If we were going to do something specific to a single initializer, something along the lines of David’s suggestion makes the most sense to me.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">On the other hand, if you are suggesting something type-wide that would be shared by all memberwise initializers, this is really an alternate way to accomplish an opt-in model. &nbsp;Rather than applying an attribute to properties you would have a declaration specify which properties are included in memberwise initializers, with the ability to specify order, labels, and defaults if necessary. &nbsp;</div></div></blockquote><div><br class=""></div>This is what I meant, essentially. An explicit @memberwise as per the above saves minimal effort if you had to do it on a per-init basis, but in scenarios with a bunch of basic parameters + various convenience inits for the remaining parameters it could still be a net win.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">That might be a reasonable syntax for an opt-in model. &nbsp;As noted in the proposal, an opt-in model could be added by a future enhancement and would be used in place of the automatic model if the opt-in syntax was present.</div></div></blockquote></div><br class=""><div class="">If this goes anywhere I am hoping someone will improve the syntax, actually, what I sketched seems clunky and non-idiomatic.</div><div class=""><br class=""></div><div class="">In any case, having seen how this discussion has gone I think it’s safe that at least in hindsight starting from the purely-automatic/purely-inferred synthesis standpoint may ultimately have made this proposal than it needs to have been.</div><div class=""><br class=""></div><div class="">It’s a *really* good goal — I’d like to be able to get the memberwise init synthesized automatically where possible! — and I think within the design constraints you’ve been working under it may not be possible to do it that much better than as per your proposal…but I think the conclusion here is that “it seemed plausible to extend the memberwise-init synthesis like this, but if you work through it in enough detail to make it concrete, it has a surprising amount of intrinsic complexity/inference rules/edge-cases to worry about”.</div><div class=""><br class=""></div><div class="">That’s my overall 2c here (along with what’s in the earlier emails).</div><div class=""><br class=""></div></body></html>