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

David Owens II david at owensd.io
Thu Jan 7 12:32:26 CST 2016


> On Jan 7, 2016, at 10:14 AM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On Jan 7, 2016, at 10:03 AM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>> 
>> 
>>> On Jan 7, 2016, at 11:39 AM, Joe Groff <jgroff at apple.com <mailto:jgroff at apple.com>> wrote:
>>> 
>>> 
>>>> On Jan 7, 2016, at 8:28 AM, Dave Abrahams <dabrahams at apple.com <mailto:dabrahams at apple.com>> wrote:
>>>> 
>>>> The latter I'm afraid. 
>>> 
>>> I was just discussing this design space with Chris Willmore, who's been working on revamping how our function type model works. If we move to a multiple-argument model for functions rather than the current every-function-takes-a-tuple-argument model, then we will likely need at least limited support for packing and unpacking tuples from and to arguments in order to avoid regressing at argument forwarding use cases. However, even that limited packing/unpacking functionality might be enough to seriously consider a more general magic "members" property as an alternative.
>> 
>> I don’t mind discussing an alternative using this approach.  If we’re going to do that I think it must be clear how it would cover various intended use cases in detail.  Specifically, how would we address:
>> 
>> 1. Default parameter values (at least for `var` properties)
>> 2. `let` properties: it seems pretty magical indeed if the computed `var` property exposing the tuple could be used to initialize a `let` property.
> 
> Yeah, this member would need special initialization abilities, I agree.
> 
>> 3. Partial memberwise initialization exposing a subset of members following some kind of “automatic” or “opt-in” model for determining the subset.
> 
> Seems to me that could be done by factoring the interesting subsets into structs, e.g.:
> 
> class Foo {
>   internal struct MemberwiseProperties {
>     var x,y,z: Int
>   }
>   internal var state: MemberwiseProperties
> 
>   init(members...: MemberwiseProperties.Members) {
>     state.members = members
>   }
> }

And this is more clear than this?

class Foo {
  var x,y,z: Int
  init(x: Int, y: Int, z: Int) {
    self.x = x
    self.y = y
    self.z = z
  }
}

It seems odd to me to change the design of your type for the sole purpose of using a language feature. 

It’s the complexity of the feature and its applicability only to initialization that lead me to vote no for the proposal. I've wanted public, generated initializers (ask to the internal generated struct inits). However, as you dig into to see what you really need to support, the complexities become quite nuanced.

I keep coming back to a much simpler and more explicit desire of being able to use “self” (this is not a label, but an annotation like "inout") in the parameter list. This is applicable to all members of a type.

class Foo {
  var x,y,z: Int
  init(self x: Int, self y: Int, self z: Int) {
    // the compiler auto-inserts these lines
    self.x = x
    self.y = y
    self.z = z
  }

  func fooey(self x: Int) {
    // the compiler generates
    self.x = x
  }
}

I’m not convinced that even that is worth the magic it brings to the table, but it does get rid of nearly all of the complexities, becomes more applicable than just initialization, and has only a single rule to learn that is fairly self-explanatory. The trade-off is you must be explicit about the members of the initializer. I’m OK with that because if I have a type that really has so many members that this is a burden, then I should probably refactor it. A sufficient macro system also trivially solves this issue as well.

-David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160107/169f2c62/attachment.html>


More information about the swift-evolution mailing list