Why can’t we iterate over ranges of
It seems like
bool should implement
Step given its description.
Why can’t we iterate over ranges of
true..=false range contain both
false or be empty? Same for
I feel that the
Ord implementation gives a pretty clear answer to this. The order is
true..=false is empty,
false..=true is all values.
Can you give an example where that would be helpful? I can't think of anything right now. So that might be the answer. I think when it comes to the standard library it's usually "don't add anything unless it's more useful than the added maintenance cost".
I think that the Ord impl exists mainly to make derive(Ord) work smoothly. I think that the specific order in such cases is not very important, only that one exists. In contrast, Step is only useful for constructing ranges. This can easily be expressed by iterating over an array of true/false.
step we need to know if
true is greater or lesser than
false? Sounds like a deep philosophical question to me.
When acting bool to integer
true becomes 1 and
false becomes 0. But that seems totally arbitrary to me. Might as well be any other encoding. Like 1 and -1 or 42 and 666.
Which together make me thing ordering
false makes no sense and so step is not required.
There's only one range with more than one element, so why would we want to?
[false, true] is a perfectly serviceable alternative to
And if by "range" you mean
bool is 1 bit so the only non-empty range is
false..true, which is the same as
iter::once(false), so not very useful.
I study three and four value logics where it's very convenient to define logical AND and OR operations in terms of a "truth ordering" where
false < unknown < true < contradictory
if x and y are variables containing a truth-value, then
x AND y = min(x, y)
x OR y = max(x, y)
You'll note that if we remove "unknown" and "contradictory", these definitions are still correct for boolean logic
A truth ordering doesn't need to be "philosophically right" it just needs to be useful Convention usually gives false a "smaller" truth value than true
All these kinds of mappings have the problem that they're duals, so you could flip the values and the operations and it'd still work, so it doesn't justify either choice of value assignment.
For example, "
&& is multiplication, so
true is 1" and "
|| is multiplication, so
false is 0" both work.
Sure, but I don't consider that a problem -and that's why I made effort to note what the "convention" is.
You can just as easily flip the ordering for natural numbers and say that 1 < 0, but we don't do that.
I'm not sure if Rust implements Ord for bool, but
false < true would definitely be inline with other languages that coerce booleans to integers before comparing them
The reference also lists the results of comparisons of
Just in general, iterating over
false..x is valuable if you want to iterate once if it’s true, and iterate never if it’s false. And iterating over
false..=x is valuable if you want to iterate once if it’s false, and twice if it’s true.
true..=x is useful if you have case one but want to get a reverse result yielded.
true..x is not useful, but neither is
usize::MAX..x. Also you can collect these to conditionally get
. You can and probably should in most cases implement these functions yourself, but for generic code dealing with arbitrary ranges & types as well for mathematical code it might be useful.
Other types that I think should implement
OK I made an ACP about this among other types: ACP: Implement Step for all PartialOrd types that have a notion of predecessor and successor · Issue #189 · rust-lang/libs-team · GitHub
Maybe it's also worth mentioning that
std also guarantees
bools to cast to
true), see docs.