4 ms·
I don't feel that Rust is actually well designed. The borrow checker and lack of GC makes it well suited to the tasks that traditionally one would use C or C++
by tensor 3y ago
I don't feel that Rust is actually well designed. The borrow checker and lack of GC makes it well suited to the tasks that traditionally one would use C or C++ for, and it is definitely safer than those language.
But in terms of overall design it doesn't feel very cohesive, and priority is put in odd places. For example, error handling is an area where people almost always resort to 3rd party libraries. That, to me, having to rely on third party libraries for such basic features is a sign of a serious design flaw. Meanwhile, "clever" things like zero cost map and filter are prioritized and in the language for a long time.
Overall it feels like a language that prioritizes "clever" features at the expense of boring but basic needs. Also any criticism is met with hostility rather than accommodation.
It's a fine language, but I can't say that I love it.
- rhodysurf 3y agoI would consider error handling in rust my favorite of all the lanuages i use by a long margin, im not sure how it would be improved. Python I have to try catch, JS i have to try catch, C++ i have to try catch, Go I need more boilerplate than rust. Swift is close to rust, but without the Map Error logic its less ergonomic.
- tensor 3y agoAn incredibly typical scenario is that a function makes several calls that each have their own error. E.g. maybe initialize the database and a web server. If you want this function to return an error that encompasses any of the sub-error types you are forced to write the most incredible amount of boilerplate that I've ever seen in a language. You need to define a composite error type and then implement all the required traits for it. I'm not sure how some people avoid this situation, but it's an incredibly common scenario and the only reasonable solution is to use a library like anyhow. Defining your own errors is also heavily boilerplate prone giving rise to things like thiserror. Why these third party libraries are not made into first class language features is beyond me, but it is an example of very poor design and is typical of what I mean. Rust implemented a solid error handling core, but then just didn't bother with the things that would make the error handling actually good. Fancy over pragmatic.
- thinkharderdev 3y agoI don't understand what you would include in the std lib exactly. Defining error types is just defining regular types with domain-specific error information. Macros to make that less verbose seems like the exact sort of thing you would want to be implemented in third-party libraries.
- tensor 3y agoExcept as a newcomer to the language, I didn't know about anyhow or thiserror and spent an immense amount of time figuring out how to solve this problem, and writing all the boilerplate. This is not pragmatic and not ok. I would say a language like Go is well designed in that it has an overall design philosophy and you can see that throughout the language, including in the limitations which are often intentionally chosen. One part of their philosophy that I really appreciate is their intention to make the language pragmatic in industry settings, and making typical things obvious to newcomers is a huge part of that. Even if your solution is macros (which may be ok, but can also make the underlying generated code more opaque), it should be part of the standard library and part of the language manual. Making things the "officially approved way of handling a problem" has benefits beyond newcomers too, it gives the entire language more consistency resulting in a far more cohesive design.
- thinkharderdev 3y ago"The" solution is not macros. The solution is what is provided by the language. If you are calling a bunch of different functions that return different error types then you either have to map them manually (using map_err) or you can create your own error type and implement From<XYZError> to automatically lift into your own error type. I agree that it is a lot of boilerplate which is why there are good libraries for generating the boilerplate with macros. But the underlying mechanism is not really obscure. It is covered quite well in the rust book (https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html https://doc.rust-lang.org/book/ch09-02-recoverable-errors-wi...).
- Klonoar 3y ago> For example, error handling is an area where people almost always resort to 3rd party libraries. IME people mostly resort to those libraries just to avoid verbosity, since implementing error types is frankly boring and macros/etc make it a non-issue. Some have neat context-attachment functionality that can be useful as well, though I've personally never needed it.
- zanellato19 3y ago> Meanwhile, "clever" things like zero cost map and filter are prioritized and in the language for a long time. This is because of what the language is trying to do. Providing map and filter with zero is a priority 0. I think people think Rust had more development manpower than it actually had. Java/C# (and I would bet Go) have had significantly more money poured into them than Rust.