permit with a class which is not a subtype is allowed

forax at forax at
Tue Sep 3 20:11:25 UTC 2019

> De: "John Rose" <john.r.rose at>
> À: "Remi Forax" <forax at>
> Cc: "Brian Goetz" <brian.goetz at>, "amber-spec-experts"
> <amber-spec-experts at>
> Envoyé: Mardi 3 Septembre 2019 21:45:13
> Objet: Re: permit with a class which is not a subtype is allowed

> On Sep 3, 2019, at 8:25 AM, [ mailto:forax at | forax at ]
> wrote:

>> Conceptually, i've a hard time to think that i want simultaneously a closed
>> hierarchy and let the subtype open by specifying only it's name that may exist
>> or not or that may not visible.

> This is a very narrow corner case. There are known-useful wider
> corner cases involving an open subtype, as follows:

> public sealed interface Container permits TrustedC, GeneralC { }

> private interface TrustedC { }
> //or non-exported public interface TrustedC { }
> //or public final class TrustedC { }

> public interface GeneralC { }
> //or public abstract class GeneralC { }

> Here, TrustedC is a constrained implementation of Container, while
> GeneralC is unconstrained. (In the case of an abstract class, it is
> differently constrained).

> An API which accepts a Container operand can test whether it is
> of the trusted subtype and perform optimized access that assumes
> that the operand behaves properly. Meanwhile, users of the API
> can create less-constrained implementations of the same interface.
> Operands of those less-constrained implementations can be treated
> with more care, perhaps by making temporary copies if race conditions
> are a concern.

> The above design pattern would allow us to define things like
> immutable lists with controlled access for untrusted implementors.

> The design pattern is not exactly what you requested, Remi, but it
> is similar enough to suggest that there might be times when the
> “more open” arms of the pattern (GeneralC) could be in different
> packages or even modules, which implies a sort of loose coupling.

I like this design, but in this case both TrustedC and GeneralC are available and visible from Container. 

It's very interesting because it also shows that when you want to permit a non-existing or non visible class, you can always insert a public non-sealed interface (your GeneralC) in between. 
So given that this simple refactoring exists, the compiler should always emit an error if one of the permit class is not available at compile time. 


More information about the amber-spec-observers mailing list