Vavr: Option is missing orElseThrow

Created on 11 May 2018  路  12Comments  路  Source: vavr-io/vavr

There is use case where we want to thow exception when option is null. This is present in Jdk implementation of Optional. Not sure why it was left out in Vavr

feature revertecloseduplicate 芦vavr-control禄

Most helpful comment

Table with compare exists java.util.Optional methods with io.vavr.control.Option (with simplified generics):

java.util.Optional | Behavior | io.vavr.control.Option
------------ | ------------- | -------------
T get() | Return wrapped value or throw NoSuchElementException | T get()
boolean isPresent() | Return true if not empty and false otherwise | boolean isDefined()
void ifPresent( Consumer<T> ) | Call to consumer if not empty | Option<T> peek( Consumer<T> )
Optional<T> filter( Predicate<T> ) | Return non empty wrapper if value matches the predictae and empty otherwise | Option<T> filter( Predicate<T> )
Optional<U> map( Function<T, U> ) | Convert exists value to other with given mapper or empty if already empty | Option<U> map( Function<T, U> )
Optional<U> flatMap( Function<T, Optional<U>> ) | Convert exists value to other with given mapper or empty if already empty | Option<U> flatMap( Function<T, Option<U>> )
T orElse(T other) | Return wrapped value or given value | T getOrElse(T other)
T orElseGet( Supplier<T> ) | Return wrapped value or value from given supplier | T getOrElse( Supplier<T> )
T orElseThrow( Supplier<Throwable> ) | Return wrapped value or throw exception from given supplier | T getOrElseThrow( Supplier<Throwable> )

What function from java.util.Optional you can not find in io.vavr.control.Option?
As I see all methods exists in java.util.Optional has direct or better alternatives in io.vavr.control.Option.

All 12 comments

Are you looking for Option.getOrElseThrow(Supplier)? Note that while Option is very similar to JDKs Optional, you can still get null value out of it. This method will throw when the Option is _empty_, not when it holds a null value. It __can__ hold a null value, in contrast with JDK's Optional.

I do not want to open the option when it is not empty just throw exception when it is empty. Especially useful when you have built the chain using flatmap. If I use Option.getOrElseThrow(Supplier), it will open the option and I will have to close again if I want to return Option from a function. Think it as
Option.OrElseThrow(Supplier) ~ Option.of(Option.getOrElseThrow(Supplier))

Fair enough, but then, JDK doesn't contain that method either. But still, I fail to see why would you wrap a return value with Option if you don't allow the empty case by throwing exceptions. Wouldn't it be easier to just return the value itself or throw?

As a workaround, if you don't need to throw checked exceptions, you could use Option.onEmpty(Runnable)

option.onEmpty(() -> throw new RuntimeException());

use case when I would want to do do that is when I call flatmap with a funtion, that returns a Option, but does not throw exception on null
something like .flatmap( a -> f1(a).orElseThrow(new RuntimeException() ))
instead of
.flatmap( a -> Option.of(f1(a).getorElseThrow(new RuntimeException() )))

f1(a) is returning a option

If you want to get rid of unnecessary wrapping why don't use use map instead of flatMap?

With f being a method with the signature Option<B> f(A value) you can use both

option.map(value -> f(value).getOrElseThrow(() -> new RuntimeException());

and

option.flatMap(value -> f(value).onEmpty(() -> { throw new RuntimeException();}));

Map does the implicit wrapping. I wanted avoid that as well. Second option will kind of work, butit will be good to have supplier instead of runnable.

Yes, it does, it's just you don't have to do it manually like in your example. But you can use either of the above two examples that I provided and neither involves manual wrapping. You can also use the second example I provided and that involves one less wrap/unwrap cycle.

Table with compare exists java.util.Optional methods with io.vavr.control.Option (with simplified generics):

java.util.Optional | Behavior | io.vavr.control.Option
------------ | ------------- | -------------
T get() | Return wrapped value or throw NoSuchElementException | T get()
boolean isPresent() | Return true if not empty and false otherwise | boolean isDefined()
void ifPresent( Consumer<T> ) | Call to consumer if not empty | Option<T> peek( Consumer<T> )
Optional<T> filter( Predicate<T> ) | Return non empty wrapper if value matches the predictae and empty otherwise | Option<T> filter( Predicate<T> )
Optional<U> map( Function<T, U> ) | Convert exists value to other with given mapper or empty if already empty | Option<U> map( Function<T, U> )
Optional<U> flatMap( Function<T, Optional<U>> ) | Convert exists value to other with given mapper or empty if already empty | Option<U> flatMap( Function<T, Option<U>> )
T orElse(T other) | Return wrapped value or given value | T getOrElse(T other)
T orElseGet( Supplier<T> ) | Return wrapped value or value from given supplier | T getOrElse( Supplier<T> )
T orElseThrow( Supplier<Throwable> ) | Return wrapped value or throw exception from given supplier | T getOrElseThrow( Supplier<Throwable> )

What function from java.util.Optional you can not find in io.vavr.control.Option?
As I see all methods exists in java.util.Optional has direct or better alternatives in io.vavr.control.Option.

From the viewpoint of the control-flow of an application this is really _dirty_. 馃挬
But I'm fine with adding it 馃槄 (consistently to all of our single-valued types, i.e. Try, Option, Either, Validation, Future).

@rajneeshg0 are you volunteering for a PR?

@danieldietrich, all listed classes (Try, Option, Either, Validation, Future) are extend io.vavr.Value which already has method getOrElseThrow(Supplier<X extends Throwable> supplier).
We really need same method with different name?

I think this issue can be closed soon. The io.vavr.control module of Vavr 1.0 unclutters the API surface area and aligns more to Scala (and Java):

API

Please note that the Option API will be very similar to Try (but not completely identical.

Please note that this is still work in progress.

I've aligned the Vavr 1.0 API (of Option, Try and Either) to Scala 2.13-M5 and Java 11.
We strive for reducing the API surface area. For now, we will not add additional methods which aren't present in Java or Scala.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manu-m picture manu-m  路  6Comments

ashrwin picture ashrwin  路  6Comments

bhchandra picture bhchandra  路  3Comments

enelson picture enelson  路  5Comments

nfekete picture nfekete  路  5Comments