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

Vladimir.S svabox at gmail.com
Thu Feb 23 06:49:42 CST 2017


On 23.02.2017 14:17, Haravikk wrote:
>
>> On 22 Feb 2017, at 21:25, Patrick Pijnappel <patrickpijnappel at gmail.com
>> <mailto:patrickpijnappel at gmail.com>> wrote:
>>
>> To summarize, there's one ambiguous case we'd need to resolve:
>>
>> func foo(_ x: Int, reportingOverflow)
>> func foo(_ x: Int, _ reportingOverflow: Bool)
>>
>> let reportingOverflow = true
>> foo(5, reportingOverflow) // Ambiguous
>>
>> One solution is to make trailing argument labels syntactic sugar for a
>> trailing void argument.
>> That would allow breaking ambiguity by specifying it explicitly:
>>
>> foo(5, reportingOverflow: ())
>>
>> A related issue is the call-site ambiguity for the reader (less of a
>> problem if Xcode highlighted argument labels).
>
> Vladimir suggested that an alternative might be to use a leading colon to

There is another alternative I can think of, based on feature that was 
discussed at some point of time the list: anonymous enums, i.e. when you 
can declare enum inside function declaration, when such enum has almost no 
meaning outside of the function call.

I.e. something like this:

func foo(_ x: Int, with: (.reportingOverflow))

foo(10, with:.reportingOverflow)

I.e. you can have more than one enum case here if you want:
func foo(_ x: Int, with: (.reportingOverflow, .otherFlag))
// IIRC, such syntax was discussed:
// func foo(_ x: Int, with: (.reportingOverflow | .otherFlag))

foo(10, with:.otherFlag)

But such anonymous enums were considered as bad idea during the discussion, 
so...

> indicate that the label is for selecting a function only, which would solve
> the ambiguity issues. Of course this means it's much the same as using the
> single enum case trick, but at least this way it'd still be a proper
> language feature rather than a workaround, and no extra types are declared
> just to support it.
>
> So you'd have something like:
>
> func foo(_ x:Int, :reportingOverflow) { … }
> func foo(_ x:Int, _ reportingOverflow:Bool) { … }
>
> let reportingOverflow = true
> foo(5, reportingOverflow) // Calls the second declaration of foo using the
> boolean argument
> foo(5, :reportingOverflow) // Calls the first declaration of foo
>
> It's still a little subtle, but the single-case enum that this feature
> would replace has the exact same problem. So long as the label is
> sufficiently descriptive it shouldn't be a very likely target for a naming
> collision.
>
> I think the leading colon alternative is probably the one I'd favour, as a
> plain argument label probably isn't clear enough, so having an indicator is
> better overall. It means that as a feature it won't have any advantages
> over the single-case enum, except that you don't have to declare an
> unnecessary extra type (which needs to be documented somehow), so I think
> it's still worth having to make this capability part of the function
> signature proper.


More information about the swift-evolution mailing list