Forget Optional<T>, adopt Try<T>?
John Nilsson
john at milsson.nu
Tue Jun 4 05:08:21 PDT 2013
Optional also makes for a better input type if you really mean to take an optional value.
Would it make senare to establish type hierarchy? (Wether by subtyping or implicits)
Such that Try <: Either <: Option
BR
John
Skickat från min iPhone
4 jun 2013 kl. 09:52 skrev Jed Wesley-Smith <jed at wesleysmith.io>:
> Actually Try is a (sort of*) monad on exception handling. It is really an
> Either (or disjunction) class that is specialised to catch exceptions
> during map/flatMap.
>
> As you point out, Option is isomorphic to an Either with no useful value on
> the left hand side (Unit or Void for instance), and a true Either can
> return something meaningful as to the reason why there was nothing.
>
> Making something that was returning @Nullable T an Optional<T> simply says
> to the client, "there may not be a return value here". Making it return an
> Either<X, T> says to the client "there may not be a return value here and X
> is why". This is actually not necessary in many cases. Imagine a
> Map.getOptional, there is no real reason to supply
> BecauseThisMapDidntContainValue on the left hand side if the key isn't
> found– it is somewhat obvious.
>
> So, while Either and Option to serve similar purposes, there are important
> differences. Rather than choose one, you really want to have both in the
> kit.
>
> cheers,
> jed.
>
> * it is sort of a monad as a monad should really obey the contravariant
> functor laws, and it doesn't due to the fact that composition is violated:
> https://issues.scala-lang.org/browse/SI-6284
>
>
> On 4 June 2013 14:21, Zhong Yu <zhong.j.yu at gmail.com> wrote:
>
>> I'm thinking that if we have something like scala's Try<T>, it'll
>> express APIs' intentions better than Optional<T>.
>>
>> Some people view Optional as a collection of either 0 or 1 element.
>> That doesn't seem to be what an API author wants to express by
>> returning an Optional. The actual intention is that, either the action
>> succeeds with a value (not a collection of!), or it fails (with an
>> unspecified or implied reason). Try<T> describes that intention
>> precisely (but it probably needs a better name)
>>
>> Suppose we have a good old method that returns a nullable
>>
>> /** return null if there's no element */
>> T getFirst();
>>
>> Why do we hate it? Probably because we need to insert null handling in
>> the code path
>>
>> T first = getFirst();
>> if(first==null)
>> blah blah
>> first.doSomething()...
>>
>> we would rather defer null handling to some later time, leaving the
>> main code path cleaner. Java already has a way to do that - exception
>> propagation. For example the method can be designed to throw
>>
>> T getFirst() throw NotFoundExcpetion;
>> // for efficiency, throw a cached immutable exception object
>>
>> T first = getFirst(); // may throw - exception will be handled
>> somewhere else
>> // no null handling here
>> first.doSomething()
>>
>> But lots of try-catch blocks may make code look ugly. Try<T> may be nicer
>>
>> /** fail with NotFoundException if there's no element */
>> Try<T> getFirst();
>>
>> Try<T> first = getFirst();
>> first.map().filter().recover()....
>>
>> So we don't need Optional. Try<T> does the same thing, and expresses
>> the intention better. And Try<T> has broader use cases. It'll also
>> appease those who prefer returning errors over throwing errors.
>>
>> Sounds good?
>>
>> Zhong Yu
>
More information about the lambda-dev
mailing list