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

Brent Royal-Gordon brent at architechies.com
Sat Dec 5 15:03:55 CST 2015


> 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) {
>     }
> }
> ```

I’d like to propose an alternative approach.

Swift already generates a default initializer for structs that don’t have any initializers explicitly defined. However, the moment you write init(, that initializer disappears. It’s also never available on classes, because they have to dispatch to another initializer.

I propose that we make it possible to explicitly ask for that default initializer:

    struct Foo {
        let bar: String
        let baz: Int
        
        init() {
            bar = “default”
            baz = 0
        }

        init default	// automatically generates init(bar: String, baz: Int)
    }

Moreover, I propose we extend this to classes:

    struct Foo: Bar {
        let bar: String
        let baz: Int
        
        init() {
            bar = “default”
            baz = 0
        }

        init default()	// automatically generates init(bar: String, baz: Int) with super.init()
    }

In a class, the “default” statement must have parens after it; these indicate the parameters to be added for the superclass initializer. If you need to super up to an initializer that takes parameters, you add the needed parameters there:

    struct Foo {
        let bar: String
        let baz: Int
        
        init() {
            bar = “default”
            baz = 0
        }

        init default(quux: Double)	// automatically generates init(quux: Double, bar: String, baz: Int) with super.init(quux: quux)
    }

If you super up to a failable initializer, of course, that will have to be “init? default(quux: Double)”.

Now, one little quirk of the current system is that Swift may actually generate *two* default initializers: a parameterless initializer when all properties have default values, and a memberwise initializer which requires all values be provided. I further propose that these be unified into one default initializer by giving default values to parameters which map to properties with default values. This gives you all the parameter sets currently supported, plus a whole range in between.

    struct Foo {
        let bar: String = “default"
        let baz: Int
        
        init() {
            bar = “default”
            baz = 0
        }

        init default	// automatically generates init(bar: String = “default", baz: Int)
    }

Finally, you can continue to decorate the “init” keyword with attributes as you normally would.

	public init default
	internal init default
	private init default
	required init default
	override init default
	@objc init default
	@objc public required init default

(I don’t think convenience initializers make much sense here.)

This does not, unfortunately, eliminate boilerplate in initializers which do more than just set properties. Nor does it allow you to rename parameters, as your example does with “counter”. 

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list