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