# SE-0242: Synthesize default values for the memberwise initializer

**URL:** <https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618>\
**Category:** Proposal Reviews\
**Created:** [February 18, 2019, 4:35pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618 "2019-02-18T16:35:24Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [February 21, 2019, 3:16pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/61 "2019-02-21T15:16:22Z")

</div>

I'm not sure I follow:

> [@xwu](#):
>
> No, that’s only if the default value is nil.

But the default value _is_ `nil`. It will always be `nil`, as the type of the property gets wrapped in an `Optional`, and `some` means "do use this value" and `none` means "keep the default value".

> [@xwu](#):
>
> Otherwise, you could write something like this only if the value is otherwise fully initialized

It is, as it happens only for properties with a default value?

> [@xwu](#):
>
> and the type of the member in question is Equatable.

Why is this constraint required?

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 3:27pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/62 "2019-02-21T15:27:37Z")

</div>

> [@xwu](#):
>
> The spelling `var x = f()` cannot be pure sugar because it is evaluated _regardless of the initializer that is called_ . Similarly, the behavior today cannot be described as a bug because this notation is _the only way to evaluate and assign the return value of `f()` to `x` regardless of the initializer that is called_ . This has many crucial implications, such as the answer to the question, “When has my value been fully initialized?”

Evaluating this regardless of the initializer that is called is precisely the behavior that is questionable. The implications for the initialization model are the reason we cannot fix it without revisiting SE-0018 and the initializer model more broadly.

> [@xwu](#):
>
> There is already a way to spell what you are describing as “what the user wants.” It is to choose **not** to use the notation that explicitly and exclusively means “evaluate `f()` no matter what initializer is used.”

What users often _actually_ want is to declare a “default value” that is used if no other value is specified by the initializer. Usually when an initializer _does_ specify a different value users _do not_ want the “default value” expression to be evaluated at all. Not only is this more aligned with what people intend regarding side effects, it is also compatible with having a “default value” for `let` properties.

Assignment to the property is the only existing syntax that could support the desired behavior. At one point in the SE-0018 discussions I suggested we could have an alternate syntax for “default value” expressions that would _only_ be used in memberwise initailizers and _would not_ be evaluated otherwise. @Chris_Lattner3 was not a fan of this duplication and instead suggested that it might be better to revisit existing semantics. The core team even indicated support for _some_ “default value” solution that would support `let` properties, presumably using the existing syntax.

So I believe changing the semantics of the existing syntax is on the table whenever the topic is revisited in a more broad form. As far as I can tell, this proposal is aligned with the semantics that we would move to. You are of course welcome to have an opinion that it would be a bad direction, but that would only be your opinion. Others are welcome to (and clearly do) have different opinions.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 3:33pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/63 "2019-02-21T15:33:02Z")

</div>

> [@Slava\_Pestov](#):
>
> I'm wondering if the nullary initializer that we synthesize when all properties have a default would still be needed, since with this proposal its equivalent to an invocation of the memberwise init with no arguments.

I had been thinking it would be an unnecessary overload that could cause problems and assumed it would replace that initializer. In thinking deeper though, it would behave differently when the initializer is used as a function value rather than being invoked since default arguments are not used in that case.

With that realization, I’m not sure what the answer is. It would be a breaking change to remove the default initializer, but it does still seem undesirable to have both.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 21, 2019, 3:36pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/64 "2019-02-21T15:36:30Z")

</div>

> [@xwu](#):
>
> Neither of these views would be consistent or source compatible.

They would both be consistent. Each of the two options reflects an internally-consistent perspective. And the second one (pure sugar) would also be source compatible.

On the other hand, if we declare the unwanted behavior to be a bug, then yes, fixing it would not be source-compatible. That is kind of the point of bug-fixes: if the buggy behavior were not observable, there would be nothing to fix.

> [@xwu](#):
>
> The spelling `var x = f()` cannot be pure sugar because it is evaluated _regardless of the initializer that is called_ .

Yes it can be pure sugar, as I demonstrated.

Furthermore, we are talking specifically about `structs` with zero user-defined initializers, meaning the \*only\* initializer available is the implicit default one. There are no other initializers involved.

> [@xwu](#):
>
> Similarly, the behavior today cannot be described as a bug because this notation is _the only way to evaluate and assign the return value of `f()` to `x` regardless of the initializer that is called_ . This has many crucial implications, such as the answer to the question, “When has my value been fully initialized?”

I literally described it as a bug, therefore it can be described as a bug. QED.

And again, there is only one initializer involved, which is synthesized by the compiler. So the answer is that the value has been fully initialized when it is returned from the compiler-synthesized initializer.

> [@xwu](#):
>
> At present, the proposal does not specify the behavior of this scenario, and the implementation currently behaves in a way that cannot be spelled explicitly.

I already provided an example of how to spell the proposed behavior explicitly. Please stop with the false statements.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [February 21, 2019, 3:36pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/65 "2019-02-21T15:36:43Z")

</div>

> [@anandabits](#):
>
> Evaluating this regardless of the initializer that is called is precisely the behavior that is questionable. The implications for the initialization model are the reason we cannot fix it without revisiting SE-0018 and the initializer model more broadly.

Evaluating regardless of the initializer used is the meaning of the syntax in question. I agree that it would be nice to have the feature you describe, but I simply don’t see how it can _supplant_ the meaning of this syntax: it would have to be spelled differently because any such change would be wildly source breaking.

> [@anandabits](#):
>
> So I believe changing the semantics of the existing syntax is on the table whenever the topic is revisited in a more broad form. As far as I can tell, this proposal is aligned with the semantics that we would move to. You are of course welcome to have an opinion that it would be a bad direction, but that would only be your opinion. Others are welcome to (and clearly do) have different opinions.

I don’t think it would be a bad direction; in fact, if designed from scratch, I think it would be a superior design. However, because it would be source breaking, I do think it is an _impossible_ direction for evolution to take.

On that basis, I would be opposed to the current proposal incorporating an unutterable behavior.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [February 21, 2019, 3:49pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/66 "2019-02-21T15:49:41Z")

</div>

> [@DeFrenZ](#):
>
> I'm not sure I follow:
> 
> ![](https://global.discourse-cdn.com/swift/original/2X/e/e99662952abc555ef7669facfb662561a62190b8.png) xwu:
> 
> > No, that’s only if the default value is nil.
> 
> But the default value _is_ `nil` . It will always be `nil` , as the type of the property gets wrapped in an `Optional` , and `some` means "do use this value" and `none` means "keep the default value".

What we are discussing regarding double evaluation is orthogonal to the issue with Optional members. We are taking about functions with side effects being evaluated twice:

```swift
var global: Int = 0
func f() -> Int { global = global + 1; return global }

struct S {
  var x: Int = f()
  var y: Int
  init(_ x: Int = f()) { self.x = x; self.y = f() }
}

```

To avoid evaluating the function twice, you would have to test if `x` already has the desired default value. To do so, the object has to be fully initialized and the member has to be Equatable.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 3:50pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/67 "2019-02-21T15:50:59Z")

</div>

> [@xwu](#):
>
> I agree that it would be nice to have the feature you describe, but I simply don’t see how it can _supplant_ the meaning of this syntax: it would have to be spelled differently because any such change would be wildly source breaking.

Obviously source compatibility is a much bigger concern now than it was back during the SE-0018 discussions early in the Swift 3 timeframe so perhaps you’re right. At that time, having two sets of syntax with subtly different behavior was considered undesirable. I don’t think it’s clear that it would be acceptable today.

I think it’s an overstatement to call it _wildly_ source breaking. The only actual breakage would be when people are actually relying on side effects being performed and the number of times the expression is evaluated changes in the new model.

> [@xwu](#):
>
> because it would be source breaking, I do think it is an _impossible_ direction for evolution to take.

Source breakage is still allowed, it just has to be very well motivated. It’s certainly conceivable that the “actively harmful” threshold could be met in this case. But that’s a discussion for another day.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [February 21, 2019, 3:54pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/68 "2019-02-21T15:54:18Z")

</div>

> [@Nevin](#):
>
> Yes it can be pure sugar, as I demonstrated.
> 
> Furthermore, we are talking specifically about `structs` with zero user-defined initializers, meaning the _only_ initializer available is the implicit default one. There are no other initializers involved.

_I_ am talking about how we would spell the proposed behavior explicitly, when other initializers are involved. _You_ are talking about how to reinterpret the meaning of `var x = f()` as sugar, which of course has to mean the same thing regardless of how many initializers are involved. I urge you to re-read my reply.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [February 21, 2019, 3:57pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/69 "2019-02-21T15:57:49Z")

</div>

> [@anandabits](#):
>
> I think it’s an overstatement to call it _wildly_ source breaking. The only actual breakage would be when people are actually relying on side effects being performed and the number of times the expression is evaluated changes in the new model.

This cuts both ways though; the only observable difference we are discussing here occurs when people are relying on a function to produce a default value and when that function has side effects. By definition no one today is relying on that side effect happening only once, but there are inevitably people relying on it happening more than once.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [February 21, 2019, 4:00pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/70 "2019-02-21T16:00:49Z")

</div>

> [@anandabits](#):
>
> Source breakage is still allowed, it just has to be very well motivated. It’s certainly conceivable that the “actively harmful” threshold could be met in this case. But that’s a discussion for another day.

It is, but whatever the case, I argue here that it is essential for the behavior of this proposal in all circumstances to be utterable.

If you believe it would be reasonable to change the behavior of `var x = f()` in a source-breaking way later, then naturally it would be acceptable to specify one behavior now for the default initializer consistent with the current state of Swift and to change that later. If such a change would be unacceptable, then a fortiori so would the larger proposed change to the meaning of `var x = f()`.

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [February 21, 2019, 4:01pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/71 "2019-02-21T16:01:40Z")

</div>

> [@xwu](#):
>
> To avoid evaluating the function twice, you would have to test if `x` already has the desired default value. To do so, the object has to be fully initialized and the member has to be Equatable.

I see what you mean now.  
Yeah for what I was saying to work it'd need for the default values declared directly on the property to _not_ be applied if a non-`nil` argument is passed, so something like `self.c = c ?? c_default()`

I had no comparisons in mind when I was suggesting that :)

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 4:03pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/72 "2019-02-21T16:03:00Z")

</div>

> [@xwu](#):
>
> _I_ am talking about how we would spell the proposed behavior explicitly, when other initializers are involved.

I agree with @xwu here that the simplistic desugaring @Nevin suggested is not viable. If memberwise initialization were that easy SE-0018 would have looked a lot different, probably would have been accepted, and we would not be discussing memberwise initialization today. There is a lot of subtly involved in making “default value” expressions, synthesized memberwise initialization and custom initializers all play well together.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 4:09pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/73 "2019-02-21T16:09:39Z")

</div>

> [@xwu](#):
>
> By definition no one today is relying on that side effect happening only once, but there are inevitably people relying on it happening more than once.

By definition nobody is relying on it happening more than once _when calling a synthesized initializer_. As has been discussed, the default initializer only performs side effects once. All code relying on the current synthesized memberwise intiailizer is providing all arguments explicitly as there are no default arguments provided.

Nothing in this proposal or a more comprehensive revisiting of SE-0018 will break existing manually written initializers. If we accept this proposal as-is, the path forward to more comprehensive memberwise initialization features would also not be source breaking as the behavior of the synthesized initializer would be to perform side effects _once_. If we require the proposal to be modified to perform side effects _twice_ then moving forward would become more difficult as it would be a breaking change to modify that behavior.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 21, 2019, 4:11pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/74 "2019-02-21T16:11:52Z")

</div>

> [@xwu](#):
>
> > [@DeFrenZ](#):
> >
> > I'm not sure I follow:
> > 
> > > [@xwu](#):
> > >
> > > > [@DeFrenZ](#):
> > > >
> > > > ```swift
> > > > init(a: String, b: Int, c: Double? = nil) {
> > > > self.a = a
> > > > self.b = b
> > > > if let c = c { self.c = c }
> > > > }
> > > > 
> > > > ```
> > > 
> > > No, that’s only if the default value is nil.
> > 
> > But the default value _is_ `nil` . It will always be `nil` , as the type of the property gets wrapped in an `Optional` , and `some` means "do use this value" and `none` means "keep the default value".
> 
> What we are discussing regarding double evaluation is orthogonal to the issue with Optional members. We are taking about functions with side effects being evaluated twice:

The point of DeFrenZ’s example is that the initial value `var c: Double = cValue()` would always happen, including side effects, just as it does today. Then the synthesized memberwise initializer would take an `Optional` parameter for `c` with a default value of `nil.

When called, DeFrenZ’s synthesized memberwise initializer would check to see if a non-nil value was passed in for `c`, and if so it would assign that value to `c`. This means the side-effects of `cValue()` would only occur once, unless the user manually wrote `cValue()` as the argument to the initializer, in which case the duplicate side-effects would presumably be intentional.

> [@xwu](#):
>
> _I_ am talking about how we would spell the proposed behavior explicitly, when other initializers are involved. _You_ are talking about how to reinterpret the meaning of `var x = f()` as sugar, which of course has to mean the same thing regardless of how many initializers are involved. I urge you to re-read my reply.

No, I am talking about how to interpret the behavior of the synthesized memberwise initializer.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 4:12pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/75 "2019-02-21T16:12:08Z")

</div>

> [@xwu](#):
>
> It is, but whatever the case, I argue here that it is essential for the behavior of this proposal in all circumstances to be utterable.

Clearly we have a difference of opinion on this point. I think both sides have been sufficiently articulated to let the core team exercise their judgment on the matter.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 21, 2019, 4:23pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/76 "2019-02-21T16:23:11Z")

</div>

> [@Nevin](#):
>
> When called, DeFrenZ’s synthesized memberwise initializer would check to see if a non-nil value was passed in for `c` , and if so it would assign that value to `c` . This means the side-effects of `cValue()` would only occur once, unless the user manually wrote `cValue()` as the argument to the initializer, in which case the duplicate side-effects would presumably be intentiona

This design is not viable. It changes the type signature of the initializer and assigns magic meaning to `nil`. Further, it leads to very confusing behavior when optional properties are involved. Consider this type:

```swift
struct Foo {
   var bar: Int? = 42
}

```

In order to support a type like this the signature of the synthesized initializer must be `init(bar: Int?? = nil)`. The meaning of this outer `nil` is “use the default value” which is `42`. In order to provide an argument that results in `bar == nil` a caller must specify `.some(nil)` as an argument. This is absurdly complex and makes the design a non-starter even if you are willing to accept the change in type signature and magic meaning of `nil` in other cases.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 21, 2019, 4:28pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/77 "2019-02-21T16:28:06Z")

</div>

> [@anandabits](#):
>
> This design is not viable. It changes the type signature of the initializer and assigns magic meaning to `nil` . Further, it leads to very confusing behavior when optional properties are involved. Consider this type:
> 
> ```swift
> struct Foo {
> var bar: Int? = 42
> }
> 
> ```
> 
> In order to support a type like this the signature of the synthesized initializer must be `init(bar: Int?? = nil)` . The meaning of this outer `nil` is “use the default value” which is `42` . In order to provide an argument that results in `bar == nil` a caller must specify `.some(nil)` as an argument. This is absurdly complex and makes the design a non-starter even if you are willing to accept the change in type signature and magic meaning of `nil` in other cases.

I’m not advocating for it, just describing it. It is important that we all carry out these discussions based on facts and a good-faith effort to understand what other people are saying.

The person I responded to had completely mischaracterized DeFrenZ’s idea, so I wanted to spell it out clearly.

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [February 21, 2019, 4:29pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/78 "2019-02-21T16:29:27Z")

</div>

> [@anandabits](#):
>
> In order to support a type like this the signature of the synthesized initializer must be `init(bar: Int?? = nil)` . The meaning of this outer `nil` is “use the default value” which is `42` . In order to provide an argument that results in `bar == nil` a caller must specify `.some(nil)` as an argument. This is absurdly complex and makes the design a non-starter even if you are willing to accept the change in type signature and magic meaning of `nil` in other cases.

This is fair, and I did highlight that point when I explained the option

> [@DeFrenZ](#):
>
> the signature might be confusing as it might not be clear that passing `nil` to the value means leaving it at its default value

though I did use `Optional` as a quick prototype, but if this is the main issue I can see as a workaround to use something like (names just for example)

```swift
enum Defaultable<T> {
  case default
  case overrided(T)

```

and then the approach makes the init signature `init(a: String, b: Int, c: Defaultable<Double> = .default)`

I'm more worried about whether the semantics of _not_ using the default should still evaluate it

Edit: I realise now that the `enum` approach is quite horrible as it would require each call to pass `.overrided(` when using it 😞 I'm not sure we want the same compiler magic that `Optional` has...

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 21, 2019, 5:09pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/79 "2019-02-21T17:09:56Z")

</div>

> [@anandabits](#):
>
> By definition nobody is relying on it happening more than once _when calling a synthesized initializer_ . As has been discussed, the default initializer only performs side effects once. All code relying on the current synthesized memberwise intiailizer is providing all arguments explicitly as there are no default arguments provided.
> 
> Nothing in this proposal or a more comprehensive revisiting of SE-0018 will break existing manually written initializers. If we accept this proposal as-is, the path forward to more comprehensive memberwise initialization features would also not be source breaking as the behavior of the synthesized initializer would be to perform side effects _once_ . If we require the proposal to be modified to perform side effects _twice_ then moving forward would become more difficult as it would be a breaking change to modify that behavior.

I think this is the crux of the matter, and bears repeating.

+1

> [@jrose](#):
>
> Grr. I didn't mean to get mixed up with the no-arg initializer in my example, but I have a strong distaste for the compiler doing something you can't write explicitly yourself, particularly if we ever get an "expose the memberwise initializer as `public` " annotation. I'm against this proposal if it does _not_ evaluate twice if manually writing the equivalent thing _does_ evaluate twice.

Today is your lucky day!

As it turns out, you \*can\* already write code that gives the same user-facing behavior as the proposal, evaluating side-effects only once. In fact, there are two different ways to do so, one of which involves a _ **lot** _ more boilerplate than the other.

**First way:**  
Don’t use initial values with side effects, and instead manually define the initializers you want, putting the side-effectful calls into each of them as either a default value in the declaration or an assignment in the body, as appropriate. This is fairly repetitive and difficult to maintain, but it does work.

**Second way:**  
When initial values have side effects, for every initializer that “wants to” use that initial value as a default argument, instead make two versions of that initializer, one with the corresponding parameter having no default value, and the other without that parameter at all. This of course multiplies the number of initializers by 2n, where n is the number of properties whose initial values have side effects, and is thus extremely verbose.

• • •

The first way entails a small amount of boilerplate: eschewing initial values in favor of default arguments in initializers.

The second way entails an exponentially large amount of boilerplate: duplicating initializers for every possible combination of arguments being present or absent.

But the fact remains, both of these approaches result in user-facing code with the same behavior as is proposed. Thus, the proposal can in fact be viewed as an extremely convenient way to reduce unseemly boilerplate.

---

<div class="post-metadata">

**Author:** ![michelf](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michelf/32/1180_2.png) [@michelf](https://forums.swift.org/u/michelf)\
**Post date:** [February 21, 2019, 8:57pm UTC](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618/80 "2019-02-21T20:57:02Z")

</div>

I got a bit lost in all this discussion and I might have skipped over a post similar to what I'm about to write, but to me it sounds like you already can use the default initializer to sidestep default value evaluation. Take this example:

```swift
func getDefaultValue() -> Int {
	print("requested default value")
	return 0
}
struct S {
	var i: Int = getDefaultValue()
}
let s1 = S(i: 1)

```

It prints absolutely nothing because `S(i: 1)` magically skips evaluating the default value. If you try to manually write an initializer that does the same thing, it won't work:

```swift
init(i: Int) {
	// default values already evaluated at this point
	self.i = i
}

```

Synthesized initializers already behave in this particular way when you provide the initial values (not evaluating the default values) and it'd be surprising if this proposal was to change that.

Surely there is a need to have a better way to choose whether the default values get evaluated in manually written initializers, and I do have some ideas, but I don't see this as being very relevant here. Hopefully the proposal won't get derailed because of this.

[Previous page](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618.md?page=3)

[Next page](https://forums.swift.org/t/se-0242-synthesize-default-values-for-the-memberwise-initializer/20618.md?page=5)
