I have now gone back and re-read some of the previous email about totality, 
including four that I now quote below:

> On Aug 14, 2020, at 1:20 PM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
>>  . . . totality is a "subtree all the way down" property.

This observation was later refined by the message quoted below, but I think we 
never remarked explicitly on that fact.  It turns out that “weak totality” is a 
“subtree all the way down property” but “strong totality” is not.

> On Aug 20, 2020, at 3:09 PM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
> Here's an attempt at a formalism for capturing this.  
> 
> There are several categories of patterns we might call total on a type T.  We 
> could refine the taxonomy as:
> 
>  - Strongly total -- matches all values of T.  
>  - Weakly total -- matches all values of T except perhaps null.
> 
> What we want to do is characterize the aggregate totality on T of a _set_ of 
> patterns P*.  A set of patterns could in the aggregate be either of the 
> above, or also: 
> 
>  - Optimistically total -- matches all values of subtypes of T _known at 
> compile time_, except perhaps null.  
> 
> Note that we have an ordering:
> 
>     partial < optimistically total < weakly total < strongly total
> 
> Now, some rules about defining the totality of a set of patterns.  
> 
> T-Total: The singleton set containing the type pattern `T t` is strongly 
> total on U <: T.  (This is the rule we've been discussing, but that's not the 
> point of this mail -- we just need a base case right now.) 
> 
> T-Subset: If a set of patterns P* contains a subset of patterns that is 
> X-total on T, then P* is X-total on T.  
> 
> T-Sealed: If T is sealed to U* (direct subtypes only), and for each U in U*, 
> there is some subset of P* that is optimistically total on U, then P* is 
> optimistically total on T.  
> 
> T-Nested: Given a deconstructor D(U) and a collection of patterns { P1..Pn }, 
> if { P1..Pn } is X-total on U, then { D(P1)..D(Pn) } is min(X,weak)-total on 
> D.

That “min(X,weak)” is crucial here.

> 
> OK, examples.
> . . .
> 
> { Box(Object o) } weakly total on Box<Object>
> 
>  - Object o total on Object
>  - { Object o } total on Object by T-Subset
>  - { Box(Object o) } weakly total on Box<Object> by T-Nested

So, going back to my earlier email about the box of frogs and the bag of 
objects:

> On Aug 12, 2020, at 10:46 PM, Guy Steele <guy.ste...@oracle.com> wrote:
> 
>> On Aug 12, 2020, at 3:57 PM, fo...@univ-mlv.fr <mailto:fo...@univ-mlv.fr> 
>> wrote:
>> . . .
>> 
>> I agree destructuring is just as important as conditionality and those two 
>> things should be orthogonal.
>> But i still think having a keyword to signal that a pattern (not a case) is 
>> total is better than letting people guess.
> 
> Yes, and here is the example that convinced me that one needs to be able to 
> mark patterns as total, not just cases:
> 
> (Assume for the following example that any pattern may be preceded by 
> “default”, that the only implication of “default” is that you get a static 
> error if the pattern it precedes is not total, and that we can abbreviate 
> “case default” as simply “default”.)
> 
>       record Box<T>(T t) { }
>       record Bag<T>(T t) { }
> 
>       record Pair<T,U>(T t, U u) { }
> 
>       Triple<Box<Frog>, Bag<Object>> p;
> 
>       switch (x) {
>               case Pair(Box(Tadpole t), Bag(String s)): …
>               case Pair(Box(Tadpole t), Bag(default Object o)): …
>               case Pair(Box(default Frog f), Bag(String s)): …
>               default Pair(Box(Frog f), Bag(Object o)): …
>       }

and here we can see that this was wrong, now that we have the terminology to 
distinguish weak totality and strong totality.  When I wrote "you get a static 
error if the pattern it precedes is not total” we would now say "you get a 
static error if the pattern it precedes is not _strongly_ total”.  But “subtree 
all the way down” is a property of weak totality but not of string totality.  
Therefore

        default Pair(Box(Frog f), Bag(Object o)): …

and

        case Pair(Box(default Frog f), Bag(default Object o)): …

do _not_ mean the same thing after all.  We conclude that not only is the 
latter preferable, as Rémi indicated:

> On Aug 13, 2020, at 8:19 AM, fo...@univ-mlv.fr wrote:
> . . .
> 
> I think i prefer using "default" (or any other keyword) only where it makes 
> sense and doesn't allow "default" to be propagated.
> so
>   default Pair p: ...
> is ok but 
>   default Pair(Box(Frog f), Bag(Object o)): …
> should be written
>   case Pair(Box(default Frog f), Bag(default Object o)): …

(I have corrected a typo), but in fact only the latter is _correct_.

Taking all this into account in the context of my latest proposal: while 
“switch case” would forbid the use of a switch label that begins with the 
keyword “default”, nevertheless “default” as a _pattern marker_ may be 
profitably used within a “switch case” construction:

        switch case (x) {
                case Pair(Box(Tadpole t), Bag(String s)): …
                case Pair(Box(Tadpole t), Bag(default Object o)): …
                case Pair(Box(default Frog f), Bag(String s)): …
                case Pair(Box(default Frog f), Bag(default Object o)): …
        }

or perhaps just

        switch case (x) {
                case Pair(Box(Tadpole t), Bag(String s)): …
                case Pair(Box(Tadpole t), Bag(Object o)): …
                case Pair(Box(Frog f), Bag(String s)): …
                case Pair(Box(default Frog f), Bag(default Object o)): …
        }

Reply via email to