5 ms·
An Option type without pattern matching is just as useless. Before unwrapping the value, you should check if its None and if you fail to do that, you get a pani
by ImprobableTruth 4y ago
An Option type without pattern matching is just as useless. Before unwrapping the value, you should check if its None and if you fail to do that, you get a panic. That's literally how pointers already work.
- masklinn 4y ago> That's literally how pointers already work. With the huge difference that Go’s pointers don’t statically require checking if they’re `null`. Furthermore, you can add functor and monadic APIs to `Option` which provide completely safe (and somewhat efficient) usage patterns even if you build the option out of product types. Though that isn’t the case here, an other interesting item is that you can build an option type out of non-pointer, thus avoiding the indirection and allocation (though hopefully unlike the C++ committee you don’t do it just so you have a pointer without an allocation)
- ImprobableTruth 4y agoThere is no meaningful null check enforcement like with pattern matching, if you try to access the Option value and fail to handle the error correctly, you either get a panic (from the following null deref) or in this blogpost the zero initialized value (which is honestly worse than an instant crash). >Furthermore, you can add functor and monadic APIs to `Option` There's nothing preventing you from defining these functions directly on pointers, they'd be just as safe.
- moomin 4y agoNot the way it’s constructed, but there are safe patterns e.g. providing a callback which is only called when a value is present. Whetger or not that’s the way you want to program is a whole different question, but you can get a level of safety from constructs like this you can’t get from a pointer.
- moomin 4y agoNot the way it’s constructed, but there are safe patterns e.g. providing a callback which is only called when a value is present. Whether or not that’s the way you want to program is a whole different question, but you can get a level of safety from constructs like this you can’t get from a pointer.
- Mawr 4y ago> [...] if you try to access the Option value and fail to handle the error correctly, [...] It's consistent with the way Go's error handling works. Turns out it's not anywhere near as much of an issue as you might think. In practice you always notice that the function you're about to call returns an error and handle it. > There's nothing preventing you from defining these functions directly on pointers, they'd be just as safe. Pointers aren't Optionals. They happen to be nilable, yes, but their semantics are broader. A pointer can be used to avoid copying large structures around. How would you distinguish such a pointer vs one that's used as an Optional?
- d3nj4l 4y agoJava doesn't have pattern matching (not until the most recent releases, to be pedantic) and the Optional type has absolutely made my programming safer. You don't need pattern matching if you can use functions like `map` and `orElse` or `orElseThrow`, or just return the optional. I get 99% of what I do in OCaml with 'a Option with just these three functions.
- saghm 4y agoWon't those methods still throw an exception if the object is null though? (Honest question, I have not done much Java since Optional was added and was under the impression that it didn't support implementing methods that wouldn't throw exceptions on null like Go can do with nil)
- d3nj4l 4y agoNo, and I think you're misunderstanding how Java optionals work. They're just like any ML-type language's option type - a box which can either have something or nothing. You choose if you want an exception. Map will only run if the optional contains a non-null value, so it won't throw. orElse will safely give you a value if the optional contains a null, so it won't throw either. The only time you throw is when you use orElseThrow, but that's in the name and you know what you're doing. Ex. Optional<Integer> x = Optional.ofNullable(null); // This won't throw! x.map(i -> i + 1); // This won't throw either, and safeValue will *definitely* be an int! int safeValue = x.orElse(5); // This *will* throw, but you specify what to throw x.orElseThrow(() -> new RuntimeException()) These three methods cover nearly everything I did with options in OCaml as well, so I think that's about everything you need.
- saghm 4y agoRight, but what about `Optional<Integer> x = null`? Is there any static check to make sure this can't happen, or is it something you have to just avoid? I can imagine someone might accidentally return `null` instead of `Optional.ofNullable(null)` in a method that returns an Optional, but maybe in practice catching this with a lint is enough.
- everforward 4y agoThe slight advantage here is that the Option returns an error if the value is a zero value (which nil is). Existing linters will throw warnings about not checking errors. I don't believe I've seen a "not-nil" checker, although I could be wrong.