This is a nice example of “today’s problems come from yesterday’s solutions.”   
In Java 1.1, we did nested classes, and they were pretty cool, but there were 
some mismatches between the language model and the runtime model, which had 
some sharp edges.  So, as a solution to that problem, we taught the JVM about 
the notion of “nest”, to align the two.  The intent, at the time, was that the 
natural syntax for nests was — nesting.  

Now, you’re saying that it kinds of stinks that we have to take all the 
properties of nests (shared access control, hierarchical namespace) or none of 
them, and you’d like to introduce a way to get the first without the second.  
It’s a fair idea.

However, I think I’d solve the problem — which is that it is irritating to have 
to say FruitBasket.Apple all the time, rather than Apple — more directly?  Like 
some sort of more powerful “import”.  For example:

    import enum Foo;

could import the Foo enum class, _plus_ import-static all its constants.  (And 
something similar for sealed classes, of course).  

> On Jan 20, 2019, at 7:49 AM, Remi Forax <fo...@univ-mlv.fr> wrote:
> 
> Hi all,
> as Brian said recently, we have an issue because we are shortening the class 
> declaration (with records) or wants to declare in a single compilation unit a 
> hierarchy of types (with sealed types) and currently Java requires that a 
> compilation unit can only have one public class.
> 
> One solution is to get ride of this constraint, because it may be a good idea 
> in 1995 but today we are writing programs that have far more classes (the 
> introduction of modules recently was also driven by that idea). I propose 
> another way of solving that issue, introducing a mechanism to opt-in to have 
> more than one public class in a compilation unit.
> 
> Currently we have the mechanism of nestmates which has a runtime 
> representation (VM + reflection) but no language representation, i propose to 
> introduce a new declaration in the language in between the package 
> declaration and the first import,
>  nest NestHostClass;
> which define the class that will be used as nest host (obviously it can be 
> another keyword instead of "nest").
> 
> So a closed hierarchy can defines like this in one compilation unit:
>  nest Expr;
> 
>  public sealed Expr permits Variable, Value, Add;
>  public record Variable(String name) implements Expr;
>  public record Value(int value) implements Expr;
>  public record Add(Expr left, Expr right) implements Expr;
> 
> at runtime, Variable.class.getNestHost() == Expr.class
> 
> Another simpler example
>  nest FruitBasket;
> 
>  public record Fruit(String name);
> 
>  public class FruitBasket {
>    private final ArrayList<Fruit> fruits = new ArrayList<>();
> 
>    public void add(Fruit fruit) {
>      Objects.requireNonNull(fruit);
>      fruits.add(fruit);
>    }
>  }
> 
> at runtime, Fruit.class.getNestHost() == FruitBasket.class
> 
> I believe that the nest host class defined by the keyword "nest", doesn't 
> have to be public, but it's not a qualified name (obviously) and the class 
> has to be defined in the compilation unit.
> 
> Defining a nest can be seen as an extension of the case with only one class, 
> if there is only one class in the compilation unit, the class is it's own 
> nest host.
> If there is more than one class in the compilation unit, but only one class 
> is public, currently, they are not nestmates, i think we should not do 
> anything to try to retcon that compilation unit because this case is rare 
> (one may argument that if we introduce the nest syntax, it can be more 
> frequent). Also the compiler message should be tweaked if there are more than 
> one public classes to say that a nest can be defined.
> 
> Rémi

Reply via email to