Possible refinement for sealed classes

Remi Forax forax at univ-mlv.fr
Thu Apr 1 14:18:02 UTC 2021


> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Jeudi 1 Avril 2021 15:23:28
> Objet: Possible refinement for sealed classes

> 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 |
> 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.
I'm not sure to understand why this case is special enough to get a special way of delegating the "sealness" (the fact to be sealed, i don't know if there is a term in English for that) apart that it would be cool to have it. 

Delegating the "sealness" in that direction, from an interface which subtypes are subtypes to the sealed type, seems less readable that the other direction, from the sealed type to the interface that will have subtypes that implement the sealed type. 
So is it equivalent to 
sealed interface Sandwich permits __relaxed WithCheese, WithToast, etc 
with __relaxed meaning that WithCheese doesn't have to be a subtype of Sandwich, but the subtypes of WithCheese, etc have to ? 

If Sandwich see WithCheese but not the subtypes of WitchCheese, it can still be sealed with those types ? 

How it works in term of separate compilation, if I add "__refines Sandwich" to a WithCheese without recompiling Sandwich ? 

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210401/ed26425d/attachment.htm>


More information about the amber-spec-experts mailing list