[swift-evolution] protocol-oriented integers (take 2)
Dave Abrahams
dabrahams at apple.com
Tue Jan 31 22:15:19 CST 2017
on Tue Jan 31 2017, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote:
> On Tue, Jan 31, 2017 at 2:53 PM, Max Moiseev <moiseev at apple.com> wrote:
>
>> Hi Brent,
>>
>> Thanks a lot for your suggestions! After having discussed them with Dave,
>> we came up with the following design that I personally like a lot.
>>
>> enum Overflowing { case .withOverflow }
I really dislike “Overflowing”; it seems to imply that there *will* be
overflow. How about
enum ReportingOverflow { case .reportingOverflow }
>>
>> enum FullWidth { case .fullWidth }
>>
>> protocol FixedWidthInteger {
>> func adding(_ other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>> func subtracting(_ other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>> func multiplied(by other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>> func divided(by other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>>
>> func multiplied(by other: Self, _: FullWidth) -> DoubleWidth<Self>
>> func dividing(_ other: DoubleWidth<Self>, _: FullWidth) -> (quotient:
>> Self, remainder: Self)
>> }
>>
>>
>> Call sites would look like:
>>
>> x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)
>>
>> a little different for the division:
>>
>> x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)
>>
>> Note the inverse-ness of `dividing`, but the lack of the argument label
>> makes it quite natural.
>>
>
> This is an improvement in many ways, I think. However `.fullWidth` vs.
> `DoubleWidth` seems less than ideal.
IMO .fullWidth is an improvement over .DoubleWidth, at least for
multiplication. The latter just repeats type information, where the
former tells you something about *how* the operation is to be performed.
> I get that you can't reuse `DoubleWidth` for the single-case enum, but
> still.
>
> Now that * and &* no longer used the `multiplied(by:)` spelling, is there a
> reason not to take advantage of overloading on the return value for these
> very specialized methods?
>
> ```
> protocol FixedWidthInteger {
> typealias OverflowFlagging = (partialValue: Self, overflow:
> ArithmeticOverflow)
> func multiplied(by other: Self) -> OverflowFlagging
> func multiplied(by other: Self) -> DoubleWidth<Self>
> }
> ```
>
> You'd then write `x.multiplied(by: y) as OverflowFlagging` and
> `x.multiplied(by: y) as DoubleWidth`
It's too subtle, IMO, and any place that type context is available to
disambiguate the result, it
x.multiplied(by: y)
will look like it should be rewritten as
x * y
> With respect to `dividing` vs `divided`, IMO it'd be a tricky name,
> especially for non-English speakers. The "ed/ing" rule has these suffixes
> used pretty interchangeably to indicate a non-mutating operation, depending
> on the vagaries of the English language, but we've never had an "ed" and an
> "ing" used for completely different things on the same type, as far as I'm
> aware. Why not move the `dividing` version to DoubleWidth, where it can be
> a proper `divided(by:)`?
Max and I discussed this; I'll let him answer.
--
-Dave
More information about the swift-evolution
mailing list