[swift-evolution] [Pitch] Allow trailing argument labels
Haravikk
swift-evolution at haravikk.me
Thu Feb 23 08:35:00 CST 2017
> On 23 Feb 2017, at 12:49, Vladimir.S <svabox at gmail.com> wrote:
>
> 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…
Yeah, I was one of the ones who liked the idea but it never seemed to get much traction unfortunately.
Part of the problem though with using enums to select methods is that it's not immediately obvious what they're doing; if you look at the signature for a method you see a type, then have to investigate what it is and find it only has one case, which is confusing. Documentation then needs to fill in all the gaps to explain that it will only ever have one case (e.g- it's not an enum that may be expanded with more options in future), and that's it's for selecting methods. A single-case ad-hoc enum could be a bit clearer, but it's still more of a workaround.
I think having a proper language feature is still the way to go, as it can be more obvious at the function declaration that it's something different, since it would be an untyped parameter.
You mentioned another possibility of putting the extra label after the function, and I've been thinking about that as well, because the interesting thing about that is it could be thought of as a kind of label on the return type.
func adding(_ other:Self) -> Self
func adding(_ other:Self):reportingOverflow -> (Self, Bool)
let resultOnly = a.adding(b)
let resultReportingOverflow = a.adding(b):reportingOverflow
You did say it looks a bit like an operation on the result, but I suppose another way of thinking about it is that until you set (or omit) :reportingOverflow then you're actually calling *both* methods with two possible results, and by adding that you tell Swift which one you want. It could be a very neat thing to use as well within modern auto-complete; type out the method at which point you can either hit space to move onto something else, hit period to call a method on the result, or hit colon to narrow down the result to something more specific.
Ack, I think I'm confusing myself now as to which solution I prefer. Having the trailing label *after* the function call does have merits as well.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170223/4c7edf5c/attachment.html>
More information about the swift-evolution
mailing list