> 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 22:43:06 > Objet: Re: nest syntax proposal
> So, there are about 100 people in the world who know what “nest mates” means, > which is a huge black mark against introducing an explicit “nest” concept into > the language. Nest mates has been a low-level implementation detail, and the > fact that it it is hidden from the user model is a feature, not a bug. This is > a big new concept to teach to a large audience that doesn’t yet have any > conception of it. So far, the benefits do not remotely outweigh the degree to > which it exposes new complexity to everyone. > I would much prefer a solution that builds on existing concepts that people > already understand, than one that requires them to learn a new concept just to > support a particular use of a new feature. yes, introducing a new concept is the weak part of my proposal. I would prefer to not introduce the concept of nest in the language and just say every classes inside the same compilation unit has nestmate access (almost an extension of the current meaning). There are two issues with that: - it's a source compatible change but dangerous because it means that an existing .java class that declares a public class and a non public class, something which is currently allowed, if recompiled the two classes will gain nestmate access. - nestmates in the VM is based on the notion of nest host, how the compiler determine which class is the nest host when they are several public classes in the compilation unit ? maybe someone has a better idea that the keyword 'nest' ? > People understand import. compiler devs and JLS maintainers don't :) import/import static is still a regular source of bugs, adding more overloaded meanings to import is something dangerous IMO. > And they understand auxiliary classes. Let’s work with the familiar concepts. but your solution seems tailored to sealed types, what if i have several record classes with no common abstract type, how it works ? and again there is no refactoring between a classical interface and a sealed interface, something we should try offer. Rémi >> On Jan 20, 2019, at 4:31 PM, [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] >> wrote: >> ----- Mail original ----- >>> De: "Brian Goetz" < [ mailto:brian.go...@oracle.com | >>> brian.go...@oracle.com ] > >>> À: "Remi Forax" < [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] > >>> Cc: "amber-spec-experts" < [ mailto:amber-spec-experts@openjdk.java.net | >>> 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 < [ mailto:fo...@univ-mlv.fr | >>>> 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