[swift-evolution] [Pitch] Allow trailing argument labels

Haravikk swift-evolution at haravikk.me
Wed Feb 22 05:32:59 CST 2017

> On 22 Feb 2017, at 10:24, Patrick Pijnappel via swift-evolution <swift-evolution at swift.org> wrote:
> I'd like to discuss allowing a trailing 'argument label' without an actual argument:
> func adding(_ other: Self, reportingOverflow) -> … // Actual case in SE-104 where this came up
> func tableView(_ tableView: UITableView, numberOfSections) -> Int // Referenced as tableView(_:numberOfSections)
> As illustrated above, the way we reference functions extends very naturally to include these.
> This would be very useful for several cases:
> • Delegate methods, which currently all start with the same prefix, except for some odd cases that really actually just needed a trailing argument label.
> • Cases where the function is a more specialized version of one with the same name, but can't use a flag because the return type is different (e.g. reportingOverflow), or the extra flag check is just undesirable. The standard library now uses some workarounds to achieve this (e.g. having a trailing argument of type void).
> • Function names that just work more naturally with some additional words after the last argument. If we allow trailing argument labels, you can form any sentence, rounding out the syntax. 
> Overall, I think this could be the final missing piece to complete Swift's functions-as-sentences approach.

I'm a +1 for this.

I think the best way to define it though would be to use Void arguments, and simply eliminate the need to add :() to call them if they are trailing. We should however retain the ability to add the colon for disambiguation.

Some examples to illustrate:

	struct Foo { func adding(_ other:Foo, reportingOverflow:Void) { … } }
	var a = Foo(), b = Foo()

	a.adding(b, reportingOverflow) // Trailing Void argument doesn't require a value, so :() can be omitted

	let reportingOverflow = "I don't know why I defined this"
	a.adding(b, reportingOverflow) // This is now ambiguous thanks to my stupidly named variable
	a.adding(b, reportingOverflow:) // However, this isn't, thanks to the colon clarifying that it's a label

It's possible the feature doesn't have to be restricted to only trailing arguments; the key is the ambiguity due to variable names and/or function selection. For example:

	struct Foo { func example(foo:Void) -> String { … }}
	var foo = Foo()

	foo.example(foo) // What did I mean here?
	let result = foo.example(foo:) // This looks like I might be trying to select a function, rather than call it

So it's possible it could be allowed for any function that has at least one non-Void argument?

I think to really seal the deal it would be nice if Xcode would highlight argument labels differently, as that would make it clearer to user's what something is at a glance, but that's a separate issue.

Just some thoughts; I do prefer this to using single case enums just to create a different method signature. Labels are definitely the right way to do this. The main thing for me is that I think we should keep the requirement to specify the type in the function declaration as Void, just for clarity.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170222/5be727bf/attachment.html>

More information about the swift-evolution mailing list