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