You can have both !
This is basically what we are doing with lambdas, you have a structural syntax 
+ a named type that are bound together using inference.

Let say we have a tuple keyword that means, value + record + 
constructor/de-constructor
  tuple Range(int lo, int hi) { … }

then you can write:
  Range method(int x) {
    return (x, x + 1);  // the compiler infers "new Range(x, x + 1)"
  }

and also
  var (x, y) = method();  // the compiler uses the de-constructor or the record 
getters if there is no de-constructor
  

With Stream<???> s = aStream.map(Lukas::method), ??? is a Range,
and if someone want to use the tuple syntax inside a call to map(), a type as 
to be provided,
by example
  aStream.<Range>map(x -> (x, x + 1)).collect(...)

Rémi

----- Mail original -----
> De: "Brian Goetz" <brian.go...@oracle.com>
> À: "Lukas Eder" <lukas.e...@gmail.com>
> Cc: "amber-spec-comments" <amber-spec-comme...@openjdk.java.net>
> Envoyé: Vendredi 11 Janvier 2019 17:07:43
> Objet: Re: Multiple return values

> While I understand where you’re coming from, I think multiple return is likely
> to be both more intrusive and less satisfying than it first appears.
> 
> First, it’s a relatively deep cut; it goes all the way down to method
> descriptors, since methods in the JVM can only return a single thing.  So what
> you’re really asking the compiler to do is create an anonymous record (whose
> denotation must be stable as it will be burned into client classfiles.)  
> That’s
> the “more intrusive” part.
> 
> The “less satisfying” part is that if you can return multiple values:
> 
>    return (x, y)
> 
> and then obviously you need a way to destructure multiple values:
> 
>    (x, y) = method()
> 
> (since otherwise, what would you do with the return value?)
> 
> But here’s where people will hate you: why can I use tuples as return values,
> and destructure them into locals, but not use them as method arguments, or 
> type
> parameters?  Now I can’t compose
> 
>    someMethod(method())
> 
> because I can’t denote the return type of method() as a parameter type.  And I
> can use your multiple-returning method in a stream map:
> 
>    Stream<T> s = aStream.map(Lukas::method)   // stream of what?
> 
> When we tug on this string, we’ll be very disappointed that it’s not tied to
> anything.
> 
> 
> Instead, what you can do is expose records in your APIs:
> 
> ```
> class MyAPI {
>    record Range(int lo, int hi) { … }
> 
>    Range method() { … }
> }
> ```
> 
> and now a caller gets a Range back, which is a denotable type and whose
> components have descriptive names.
> 
> You say you don’t want to do this because creating new types is so much work.
> Is the one-line declaration of `Range` above really so much work?  (Ignoring
> the fact that returning a Range is far more descriptive than returning an 
> (int,
> int) pair.)
> 
> 
> 
>> On Jan 11, 2019, at 10:57 AM, Lukas Eder <lukas.e...@gmail.com> wrote:
>> 
>> Hello,
>> 
>> I'm referring to the exciting proposed new features around destructuring
>> values from records and other types as shown here:
>> https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html#pattern-bind-statements
>> 
>> The example given was:
>> 
>>  Rect r = ...
>>  __let Rect(var p0, var p1) = r;
>>  // use p0, p1
>> 
>> This is a very useful construct, which I have liked using in other
>> languages a lot. Just today, I had a similar use case where I would have
>> liked to be able to do something like this, but without declaring a nominal
>> type Rect. Every now and then, I would like to return more than one value
>> from a method. For example:
>> 
>>  private X, Y method() {
>>    X x = ...
>>    Y y = ...
>>    return x, y;
>>  }
>> 
>> I would then call this method as follows (hypothetical syntax. Many other
>> syntaxes are possible, e.g. syntaxes that make expressions look like
>> tuples, or actual tuples of course):
>> 
>>  X x, Y y = method();
>> 
>> The rationale is that I don't (always) want to:
>> 
>> - Modify either type X or Y, because this is just one little method where I
>> want to indicate to the call site of method() in what context they should
>> interpret X by providing a context Y
>> - Wrap X and Y in a new type, because creating new types is too much work
>> - Wrap X and Y in Object[] because that's just dirty
>> - Rely on escape analysis for some wrapper type (minor requirement for me)
>> - Assign both X and Y. Something like "X x, _ = method()" or "_, Y y =
>> method()" would be useful, too.
>> 
>> I was wondering if in the context of all the work going on in Amber around
>> capturing local variables, etc. if something like this is reasonably
>> possible as well in some future Java.
>> 
>> This is possible in Python. Go uses this syntax to return exceptions.
>> 
>> Thanks,
> > Lukas

Reply via email to