----- Mail original ----- > De: "Brian Goetz" <brian.go...@oracle.com> > À: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Envoyé: Dimanche 20 Janvier 2019 18:04:00 > Objet: Re: nest syntax proposal
> 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. Yes, i see the fact that in Java the language force classes to be enclosed to have private access as an accidental complexity. The JVM has no such requirement so i propose to reconcile the language and the VM netsmates. > > 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). In a sense, you are doubling-down on the notion of hierarchy, or at least of enclosing, by saying that you have an "import tree" that can import a set of types that are declared inside another one. The main issue with your solution is that you can not retrofit an existing hierarchy/set of classes to this new scheme because moving a class inside another change its name so it's not a backward compatible change hence the idea to de-couple nestmates access and nested classes. Rémi > >> 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