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

Howard Lovatt howard.lovatt at gmail.com
Wed Jan 6 22:56:33 CST 2016


Yes I did mess up the translation, that will teach me to do it at night on
an iPad (therefore no compiler). The correct translation is:

Types and let's needed for example:

    public class SuperType {
        init(_: SPType) {}
    }
    public struct SPType {}
    public struct PPType {}
    public struct CPType {}
    let sPInitial = SPType()
    let pPInitial = PPType()
    let cPInitial = CPType()

Example:

    public class Ex public init(
        superParam: SPType = sPInitial,
        private label privateParam: PPType = pPInitial,
        calculatedParam: CPType = cPInitial
    ): SuperType(superParam) {
        var calculatedParam: CPType {
            get { return CPType() }
            set {}
        }
    }

Would be translated to:

    public class Ex: SuperType {
        private let privateParam: PPType
        public init(superParam: SPType = sPInitial, label
privateParam: PPType = pPInitial, calculatedParam: CPType = cPInitial) {
            // 1. Initialize generated stored properties and existing
stored properties, but not calculated properties
            self.privateParam = privateParam
            // 2. Call super
            super.init(superParam)
            // 3. Initialize calculated properties
            self.calculatedParam = calculatedParam
        }
        var calculatedParam: CPType {
            get { return CPType() }
            set {}
        }
    }

You say "There are also several aspects of this translation that are
somewhat vague"; without more detail it is difficult to know what you mean,
can you elaborate please. The proposal is meant to be equivalent to a
textual translation so I was hoping that an example would be sufficient;
happy to elaborate if you say what you don't get.

You say "Several of these points are also true of my proposal and several
others would be true if what I believe are the most important future
enhancements are added." Again can you elaborate, difficult to respond
without knowing what points and why. I am not trying to be awkward but I am
unsure what you mean. As a general note there is a lot in the current
proposal that says this could be added in the future, I was responding to
the proposal as proposed not what might be added in the future. Also if
there are some aspects of the proposal that really need to be added then
they should be part of the proposal.

Pretty much along the same lines, you say "This is not true.  There are
additional differences." What additional differences?

And again, you say "I disagree.  The current proposal clearly states
reasons not addressed here." Can you expand? Obviously I thought I had
covered everything otherwise I wouldn't have said that the points are
covered. So can you point me in the direction of your concerns?

On Thursday, 7 January 2016, Matthew Johnson <matthew at anandabits.com> wrote:

>
> On Jan 6, 2016, at 4:52 PM, Howard Lovatt <howard.lovatt at gmail.com
> <javascript:_e(%7B%7D,'cvml','howard.lovatt at gmail.com');>> wrote:
>
> 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
>             super.init(superParam)
>             // 2. Initialize generated parameters and existing parameters
>             self.privateParame = privateParam
>             self.calculatedParam = calculatedParam
>         }
>         calculatedParam: cPType {
>             get {…}
>             set {…}
>         }
>     }
>
>
> This translation is not valid Swift for several reasons.  There are also
> several aspects of this translation that are somewhat vague and a detailed
> design is necessary to evaluate how you envision it working.
>
>
> 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
> value.
> 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.
>
>
> Several of these points are also true of my proposal and several others
> would be true if what I believe are the most important future enhancements
> are added.
>
>
> 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
> this).
> 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.
>
>
> This is not true.  There are additional differences.
>
>
> The above more than addresses the reasons given in the current proposal
> for not using the Scala syntax and demonstrates superiority in many areas.
>
>
> I disagree.  The current proposal clearly states reasons not addressed
> here.
>
> I don’t wish to
>
> 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
> <javascript:_e(%7B%7D,'cvml','matthew at anandabits.com');>> wrote:
>
>>
>> On Jan 5, 2016, at 12:12 PM, Tino Heth <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.
>
>
>

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


More information about the swift-evolution mailing list