Loose ends: Optional
Remi Forax
forax at univ-mlv.fr
Fri Jun 7 11:25:20 PDT 2013
So let's be a little constructive.
I think we have clearly two options, and I'm fine with both of them:
Option A: We want to add map/flatMap.
In that case, we also need to add a way to do the conversion back and
fore to null (orNull() and fromNullable()).
Note that the original code proposed by Brian below already does a
null check in map().
In that case, Optional is not only something that represent a value
that doesn't exist,
it's also a way see null as an object.
Option B: We don't want the conversion to null
In that case, map should throw a NPE if the result of a call to the
mapper function is null
like it does when an Optional is created from a value.
In that case, flatMap is in my opinion useless because the code that
returns null will not magically
be re-written to send an Optional as parameter.
So Optional just represent when a value is absent or not and null is
not a possible value.
Regardless the option chosen above,
- Optional should not implement Iterable or have a forEach method. It
makes the code weird to read.
- filter doesn't seem to pull it's own weight, for what it worth, I
never use it on an Option in Scala.
Rémi
On 05/24/2013 09:20 PM, Brian Goetz wrote:
> Proposed spec for methods on Optional, which would have the obvious
> counterparts in Optional{Int,Long,Double}.
>
> These methods are known to be useful and seem mostly harmless now that
> other things have settled. (I don't think they greatly increase the
> moral hazard of Optional in general, and they do make it more
> expressive.)
>
>
> /**
> * If a value is present, and the value matches the given predicate,
> * return an {@code Optional} describing the value, otherwise
> return an
> * empty {@code Optional}.
> *
> * @param predicate a predicate to apply to the value, if present
> * @throws NullPointerException if the predicate is null
> * @return an {@code Optional} describing the value of this {@code
> Optional}
> * if a value is present and the value matches the given predicate,
> * otherwise an empty {@code Optional}
> */
> public Optional<T> filter(Predicate<T> predicate) {
> Objects.requireNonNull(predicate);
> if (!isPresent())
> return this;
> else
> return predicate.test(value) ? this : empty();
> }
>
> /**
> * If a value is present, apply the provided mapping function to it,
> * and if the result is non-null, return an {@code Optional}
> describing the
> * result. Otherwise return an empty {@code Optional}.
> *
> * @param <U> The type of the result of the mapping function
> * @param mapper a mapping function to apply to the value, if present
> * @throws NullPointerException if the mapping function is null
> * @return an {@code Optional} describing the result of applying a
> mapping
> * function to the value of this {@code Optional}, if a value is
> present,
> * otherwise an empty {@code Optional}
> */
> public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
> Objects.requireNonNull(mapper);
> if (!isPresent())
> return empty();
> else {
> U result = mapper.apply(value);
> return result == null ? empty() : Optional.of(result);
> }
> }
>
> /**
> * If a value is present, apply the provided {@code Optional}-bearing
> * mapping function to it, return that result, otherwise return an
> empty
> * {@code Optional}.
> *
> * @param <U> The type parameter to the {@code Optional} returned by
> * @param mapper a mapping function to apply to the value, if present
> * the mapping function
> * @throws NullPointerException if the mapping function is null or
> returns
> * a null result
> * @return the result of applying an {@code Optional}-bearing mapping
> * function to the value of this {@code Optional}, if a value is
> present,
> * otherwise an empty {@code Optional}
> */
> public<U> Optional<U> flatMap(Function<? super T, ? extends
> Optional<U>> mapper) {
> Objects.requireNonNull(mapper);
> if (!isPresent())
> return empty();
> else {
> return Objects.requireNonNull(mapper.apply(value));
> }
> }
> }
More information about the lambda-libs-spec-observers
mailing list