Then in the mathematical style, 0..100 should be an uncountable range. It’s implicitly (0..100).step_by(1) but conceptually it could just as easily be (0..100).step_by(0.1) or (0..100).step_by(10) by default. The fact that the step can’t be 0.1 is likely an artifact of the type system. There’s nothing about real numbers which would inhibit this behaviour.
So if 0..100 only makes sense with an implicit positive step, would it be that big a stretch to use 100..0 where step(-1) is also implicit? As a range that seems perfectly clear (I’m not suggesting making step_by(-1) implicit. It’s unusual enough that making it explicit seems like a good idea). Conceptually this shouldn’t be difficult.
It’s also very common. In matlab (actually octave the matlab clone) it looks like (you can even use decimals):
0:3 // 0-3
0:1:3 // same
3:1 // empty array []. Ranges go up unless a step is added.
3:-1:0 // 3-0
1.8:0.2:2 // 1.8 2.0
2.0:-0.2:1.8 // 2.0 1.8
In rust:
// Make life easy: 10 and down except last element
(10..0).step_by(-1)
// Make life hard: 0-9 but it's backwards so 9-0...does
// the step agree? Oh, good it does. Drat. Wanted 10-1...
(0..10).rev().step_by(-1)
Also, especially if floats are supported, this gets harder with complex equations:
let start = // really complex equation
let end = // another really complex equation
let step = // complex equation
// Gotta think abstractly now:
// So `start` goes to `end`-1 but it's reversed...so
// `end`-1 goes to `start`. Will my `step` still always
// agree in direction?
(start..end).rev().step_by(step)