Multiple return (was: JEP 186: Collection Literals)

Jed Wesley-Smith jed at wesleysmith.io
Wed Jan 22 13:36:10 PST 2014


(reposting to the list as I replied to Zhong Yu only)

On 22 January 2014 15:13, Zhong Yu <zhong.j.yu at gmail.com> wrote:

> There is value in meticulously handling error condition after each
> single action. Sometimes I wish Java had a simpler syntax to do just
> that (try-catch is too clunky).


Either style solutions force you to deal with error conditions, whereas a
multiple return does not.


> Go's solution for this kind of error
> handling strategy is syntactically beautiful.


No, it is horrid. Every call must be followed by an error check, eg in
pseudo:

    if error_occurred
       // error handler
    else
       // happy path


> If someone wants to
> emulate that strategy in Java, `Either` won't work as beautifully
> (correct me if I'm wrong - but limit the solution to simple C style
> code)
>

You can do exactly the same in Java right now with a Pair<Err, A>. The real
point is that Either can only be an error OR a result, not both.

A useful Either class will also allow you to map/flatMap across the happy
path:

Either<Err, String> a = someMethodThatReturnsEither();
Either<Err, Integer> b = a.map(String s -> s.length());
Either<Err, Integer> c = b.flatMap(Int i ->
someOtherMethodThatReturnsEither(i));

and if an error is returned anywhere in lines 1 or 3 above, the final
Either will be an Err, otherwise it will be a result. We have encapsulated
error handling, and we can prove that that code correctly deals with
errors.


>     Either<String, ErrorCode> search();
>
>    // call site
>     Either<String, ErrorCode> result = search();
>     if(result.isRight()) // if it's right, it's wrong!
>         handle result.getRight();
>     else
>         use result.getLeft();
>     // what the hell is this code talking about?
>
>
There are several combinators for handling Eithers, the most common being
the catamorphism, or fold method. It allows you to provide two methods that
each take one side of the Either and return a value of the destination type:

    <X> X fold(Function<Err, X> errorHandler, Function<A, X> happy)

this can be used, for instance with the c value above:

    String desc = c.fold(
      e -> "An error occurred: " + e
    , i -> "Result! " + i
    );

Or, if you want side effects there are variations on foreach you can use
(say biforeach):

    c.biforeach(
      e -> send.error("An error occurred: " + e)
    , i -> send.response("Result! " + i)
    );

You can also use things like

    Either<A, B> onRight(Sink<B> effect)
    Either<A, B> onLeft(Sink<A> effect)

There are many other useful combinators available on a decent Either
implementation.

Anyway, as Brian pointed out, there is nothing apart from an allocation
that the Go approach provides that is not already available in Java, and
much that Go cannot due to the absence of parametric polymorphism.

cheers,
jed.


More information about the lambda-dev mailing list