Why can’t we iterate over ranges of `bool`

?

It seems like `bool`

*should* implement `Step`

given its description.

Should the `true..=false`

range contain both `true`

and `false`

or be empty? Same for `false..=true`

range.

I feel that the `Ord`

implementation gives a pretty clear answer to this. The order is `false`

, then `true`

. `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.

Interesting...

To implement `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 `true`

and `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 `false..=true`

.

And if by "range" you mean `Range`

, well, `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

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 `[false, true]`

, `[true]`

, `[false]`

and `[]`

. 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 `Step`

: `Ordering`

, `()`

.

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 `bool`

s to cast to `0`

(`false`

) and `1`

(`true`

), see docs.