SE-0242: Synthesize default values for the memberwise initializer

Proposal Accepted

SE-0242 is accepted, with a request that the original proposal be amended for clarification of actual behavior. The Core Team felt that the proposal should more explicitly illustrate the actual behavior in a few specific cases, as this was the crux of some of the back-and-forth in the review thread.

Note: the proposal has been updated to include more details in the “proposed solution” section, as requested by the Core Team.

There was some concern in the review thread about potentially ambiguities, particularly with code looking like this:

struct A {
  var b: Int = 0
}

let c = A.init // Ambiguous between init() and init(b:)

The Core Team discussed this, and noted that there was already a more fundamental problem with ambiguity in which you can leave off the arguments when you use a function reference. This causes problems in many places today, and is something that should be explored further in a different proposal. This proposal doesn't seriously exacerbate the current problem.

The proposal review also discussed an interesting behavioral quirk with initial values and side-effects, for example:

struct Foo {
  var i: Int = getDefaultValue()
}

struct Bar {
  var i: Int = getDefaultValue()
  init(i: Int) { self.i = i }
}

let x = Foo(i: 1)  // No side effects
let y = Bar(i: 1)  // Yes side effects

The Core Team felt that this was a bug in the compiler's implementation of initializers. The failure here is that Bar calls the side effect, and it is not the right behavior. Addressing this would likely require an evolution proposal, or at least an assessment of whether or not fixing this would break existing code.

18 Likes