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

Reply via email to