I find Rust's array style more confusing than prefix, since prefix matches the order you index into the arrays (arr: [5][2]i32 can be validly indexed as arr[<5][<2]), and Rust's style is written backwards from how you index the array. Can you clarify how you find Rust unambiguous?
It's just obvious to me that it works the correct way by way of elimination of alternative parsing. The example below can be unwrapped mentally and unambiguously as "an array of 5 items of (an array of 2 items of i32)". Indexing into the array is not backwards: the outer array is deref'd first, giving you one of those five items which has length two.
Note that the Rust array declarations are also homologous to other types in the ecosystem, such as nested Option types or nested collections (eg: Option<Option<T>> or List<List<T>>).
Contrast w/the C version, where it's obvious to a skilled C programmer but you need to remember to read the bounds from right to left to determine the memory layout (ie: an array of 5 arrays of two elements each):
int main() {
int i[5][2] = {{1,2},{3,4}, /*...*/};
printf("%ld\n", sizeof(i[0])/sizeof(int));
return 0;
}
In this case you are required to mentally combine the type on the left of the variable with the bounds on the right of the variable to parse a type declaration in your head that eventually looks like the Rust version:
(int[2])[5]
I've been doing a lot of professional C work lately so it's currently "swapped in", but I find that any time I pick C up after spending time away I find it ambiguous and I have to reason through the ordering of the declarations.
Obviously this is all IMHO and YMMV, but this developer does find it significantly easier to unambiguously parse Rust types.
> Note that the Rust array declarations are also homologous to other types in the ecosystem, such as nested Option types or nested collections (eg: Option<Option<T>> or List<List<T>>).
To me, [[i32; 1]; 10] is homologous to Items<Items<T, ZeroOrOne>, Unlimited>, not Vec<Option<i32>>. To me, it make more sense to put the size before the inner type (either [1; i32] or [1]i32), since you need to index the array before getting an instance of the type.