4 ms·
I think it's fairly common in rust code to abuse unwrap and such behaving exactly like an unchecked access to a nullable type.
by The_rationalist 6y ago
I think it's fairly common in rust code to abuse unwrap and such behaving exactly like an unchecked access to a nullable type.
- Ygg2 6y agoThat's the opposite of true. Unwrap is heavily discouraged. I know for Result there is `?` operator, but I don't remember if that worked on Option.
- The_rationalist 6y agoThose are non mutually exclusive statements, it can be officially discouraged yet abused in practice because it often is for the developer the path of least resistance.
- johnisgood 6y agoHeavily discouraged by who? I have seen many Rust projects and they were all filled with unwraps. Two random Rust projects: https://github.com/tokio-rs/tokio https://github.com/tokio-rs/tokio: $ grep -irn 'unwrap' | wc -l 1398 https://github.com/denoland/deno https://github.com/denoland/deno: $ grep -irn 'unwrap' | wc -l 2050 I dunno, but all Rust projects I have encountered had unwraps everywhere.
- The_rationalist 6y agoThis really should get more attention. Safe null access in language like typescript or Kotlin through '?' syntax can still be abused through ('!!' ) but the incentive to abuse it is much lower than in rust because the safe syntax is just as short or shorter (in Kotlin)
- withoutboats2 6y agoThis is the opposite of reality: in Rust, the safe syntax `?` exists and there is no short syntax for the panicking form (`.unwrap()`). Users are not incentivized to unwrap in Rust, users are as disincitivized as possible to unwrap. The uses of unwrap in the projects the GP cited are overwhelmingly in tests and examples, which are not expected to handle errors in the same way as application code. The remainder are mainly lock poisoning unwrapping, which is a completely endorsed idiom.
- duckerude 6y agoFor errors the ? operator is both correct and easy most of the time. But for options it's trickier. Unless the surrounding function is structured just right, the equivalent to Typescript's and Kotlin's ? operator is .map()/.and_then(), and that's pretty ugly. .unwrap() is easier. Try blocks might help.
- saagarjha 6y agoI disagree with your characterization that "?" is the "safe syntax"; both are safe but one aborts execution.
- deleted 6y ago[deleted]
- Ygg2 6y agoYeah, in tests and simple examples. But unwrap is a code smell. You can write it as a shorthand for something Additionally that metric of yours is faulty. A) Looks at tests/examples B) Probably counts 'unwrap_or' which is fine. > Heavily discouraged by who? I'd ask to see however encouraged it?
- deleted 6y ago[deleted]
- johnisgood 6y agoYou are right. I should not have even picked two random projects. I merely just wished to say that most Rust projects I have encountered contained a lot of unwrap.
- deleted 6y ago[deleted]
- duckerude 6y agoHere's the score for tokio without tests and examples: $ find . -name '*.rs' | grep -v -e test -e example | xargs -n1 sed '/mod test/q' | grep -v '^\s*//' | grep -cF -e '.unwrap(' -e '.expect(' 224 I see a lot of unwrapping of locks. IIRC that only fails if another thread crashed while holding the lock, in which case crashing the current thread is often unobjectionable.
- oleganza 6y agoIn addition to what Ygg2 mentioned (tests and unwrap_or), Rust is still (slowly) moving towards support of `Never` type that auto-erases impossible branches. Without `Never`, if you statically know that your function always returns `Option::Some`/`Result::Ok`, you have to use `.unwrap()` or `.expect("reason")`. This is just you doing the obvious work for the compiler that's not smart enough yet to figure it out by itself.
- edflsafoiewq 6y agoUnwrap is discouraged as an error handling scheme, it's fine when it means "I know this is Some". Every a[i] is an unwrap.
- staticassertion 6y agoThey're definitely not the same at all. Dereferencing a null pointer in C and C++ is undefined behavior. You can read more about it here: https://rootkits.xyz/blog/2018/01/kernel-null-pointer-dereference/ https://rootkits.xyz/blog/2018/01/kernel-null-pointer-derefe... In rust an unwrap of a None is defined and memory safe.
- The_rationalist 6y agoI don't understand the practical consequence, it will make your program panic and therefore stop which is order of magnitude worse than throwing a null pointer exception, can you imagine your long running application (e.g a server) stopping in production..
- saagarjha 6y agoAlmost no code can correctly reason about a stray null pointer, and usually they result in strange auxiliary crashes or data corruption. Loudly crashing is often the best choice, even in production.
- maccard 6y agoyou can likely use SEH/Signals in zig to catch the panic and resume. In C++, you'll be lucky if you throw a nullptr exception. It's undefined behaviour, and it's often exploited by compilers for optimization. Here's a super simple example [0] showing how the compiler makes assumptions and generates a very unexpected result. [0] https://gcc.godbolt.org/z/7159jGhex https://gcc.godbolt.org/z/7159jGhex
- withoutboats2 6y agoJava's NPE is not at all the same thing as the undefined behavior of dereferencing a null pointer in C (or Zig in release mode). In fact its the same exact thing as calling unwrap. Your Java server's NPE is not bringing down the entire server because the exception is caught somewhere. The same can be done in Rust (and is, by many frameworks), where panics are caught before they crash the entire application.
- Ar-Curunir 6y agoThere's a difference between a value being null, and a pointer being null. While Rust disallows both, it handles the cases differently; for the latter, a Rust program containing only safe Rust cannot create "null" references. However, for a "nullable" type, Rust encourages using `Option`, and forces you to handle the `null`/`None` case via a check.