There _may_ be value in recognizing the distinction between rings and fields, perhaps? Just as the FP protocols make room for people to implement their own decimal FP types, and just as you're trying to make Arithmetic accommodate complex numbers, the distinction would allow someone to write algorithms generic over rationals and reals (i.e. fields). Being able to represent exact fractions isn't so terribly niche, and I think the design wouldn't be terribly complicated by its accommodation:
``` // rename Arithmetic to Ring // it's acceptable to omit `.one` from Ring, though some may call that a Pseudoring // consider omitting division from Ring and pushing it down to BinaryInteger and Field protocol BinaryInteger : Ring { ... } protocol Field : Ring { static var one { get } static func / (Self, Self) -> Self static func /= (inout Self, Self) var inverted: Self { get } // default impl: .one / self } protocol FloatingPoint : Field { ... } // rational number types and complex number types // would also conform to Field ``` On Sun, Jan 15, 2017 at 09:14 Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote: on Sun Jan 15 2017, Anton Zhilin <swift-evolution@swift.org> wrote: > What about taking a mathematical approach to numbers? > > protocol Group : Equatable { > static var zero: Self { get } > static func + (Self, Self) -> Self > static func += (inout Self, Self) > static func - (Self, Self) -> Self > static func -= (inout Self, Self) > static prefix func - (Self) -> Self > } > > protocol Ring : Group { > static var one: Self { get } > static func * (Self, Self) -> Self > static func *= (inout Self, Self) > func tryDivide(by: Self) -> Self? > func tryInvert() -> Self? > } > > protocol Field : Ring { > static func / (Self, Self) -> Self > static func /= (inout Self, Self) > var inverted: Self { get } > } > > protocol VectorSpace : Group { > associatedtype Scalar : Field > static func * (Self, Scalar) -> Self > static func *= (inout Self, Scalar) -> Self > static func / (Self, Scalar) -> Self > static func /= (inout Self, Scalar) -> Self > static func * (Scalar, Self) -> Self > } The first test for the inclusion of any protocol in the standard library is: “what generic algorithm that uses this protocol as a constraint would be appropriate for inclusion in the standard library?” I don't think we have a use for any of the above directly in the standard library. All the generic algorithms I know of that would be appropriate to those protocols are part of some specialized domain that should have its own library built on top of the Swift standard lib. > Detalization of mathematical terminology will be determined by what kind of > types we have in the standard library. Integer types are rings (except for > overflow), floating-point types are fields (except for precision), point > types are linear spaces, so I thought the abstractions above are the bare > minimum. > > Unfortunately, Swift doesn’t have rename operations for protocol > requirements, so we can’t express groups that use operations other than + > and -. What we can do is to include an adapter to wrap current instance in > an additive group interface: > > struct MultiplicativeGroupAdapter<T: Field> : Group { > // ... > } > > extension Field { > var multiplicativeGroup: MultiplicativeGroupAdapter<Self> > } > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > -- -Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution