There is another option to avoid the extra types, which is to stop trying to 
force the disambiguation through argument labels, accept an ambiguous call and 
have the context disambiguate:

// compilation error: ambiguous
let x = i.multiplied(by: j)
// unambiguously overflow-checked
let (y,overflow) = i.multiplied(by: j)
// unambiguously full-width
let z: DoubleWidth = i.multiplied(by: j)

Ambiguity is bad when you want to distinguish between the “usual one” versus 
other more specialized versions. So if you really had a regular trapping 
`adding`, but then also wanted to accommodate the overflow-reporting version 
when a user explicitly requests it, then the argument label is a clear win. 
This is a slightly bogus example though, because we explicitly don’t have 
things like `adding`, we have a `static +` instead. Where the disambiguation is 
needed is instead between two less common variants as described above.


> On Feb 21, 2017, at 11:51 AM, Joe Groff via swift-evolution 
> <[email protected]> wrote:
> 
> For the review, Dave asked me to raise a design question on his behalf, since 
> he's on vacation. There are places where the proposal introduces one-case 
> types as a labeling mechanism to distinguish different operations with 
> otherwise the same argument names, for instance:
> 
> public enum ReportingOverflow { case reportingOverflow }
> 
> protocol Number {
>  func adding(_ other: Self) -> Self
> }
> 
> protocol FixedWidthInteger: BinaryInteger {
>  func adding(_ other: Self, _: ReportingOverflow) -> (partialValue: Self, 
> overflow: ArithmeticOverflow)
> }
> 
> This introduces an otherwise useless type (for which we need to emit 
> metadata, provide documentation for, list in reference documentation and code 
> completion, etc.) and turns the compiler's job of choosing among these 
> operators into an overload resolution problem rather than a simpler name 
> lookup problem. In other places, particularly when a type imported from Cocoa 
> has multiple nullary initializers, we already use the convention of a 
> Void-typed labeled argument, which would look like this:
> 
> protocol FixedWidthInteger: BinaryInteger {
>  func adding(_ other: Self, reportingOverflow: Void) -> (partialValue: Self, 
> overflow: ArithmeticOverflow)
> }
> 
> The call syntax is less aethestically pleasing, no doubt (`adding(5, 
> reportingOverflow: ())`), but that's arguably a problem we should address at 
> the language level given that we already have APIs that look like that. The 
> tradeoff of ugly syntax, which we can potentially beautify over time, in 
> return for less "stuff" in the standard library, which we can't get rid off 
> once the dylib is burned into billions of user devices, is worth considering.
> 
> -Joe
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to