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

Reply via email to