In general, I think this is fantastic. In particular, I *really* like the
notion that `BinaryFloatingPoint` conforms to `FloatingPoint`. I would do a few
things differently, though:
> On Apr 14, 2016, at 6:55 PM, Stephen Canon via swift-evolution
> <swift-evolution@swift.org> wrote:
>
> public protocol FloatingPoint: SignedArithmetic, Comparable {
> ...
> /// The greatest finite number.
> ///
> /// Compares greater than or equal to all finite numbers, but less than
> /// infinity. Corresponds to the C macros `FLT_MAX`, `DBL_MAX`, etc.
> /// The naming of those macros is slightly misleading, because infinity
> /// is greater than this value.
> static var greatestFiniteMagnitude: Self { get }
> ...
> }
Why put this in FloatingPoint? The concept is valid for any real type (IMHO,
it’s valid for rectangular Complex/Quaternion/etc types as well... I’m not sure
if it is for the various polar formats, though). I think a better place for it
is either in `Arithmetic`, or another protocol to which `Arithmetic` conforms:
protocol HasMinAndMaxFiniteValue {
static var maxFinite: Self {get} // I think “max”/“min" are clear enough
(especially if the docs are explicit), but I understand the objection
static var minFinite: Self {get} // 0 for unsigned types
}
This would unify the syntax for getting a numeric type’s min or max finite
value across all the built-in numeric types (this means that `Int.max` would
become `Int.maxFinite`). Similarly, IMHO infinity shouldn’t be tied to floating
point types. While it’s true that the *native* integer types don’t support
infinity, arbitrary precision integer types might.
protocol HasInfinity {
static var infinity: Self {get}
}
> /// Arithmetic protocol declares methods backing binary arithmetic operators,
> /// such as `+`, `-` and `*`; and their mutating counterparts. These methods
> /// operate on arguments of the same type.
> ...
> public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
> init()
> func adding(rhs: Self) -> Self
> mutating func add(rhs: Self)
> func subtracting(rhs: Self) -> Self
> mutating func subtract(rhs: Self)
> func multiplied(by rhs: Self) -> Self
> mutating func multiply(by rhs: Self)
> func divided(by rhs: Self) -> Self
> mutating func divide(by rhs: Self)
> }
I’d restructure this a bit:
protocol Arithmetic { //AFAIK *all* numeric types should be able to do these
init()
func adding(rhs: Self) -> Self
mutating func add(rhs: Self)
func subtracting(rhs: Self) -> Self
mutating func subtract(rhs: Self)
}
protocol ScalarArithmetic : Arithmetic { //These can be iffy for non-scalar
types
func multiplied(by rhs: Self) -> Self
mutating func multiply(by rhs: Self)
func divided(by rhs: Self) -> Self
mutating func divide(by rhs: Self)
}
Multiplication isn't always defined for any two arbitrarily-dimensioned
matrices (plus, there are so many reasonable matrix “subtypes” that there's no
guarantee that the return type should always be the same), and I don’t think
there’s a generally agreed-upon meaning for matrix division at all.
[Slight_Rabbit_Trail] For a while, I was trying to get work around the issue in
my own code by doing something like (this was before the change to
“associatedtype”):
public protocol MathLibNumberType {
typealias AddType
typealias AddReturnType
...
func +(_: Self, _: Self.AddType) -> Self.AddReturnType
...
}
But there was some problem when I got to this part:
public protocol ScalarType : MathLibNumberType {
typealias AddType = Self
typealias AddReturnType = Self
...
}
extension Int : ScalarType {}
I can’t remember what the exact problem was anymore. It’s been a while… I think
maybe even pre-Swift 2. Hmm… maybe I should try it again...
[/Slight_Rabbit_Trail]
Anyway, those are my thoughts on the matter.
- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution