[swift-evolution] Proposal: helpers for initializing properties of same name as parameters

Tal Atlas me at tal.by
Sat Dec 5 09:23:52 CST 2015


I still think that it should include the type in the initializer definition
because if you have private properties you’d need to expose the type
information somehow and that type inference doesn’t work that way anywhere
else in swift, so explicitly requiring the type information in the
initializer is consistent with the rest of swift.

On Sat, Dec 5, 2015 at 12:20 AM <crk at fastmail.com> wrote:

> I'm not entirely sure what your proposal changes, other than omitting the
> argument labels and us wing self to refer to the property. Could you try a
> trivial example that would be runnable if the change was implemented?
>
> Thanks for your time,
> Cole Kurkowski
>
> On Dec 4, 2015, 21:59 -0600, Matthew Johnson <matthew at anandabits.com>,
> wrote:
>
> I think this idea scratches at the surface of a problem with initializers
> that definitely merits some attention.  Boilerplate is common in
> initializers which can lead to types that don’t allow as much flexibility
> to callers as might be desirable.
>
> More importantly, it can also lead to “initialized” instances that are not
> fully or properly configured, (implicitly unwrapped?) optional members, and
> mutability that shouldn’t be necessary past the initial configuration stage
> of the instance.  For example, if a type provides a family of initializers,
> but also has several members which are intended to be initialized /
> configured directly by callers a developer could choose to avoid the
> boilerplate by declaring the additional members as as an implicitly
> unwrapped optional var members.  No doubt this is a bad idea.  If the
> caller does not initialize all of the additional members there is a bomb
> waiting to go off.  Furthermore, there is the potential for mutation after
> initialization that may not be expected or intended.  By requiring a
> nontrivial amount of boilerplate to avoid this situation the language is
> unintentionally nudging lazy developers towards bad practices like this.
>
> Let's start with the current proposal but go a bit further and see how
> much boilerplate can be removed.  The type information is already known
> from the property declaration, and furthermore a default may also be
> available in the property declaration.
>
> struct Foo {
>     let bar: String
>     let bas: Int = 1
>     let bat:  Float = 0
>     let bax: String = “default"
>     let baz: Double
>
>     // self.bar is known to be a String but does not have a default value
> so it must be provided by the caller
>     // self.bas is known to be an Int and implicitly has a default value
> of 1 specified by the property
>     // so it does not need to be provided by the caller
>     // self.bat is known to be a Float, but the default is overridden to
> be 1 instead of 0
>     // external labels are provided that correspond to the names of the
> properties
>     init(self.bar, self.bas, self.bat = 1) {
> // the initializer does not receive a value for baz and the property does
> not provide a default
>         // so it must be initialized here before the first phase of
> initialization is complete
>         // if all stored properties had received values through parameters
> or through property defaults
>         // the first phase of initialization would have already been
> completed when the body of the initializer was entered
>         self.baz = someComputedDoubleValue()
>         // now all stored properties have been initialized so the first
> phase of initialization is complete
>     }
> }
>
> This structure allows us to remove the boilerplate of the property type
> and default value.
>
> Given the significant difference from regular function parameters, it may
> make sense to set these apart syntactically in some way, although I am not
> sure what would make the most sense.  For example, we could just have a
> second parameter tuple in the initializer declaration which represents the
> “member parameters” to the initializer like this:
>
> init(foo: Int)(self.bar, self.bas, self.bat = 1)
>
> or a vertical pipe like this:
>
> init(foo: Int | self.bar, self.bas, self.bat = 1)
>
> Setting these “member parameters” apart syntactically could also
> facilitate additional mechanisms to further reduce boilerplate if we find
> that the same group of “member parameters" exist for several different
> initializers in the same type.  For example, it might become possible to
> implement a memberwise initializer like this:
>
> // @automembers expands to match all stored properties
> init()(@automembers) {}
>
> At this point we have eliminated virtually all of the boilerplate,
> encouraging developers to use concise *and* safe, yet still flexible
> initialization strategies.
>
> Matthew
>
>
>
> On Dec 4, 2015, at 9:05 PM, Dan Appel <dan.appel00 at gmail.com> wrote:
>
> I'm not sure how I feel about this, but in either case, why limit it to
> default parameters? It's useful in other situations, too.
>
> Take this for example:
> struct Foo {
>     let bar: String
>     let bas: Int
>     let baz: Double
>     init(self.bar: String, self.bas: Int, bax: Int) {
>         self.baz = Double(bax)
>     }
> }
>
> where the need to say
>
> self.bar = bar
> self.bas = bas
>
> is now avoided.
>
> On Fri, Dec 4, 2015 at 3:16 PM Tal Atlas <me at tal.by> wrote:
>
>> There’s lots of boilerplate of initializing structs with stored
>> properties and initializer parameters. I’d like to create a syntax for
>> alleviating that in the 90% case.
>>
>> ```swift
>> struct Foo {
>>     let bar: String
>>     let baz: Int
>>
>>     init(self.bar: String = "default", counter self.baz: Int) {
>>     }
>> }
>> ```
>>
>> This would be identical to:
>> ```swift
>> struct Foo {
>>     let bar: String
>>     let baz: Int
>>
>>     init(bar: String = "default", counter baz: Int) {
>>         self.bar = bar
>>         self.baz = baz
>>     }
>> }
>> ```
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
> --
> Dan Appel
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151205/7920b864/attachment-0001.html>


More information about the swift-evolution mailing list