This part of the D design isn’t stupid, it’s good for a system language, and better than Python.
Let’s assume you have an array (here a slice) arr, you don’t know its length at compile-time, and you want to return the eighth-to-last item of the slice.
In Python you write something that approximatively looks like:
>>> arr = [10 * i for i in range(12)]
>>> arr
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110]
>>> arr[-8]
40
In Rust you currently could write:
fn foo(arr: &[u32]) -> u32 {
arr[arr.len() - 8]
}
fn main() {
let arr: Vec<_> = (0 .. 12).map(|i| 10 * i).collect();
println!("{:?}", arr);
println!("{:?}", foo(&arr));
}
My proposal is to allow to write something like:
fn foo(arr: &[u32]) -> u32 {
arr[# - 8]
}
I think you are suggesting to not use that syntax and to write instead:
fn foo(arr: &[u32]) -> u32 {
arr[-8]
}
How can the Rust language implement this? In general the index is not a compile-time constant. So the function that implements the [] indexing must test if the input index value is negative, and in that case add to it the length of the array/slice. If it’s positive it must not add the length. And then it has to use this resul to index the memory. So if we use the Python syntax we have to pay one if test for each access to the array. The D syntax avoids such run-time cost.
With a friend we created ShedSkin, it was a Python->C++ compiler, it has a switch to tell the compiler that you will not use negative indexes in your Python code, to increase performance…
So it’s a significant problem, that D avoids.