4 ms·
I find this example extremely unconvincing. If you're not talking about an immediate check (for example, you have a list of files in a sidebar), it's quite pos
by Jweb_Guru 11y ago
I find this example extremely unconvincing. If you're not talking about an immediate check (for example, you have a list of files in a sidebar), it's quite possible that it hasn't been refreshed for a long while; there's no particular reason to assume that the file is still there. And even if it is, there are many other errors that can occur when you open a file (insufficient permissions, for example). In that situation, I don't see why it's better to fail with an (unchecked) exception, which the developer is going to have to remember to catch and try to tie back to the originating event (which might be quite tricky, given how much I/O occurs in something like an editor), than to require the developer to handle the potential failure immediately (by popping up a dialog box saying the file was deleted, for example).
In any case, what you're talking about is hardly the common case to optimize for. In basically every language I've ever used, the majority of files were opened without any user interaction, in which case Rust's API is absolutely the correct approach.
That is not to say that there aren't times where you have to do a redundant check, but generally speaking they only occur when you have control over the entire system under consideration and statically know (perhaps can even prove) that the error can't happen. In that situation, you should of course unwrap(), as there is no good way to recover from a logic bug in the existing program.
- seanmcdirmid 11y ago> If you're not talking about an immediate check (for example, you have a list of files in a sidebar), it's quite possible that it hasn't been refreshed for a long while; there's no particular reason to assume that the file is still there. Exactly. It is probably still there, just someone could have deleted it in the few seconds or so that it took for the user to make an action. UIs are filled with a bunch of invariants that are probably true but not necessarily so. 99% of these programs will just exception out if say that file is deleted between the non-atomic time it takes to do verification and action. And there is nothing considered very wrong with that: you screw with the environment of an application while its running, bad things are expected to happen. Now, a language like Rust expects that everything is atomic in the normal case. But since users aren't very batchy, that means re-verifying things over and over again. It is not the overhead that is the problem here, the fact that the check is redundant is not the issue. The fact that the programmer is pestered into handling these cases is a huge issue: Java/C# will just exception out and that's the end of it (you don't really want to bother trying to handle that file being deleted in the few seconds it took for the user to make a decision, or if you deal with it, deal with it at a very coarse granularity). Rust is not designed for writing interactive programs, it is designed for batchy systems code where "files are opened without any user interaction." But let's not discount why existing languages that are designed for writing user facing code make the decisions that they made.
- Jweb_Guru 11y agoI think we've hit on our point of disagreement: > 99% of these programs will just exception out if say that file is deleted between the non-atomic time it takes to do verification and action. And there is nothing considered very wrong with that: you screw with the environment of an application while its running, bad things are expected to happen. I would much rather strive to always do the right thing, if possible, because I do consider that wrong. The pervasiveness of the `Result` type in Rust makes it much easier for me to do so; the cost to you is that you must write `unwrap()` instead of nothing. On the other hand, if unchecked exceptions are the error handling default, I have no recourse in order to discover what possible errors can occur from a function call other than to read the function's source code, while you just save typing `unwrap()`. To me, Rust's solution seems like an eminently reasonable tradeoff.
- seanmcdirmid 11y agoI get that philosophy, it works wonderfully in batch non-interactive environments. But when almost everything is occurring non-atomically, you wind up throwing unwrap everywhere since nothing is actually guaranteed, the state of the world can change between any operation, even if that is unlikely. I've specialized in very interactive systems so my world is quite messy. When you run a compiler (and the program being compiled) while the user is editing it, there are lots of transient error conditions to deal with. I just couldn't imagine writing such a system in Rust, error propagation and resolution is a much more global affair that can't tunnel explicitly through function signatures. But then, I understand that Rust wasn't designed for my problems.