[swift-evolution] [Proposal Draft] Flexible memberwise initialization
Chris Lattner
clattner at apple.com
Tue Dec 22 12:15:29 CST 2015
> On Dec 22, 2015, at 9:59 AM, David Owens II <david at owensd.io> wrote:
>
>
>> On Dec 22, 2015, at 9:43 AM, Matthew Johnson <matthew at anandabits.com> wrote:
>>
>> Adding a new member to a struct is itself a breaking change. I don’t see how memberwise initialization makes this worse.
>
> It may have been a bad example as you handle the case where they wouldn’t be a breaking change by promoting the default initialization to the memberwise init().
There are already a number of features in Swift which make it “too easy” to accidentally break API/ABI of a framework. We plan to address this (in time) with an API diff’er tool which you can use to identify these problems for you. We would like to integrate this into the package manager as well, so it helps “enforce” proper semantic versioning.
In your previous email you wrote:
> Example:
>
> v1.0 of the API ships:
>
> struct Person {
> let name: String
> }
>
> v1.1 of the API ships:
>
> struct Person {
> let name: String
> let age: Int
> }
This is a perfect example of this problem. I agree with you completely that it is “too easy” to make this mistake and not know that you’re breaking clients of your API. The only way to handle this in full generality is with a diff’er tool. Such a tool would tell you that the right solution to this is:
struct Person {
let name: String
let age: Int = 0 // or some other default value.
}
or to remove memberwise, and write out the initializer long hand.
A lot of folks on the Swift team care - a lot - about long term API evolution and features to make this possible. That’s the whole point of the resilience feature (aka “nonfragile everything” :) that we’re working on this year. However, framework development is somewhat specialized, and memberwise initializers make common issues in app development much simpler.
If we were overly concerned about memberwise initializers being an API evolution problem, then there is a simple solution: do not allow a *public* memberwise initializer. We effectively already have that approach today in Swift 2.
-Chris
More information about the swift-evolution
mailing list