Proposal: Specifying local parameter names for closures to generate strict argument list


(Adrian Zubarev) #1

// I'll use this `function` as a closure later
func setup(_ this: SomeType) -> Void {

    this.doSomeStuff() // local parameter `this`
}

setup(this: /* instance of SomeType */)
The example I’ll use here will build upon the code samples from the “Request for Discussion: Setup closures” topic.

protocol SettableType: class {
     
    init() // designated initializer
}

extension SettableType {
     
    init(@noescape setup: (this: Self) -> Void) {
         
        self.init()
        setup(this: self)
    }
}

func << <T: SettableType>(instance: T, @noescape setup: (this: T) -> Void) -> T {
     
    setup(this: instance)
    return instance
}

extension NSObject: SettableType {}
Right now this will look like this:

NSObject() { anyArgumentName in

    anyArgumentName.doSomeStuff()
}

// or
NSObject() {

    $0.doSomeStuff()
}
If we had strict local parameter names we couold omit the argument list and don’t need the shorthand argument names ($0, $1) anymore. At least the argument list could be generated automaticaly.

Lets reuse the SettableType from before.

extension SettableType {
     
    init(@noescape setup: (_ this: Self) -> Void) {
         
        // notice that `this` is now a local parameter and _ the external paramter
        self.init()
        setup(self) // in this scope only the external parameter is visible
    }
}

func << <T: SettableType>(instance: T, @noescape setup: (_ this: T) -> Void) -> T {
     
    setup(instance) // same here
    return instance
}

let object = NSObject() { this in // we could omit the argument list

    this.doSomeStuff() // `this` is the generated argument name from the strict local parameter
    $0.doSomeStuff() // should raise an error even if we omit the argument list
}

object << {
    this.doSomeStuff()
}
Do you thing this feature is worth it?

Any feedback is welcome.

···


Regards Adrian