3 ms·
And you can write sth.unwrap() in Rust, and then it panics when it is null. Kotlin solves it much better. sth?.do_something() ?: nothing_to_do
by benibela 7y ago
And you can write sth.unwrap() in Rust, and then it panics when it is null.
Kotlin solves it much better. sth?.do_something() ?: nothing_to_do
- aw1621107 7y agoRust does in fact have a ? operator [0], but it works slightly differently than Kotlin's in that it returns early if a None/Result<Err> is encountered instead of just resolving to that None/Result<Err>. If that isn't what you want, then Option::map() is a fine substitute. [0]: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html https://doc.rust-lang.org/edition-guide/rust-2018/error-hand...
- benibela 7y agoBut there is still a function that panics. Java has solved memory safety. Now the task is to make sure that code that can panic will not compile
- aw1621107 7y agoThe function that can panic still exists, but the ? operator itself won't invoke a panic. Sort of like how you can still get NullPointerExceptions in Kotlin using !!, but standard practice is to use a safer option. Exception/panic-free code is fairly straightforward; you just need to have APIs return Option<_>/Result<_>/other error code equivalents to indicate failure. The problem with that is that it introduces some amount of friction that will probably make some programmers unhappy. If you want to avoid returning Option<_>/Result<_>/other error code equivalents, you need some way to prove your inputs cannot trigger an invalid result, and that is a very difficult problem.
- lmm 7y agoPanicing is the right thing to do: fail-fast is much better than silently continuing in an invalid state. If the None state is valid then don't call unwrap() (which you should almost never use, because if None was not a valid state then why were you using an Option in the first place?), call a function that lets you handle both cases, e.g. unwrap_or.
- thu2111 7y agoIt's sometimes the right thing to panic, in which case use the !! operator to cast away the nullness and get an NPE at that point (now a helpful one as the new Java feature is really a JVM feature!) With this new feature I'd argue the Java/Kotlin world now has the best handling of optionality of any language, anywhere: • Pleasant, concise syntax for handling optionality. Not bolted on with an option type. • Highly efficient translation to machine code. No boxing, no unnecessary branching in the unwrap/!! case. • Excellent interop with older code written in OOP languages that don't represent nulls in the type system. • But that older code can be annotated with @NotNull and @Nullable to retrofit the information; within Java IntelliJ will statically analyse these and add warnings where an NPE/panic would occur, when such code is used by Kotlin the annotations cause the types to be correctly derived as nullable or non-null. • The large wealth of libraries that want to explore object graphs continue to work without being distracted by option/maybe types (e.g. serialisation, UI binding) • On the rare occasions where you do need to unwrap and you got it wrong, you now get an error message that breaks down the sub-expression where the null pointer occurred, so there's no incentive to break up long chains of dereferences just to get better debugging in case of failure. That's a featureset around optionality that's hard to match.
- lmm 7y agoI have to disagree. This is an improvement, but it still leaves Kotlin behind where languages like OCaml were 20+ years ago, because nullable types don't compose the way you'd expect. (If you write generic code that uses T?, your code will break when T is itself a nullable type). > • Pleasant, concise syntax for handling optionality. Not bolted on with an option type. Optionality is not special enough to be worth a special case in the type system, IMO. Maybe some syntactic sugar could be worthwhile, but not a magic type that behaves differently from other types (which is what Kotlin's ? is) - you need it to behave like a normal type so that you can write and reuse generic code. Arrow-kt can't implement functions that work with nullable values, and has to implement its own Option type instead. > • Highly efficient translation to machine code. No boxing, no unnecessary branching in the unwrap/!! case. Getting the semantics right is the important thing; it doesn't matter how fast the code runs if it's broken. It's still possible to compile a well-behaved option type into something unboxed in the cases where it can be represented that way (look at what Rust does, where the option is "packed" if 0 is not a valid value for the inner type, but still does the right thing for Option<Option<T>>, Option<Int> and so on).