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