Switch labels (null again), some tweaking
forax at univ-mlv.fr
forax at univ-mlv.fr
Thu Apr 29 12:17:07 UTC 2021
----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "Brian Goetz" <brian.goetz at oracle.com>, "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Jeudi 29 Avril 2021 11:43:54
> Objet: Re: Switch labels (null again), some tweaking
>>>
>>> If I read the rules correctly, Box(Soup) + Bag(Soup) "cover"
>>> Container<Lunch>, with the exception of the { null, Box(null),
>>> Bag(null) }. So the above will throw when `lunch` is null, and will
>>> also throw with Box(null) or Bag(null). Correct?
>>>
>>
>> Correct (under the "we make switches total" plan.)
>
> I realized there's also another remainder Box/Bag(*) - e.g.
> Box/Bag(Pizza), where Pizza is a new type that shows up in the sealed
> hierarchy.
>
> To cover that (not that it's required at compile-time, just to imagine
> what javac would emit), we need probably one of these:
>
> case Box b:
>
> or
>
> case Container c
>
> Right?
Not necessarily.
First, let's acknowledge that you are moving the discussion from the basic semantics to talk about the translation strategy which touch more the binary compatibility,
aka, what is the semantics when the view of the world at compile time and at runtime are disagreeing.
There are at least two reasons to let javac emits such cases,
first like with null as remainder, you have to add a lot of cases once you have sub-patterns, so it will bloat the bytecode,
then if we insert such cases, it means that we also have a code that throw a specific exception bolt into the bytecode which means that we can not change the binary compatibility story later.
The jobs to implement the binary compatibility semantics is the job of the runtime not the compiler, like with lambdas, where the LambdaMetaFactory does some runtime checks before generating + linking the lambda proxy,
I expect a SwitchMetafactory to do the same job. This is more flexible and allows the runtime to be updated when the VM change by example, the lambdaMetafactory code was changed with the introduction of hidden classes.
Now, the big question is what binary compatibility semantics we want ?
We can by example throw a subclass of LinkageError upfront during the linking when we detect that the sealed type as more subclasses that the one accessible at compile time, but it means that adding a new subclass to a sealed type is not a binary compatible change anymore. We can delay the detection the an incompatible class until we see one at runtime, so adding a new subclass is a compatible change but calling a switch with an instance of such subclass is not.
There is also the question about the order of the cases, should the order of the cases be validated at runtime or not, by example, if we have B < A at compile time but A < B at runtime with a switch that like case B first and case A second.
>
> Maurizio
Rémi
More information about the amber-spec-experts
mailing list