Say I'd like to write a generic function dotProduct, something like:
func dotProduct<T: FixedSizeArrayType where T.Element: BasicArithmeticType>(a: T, b: T) -> T.Element {
var sum = T(0)
for i in 0 ..< T.Count { sum = sum + a[i] * b[i] }
return sum
}
This is just some haphazard pseudo code meant to illustrate the requirements for the function:
- It takes as arguments two "fixed size" arrays of equal length and element type and returns the dot product of the two arguments (the type of the return value is of course the same as the element type of the two arguments). It's also ok to make it as a method, with self replacing the first arg.
- I want compile time errors if I try to call it with arguments of different size/count/length or element type, and if I try to receive a return value of some other type than the element type of the two arguments.
- And as can be seen, The T.Element type should conform to an imaginary BasicArithmeticType protocol. This protocol is possible to write yourself, but currently the Swift standard library only has IntegerArithmeticType. Anyway, conforming to it would simply imply things like being able to perform the multiplication, addition and initialization from an integer literal (0 in this case).
- Also, if the values of the arguments are knowable at compile time I want Swift to "run it at compile time" similar to what it can do thanks to the Swift standrad library type StaticString, as demonstrated by Airspeed Velocity at around 5:40 into this Swift Summit talk entitled Zero-Cost Abstractions (link omitted, see why below). Also, as already mentioned, the compiler should be able to know about the number of elements in the arguments so that they can be "true" value types (containing no references) and optimized as such.
After watching the WWDC 2015 video Protocol Oriented Programming in Swift (link omitted, see why below), I wouldn't be surprised if there is a really elegant way to achive this but I can't figure out how. I find it especially hard to come up with something nice for the fixed size "staticly knowable" array type(s). Using ordinary arrays and checking their length dynamically is both much slower than using eg structs with let x, y, z: T (for the 3 element type). Also, using regular arrays will not give me a compile time error when calling the function with arguments of different length/counts.
It is possible to achieve all this using a lot of duplicated code for "fixed size array" structs of length 1, 2, 3, etc, but it feels like fighting the type system, doing the job of the compiler and repeating yourself.
So, does anyone know "the proper way" to write this function/method (including any scaffolding)?
And if there is a nice solution to this, I would also like to see a similar function/method crossProduct (which would of course return a T instead of a T.Element).
(About the omitted links:
Apparently, including them makes this forum software condemn this post to an eternity in Drafts along with the warning message: "Please note: your content was added successfully, but a moderator needs to approve it before it can be posted." So until this forum bug is fixed, you'll have manually search for the videos.)
Edit: Turns out "there is a really elegant way to achive this":