[Idea] Custom default names for arguments of closures


(Eugene Gubin) #1

Right now Swift provides shorthand argument names ($0, $1 etc) by default
which could be overriden with more specific names. I think it would be nice
to define our own default names as part of type definition:

typealias Closure = (first one: String, second two: String) -> Void

func executeClosure(closure: Closure) {
// the caller uses external parameter names, nothing changed here
closure(first: "first", second: 2)
}

executeClosure {
// the callee uses custom arguments instead of $0, $1
// also it is possible to override these names here as usual
print("one \(one) two \(two)")
}

This feature is backward compatible in that way what both

typealias Closure = (first: String, second: String) -> Void

and

typealias Closure = (String, String) -> Void

will provide the same behavior like now.

Possible applications: providing default argument names more meaningfull
than $0, $1, DSL-like constructions.

Possible problem: names could overlap. Nothing new. $0, $1 could overlap
too. Override argument names or variable names in a scope.


(Patrick Gili) #2

Hi Eugene,

I think you'll be able to accomplish this with SE-0021 (https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md), which has been accepted for Swift 2.2.

Cheers,
-Patrick

···

On Feb 13, 2016, at 3:38 PM, Eugene Gubin via swift-evolution <swift-evolution@swift.org> wrote:

func executeClosure(closure: Closure) {
  // the caller uses external parameter names, nothing changed here
  closure(first: "first", second: 2)
}

executeClosure {
  // the callee uses custom arguments instead of $0, $1
  // also it is possible to override these names here as usual
  print("one \(one) two \(two)")
}


(Alexey Demedetskiy) #3

Great idea!

But I see little problem here.

In regular functions parameters names are written near their usage. $0 are also all-known. So you don’t need to ‘guess’ parameter name.
But if we will introduce some closure typealias in one file, and will use it in another - then we need somehow to know this parameter name.

Also, if closure definition will change parameters names for some reason - all client code need to be updated.

As an alternative solution, IDE hints can include these parameter names in closure autocomplete.
For your example:

executeClosure { *first, second in <#code#>* }

where *…* is a content of an autocomplete hint.

But I like the general direction anyway.

···

Right now Swift provides shorthand argument names ($0, $1 etc) by default which could be overriden with more specific names. I think it would be nice to define our own default names as part of type definition:

typealias Closure = (first one: String, second two: String) ->Void

func executeClosure(closure: Closure) {
// the caller uses external parameter names, nothing changed here
closure(first: "first", second: 2)
}

executeClosure {
// the callee uses custom arguments instead of $0, $1
// also it is possible to override these names here as usual
print("one \(one) two \(two)")
}

This feature is backward compatible in that way what both

typealias Closure = (first: String, second: String) ->Void

and

typealias Closure = (String, String) ->Void

will provide the same behavior like now.

Possible applications: providing default argument names more meaningfull than $0, $1, DSL-like constructions.

Possible problem: names could overlap. Nothing new. $0, $1 could overlap too. Override argument names or variable names in a scope._______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Eugene Gubin) #4

Thanks to all for comments!

In regular functions parameters names are written near their usage. $0 are
also all-known. So you don’t need to ‘guess’ parameter name.
But if we will introduce some closure typealias in one file, and will use
it in another - then we need somehow to know this parameter name.

I think these argument names become part of API. When one meets some new
API usually some time spent to get familiar with it. Same here.

As an alternative solution, IDE hints can include these parameter names in

closure autocomplete.

Yes it could. However in this case the feature transforms to autocomplete
hint. If so, I don't see any reason to change anything because it is
possible to write these already.

Actually you suggestion revealed another issue for me. These default names
could shadow names from outer scope. Result could be unexpected.

let one = "outer one"
executeClosure {
        // here one is closure argument not a variable from closure scope
print("one \(one) two \(two)")
}

However this is a common problem. There was proposal about mandatory self
because of it. I think compiler should warn about name shadowing.

I think you'll be able to accomplish this with SE-0021

I don' think so. That proposal describes a way to unambiguously make
reference to overloaded function using its full name.

···

2016-02-14 0:16 GMT+03:00 Patrick Gili <gili.patrick.r@gili-labs.com>:

Hi Eugene,

I think you'll be able to accomplish this with SE-0021 (
https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md),
which has been accepted for Swift 2.2.

Cheers,
-Patrick

On Feb 13, 2016, at 3:38 PM, Eugene Gubin via swift-evolution < > swift-evolution@swift.org> wrote:

func executeClosure(closure: Closure) {
// the caller uses external parameter names, nothing changed here
closure(first: "first", second: 2)
}

executeClosure {
// the callee uses custom arguments instead of $0, $1
// also it is possible to override these names here as usual
print("one \(one) two \(two)")
}


(Howard Lovatt) #5

Sorry, not keen. Too much overlap with labels, therefore not worth the
addition.

  -- Howard.

···

On 14 February 2016 at 07:38, Eugene Gubin via swift-evolution < swift-evolution@swift.org> wrote:

Right now Swift provides shorthand argument names ($0, $1 etc) by default
which could be overriden with more specific names. I think it would be nice
to define our own default names as part of type definition:

typealias Closure = (first one: String, second two: String) -> Void

func executeClosure(closure: Closure) {
// the caller uses external parameter names, nothing changed here
closure(first: "first", second: 2)
}

executeClosure {
// the callee uses custom arguments instead of $0, $1
// also it is possible to override these names here as usual
print("one \(one) two \(two)")
}

This feature is backward compatible in that way what both

typealias Closure = (first: String, second: String) -> Void

and

typealias Closure = (String, String) -> Void

will provide the same behavior like now.

Possible applications: providing default argument names more meaningfull
than $0, $1, DSL-like constructions.

Possible problem: names could overlap. Nothing new. $0, $1 could overlap
too. Override argument names or variable names in a scope.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Myles La Verne Schultz) #6

Agreed, -1, I actually prefer using $0, $1, etc.

Myles

···

Sent from my iPhone

On Feb 14, 2016, at 6:04 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, not keen. Too much overlap with labels, therefore not worth the addition.

  -- Howard.

On 14 February 2016 at 07:38, Eugene Gubin via swift-evolution <swift-evolution@swift.org> wrote:
Right now Swift provides shorthand argument names ($0, $1 etc) by default which could be overriden with more specific names. I think it would be nice to define our own default names as part of type definition:

typealias Closure = (first one: String, second two: String) -> Void

func executeClosure(closure: Closure) {
  // the caller uses external parameter names, nothing changed here
  closure(first: "first", second: 2)
}

executeClosure {
  // the callee uses custom arguments instead of $0, $1
  // also it is possible to override these names here as usual
  print("one \(one) two \(two)")
}

This feature is backward compatible in that way what both

typealias Closure = (first: String, second: String) -> Void

and

typealias Closure = (String, String) -> Void

will provide the same behavior like now.

Possible applications: providing default argument names more meaningfull than $0, $1, DSL-like constructions.

Possible problem: names could overlap. Nothing new. $0, $1 could overlap too. Override argument names or variable names in a scope.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution