4 ms·
Optionals only throw NPE if you’re using them wrong. You are not wrong about cancelabel futures, though.
by DarkNova6 3y ago
Optionals only throw NPE if you’re using them wrong.
You are not wrong about cancelabel futures, though.
- marginalia_nu 3y agoEither way it feels like optionals are going to be deprecated real quick now we have sealed interfaces and record matching. They let you get rid of so much of the unpleasantness in dealing with this API. Instead you can public sealed interface Maybe<T> { <T2> Maybe<T2> map(Function<T, T2> mapper); <T2> Maybe<T2> flatMap(Function<T, Maybe<T2>> mapper); T elseGet(T fallback); record Just<T>(T value) implements Maybe<T> { public <T2> Maybe<T2> map(Function<T, T2> mapper) { return new Just<T2>(mapper.apply(value)); } public <T2> Maybe<T2> flatMap(Function<T, Maybe<T2>> mapper) { return mapper.apply(value); } public T elseGet(T fallback) { return value; } } record Empty<T>() implements Maybe<T> { public <T2> Maybe<T2> map(Function<T, T2> mapper) { return new Empty<>(); } public <T2> Maybe<T2> flatMap(Function<T, Maybe<T2>> mapper) { return new Empty<>(); } public T elseGet(T fallback) { return fallback; } } } public void demo() { Maybe<String> foo = new Maybe.Empty<String>(); System.out.println( switch (foo) { case Maybe.Just(String val) -> "Hello " + val; case Maybe.Empty() -> "Fine, leave me hanging"; } ); };
- pron 3y agoYou're assuming that deconstructing and exhaustive patterns will continue to be restricted to ADTs only. That may or may not be the case.
- marginalia_nu 3y agoNot really, I'm just highlighting that this is possible with records today. .
- lkitching 3y agoSince this defines an interface, does this solve the null problem? e.g. Maybe<String> foo = null; foo.map(s -> "bar"); explicit pattern matching is usually discouraged anyway though, and you can do this now with Optional Optional<String> foo = Optional.empty(); String message = foo.map(s -> "Hello " + s).orElse("Fine, leave me hanging"); Other languages like Scala also have an Option.fold method for this specific case.
- kaba0 3y agoThe more likely scenario is that Optional will get made into a value type.
- imtringued 3y agoShowing an error on broken code will cost you backwards compatibility. The best you will get is a warning and the JVM will deoptimize Optional back to a regular object, because somewhere someone set an Optional to null somewhere in a library. It doesn't even have to be as obvious as Optional<String> o = null; Any cast to Optional can let a null pointer slip from an Object reference. List<Optional<String>> is allowed to contain null pointers and you are allowed to assign o = list.get(0) which generates an implicit cast. There is no good solution for this. Due to the way generics are implemented.
- kaba0 3y agoAh, you mean the Optional itself being null. That’s not any bigger an issue than anything else being Optional. Also, value types might come combined with nullability — so you might have Optional<String>!, which can’t be null, and will efficiently be stored in-place.
- DarkNova6 3y agoOptional *is going to* be made a value type. However, unlike the binary choice of class/value type, project valhalla will provide a more granular approach, coming with incremental performance benefits and constraints. In the current spec draft, the type system boils down to 4 categories: - Fully mutable, polymorph classes - Immutable, monomorphic classes - Immutable, monomorphic classes + null-hostile - Immutable, monomorphic classes + null-hostile + multithreading-unsafe Another story for nullability is being investigated as well which would allow for full performance gain as well as full backwards compatibility.
- DarkNova6 3y agoJava started with Records + improved switch expressions to pave the way for Pattern matching, but the feature is far from being done. Deconstruction patterns for classes are being worked. In fact, Optional has been brought up as an example in internal discussions time and time again. The way Pattern matching works right now is just the beginning.