You are right that varargs records are dancing on the edge of a cliff.
But (a) we have varargs records, and (b) array/varargs patterns are not
only for records.
If you're arguing that they are not essential *right now* and can be
deferred, that's a reasonable argument, but you'd have to actually make
that argument.
But it seems you are arguing that array and varargs patterns are
*fundamentally incoherent.* This argument seems way overblown, and as
you've seen, overblown arguments are usually counterproductive.
On 5/20/2022 8:46 AM, Remi Forax wrote:
------------------------------------------------------------------------
*From: *"Brian Goetz" <brian.go...@oracle.com>
*To: *"amber-spec-experts" <amber-spec-experts@openjdk.java.net>
*Sent: *Wednesday, May 18, 2022 9:18:01 PM
*Subject: *Pattern matching: next steps after JEP 405
JEP 405 has been proposed to target for 19. But, it has some
loose ends that I'd like to refine before it eventually becomes a
final feature. These include:
[...]
-*Varargs patterns. * Records can be varargs, but we have an
asymmetry where we can use varargs in constructors but not in
deconstruction. This should be rectified. The semantics of this
is straightforward; given
record Foo(int x, int y, int... zs) { }
just as
new Foo(x, y, z1, z2)
is shorthand for
new Foo(x, y, new int[] { z1, z2 })
we also can express
case Foo(var x, var y, var z1, var z2)
as being shorthand for
case Foo(var x, var y, int[] { var z1, var z2 })
This means that varargs drags in array patterns.
Thinking a bit about the varargs pattern, introducing them is not a
good idea because a varargs record is not a safe construct by default,
- varargs are arrays, and arrays are mutable in Java, so varargs
records are not immutable by default
- equals() and hashCode() does not work as is too.
The record Foo should be written
record Foo(int x, int y, ... zs) {
Foo {
zs = zs.clone();
}
public int[] zs() {
return zs.clone();
}
public boolean equals(Object o) {
return o instanceof Foo foo && x == foo.x && y == foo.y &&
Arrays.equals(zs, foo.zs);
}
public int hashCode() {
return hash(x, y, Arrays.hashCode(zs));
}
}
Given that most people will forget that the default behavior of a
varargs record is not the right one, introducing a specific pattern
for varargs record to mirror them is like giving a gentle nudge to
somebody on a cliff.
Note that, it does not mean that we will not support varargs record,
because
one can still write either
case Foo(int x, int y, int[] zs)
or
case Foo(int x, int y, int[] { int... zs }) // or a similar syntax
that mix a record pattern and an array pattern
but just that there will be no streamlined syntax for a varargs record.
Rémi