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