I have a question regarding the SIMD protocol. Since SIMD is a vector, which is a regular mathematical object where additive operations are defined, why doesn't SIMD conform to the AdditiveArithmetic protocol?
This question arrises from the following issue I'm having. If I make the structs SIMD2/SIMD4 etc. conform to AdditiveArithmetic, there is a problem that both the AdditiveArithmetic and SIMD protocols define default implementations of the various additive operators, so the compiler can't pick between the 2.
SIMD cannot conform unconditionally to AdditiveArithmetic, because SIMD supports vectors of any type that conforms to SIMDScalar. E.g. you can have a SIMD2<Int32>, which doesn't define +, only &+, or a SIMD vector with Bool elements, which doesn't support addition at all.
SIMD types can conform conditionally:
extension SIMD4: AdditiveArithmetic where Scalar: BinaryFloatingPoint { }
I'm not sure what toolchain you're using where you're having that problem, and I'm not able to reproduce it on any toolchain I have handy (but, you shouldn't need to add zero; that's already conditionally defined on SIMD types with FloatingPoint scalars).
Ahh yes that is my mistake. So I'm using the Swift for TensorFlow toolchain, which has modified AdditiveArithmetic by providing default implementations of += and -= as can be seen here.
I was wondering what you think about this, and whether a proposal or something should be done in order to provide the default implementation in master.
Naively, the (generic, but concrete) conditional implementation on the SIMD types should probably win over the protocol implementation in this case, though I haven't thought through all the details of that. (cc @Douglas_Gregor)
...conditional implementation on the SIMD types should probably win over...
Just to confirm, you mean that each of the SIMD2/SIMD4 structs should conditionally define the operators?
Also I'm guessing this may break ABI stability, but could the SIMD${n} structs (or the SIMD protocol instead) conform to the AdditiveArithmetic protocol?
I'm saying they already do conditionally define the operators, and those existing definitions should "win" over the AdditiveArithmetic defaults, so there wouldn't be a conflict.
I created a PR about this merging into the tensorflow branch. Feel free to ignore the Differentiable part which is a different implementation detail regarding the JIRA ticket. Wanted to see what everyone's opinion is on this CIMD change!
Based on the current rules protocol requirements always wins over declarations found in extensions, but at the same time, protocol requirement is going to be worse than something found in the concrete type.
Ah. So if there is an overload defined in a protocol extension (that is not a requirement), there's no rule to tie-break against an overload defined in a constrained extension on a generic type, because they're both "extensions"?
Yes, if both overloads are found in extension we try to see whether Self of one could be used in other but that's pretty much the only thing ranking does (at the moment), so if both declarations came from extension of the same type they would be considered ambiguous.
Same problem exists when there is a protocol requirement and two extensions of the same protocol where one of them is default implementation e.g.
protocol P {
func foo()
}
// default implementation
extension P {
func foo() {
}
}
extension P where Self : BinaryInteger {
func foo() { ... }
}
Type-checker would find all three declarations but always prefers the protocol requirement, although it's better to prefer constrained extension if Self is indeed a BinaryInteger.