This should work. Why make developer tack on extra code to get something that should've worked like the below? With this change, developers won't need to is_ok() and they can write code faster.
let n = Ok("test");
if n {
println!("woah");
}
This should work. Why make developer tack on extra code to get something that should've worked like the below? With this change, developers won't need to is_ok() and they can write code faster.
let n = Ok("test");
if n {
println!("woah");
}
Rust prefers explicit type conversions, so it doesn't have truthiness for integers or anything else. But if you like, I made a sort of joke crate that will do what you want for Result
:
It's not really any better than is_ok
, except that you can use it generically.
Because it's more obvious what the explicit code does.
Having to call methods explicitly is not a prime obstackle of writing code quickly. Programmers don't power-type pre-memorized snippets.
Anyway, languages shouldn't be optimized for writing quickly. They should be optimized for reading easily and maintaining/changing code with the smallest possible chance of introducing bugs. We spend much more time reading code than writing.
Note that right now Rust doesn't have any "truthiness" -- only bool
can be used in if
and while
conditions. No containers; no pointers; no options; no integers. This is unlikely to change.
A big reason for that is that truthiness actually works poorly in a type-oriented language. Having it leads to code like
if n {
println!("woah {}!", n.unwrap());
}
But that's not a good way to write it.
Rather than truthiness, that code wants pattern matching:
if let Ok(n) = n {
println!("woah {}!", n);
}
See Boolean Blindness | Existential Type for a good explanation of how bool
is often an anti-pattern, since it doesn't mean anything on its own -- you have to look of where it came from to understand it.
(As a simple example of that, both .is_ok()
and .is_err()
return true
. So you clearly don't know anything just from having a true
. If you want a very long article explaining the consequences of following through on this idea, see Aiming for correctness with types .)
Beside the general objection to implicit bool
ness, there is one more problem here. A pretty big one.
Is Ok
the truish value, or is it Err
?
That's actually unambiguous, because of the existing methods like Result::and
and Result::or
. Their semantics only match the normal definition of ∧
and ∨
if Ok
is "true" and Err
is "false".
You might still ask about the value within Ok
-- the truthy
crate chose to look for inner truthiness too. Though as you say, that doesn't fully align with Result
's own and
/or
.
OK, but consider BufRead::has_data_left
if reader.has_data_left() {
println!("Yes");
} else {
println!("No");
}
If there is data left to read, it'd print "Yes". If there is no data left to read, it'd also print "Yes". Only if there was an IO error when checking the reader it would print "No".
Sure, inner truthiness makes sense in that scenario. It's still not consistent with Result::and
/or
, but sometimes it may be what you want. The truthy
crate also gives you truthy_and
/or
methods, so I guess they tried to answer that difference.
You can also pattern-match that particular case:
if let Ok(true) = reader.has_data_left() { ... }
I think that's another excellent of why not to have truthiness. I can immediately think of three different things that I might want that to do, and I'm glad that Rust makes me pick.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.