other languages (Ada, Matlab) have solved this issue by only having a single syntax (for inclusive) ranges and starting their indexing at 1. By no means do i support this, i like my zeros. But these languages have another feature that makes inclusive ranges actually usable.
In my opinion, that is a bias introduced by the fact that there is no last_idx() function and only a len() function. I find 0 ... vec.last_idx() much more intuitive than 0 .. vec.len() (I always get the feeling I’m running one over the length of the array).
Ok, back to objectivity:
I did a search for [^\.]\.\.[^\.\}\]\)] in the rust repos and went through the first 25% of the results (skipping all tests and benchmarks which just had random numbers in there).
Places where inclusive and exclusive ranges would result in the same effort (and subjective readability)
libcollections\bits.rs:323
libcollections\dlist.rs:595
libcollections\dlist.rs:602
libcollections\ring_buf.rs:561 -> just a matter of how head/tail are used
libcollections\ring_buf.rs:584 -> just a matter of how head/tail are used
libcollections\str.rs:147 -> change iteration together with line 149
libcore\iter.rs:1517
libcore\iter.rs:1519
Places where inclusive ranges would be better
libcollections\btree\node.rs:1553
libcollections\ring_buf.rs:486 -> write as 1..len
libcollections\vec_map.rs:492
libcore\fmt\float.rs:245
Places where exclusive ranges are better
libcollections\bits.rs:323
libcollections\bits.rs:356
libcollections\bits.rs:663
libcollections\bits.rs:833
libcollections\btree\node.rs:1555
libcollections\btree\node.rs.1556
libcollections\string.rs:175, 192 -> that function could be prettier
libcollections\vec.rs:609
libcore\fmt\float.rs:182
libcore\fmt\float.rs:335
libcore\fmt\mod.rs:488
libcore\fmt\mod.rs:597
libcore\fmt\mod.rs:599 -> better would be repeat
libcore\fmt\mod.rs:605 -> better would be repeat
libcore\fmt\mod.rs:721
libcore\iter.rs:727
libcore\slice.rs:134
libcore\slice.rs:215
libcore\slice.rs:312
libcore\slice.rs:404
libcore\slice.rs:483
libcore\slice.rs:484
libcore\slice.rs:485
libcore\slice.rs:958
libcore\slice.rs:985
libcore\slice.rs:1181
libcore\slice.rs:1272
libcore\str\mod.rs:771
libcore\str\mod.rs:819
libcore\str\mod.rs:831
libcore\str\mod.rs:972
libcore\str\mod.rs:978
libfmt_macros\lib.rs:246
libfmt_macros\lib.rs:251
libfmt_macros\lib.rs:412
Why would you ever do &x[..0]? I’m sure there’s a better way to create an empty slice with the proper lifetime (isn’t there sth like &x[]?
libfmt_macros\lib.rs:291
libfmt_macros\lib.rs:400
So… overwhelming number of situations where exclusive slices are “better” (in the current way stuff is done idiomatically in rust). Most of these situations are x .. v.len().
My suggestion stands: stop using the length of anything to get an index, and instead have a function returning the index of the last item in a sequence. Then inclusive ranges can replace a lot of exclusive ones.