nest syntax proposal

Brian Goetz brian.goetz at oracle.com
Sun Jan 20 17:04:00 UTC 2019


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 <forax at 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



More information about the amber-spec-experts mailing list