8 ms·
I think making things syntactically explicit which are core concepts is stupid: ```pub fn horror()->Result{Ok(Result(mut &self))}``` A function returns a Resu
by singularity2001 4y ago
I think making things syntactically explicit which are core concepts is stupid:
```pub fn horror()->Result{Ok(Result(mut &self))}```
A function returns a Result. This concept in Rust is so ubiquitous that it should be a first class citizen. It should, under all circumstances, be syntactically implicit:
```pub fn better->self```
No matter what it takes to make the compiler smarter.
- dragonwriter 4y ago> A function returns a Result. That is not, in fact, a core concept in Rust. Plenty of functions have no reason to return Result. (And some that do also have a reason for the inner class to be a result.) > This concept in Rust is so ubiquitous that it should be a first class citizen. It should, under all circumstances, be syntactically implicit: “Implicit” is an opposed concept to “first-class citizen”. Result is first-class in Rust, and would not be if function returns were implicitly Result.
- singularity2001 4y ago> Result is not a core concept in Rust. If you don't see std::result::Result as a core concept in Rust, which might be fair, one can still argue that it _should_ be a core concept, given its ubiquitous usage.
- dragonwriter 4y agoYou misquoted, I never said Result is not a core concept. What I said is that “A function returns Result” in the universal sense (that is, everything that is a function returns Result) is not a core concept in Rust. Some functions return Result<T,E> for some <T,E>. Some functions return Option<T> for some T. Some functions have no reason to use that kind of generic wrapper type (a pure function that handles any value in its range and returns a valid value in a simple type for each doesn't need either; Option/Result are typically needed with otherwise non-total functions or functions that perform side effects that can fail.)
- jherico 4y ago
- dragonwriter 4y ago> I remain convinced that the whole Result concept was just created by people butt-hurt over the concept of exceptions I wouldn't use the emotionally-loaded dismissive language, but, yes, Result is a solution to the same problem as exceptions that deals with several problems of exceptions, including: (1) Unchecked exceptions obscure what is going on, and frustrate analysis because things remote from the code may bypass it in the call-stack without any evidence visible in signatures. (2) Checked exceptions are clear, but create a separate syntax for expressing type-like constraints, also limiting what you can do around them because they aren't the same thing as types. Results are basically cleaner checked exceptions.
- jherico 4y agoI'll certainly grant that unchecked exceptions are problematic for static analysis, but in regards to your second point, I don't feel like Rust has actually avoided creating "a separate syntax". It's created a different, more complex syntax which must be adopted inline in your actual normal code path, obfuscating what your code is actually expected to do under non-error conditions. IMO, one of the most valuable pieces of exception handling is a distinct separation between your error logic and your non-error logic, which makes methods easier to comprehend. I also feel like the existence of the ? syntax is a dead giveaway in this regard because it's a fig-leaf trying to cover up the most egregious parts of the code where you'd otherwise have to be write the frequent "if error then early return error" statements which plague Golang.
- pcwalton 4y agoThe main reason behind the panic/Result distinction is that systems programmers, particularly those working in embedded, want to be able to turn off unwinding support entirely. Unwinding adds control flow edges everywhere, inhibiting optimizations, and it either adds code size bloat for the unwind tables or runtime overhead at every function call, depending on how it's implemented. I don't know of any way to implement exceptions that doesn't have this overhead. So although I like exceptions myself, I agree with Rust's decision not to embrace them in its domain.
- pcwalton 4y agoThis would break the principle that you always know how to invoke a function by looking at its signature. Option of T and Result of T are not the same type as T. You would have to look at the body of the function, or rustdoc, to know how to invoke it, which would be very annoying. Besides, what is the error type for Result? You haven't declared it.
- dllthomas 4y agoOthers have addressed the problem with "implicit", but I might be on board with "lightweight"; maybe in a type context `T?` can mean `Result<T>` for whatever Result is in scope? That way you can still define functions with various distinct error types the same as today, but the common (idk just how common, not claiming a majority) case of using the same error across a module or package with a Result type alias will get cleaner.
- scns 4y agoThat would be confusing, because T? means Option<T> in other languages (Kotlin, Typescript).
- dllthomas 4y agoThat's a good point, but I am not sure it would actually be a problem. For one thing, we already have syntactic collisions that don't seem to cause much problem (consider `foo?.bar` in .ts vs .rs), and this one would probably be prevalent enough that it would quickly be familiar to anyone using the language. For another, if we squint I'm not sure those other languages aren't "really" using it for the same thing. If in some module we define `type Result<T> = Option<T>` then we have the same behavior in Rust, and we can imagine that those other languages have basically done so implicitly, meaning it's a less flexible version of the same mechanism (put to slightly different purposes).