Multiple return (was: JEP 186: Collection Literals)

Sam Pullara spullara at gmail.com
Tue Jan 21 21:22:07 PST 2014


I would implement this with a different pattern:

search()
  .left( s -> … )
  .right( e -> …);

Though I think for this case you might name it Try with onSuccess and onFailure.

Sam

On Jan 21, 2014, at 8:13 PM, 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). Go's solution for this kind of error
> handling strategy is syntactically beautiful. 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)
> 
>    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?
> 
> 
> Zhong Yu
> 
> 
> 
> On Tue, Jan 21, 2014 at 6:58 PM, Jed Wesley-Smith <jed at wesleysmith.io> wrote:
>> Also note that a common use for multiple returns (for instance in the Go
>> language) is to support error reporting as opposed to throwing exceptions.
>> This pattern has a number of shortcomings however. Not least is that it
>> requires the caller to manually check for the presence of an error, and if
>> not present then to use the happy path result. This is a failure of
>> modelling. Logically, there is not actually a result AND an error, but a
>> result OR an error – in other words the result isn't a conjunction, but a
>> disjunction of result and error.
>> 
>> Fortunately, there are disjunctive union types such as Either<A, B> that
>> can model this kind of relationship in a far superior form to the Go
>> approach (who, as a consequence of not having parametric polymorphism
>> cannot conveniently use that kind of solution, and are stuck with an
>> if-error else proceed check for every call).
>> 
>> Personally, I'd love it if Java could better support ADTs and pattern
>> matching, and add higher-kinded-types while you're at it :-)
>> 
>> But of course the number one feature Java needs is Tail Recursion
>> Optimisation!
>> 
>> cheers,
>> jed
>> 
>> 
>> On 22 January 2014 11:02, Brian Goetz <brian.goetz at oracle.com> wrote:
>> 
>>> Without getting into syntax....
>>> 
>>> One could argue that Java has multiple return today -- you write a Pair
>>> class, and return an instance of it.
>>> 
>>> However, this would likely be received as an unsatisfying answer.  Why?
>>> - Performance costs -- having to instantiate a Pair, and possibly having
>>> to box any primitive components
>>> - Having to write the Pair class.
>>> 
>>> I suspect that the first reason is at the heart of most people's
>>> objections -- that having to use an object "feels" too heavy (even if the
>>> VM is able to eliminate the cost via escape analysis.)
>>> 
>>> In any case, value types would certainly address the performance issue --
>>> returning a 2-tuple would just put the values in registers/on the stack.
>>> 
>>> Syntactically, there would certainly be some way to describe a pair
>>> literal, to be determined (but not now.)
>>> 
>>> Once you have that, multiple return really isn't needed as a standalone
>>> feature.
>>> 
>>> On Jan 21, 2014, at 5:59 PM, Roel Spilker wrote:
>>> 
>>>> As a Lombok developer I have quite some experience with value types. I
>>> do think value types are very important.
>>>> 
>>>> That said, I notice that most of them are used to return two or more
>>> values from a method. In concurrent programming this is even more
>>> important. The current workaround in AtomicMarkableReference and
>>> AtomicStampedReference is to return one value and put the other value in
>>> the array that was passed as a parameter.
>>>> 
>>>> There is a way to have multiple return values without introducing new
>>> types (at least for the java programmer). At the risk of getting into a
>>> syntax discussion, one possible way would be to only allow the results to
>>> be assigned to fields, local variables or parameters directly. Example:
>>>> 
>>>> public {int, String} foo() {
>>>>  return {1, "foo"};
>>>> }
>>>> 
>>>> void printFoo() {
>>>>  {int count, String message} = foo();
>>>>  for (int i = 0; i < count, i++) System.out.println(message);
>>>> 
>>>>  // call a method using the multiple results
>>>>  String repeated = repeat(foo(), false);
>>>> }
>>>> 
>>>> String repeat(int count, String message, boolean newLines) {
>>>>  String result = "";
>>>>  for (int i = 0; i < count, i++) {
>>>>    result += message;
>>>>    if (newLines) result += "\n";
>>>> }
>>>> 
>>>> Would having multiple return values be part of the design space?
>>>> 
>>>> 
>>>> On Tue, Jan 21, 2014 at 8:39 PM, Brian Goetz <brian.goetz at oracle.com>
>>> wrote:
>>>> So, there's been some good discussion regarding the proper scope of
>>>> Collection Literals, so let me summarize what I heard.  I am sensing
>>>> that the center of gravity is roughly behind these points:
>>>> 
>>>> 1.  A "collection literals" feature that only worked for the built-in
>>>> types (e.g., List, Set, Map), but was not extensible to user-defined
>>>> types, would be disappointing.
>>>> 
>>>> 2.  Having these literals be mutable would be surprising.
>>>> 
>>>> 3.  The real pain is in Maps, not Lists, Sets, or Arrays.  Library-based
>>>> solutions would be mostly acceptable for the latter, but we still lack a
>>>> reasonable way to describe pair literals, which is what's in the way of
>>>> a library-based solution for Map (other than a MapBuilder.)  Static
>>>> methods in interfaces make a library-based solution more practical.
>>>> With value types, though, library-based solutions for Map become far
>>>> more practical too.
>>>> 
>>>> 4.  This feature is less critical that many other features, such as
>>>> value types, tuples, or primitive specialization of generics.  For the
>>>> most part, this feature is a nice-to-have, but no one would vote for
>>>> delaying value types because of it.
>>>> 
>>>> 5.  The underlying mechanics (varargs at the language level; lack of
>>>> constant pool support for arrays at the bytecode level; ad-hoc support
>>>> for caching of (and GC'ing under memory pressure) intermediate immutable
>>>> results) remain a limiting factor, even with syntactic sugar.  Working
>>>> on these foundational issues might provide more bang-for-buck.
>>>> 
>>>> Of course, in a community of 10M, there will be some range of opinion,
>>>> but the goal of posting this here was to sanity-check our assumptions
>>>> about priorities.  Thanks to all who provided feedback!
>>>> 
>>>> 
>>> 
>>> 
>>> 
>> 
> 



More information about the lambda-dev mailing list