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

Reply via email to