Seems like a reasonable proposal.

> sealed interface WithCheese __refines Sandwich { }

Would `_refines` operate at compile time with javac copy/pasting the
sealed list from Sandwich into WithCheese?  An alternative is some new
classfile info to tell the VM to do the copy/paste at classload.  Both
are possible but the VM option is more expensive to implement.

--Dan

On Thu, Apr 1, 2021 at 9:24 AM Brian Goetz <brian.go...@oracle.com> wrote:
>
> Been working with sealed classes a lot lately, and have run into a pattern 
> that we might want to consider supporting more directly, which is interfaces 
> that exist solely to refine a sealed class or interface.  Suppose we have:
>
>     sealed abstract class Sandwich { }
>
>     interface WithCheese { }
>     interface Toasted { }
>     interface NontraditionalStructure { }
>     interface NontraditionalIngredients { }
>
>     class Cheeseburger extends Sandwich implements WithCheese { }
>
>     class TunaMelt extends Sandwich implements Toasted, WithCheese { }
>
>     class Burrito extends Sandwich implements WithCheese, 
> NontraditionalStructure { }
>
>     class ChipButty extends Sandwich implements NontraditionalIngredients { }
>
>     class PopTart extends Sandwich implements NontraditionalIngredients, 
> NonTraditionalStructure { }
>
> (see, e.g., https://twitter.com/matttomic/status/859117370455060481, for 
> those who don't get the joke.)
>
> The constraint we would like to express here is that the interfaces 
> WithCheese and Toasted exist to serve Sandwich, which is 
> extension-controlled.  To capture this, we also seal these interfaces, but 
> now have to redundantly enumerate their subtypes.  This is annoying and 
> brittle, because we're stating it indirectly; a more direct capture of intent 
> would be to say "Toasted can only be used with Sandwich."
>
> Even if Sandwich were an interface, and then we can say "Toasted extends 
> Sandwich", we still have to redundantly enumerate the subtypes.  If this game 
> is about Sandwich, just having Sandwich enumerate its subtypes should be 
> enough.
>
> Without trying to paint the bikeshed, this is a pretty simple extension to 
> sealing:
>
>     sealed interface WithCheese __refines Sandwich { }
>
> This says that WithCheese is sealed to either classes that extend Sandwich, 
> or other interfaces that __refines Sandwich.  As a bonus, default methods in 
> WithCheese can refer to methods in Sandwich, since it must always be the case 
> that `this instanceof Sandwich`.
>
> Essentially, I want to put the `permits` list on Sandwich, and have 
> `WithCheese` and friends delegate their permits to `Sandwich`, rather than 
> having each interface enumerate their subtypes.

Reply via email to