[swift-evolution] [Proposal Draft] Flexible memberwise initialization

Howard Lovatt howard.lovatt at gmail.com
Wed Jan 6 16:52:07 CST 2016

Here is an expanded proposal for the syntax for a Scala style memberwise
syntax and equivalent code, specification is via an example rather than
formal syntax since this is easier to follow. Note it is like Scala’s
syntax but it is ‘Swiftified” (in particular still retains `init` keyword).

    class Ex public init(
        superParam: sPType = sPInitial,
        private label privateParam: pPType = pPInitial,
        calculatedParam: cPType = cPInitial
    ): SuperType(superParam) {
        calculatedParam: cPType {
            get {…}
            set {…}

This gets translated to:

    class Ex: SuperType(superParam) { {
        private privateParam: pPType = pPInitial,
        public init(superParam: sPType = sPInitial, label privateParam:
pPType = pPInitial, calculatedParam: cPType = cPInitial) {
            // 1. Call super
            // 2. Initialize generated parameters and existing parameters
            self.privateParame = privateParam
            self.calculatedParam = calculatedParam
        calculatedParam: cPType {
            get {…}
            set {…}

Because the syntax is so short it is part of this proposal to remove both
the current default and memberwise initialisers thus simplifying the
language overall (remove two features, add one) and at the same time gain
power, which is a rare situation and therefore I would suggest optimal.

It is also more powerful than the proposed `memberwise init(..)` and/or
existing automatic `inits` in the following ways:

1. Allows `lets` to have a default value.
2. Allows other properties including computed properties to have a default
3. Allows any `super.init` to be called (not restricted to `super.init()`).
4. Allows control of which properties participate in the `init` (they are
listed in the brackets and are not in a super call and are not
an existing property).
5. Allows private properties to be initialised.
6. Allows properties including private properties to have a label instead
of their actual name and hence not expose internals (also allows migration
of implementation whilst retaining external interface).
7. Allows calls to the generated `init` that don’t specify all members,
i.e. for `struct Ex init(i: Int = 0, s: String = “") {}` the following are
allowed `Ex()`, `Ex(i: 1)`, `Ex(s: “A”)`, and `Ex(i: 2, s: “B”)`.
8. Allows visibility of automatically generated `init` to be controlled.
9. Supports property behaviours.
10. Does not require a new keyword.

The downsides of the proposal relative to  `memberwise init(..)` and/or
existing automatic `inits` are:

1. That people would need to be careful when laying out their code
otherwise the first line could become long (a bit of pretty printing solves
2. Existing structs/classes that have automatically generated inits would
need to be refactored, e.g. `CGRect` would become `struct CGRect init(var
origin: CGPoint, var size: CGSize) {}` (a migration tool would help here).

Other than the downsides listed above the proposal does everything the
current proposal and current implementation does and more (more also listed
above) and is simpler to both explain and implement.

The above more than addresses the reasons given in the current proposal for
not using the Scala syntax and demonstrates superiority in many areas.
However if it were the current proposal or nothing I would go with the
current proposal since something is better than nothing.

On Wednesday, 6 January 2016, Matthew Johnson <matthew at anandabits.com>

> On Jan 5, 2016, at 12:12 PM, Tino Heth <2th at gmx.de
> <javascript:_e(%7B%7D,'cvml','2th at gmx.de');>> wrote:
> The “type parameter list” syntax is sugar that could be implemented as a
> layer on top of the current proposal or could be implemented orthogonally.
> Hi Howard,
> I've heard this argument before, so I'll repeat my answer as well:
> Both offers don't make sense, it's either one way or the other (or
> something completely different).
> I don’t think it’s clear whether both make sense or not.  They are not
> mutually exclusive and are aimed at solving related, but different
> problems.  If we adopt the current proposal, the Kotlin / Scala syntax
> *might* make sense for some use cases.  It would depend upon whether the
> current proposal is considered too verbose in enough cases or not.  This
> may or may not turn out to be the case.
> The reason my proposal looks the way it does is because there are specific
> goals it intends to achieve and problems it is intended to solve.  These
> goals and problems are not adequately addressed by the Kotlin / Scala
> syntax.
> If diversity starts here, why not have "const" and "val" beside "let", or
> allow "fn" and "lambda"?
> @Matthew: Please, if you support something, then say so - using clear
> words, not phrases like "could be implemented”.
> This phrasing is plenty clear IMO.  I am stating a possibility.  I do not
> have a position on whether or not it is a good idea at the moment.
> I have made some modifications to the proposal over the last few days.
> These changes have been partly motivated by considering the conversation we
> have had.  You may wish to give it another look.  If so, please look here:
> https://github.com/anandabits/swift-evolution/blob/flexible-memberwise-initialization/proposals/0018-flexible-memberwise-initialization.md.
> There is currently an open PR for the latest change so it is not in the
> main Swift evolution repo yet.
> The most recent change includes a discussion of why it does not use the
> Scala / Kotlin syntax.  You may not like the choice but I hope you can at
> least understand the rationale (even if you disagree with it).

  -- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160107/33939e95/attachment.html>

More information about the swift-evolution mailing list