3 ms·
The big difference is that in Rust control flow is still explicit. All functions returning errors must declare so with Result, which in turns makes it impossibl
by giovannibajo1 7y ago
The big difference is that in Rust control flow is still explicit. All functions returning errors must declare so with Result, which in turns makes it impossible to forget to handle it on the call site.
This forces you to think: what should I do with this Result error code? Should I propagate it or handle it? This thinking is good and produces good design and good error handling.
For beginners it is very useful, that, for instance, any function doing I/O does return a Result: it forces you to think how your system should behave in case of I/O error.
In C++ or Python, exception control flow is implicit. All functions could theoretically partecipate in an error chain and you have no idea what, if and why a function will raise an exception. Functions doing I/O are completely indistinguishable from the purest functions, and only experience tells you where and if errors should be handled. The consequence is that it’s very hard to find mature code based with sensible error handling.
I should notice that Go is basically the same here: the main difference is that it’s more verbose in error propagation, and requires a configured environment (linter errcheck) to detect when functions only returning err are called without error handling/propagation. Rust is superior here, but Go has the same basic architecture, just less evolved.
- AstralStorm 7y agoYou would think just being explicit would produce good design but what actually happened in my experience is that errors are handled by ignorance, as they get hard to pass through. Exactly the same problem as throws clause in Java. Forcing a global (on thread or coroutine level) handler is better, as actually doing that will mean you have to structure the application in a particular way to handle anything, and that structure makes error handling actually easier. Just make it fail to compile if the correct handler is not being installed and ensure every error is identifiable. This is how hardware works anyway internally - interrupt vectors. Having a library to help with correct return and handling of error state is enough. Allowing return only to place that caused the error is saner than what C++ and Java do. There would be no temptation to pass the buck and you would have to model error state to be fully visible, enforcing it to be debuggable and part of explicit API. You could consider it syntactic salt much like Rust's memory management is.