[patterns] reconsidering how the created variable name binds

Reinier Zwitserloot reinier at zwitserloot.com
Sat Dec 28 22:16:10 UTC 2019


On Sat, 28 Dec 2019 at 21:49, John Rose <john.r.rose at oracle.com> wrote:

> ... Would the following example fail under your proposal?

  static String v = "field";
>   public void test(CharSequence obj) {
>       if (!(obj instanceof String v)) {
>           // Report error. Rarely taken.
>           throw stuff();
>       }
>
>       System.out.println(v);
>     }
>
>
Yes, it would fail, for the same reason this fails:

    for (int i = 0; i < 10; i++) ;
    System.out.println(i); // i not in scope here.

It's a fine example of the tradeoff between the wonky scoping, where the
mere fact that I include a variable name someplace in some expression, even
fairly deeply nested, still leads to the creation of a new local variable
(which may be shadowing a field) beyond where I expected it to exist –
that's weird, but on the flip side, that is a nice pattern I hadn't thought
of, and that'd be lost.

I can see how saving this example, even if it is at the cost of introducing
some puzzling interactions between DA rules and shadowing, is worth it.


> This is also a prototype for a future syntax, a statement which binds one
> or more pattern variables and has an implicit exception path (if the
> pattern isn’t total).  Still on the drawing board I think.
>
>   static String v = "field";
>   public void test(CharSequence obj) {
>       __LetPattern String v __Match obj
>       System.out.println(v);
>     }
>

This proposal would more or less obviate the need for the earlier example,
and can be defined to act like a LocalDeclaration. Using v later on would
be legal for the same reason:

    int i = 5;
    System.out.println(i);

is legal. However, given that the 'if no match' path is implicit, the
earlier example is still needed. For example, if returning a default value
is desired instead of throwing an exception, if the expression is not
instanceof the stated type.


> ... I’m pretty sure the core designers have anticipated all the relevant
> examples already.
>

Tagir's example with the DA rules and the compile time constant was
anticipated? I'm hesitant to just wave away the ability of the java
community to run into this situation (the interaction between compile time
constants, DA rules, and shadowing) as 'academic; is going to be very
rare') – but your earlier example (if not instanceof, run some exceptional
code, and the main tree continues with the created variable in scope) is
also quite nice to have.

I'll try to think of a solution that caters to all of these scenarios, but
I doubt it's possible to do it without sacrificing one of them; Tagir's
puzzler is probably the best one to sacrifice then (leaving it to linting
tools and IDEs to hopefully catch), as you suggest.


More information about the amber-dev mailing list