[swift-evolution] [Re-Review] SE-0104: Protocol-oriented integers

Joe Groff jgroff at apple.com
Tue Feb 21 13:51:18 CST 2017

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.


More information about the swift-evolution mailing list