I think of them in terms of operations, which is why I would like them to be exposed through distinct operators. <+>
maybe? |+|
?
But vector operations are something you do to an otherwise ordinary array. I’m not even entirely convinced they should be expressed in the syntax. Now that Zig has implicit (no index) for
loops across two arrays of the same length, it isn’t exactly playing on hard mode to vectorize those loops. It can be done with index based for loops in the C tradition, but there’s more to recognize, more cases to exclude, the Zig case makes it dead easy.
It’s probably too late in the game to make a major breaking change like introducing vectorized operators with a distinct syntax, especially since they’re ahem overloaded, so it isn’t feasible to provide a migration script.
But that doesn’t mean I like it. Operators have certain expected qualities: they don’t allocate, they’re on numbers, and they’re O(1). Zig’s autovectorizing operators are O(n), and again, you have to check the types involved to know what you’re dealing with.
And it’s kind of a hard sell to the scientific-numerics types that Zig does have array ops, but only for arrays of one dimension. If you want to do matrix ops, welcome to the land of add(a, mul(b, c))
. It’s not like matrix multiplication requires heap allocation, either, the size of the resultant is known.
You can’t exactly tell them that Zig wants operators to be predictable, because that ship has sailed. Is a + b
one instruction, or are a
and b
128k vectors, and the cost varies based on what width of SIMD is available?
Arguably, just remove them from the language. Instead of this:
const a = @Vector(4, i32){ 1, 2, 3, 4 };
const b = @Vector(4, i32){ 5, 6, 7, 8 };
// Math operations take place element-wise.
const c = a + b;
This
const arrayA = [4]i32{ 1, 2, 3, 4 };
const arrayB = [4]i32{ 5, 6, 7, 8 };
const arrayC = for (arrayA, arrayB) |a, b| a + b;
This is a compile error now, “error: value of type ‘i32’ ignored”, which is good, because it means that introducing that syntax would be backward-compatible.
You’ll note that this is trivial to vectorize, it calls for no analysis to speak of for the compiler to see that it’s a candidate.