[swift-evolution] protocol-oriented integers (take 2)
Xiaodi Wu
xiaodi.wu at gmail.com
Sun Jan 15 12:56:51 CST 2017
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 at swift.org> wrote:
on Sun Jan 15 2017, Anton Zhilin <swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
--
-Dave
_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170115/f36db3f3/attachment.html>
More information about the swift-evolution
mailing list