[swift-evolution] [Review] SE-0018 Flexible Memberwise Initialization

Kevin Ballard kevin at sb.org
Fri Jan 8 13:17:39 CST 2016

On Fri, Jan 8, 2016, at 11:15 AM, Matthew Johnson wrote:
> > On Jan 8, 2016, at 1:05 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
> > 
> > I had another thought last night about this proposal. Since it appears to be working as syntactic sugar, if I write something like
> > 
> > var x: Int
> > memberwise init(...) {
> >    // what does x refer to here?
> > }
> > 
> > Inside of the memberwise init, does the bare identifier `x` refer to the property, or to the implicit parameter? I think it should refer to the property, because making it refer to the implicit parameter means you'd be referring to a variable that was never visibly declared anywhere.
> > AFAIK the only precedent for that is the implicit argument `newValue` to setters, `oldValue` to didSet observers, and `error` to catch blocks, but those are all constant identifiers that mean the same thing in every such context, as opposed to memberwise init where the implicit parameters are different for each init. More generally, we should avoid exposing such non-declared variables without a compelling reason.
> > 
> > The other argument in favor of making `x` refer to the property is because that's just generally more useful. All the properties match the values of the parameters on the first line of the user-supplied body to the memberwise init, so there's no benefit to be had from leaving the parameters accessible to user code.
> > 
> > As for how to actually accomplish this, assuming this feature is implemented as an AST transformation, ideally we'd have some way to synthesize identifiers in the AST that cannot possibly be referenced by user code (e.g. some form of identifier namespacing if it exists, or some form of gensym-like behavior). Alternatively, if there's no particularly good way to do this, we could just use something like `__name` as the internal parameter name.
> Thanks for bringing this up Kevin.  I agree it should refer to the property.  Not sure what, but for some reason I didn’t think to state this explicitly in the proposal.  In fact, my examples accidentally implied otherwise because they didn’t show the compiler using a mangled name of some kind for the internal parameter name in the expansions.
> The only downside is that it changes behavior if you transition from a memberwsie initializer to a manual initializer.

If you transition to a manual initializer you can provide your own mangled internal parameter names for your manual initializer, so there's no behavioral change. And in most cases the distinction won't actually matter anyway, it's just the cases where a property may change during initialization (either due to modifying it directly, or due to calling a method that modifies it and then reading the property afterwards) where you actually care that the identifier refers to the property.

-Kevin Ballard

More information about the swift-evolution mailing list