Re: [records] Is C-style array declaration in components dropped?

2020-07-23 Thread Tagir Valeev
Btw if this change is intended, then it looks like the changes in
section 10.2 [1] must be dropped as well

The array type of a variable depends on the bracket pairs that may
appear as part of the type at the beginning of a variable declaration,
or as part of the declarator for the variable, or both. Specifically,
in the declaration of a field, formal parameter, local variable, or
record component (8.3, 8.4.1, 9.3, 9.4, 14.4.1, 14.14.2, 15.27.1,
8.10.1), the array type of the variable is denoted by <...>

Now, this text is inconsistent with 8.10.1.

With best regards,
Tagir Valeev.
[1] 
http://cr.openjdk.java.net/~gbierman/jep384/jep384-20200506/specs/records-jls.html#jls-10.2



On Fri, Jul 24, 2020 at 10:55 AM Tagir Valeev  wrote:
>
> Hello!
>
> The JLS 14 record preview spec allows C-style array declaration in
> components (like record R(int x[])) [1]:
>
> RecordComponent:
>   { VariableModifier } UnannType VariableDeclaratorId
>   VariableArityRecordComponent
> VariableDeclaratorId:
>   Identifier [ Dims ]
>
> However, it appears that JLS 15 draft spec doesn't allow it anymore [2]
>
> RecordComponent:
>   { Annotation } UnannType Identifier
>   VariableArityRecordComponent
>
> This change is not listed in the draft spec prolog in "The changes are
> the same as those in the first preview of Records in Java SE 14,
> except for the following", so I overlooked it when updated the records
> support in IntelliJ IDEA. Is this intended change? If yes, then
> probably the changes section should be updated to include it as well.
>
> I must say that I heavily support this change. Supporting C-style
> array declaration in records adds complexity in many places of our
> codebase and introduces subtle bugs. It's somewhat depressing to fix
> all of them, knowing that nobody would use this anyway.
>
> With best regards,
> Tagir Valeev.
>
> [1] 
> https://docs.oracle.com/javase/specs/jls/se14/preview/specs/records-jls.html#jls-8.10.1
> [2] 
> http://cr.openjdk.java.net/~gbierman/jep384/jep384-20200506/specs/records-jls.html#jls-8.10.1


[records] Is C-style array declaration in components dropped?

2020-07-23 Thread Tagir Valeev
Hello!

The JLS 14 record preview spec allows C-style array declaration in
components (like record R(int x[])) [1]:

RecordComponent:
  { VariableModifier } UnannType VariableDeclaratorId
  VariableArityRecordComponent
VariableDeclaratorId:
  Identifier [ Dims ]

However, it appears that JLS 15 draft spec doesn't allow it anymore [2]

RecordComponent:
  { Annotation } UnannType Identifier
  VariableArityRecordComponent

This change is not listed in the draft spec prolog in "The changes are
the same as those in the first preview of Records in Java SE 14,
except for the following", so I overlooked it when updated the records
support in IntelliJ IDEA. Is this intended change? If yes, then
probably the changes section should be updated to include it as well.

I must say that I heavily support this change. Supporting C-style
array declaration in records adds complexity in many places of our
codebase and introduces subtle bugs. It's somewhat depressing to fix
all of them, knowing that nobody would use this anyway.

With best regards,
Tagir Valeev.

[1] 
https://docs.oracle.com/javase/specs/jls/se14/preview/specs/records-jls.html#jls-8.10.1
[2] 
http://cr.openjdk.java.net/~gbierman/jep384/jep384-20200506/specs/records-jls.html#jls-8.10.1


Re: Next up for patterns: type patterns in switch

2020-07-23 Thread John Rose
On Jul 23, 2020, at 2:53 PM, Remi Forax  wrote:
> 
> var x and default are not on the same plane. So it's not really a third thing.
> We are introducing something special for the bottom, null, but not for the 
> top ?

Eh; null doesn’t need to be that special, but Brian’s point is that
you can just mandate that it appears at the top or nowhere.
If you don’t mandate that, then type-coverage checks ensure
that a “case null” which appears after a nullable case (a total
one) will be not-reachable, and a static error.

Re: Next up for patterns: type patterns in switch

2020-07-23 Thread John Rose
On Jul 23, 2020, at 3:15 PM, Remi Forax  wrote:
> 
> I want at least to be sure we have tried to corral mutable objects.

The horse has left the corral.

Re: Next up for patterns: type patterns in switch

2020-07-23 Thread John Rose
On Jul 23, 2020, at 3:48 PM, Brian Goetz  wrote:
> 
>> P.S. Well, not exactly.  You didn’t expect *no* comment from me? :-)
> 
> There's always one 
> 
>> It is slightly premature to completely outlaw `x instanceof 42`,
>> because of nulls:  You can replace that with `x == 42` only if `x`
>> is `int`.  With strings, identity is also a problem; `x instanceof "foo"`
>> does not replace with an `==` expression.  In the end, if we outlaw
>> `x instanceof 42` the workaround might be `Objects.equals(x,42)`
>> but that incurs boxing overhead if `x` happens to be a primitive.
>> So, I think the fate of `EXPR instanceof CON_PAT` is up for grabs.
>> That said, I’m fine with leaving it out for starters; it can be added
>> after further thought—or not.
> 
> Truth be told, I am hoping we can avoid doing constant patterns entirely.  
> The obvious denotation (a literal) leads to at least the appearance of 
> ambiguity -- when a user looks at `foo(0)`, they can't immediately tell 
> whether the 0 is a parameter or a nested pattern (and worse when patterns 
> have parameters.)
> 
> In instanceof, we can avoid them entirely by unrolling into
> 
> if (x instanceof Foo(var y) && y == 0) { ... }
> 
> which is more flexible anyway because we can have not only equality 
> constraints, but comparison constraints, etc.  If we have guards, we can do 
> the same with cases:
> 
> case Foo(var y) where y == 0
> 
> So it's not clear whether we need constant patterns _at all_, except as far 
> as it looks like existing switches are full of constant patterns.  But maybe 
> that's really just a funny form of case label….

Sure, but that wasn’t my point.  You can’t really say “y == 0” uniformly,
so it’s a trap to appeal to that nice looking workaround.  You probably have
to say “Objects.equal(y, 0)” to get the equivalent to what we are considering
with constant patterns.

Here’s the example I was trying to evoke:

Integer x = flipcoin() ? null : 42;
if (x == 42)  ; // throws NPE 50% of the time
case (x) {  // never throws
case null: ;
case 42: break;
}
if (x instanceof 42) ; // never throws



Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Mark Raynsford
On 2020-07-23T12:20:01 -0400
Brian Goetz  wrote:

> In case I wasn't clear, this was a proposal to proceed on _right now_.  
> There's been no comments so far; should I take that as "perfect, ship it?"

Apologies for my lack of participation in these lists lately. I've been
inundated with non-JDK work over the past six months or so.

That said, I've read this proposal multiple times and I can see nothing
to which to object. Best to interpret my silence as agreement. :)

-- 
Mark Raynsford | https://www.io7m.com



Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Brian Goetz





P.S. Well, not exactly.  You didn’t expect *no* comment from me? :-)


There's always one 


It is slightly premature to completely outlaw `x instanceof 42`,
because of nulls:  You can replace that with `x == 42` only if `x`
is `int`.  With strings, identity is also a problem; `x instanceof "foo"`
does not replace with an `==` expression.  In the end, if we outlaw
`x instanceof 42` the workaround might be `Objects.equals(x,42)`
but that incurs boxing overhead if `x` happens to be a primitive.
So, I think the fate of `EXPR instanceof CON_PAT` is up for grabs.
That said, I’m fine with leaving it out for starters; it can be added
after further thought—or not.


Truth be told, I am hoping we can avoid doing constant patterns 
entirely.  The obvious denotation (a literal) leads to at least the 
appearance of ambiguity -- when a user looks at `foo(0)`, they can't 
immediately tell whether the 0 is a parameter or a nested pattern (and 
worse when patterns have parameters.)


In instanceof, we can avoid them entirely by unrolling into

    if (x instanceof Foo(var y) && y == 0) { ... }

which is more flexible anyway because we can have not only equality 
constraints, but comparison constraints, etc.  If we have guards, we can 
do the same with cases:


    case Foo(var y) where y == 0

So it's not clear whether we need constant patterns _at all_, except as 
far as it looks like existing switches are full of constant patterns.  
But maybe that's really just a funny form of case label





Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Remi Forax



On July 23, 2020 9:05:08 PM UTC, John Rose  wrote:
>On Jul 23, 2020, at 11:38 AM, Remi Forax  wrote:
>> 
>> In next releases? Add constant Pattern and static Pattern. Ban
>instance pattern because you don't want to match something that depends
>on a mutable states (my worst experience with Scala).
>
>Do you mean mutable states in some sort of pattern token (which is
>not AFAIK on the table) or mutable states in the object-being-tested
>or mutable states in a pattern parameter (e.g., an object being
>compared
>to the object-being-tested)?  In the latter two cases, the mutability
>bug
>is that you test an object and it passes a test on Tuesday but not
>today,
>either because the object changed, or the *other* object hanged.
>
>I see there are horrible bugs there, but for Java that ship is already
>sailed.
>Object::equals/hashCode can depend on mutable state; equals can depend
>on mutable state in the second operand.  Programmers just have to deal
>with it, or choose to use immutables (inlines! records!).

It's not because there are some loaded guns here and there that we should not 
try to avoid to add more.

>
>Patterns amount to a more generous slice of the functionalities
>which Object::equals/hashCode also serve.  If we try to “tighten up”
>some aspect of patterns to avoid mutability bugs, we’ll just force
>users to drop down to Object::equals, for no strong reason IMO.

I hate to have to run my app only on Tuesday is a good reason.
The current switch is limited to non mutable class is another good reason and 
forcing users to explicitly use equals when something is mutable is not that 
bad too, ok it's less magical. But being able to understand the code is still 
more important that writing it.

>
>Banning instance patterns (while allowing static patterns) just puts
>in a cardboard wall that makes it slightly harder to code some bugs
>but will greatly annoy legitimate designers and users.

As you said records and inlines are ok,
Why not restricting instance patterns to them.

>
>(Or do I misunderstand your point?)

Nope :)
I want at least to be sure we have tried to corral mutable objects.

>
>— John

Remi

-- 
On mobile


Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Remi Forax



On July 23, 2020 6:52:50 PM UTC, Brian Goetz  wrote:
>
>
>On 7/23/2020 2:38 PM, Remi Forax wrote:
>> Don't do deconstruction now ! We are not ready :)
>
>Now I'm confused.  Didn't I say exactly that in the first paragraph?

Yes, we agree.

>
>> On guards, they do not work well with exhaustiveness. Still not sure 
>> they are useful.
>
>It works fine, it's just more work for the user to get right.
>
>We induce a domination ordering on patterns.  If `T <: U`, then `T t` <
>
>`U u` (`T t` is less specific than `U u`.)  Similarly, for all guard 
>conditions g, `P & g` < `P`.  What this says is that if you want 
>exhaustiveness, you need an unguarded pattern somewhere, either:
>
>     case A:
>     case B & g:
>     case B:  // catches B & !g
>     case C:
>
>or
>
>     case A:
>     case B & g:
>     case C:
>     case Object:    // catches B & !g
>
>I understand your diffidence about guards, but I'm not sure we can do 
>nothing.  The main reason that some sort of guards feel like a forced 
>move (could be an imperative guard, like `continue`, but I don't think 
>anyone would be happy with that) is that the fall-off-the-cliff
>behavior 
>is so bad.  If you have a 26-arm switch, and you want the equivalent of
>
>the second of the above cases -- B-but-not-g gets shunted into the 
>bottom clause -- you may very well have to refactor away from switch,
>or 
>at least mangle your switch badly, which would be pretty bad.

I am worry about the whole complexity.

What about guard clauses with an order
switch(a) {
 case Object & a instanceof A -> 
 case Object & a instanceof B ->
}
Can the two cases be swapped ?

And the size of the JLS section that will explain how to compute the 
exhaustiveness. 

By example
switch(p) {
 case P & v >= 0 ->
 case P & v < 0 ->
}
Can be ok or not depending if v is an int or  a double.

or
switch(opt) {
  case Optional & opt.isPresent() ->
  case Optional & opt.isEmpty() ->
}

You will have to draw a line somewhere and because Java uses a lot of 
abstraction in libraries collection, optional, etc you may have to go pretty 
far.

>
>> On nullity, I prefer the total pattern to be explicit instead of 
>> implicit (given we have var, the type on the expression taken by the 
>> switch can be fuzzy for someone doing a quick look to the code), case
>
>> any x, case _ x or whatever the syntax is, is more readable IMO.
>
>It is unfortunate that `var x` is more fuzzy about types, but less
>fuzzy 
>about totality (`var x` is always total.)  It is also unfortunate that 
>`default` can't be our "any" clause.   Not sure that introducing a
>third thing is helpful, though.

var x and default are not on the same plane. So it's not really a third thing.
We are introducing something special for the bottom, null, but not for the top ?

Remi

--
On mobile


Re: Next up for patterns: type patterns in switch

2020-07-23 Thread John Rose
On Jul 23, 2020, at 11:38 AM, Remi Forax  wrote:
> 
> In next releases? Add constant Pattern and static Pattern. Ban instance 
> pattern because you don't want to match something that depends on a mutable 
> states (my worst experience with Scala).

Do you mean mutable states in some sort of pattern token (which is
not AFAIK on the table) or mutable states in the object-being-tested
or mutable states in a pattern parameter (e.g., an object being compared
to the object-being-tested)?  In the latter two cases, the mutability bug
is that you test an object and it passes a test on Tuesday but not today,
either because the object changed, or the *other* object hanged.

I see there are horrible bugs there, but for Java that ship is already sailed.
Object::equals/hashCode can depend on mutable state; equals can depend
on mutable state in the second operand.  Programmers just have to deal
with it, or choose to use immutables (inlines! records!).

Patterns amount to a more generous slice of the functionalities
which Object::equals/hashCode also serve.  If we try to “tighten up”
some aspect of patterns to avoid mutability bugs, we’ll just force
users to drop down to Object::equals, for no strong reason IMO.

Banning instance patterns (while allowing static patterns) just puts
in a cardboard wall that makes it slightly harder to code some bugs
but will greatly annoy legitimate designers and users.

(Or do I misunderstand your point?)

— John

Re: Next up for patterns: type patterns in switch

2020-07-23 Thread John Rose
Just one comment here:  This is a masterful summary of many months
work pursuing hard-won insights; thank you; let’s do this.

— John

P.S. Well, not exactly.  You didn’t expect *no* comment from me? :-)

It is slightly premature to completely outlaw `x instanceof 42`,
because of nulls:  You can replace that with `x == 42` only if `x`
is `int`.  With strings, identity is also a problem; `x instanceof "foo"`
does not replace with an `==` expression.  In the end, if we outlaw
`x instanceof 42` the workaround might be `Objects.equals(x,42)`
but that incurs boxing overhead if `x` happens to be a primitive.
So, I think the fate of `EXPR instanceof CON_PAT` is up for grabs.
That said, I’m fine with leaving it out for starters; it can be added
after further thought—or not.

Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Brian Goetz




On 7/23/2020 2:38 PM, Remi Forax wrote:

Don't do deconstruction now ! We are not ready :)


Now I'm confused.  Didn't I say exactly that in the first paragraph?

On guards, they do not work well with exhaustiveness. Still not sure 
they are useful.


It works fine, it's just more work for the user to get right.

We induce a domination ordering on patterns.  If `T <: U`, then `T t` < 
`U u` (`T t` is less specific than `U u`.)  Similarly, for all guard 
conditions g, `P & g` < `P`.  What this says is that if you want 
exhaustiveness, you need an unguarded pattern somewhere, either:


    case A:
    case B & g:
    case B:  // catches B & !g
    case C:

or

    case A:
    case B & g:
    case C:
    case Object:    // catches B & !g

I understand your diffidence about guards, but I'm not sure we can do 
nothing.  The main reason that some sort of guards feel like a forced 
move (could be an imperative guard, like `continue`, but I don't think 
anyone would be happy with that) is that the fall-off-the-cliff behavior 
is so bad.  If you have a 26-arm switch, and you want the equivalent of 
the second of the above cases -- B-but-not-g gets shunted into the 
bottom clause -- you may very well have to refactor away from switch, or 
at least mangle your switch badly, which would be pretty bad.


On nullity, I prefer the total pattern to be explicit instead of 
implicit (given we have var, the type on the expression taken by the 
switch can be fuzzy for someone doing a quick look to the code), case 
any x, case _ x or whatever the syntax is, is more readable IMO.


It is unfortunate that `var x` is more fuzzy about types, but less fuzzy 
about totality (`var x` is always total.)  It is also unfortunate that 
`default` can't be our "any" clause.   Not sure that introducing a third 
thing is helpful, though.




Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Remi Forax
Right now: add only the type Pattern and the null Pattern so people can test 
and report if we go in the right direction or not.

Don't do deconstruction now ! We are not ready :)

In next releases? Add constant Pattern and static Pattern. Ban instance pattern 
because you don't want to match something that depends on a mutable states (my 
worst experience with Scala).

On guards, they do not work well with exhaustiveness. Still not sure they are 
useful.
On nullity, I prefer the total pattern to be explicit instead of implicit 
(given we have var, the type on the expression taken by the switch can be fuzzy 
for someone doing a quick look to the code), case any x, case _ x or whatever 
the syntax is, is more readable IMO.

And I agree on banning total patterns in instanceof.

Remi



On July 23, 2020 4:20:01 PM UTC, Brian Goetz  wrote:
>In case I wasn't clear, this was a proposal to proceed on _right now_. 
>
>There's been no comments so far; should I take that as "perfect, ship
>it?"
>
>
>On 6/24/2020 10:44 AM, Brian Goetz wrote:
>> There are a lot of directions we could take next for pattern 
>> matching.  The one that builds most on what we've already done, and 
>> offers significant incremental expressiveness, is extending the type 
>> patterns we already have to a new context: switch.  (There is still 
>> plenty of work to do on deconstruction patterns, pattern assignment, 
>> etc, but these require more design work.)
>>
>> Here's an overview of where I think we are here.
>>
>> [JEP 305][jep305] introduced the first phase of [pattern 
>> matching][patternmatch]
>> into the Java language.  It was deliberately limited, focusing on
>only 
>> one kind
>> of pattern (type test patterns) and one linguistic context
>(`instanceof`).
>> Having introduced the concept to Java developers, we can now extend 
>> both the
>> kinds of patterns and the linguistic context where patterns are used.
>>
>> ## Patterns in switch
>>
>> The obvious next context in which to introduce pattern matching is 
>> `switch`;  a
>> switch using patterns as `case` labels can replace `if .. else if` 
>> chains with
>> a more direct way of expressing a multi-way conditional.
>>
>> Unfortunately, `switch` is one of the most complex, irregular 
>> constructs we have
>> in Java, so we must teach it some new tricks while avoiding some 
>> existing traps.
>> Such tricks and traps may include:
>>
>> **Typing.**  Currently, the operand of a `switch` may only be one of
>the
>> integral primitive types, the box type of an integral primitive, 
>> `String`, or an
>> `enum` type.  (Further, if the `switch` operand is an `enum` type,
>the 
>> `case`
>> labels must be _unqualified_ enum constant names.)  Clearly we can 
>> relax this
>> restriction to allow other types, and constrain the case labels to
>only be
>> patterns that are applicable to that type, but it may leave a seam of
>
>> "legacy"
>> vs "pattern" switch, especially if we do not adopt bare constant 
>> literals as
>> the denotation of constant patterns.  (We have confronted this issue 
>> before with
>> expression switch, and concluded that it was better to rehabilitate 
>> the `switch`
>> we have rather than create a new construct, and we will make the same
>
>> choice
>> here, but the cost of this is often a visible seam.)
>>
>> **Parsing.**  The grammar currently specifies that the operand of a 
>> `case` label
>> is a `CaseConstant`, which casts a wide syntactic net, later narrowed
>with
>> post-checks after attribution.  This means that, since parsing is
>done 
>> before we
>> know the type of the operand, we must be watchful for ambiguities
>between
>> patterns and expressions (and possibly refine the production for 
>> `case` labels.)
>>
>> **Nullity.**  The `switch` construct is currently hostile to `null`, 
>> but some
>> patterns do match `null`, and it may be desirable if nulls can be
>handled
>> within a suitably crafted `switch`.
>>
>> **Exhaustiveness.**  For switches over the permitted subtypes of 
>> sealed types,
>> we will want to be able to do exhaustiveness analysis -- including
>for 
>> nested
>> patterns (i.e., if `Shape`  is `Circle` or `Rect`, then `Box(Circle 
>> c)` and
>> `Box(Rect r)` are exhaustive on `Box`.)
>>
>> **Fallthrough.**  Fallthrough is everyone's least favorite feature of
>
>> `switch`,
>> but it exists for a reason.  (The mistake was making fallthrough the 
>> default
>> behavior, but that ship has sailed.)  In the absence of an OR pattern
>> combinator, one might find fallthrough in switch useful in
>conjunction 
>> with
>> patterns:
>>
>> ```
>> case Box(int x):
>> case Bag(int x):
>>     // use x
>> ```
>>
>> However, it is likely that we will, at least initially, disallow 
>> falling out
>> of, or into, a case label with binding variables.
>>
>>  Translation
>>
>> Switches on primitives and their wrapper types are translated using
>the
>> `tableswitch` or `lookupswitch` bytecodes; switches on strings and 
>> enums are
>> lowered in the 

Re: Next up for patterns: type patterns in switch

2020-07-23 Thread Brian Goetz
In case I wasn't clear, this was a proposal to proceed on _right now_.  
There's been no comments so far; should I take that as "perfect, ship it?"



On 6/24/2020 10:44 AM, Brian Goetz wrote:
There are a lot of directions we could take next for pattern 
matching.  The one that builds most on what we've already done, and 
offers significant incremental expressiveness, is extending the type 
patterns we already have to a new context: switch.  (There is still 
plenty of work to do on deconstruction patterns, pattern assignment, 
etc, but these require more design work.)


Here's an overview of where I think we are here.

[JEP 305][jep305] introduced the first phase of [pattern 
matching][patternmatch]
into the Java language.  It was deliberately limited, focusing on only 
one kind

of pattern (type test patterns) and one linguistic context (`instanceof`).
Having introduced the concept to Java developers, we can now extend 
both the

kinds of patterns and the linguistic context where patterns are used.

## Patterns in switch

The obvious next context in which to introduce pattern matching is 
`switch`;  a
switch using patterns as `case` labels can replace `if .. else if` 
chains with

a more direct way of expressing a multi-way conditional.

Unfortunately, `switch` is one of the most complex, irregular 
constructs we have
in Java, so we must teach it some new tricks while avoiding some 
existing traps.

Such tricks and traps may include:

**Typing.**  Currently, the operand of a `switch` may only be one of the
integral primitive types, the box type of an integral primitive, 
`String`, or an
`enum` type.  (Further, if the `switch` operand is an `enum` type, the 
`case`
labels must be _unqualified_ enum constant names.)  Clearly we can 
relax this

restriction to allow other types, and constrain the case labels to only be
patterns that are applicable to that type, but it may leave a seam of 
"legacy"
vs "pattern" switch, especially if we do not adopt bare constant 
literals as
the denotation of constant patterns.  (We have confronted this issue 
before with
expression switch, and concluded that it was better to rehabilitate 
the `switch`
we have rather than create a new construct, and we will make the same 
choice

here, but the cost of this is often a visible seam.)

**Parsing.**  The grammar currently specifies that the operand of a 
`case` label

is a `CaseConstant`, which casts a wide syntactic net, later narrowed with
post-checks after attribution.  This means that, since parsing is done 
before we

know the type of the operand, we must be watchful for ambiguities between
patterns and expressions (and possibly refine the production for 
`case` labels.)


**Nullity.**  The `switch` construct is currently hostile to `null`, 
but some

patterns do match `null`, and it may be desirable if nulls can be handled
within a suitably crafted `switch`.

**Exhaustiveness.**  For switches over the permitted subtypes of 
sealed types,
we will want to be able to do exhaustiveness analysis -- including for 
nested
patterns (i.e., if `Shape`  is `Circle` or `Rect`, then `Box(Circle 
c)` and

`Box(Rect r)` are exhaustive on `Box`.)

**Fallthrough.**  Fallthrough is everyone's least favorite feature of 
`switch`,
but it exists for a reason.  (The mistake was making fallthrough the 
default

behavior, but that ship has sailed.)  In the absence of an OR pattern
combinator, one might find fallthrough in switch useful in conjunction 
with

patterns:

```
case Box(int x):
case Bag(int x):
    // use x
```

However, it is likely that we will, at least initially, disallow 
falling out

of, or into, a case label with binding variables.

 Translation

Switches on primitives and their wrapper types are translated using the
`tableswitch` or `lookupswitch` bytecodes; switches on strings and 
enums are

lowered in the compiler to switches involving hash codes (for strings) or
ordinals (for enums.)

For switches on patterns, we would need a new strategy, one likely 
built on
`invokedynamic`, where we lower the cases to a densely numbered `int` 
switch,
and then invoke a classifier function with the operand which tells us 
the first

case number it matches.  So a switch like:

```
switch (o) {
    case P: A
    case Q: B
}
```

is lowered to:

```
int target = indy[BSM=PatternSwitch, args=[P,Q]](o)
switch (target) {
    case 0: A
    case 1: B
}
```

A symbolic description of the patterns is provided as the bootstrap 
argument
list, which builds a decision tree based on analysis of the patterns 
and their

target types.

 Guards

No matter how rich our patterns are, it is often the case that we will 
want

to provide additional filtering on the results of a pattern:

```
if (shape instanceof Cylinder c && c.color() == RED) { ... }
```

Because we use `instanceof` as part of a boolean expression, it is easy to
narrow the results by conjoining additional checks with `&&`.  But in 
a `case`
label, we do not necessarily have this