Not sure if it's an implementation bug (bad error message from the compiler) or 
a spec bug,
hence this message to both amber-dev and amber-spec-experts.

If i try to compile this code with Java 19 (which currently still uses && 
instead of when for a guard)

interface reverse_polish_notation {
  static Map<String, IntBinaryOperator> OPS =
      Map.of("+", (a, b) -> a + b, "*", (a, b) -> a * b);

  static int eval(List<String> expr) {
    var stack = new ArrayDeque<Integer>();
    for(var token: expr) {
      final IntBinaryOperator op;
      stack.push(switch (token) {
        case String __ && (op = OPS.get(token)) != null -> {
          var value1 = stack.pop();
          var value2 = stack.pop();
          yield op.applyAsInt(value1, value2);
        }
        default -> Integer.parseInt(token);
      });
    }
    return stack.pop();
  }

  static void main(String[] args) {
    var expr = List.of("1",  "2",  "+", "3", "*", "4");
    System.out.println(eval(expr));
  }
}

I get the following error

java --enable-preview --source 19 reverse_polish_notation.java
reverse_polish_notation.java:17: error: local variables referenced from a guard 
must be final or effectively final
        case String __ && (op = OPS.get(token)) != null -> {
                           ^
Note: reverse_polish_notation.java uses preview features of Java SE 19.
Note: Recompile with -Xlint:preview for details.
1 error
error: compilation failed
  
Obviously the error message is funny, IntBinaryOperator is declared final so it 
is effectively final.

In case of a lambda,
  final IntBinaryOperator op;
  Supplier<String> supplier = () -> op = null;

supplier.get() can be called several times so "op = null" does not compile.

But in the example above, "op" can not be assigned more than once so maybe it 
should compile.

regards,
RĂ©mi

Reply via email to