<div dir="ltr">Dear Amber Expert Group,<br><br>I'd like to share with you some feedback on the syntax of member patterns.<br>Please tell me if I make any wrong assumptions.<br><br>I'd prefer the generic type parameters (`<T>`) to be on the right hand side of<br>the `pattern` keyword to have all the keywords on the same side, and the types<br>on the other side. I like the familiarity of declaring a pattern almost like we<br>declare a method :<br><br>```<br>public static pattern <T> Optional<T> of(T t) {<br>  if (that.isPresent()) {<br>    match(that.get());<br>  }<br>}<br>```<br><br>I like the `match` keyword for explicitly indicating a match success. The<br>language already has "callable" keywords such as `this()` and `super()`. It<br>also works when there's no match variable to extract :<br><br>```<br>public static pattern <T> Optional<T> empty() {<br>  if (that.isEmpty()) {<br>    match();<br>  }<br>}<br>```<br><br>For a moment I thought it could also be useful to be allowed to use it inside a<br>lambda expression :<br><br>```<br>public static pattern <T> Optional<T> of(T t) {<br>  that.ifPresent(value -> match(value))<br>  // or "match-reference" ? Maybe not that useful.<br>  that.ifPresent(::match);<br>}<br>```<br><br>But I'm not sure what should happen if such a lambda expression is called at a<br>later point, when the body of the pattern member has already finished executing.<br>Maybe seeing the `match` keyword as a kind of `return` is simpler.<br><br>I wouldn't allow using any other name than `that` for the match candidate, just<br>like `this` cannot be renamed. I also wouldn't explicitly declare the `that`<br>variable in most cases. If really necessary, it could be added at the beginning<br>of the "parameter" list, just like the `this` keyword can be added at the<br>beginning of the parameter list of an instance method (to put annotations on it,<br>for example) :<br><br>```<br>public static pattern <T> Optional<T> of(@NonNull Optional<T> that, T t) {<br>  ...<br>}<br>```<br><br>The functional `match` keyword seems more concise than assigning each variable,<br>it avoids repeating each "parameter" name 3 times (in opposition to the good-old<br>constructor ceremony of `(int x, int y) { this.x = x; this.y = y; }`). It also<br>reinforces the positional (vs named) nature of pattern matched variables :<br><br>```<br>class Point {<br>  private final int x;<br>  private final int y;<br><br>  public Point(int x, int y) {<br>    this.x = x;<br>    this.y = y;<br>  }<br><br>  public pattern Point(int x, int y) {<br>    match(that.x, that.y);<br>  }<br>}<br><br>// Here, x and y are not extracted by name but by position if I'm not mistaken<br>if (p instanceof Point(int x, int y)) {<br>  ...<br>}<br>```<br><br>One question I have in mind is the following : should the pattern "parameter"<br>names be part of the API/class-file if we want to be able to use `with`<br>expressions with non-record classes which define a deconstructor?<br><br>```<br>var p = new Point(5, 8);<br>var newP = p with { x = 3; };<br>```<br><br>-- Loïc<br></div>