Multiple return (was: JEP 186: Collection Literals)
Zhong Yu
zhong.j.yu at gmail.com
Wed Jan 22 08:09:37 PST 2014
I'm not sure how you can do this way with a more complex flow graph.
On Tue, Jan 21, 2014 at 11:22 PM, Sam Pullara <spullara at gmail.com> wrote:
> 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