Multiple return values

Remi Forax forax at
Mon Jan 14 11:20:43 UTC 2019

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 =, ??? 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(...)


----- Mail original -----
> De: "Brian Goetz" <brian.goetz at>
> À: "Lukas Eder" <lukas.eder at>
> Cc: "amber-spec-comments" <amber-spec-comments at>
> 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 =   // 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.eder at> wrote:
>> Hello,
>> I'm referring to the exciting proposed new features around destructuring
>> values from records and other types as shown here:
>> 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

More information about the amber-spec-observers mailing list