Revisiting the rule for merging type patterns ?

Brian Goetz brian.goetz at oracle.com
Mon Aug 30 16:08:31 UTC 2021


The thing to recognize here is that the restriction against merging (and 
fallthrough) is not about _cases_, but about _bindings_, because a 
binding would have an impossible type.  Right now, there's no way to 
have one without the other, so its easy to conflate them. As you say, 
once there's a way to say "there's no binding", it becomes possible to 
merge otherwise incompatible patterns.

So yes, I agree once we revisit underscore (or other means of no-binding 
patterns), we should refine this.

> We use comma in between constants, we should be able to use comma in 
> between patterns.

This was always the intent.  Recall that we discussed cases like:

     case IntBox(int x), IntBag(int x):

and backed away not because they were unsound, but because they 
presented confusing questions like "where is the declaration of x".

On 8/28/2021 5:42 PM, Remi Forax wrote:
> I believe that the rule for merging type pattern is overly restrictive,
> here is an example of a method that collects all the declared variables (the language is a kind of functional JavaScript i'm using for teaching)
>
>      private static void visitVariable(Expr expr, JSObject env) {
>        switch (expr) {
>          case Block block -> {
>            for (Expr instr : block.instrs()) {
>              visitVariable(instr, env);
>            }
>          }
>          case Literal literal -> {
>            // do nothing
>          }
>          case FunCall funCall -> {
>            // do nothing
>          }
>          case LocalVarAssignment localVarAssignment -> {
>            if (localVarAssignment.declaration()) {
>              env.register(localVarAssignment.name(), env.length());
>            }
>          }
>          case LocalVarAccess localVarAccess -> {
>            // do nothing
>          }
>          case Fun fun -> {
>            // do nothing
>          }
>          case Return _return -> {
>            // do nothing
>          }
>          case If _if -> {
>            visitVariable(_if.trueBlock(), env);
>            visitVariable(_if.falseBlock(), env);
>          }
>          case New _new -> {
>            // do nothing
>          }
>          case FieldAccess fieldAccess -> {
>            // do nothing
>          }
>          case FieldAssignment fieldAssignment -> {
>            // do nothing
>          }
>          case MethodCall methodCall -> {
>            // do nothing
>          }
>          default -> throw new AssertionError("unknown case " + expr.getClass());
>        };
>      }
>
> Here i can not group the cases that do nothing together because we have explicitly disallow it,
> so the code below does not compile
>    case Literal literal, FunCall funcall -> {
>       // do nothing
>    }
>
> I think we should revisit that discussion and just not introduce the any bindings in that case so the example above will compile but "literal" or "funcall" are not added as local variable.
>
> Once we will introduce '_', the "correct" way to  write such code will be
>    case Literal _, FunCall _ -> {
>       // do nothing
>    }
>
> regards,
> Rémi



More information about the amber-spec-experts mailing list