A proposal (pre-proposal?) to add parameter groups to Java

David Holmes david.holmes at oracle.com
Thu Jul 30 05:34:41 UTC 2020


 > P.S: Is this mailing list the correct channel for us mere mortals to
discuss topics like this?

No. This list is for "General discussion about the OpenJDK Community" 
[1]. Primarily new OpenJDK project proposals.

I'd point you to a more appropriate list but I don't think the OpenJDK 
actively has such a list.

Cheers,
David
-----

[1] https://mail.openjdk.java.net/mailman/listinfo/discuss

On 30/07/2020 2:36 pm, Behrang Saeedzadeh wrote:
>> This request is in a category that I like to call "please, can we have
> bad ad-hoc tuples."  ("Multiple return" is another one in this category.)
>   Which is to say, while it seems like it makes things better, it just moves
> the problem around.
> 
> Every discussion has to start from somewhere... ¯\_(ツ)_/¯
> 
>> If you declare a method
>>
>>      void line((int x, int y) p1) { ... }
>>
>> what is the type of P1?  What can I do with it, besides extract x and y?
> Can I return one?  Can I declare a local variable of that type?  (Your
> proposal suggests no to all of these, as you only mentioned method
> parameter grouping.)
>>
>> Which is to say, you are creating a new kind of structured literal `(a,
> b)`, but which _only_ can be used as a parameter to a method that wants one
> of these.  You can see how this would be limited.  The trouble with such
> "easy" proposals is that they help you move forward one step, and then are
> stuck in the exact same way as before, just one step farther.
>>
>> What you really want is structural tuples, where for any types T and U,
> `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd be
> able to use this as a return type, parameter type, local variable type,
> array component type, type bound for generics, etc.  But, that's a much
> bigger thing than what you are asking.  Relatively few languages have
> succeed at mixing nominal and structural types very effectively (Java's nod
> to structural types is arrays, and there are visible seams where array
> types meet the rest of the type system.)
>>
>> Many languages (e.g, Haskell, ML) do have structural tuples.  Such
> languages tend to integrate pattern matching into the language, so that
> destructuring is built into how we declare functions.  For example, in
> Haskell, I can define:
>>
>>      type IntInt = (Int, Int)
>>
>> which says IntInt is a tuple of Int and Int, and then declare a function
> like your line:
>>
>>      line :: IntInt -> IntInt -> ()
>>
>> (which means "line is a function that takes two IntInt and returns void")
> and then I can declare a definition for line:
>>
>>      line p q = ...
>>
>> where each of p and q are of type IntInt.  Alternately, I can define line
> with a destructuring pattern match:
>>
>>      line (x1, y1) (x2, y2) = ...
>>
>> These two declarations are equivalent, since the type of `line` is that
> it takes two (int, int) pairs; the first binds p and q to pairs, and the
> latter matches structurally on the pairs and binds x1, y1, x2, y2 to the
> coordinates.  (I could do the same without having declared IntInt; it's
> just the equivalent of `typedef` in C.)
>>
>> So yes, there is precedent for such a thing -- but in languages that are
> pretty different from Java.
>>
>> What we do in the Java world, instead, is lean on _nominality_.  Rather
> than structural types launching into being by simply uttering their
> structure, we declare them.  Java's nominal function types are functional
> interfaces; Java's nominal tuples are records.
>>
>> So you could declare your method as:
>>
>>      record Point(int x, int y) { }
>>
>>      void line(Point p1, Point p2) { ... }
>>
>> Within line(), you can (eventually) use pattern matching to destructure
> the point:
>>
>>      void line(Point p1, Point p2) {
>>          Point(var x1, var y1) = p1;  // destructure p1 with Point
> deconstructor into x1, y1
>>          Point(var x2, var y2) = p2;
>>      }
>>
>> (when we have destructuring patterns, which will come to records
> eventually.)  You might even be able to put the destructuring in the
> declaration (no promises!):
>>
>>     void line(Point(var x1, var y1) p1,
>>               Point(var x2, var y2) p2) { }
>> and then all of {x,y,p}{1,2} would be bound in the body.  This is a more
> general solution, since Point is an ordinary class type, so can be used
> anywhere.
> 
> This would cover my use case too, if we could declare and instantiate
> anonymous records:
> 
>      void line((int x, int y) p1, (int x, int y) p2) {
>          System.out.println(p1.x);
>          System.out.println(p1.y);
>          System.out.println(p2.x);
>          System.out.println(p2.y);
>      }
> 
>      line((0, 0), (10, 10));
> 
> Here `p1` and `p2` are anonymous records/tuples that have two `int` fields
> `x` and `y`.
> 
> P.S: Is this mailing list the correct channel for us mere mortals to
> discuss topics like this?
> 


More information about the discuss mailing list