4 ms·
The key difference is that in your second example you can just forget about the else branch, while in Rust you must explicitly handle the None case, otherwise i
by fidelramos 7y ago
The key difference is that in your second example you can just forget about the else branch, while in Rust you must explicitly handle the None case, otherwise it won't compile.
- reificator 7y agoNo that's not the key difference, because you can just call `unwrap()` and forget about it, which is effectively the same footgun as other languages. The key difference is that now the type system can tell you the truth. In other languages when you have a reference to a type T, null is considered a valid T but you cannot treat it as one or everything blows up. Meanwhile in rust when you have a reference to T, you don't have a secret (not)T that invisibly breaks everything.
- crooked-v 7y agoTypescript is another one where null and undefined are unique singleton types, which are encompassed under the catch-all `any` type but, if strictness is turned on, are rejected by any other type matching. doThingA(param: any) // you can pass anything including null and undefined doThingB(param: object | number | string | boolean | bigint | symbol) // you can pass anything except null and undefined
- imtringued 7y ago> No that's not the key difference, because you can just call `unwrap()` and forget about it, which is effectively the same footgun as other languages. Are you sure? Each line of Java or Javascript can be equivalent to multiple `unwrap()` calls. You can't see them because the compiler is generating ([0]) them but they are there and there are many hundreds of thousands (or maybe even millions including dependencies) of them in most Java projects. Here is an example: company.board.members.size() is equivalent to company.unwrap("NPE).board.unwrap("NPE).members.unwrap("NPE).size() and every single line in Java is like that. You can't opt out. You can't tell your coworkers to stop using "unwrap" during code reviews. The entire language forces you to do this in every single line that involves a reference. [0] Well, it's actually just trapping the 0 address but it's equivalent.
- reificator 7y agoPlease do not quote posts out of context in order to make your argument seem stronger. > Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith. I am well aware of the issues in other popular languages. You and I agree that there is an implicit `unwrap()` call in each dereference operation. The post I was responding to claimed that in Rust you cannot leave null/None values unhandled. This is false because `unwrap()` exists and more importantly is in fairly common use. The distinction is not whether you can (at your own peril of course) assume a value is not null. Rust lets you do that. As you point out however, it does force you to be more explicit. Why is that? It's because the concept of `None` is not hidden from the type system. The reason that your Java examples work that way is not because `unwrap()` is implicit, it's because the type system doesn't know about nulls in the first place.
- int_19h 7y agoWhen you write unwrap(), you're handling them - by forcing a panic, but it's still a choice that you make.
- reificator 7y agoI was responding to the following post: > The key difference is that in your second example you can just forget about the else branch, while in Rust you must explicitly handle the None case, otherwise it won't compile. Do you really think that `unwrap()` is meaningfully different from "forget[ting] about the else branch"? Does it require you to "explicitly handle the None case"? My goal here was not to get mired in semantic arguments that ignore the context of the discussion. It was merely to highlight that Rust lets you assume that things won't be null the same as any other language, and that the important difference is that rust lets you be clear about what can and cannot be null.
- int_19h 7y agoYes, it absolutely is different. The naive code will not have unwrap() in it, and it will fail to compile. At that point the developer can still mistakenly use unwrap() to unblock themselves, but it's still opt-in, not opt-out. If you're implying that coders use unwrap() pre-emptively, I don't think there's any evidence for that. Besides, you can't just slap it on every value you have - it must actually be a result type! - so even if it's applied incorrectly in advance, that still requires some conscious consideration. This is not at all the same as forgetting an "else" - or, far more often, forgetting the "if" altogether.
- strbean 7y agoIsn't unwrap(x) just match x { Some(v) => return v None => die painfully } ? If so, the None is still handled. Dying painfully is an escape hatch out of the type system in any language that lets you do it.
- deleted 7y ago[deleted]
- reificator 7y agoI was responding to the following post: > The key difference is that in your second example you can just forget about the else branch, while in Rust you must explicitly handle the None case, otherwise it won't compile. Do you really think that `unwrap()` is meaningfully different from "forget[ting] about the else branch"? Does it require you to "explicitly handle the None case"? My goal here was not to get mired in semantic arguments that ignore the context of the discussion. It was merely to highlight that Rust lets you assume that things won't be null the same as any other language, and that the important difference is that rust lets you be clear about what can and cannot be null.
- strbean 7y agoI get the thrust of your argument (that the expressiveness of the type system is what matters here), and it makes sense to me. I'm not sure I agree with this though: > Do you really think that `unwrap()` is meaningfully different from "forget[ting] about the else branch"? Does it require you to "explicitly handle the None case"? I haven't used Rust, so but digging up the source shows unwrap is indeed just a `match` that panics on None. The fact that "you can put thing inside a function and call that function" doesn't mean you "don't have to explicitly do thing". We end up with a pretty useless standard for "explicitly doing thing" if putting thing in a function doesn't count.
- sgift 7y agoIf you don't care about the else case you can use if let: https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html https://doc.rust-lang.org/rust-by-example/flow_control/if_le...