Obviously having the compiler generate both from the single declaration is just sugar. The key idea here is that pairing a sealed interface With a single inline implementation is a powerful combination.
I am uncomfortable with the ad-hoc-ness that this would only work for inline classes. Is there any reason such a construct couldn’t work for any class ? Sent from my MacBook Wheel > On Aug 2, 2019, at 7:58 AM, Remi Forax <[email protected]> wrote: > > Hi all, > > We (Maurizio, John and i) have spent some time to play with another proposal > of what LW10 can be based on the "confinent" idea i.e. an inine type can not > appear in a public API and you need an interface to use it in erased generics. > > So the idea is to have at Java language level a construct that desugar itself > into an interface and a package-private inline type. > > I will use the following syntax just to be able to explain the semantics and > not as a committement on any syntax. Let say you can declare an "inline > interface" (again wrong name) that will contains the impleemntation of the > inline type and surface its API as an interface. > > public inline interface Foo { > private int value; > > private Foo(int value) { > this.value = value; > } > > public Foo add(Foo foo) { > return new Foo(value + foo.value); > } > > public static Foo of(int value) { > return new Foo(value); > } > } > > this code is desugared into Foo and Foo$val, > with Foo and Foo$val nestmates (but not inner/outer classes). > > public sealed interface Foo permit Foo$val { > public Foo add(Foo foo); > > public static Foo of(int value) { > return new Foo$val(value); > } > } > /* package-private */ final inline class Foo$val implements Foo { > private int value; > > /* package-private */ Foo(int value) { > this.value = value; > } > > public Foo add(Foo foo) { > return new Foo(value + foo.value); > } > } > > So an inline interface contains only private or public members: > - private members are moved into the inline class > - public fields and public constructors are not allowed > - public instance methods are copied into the inline class, the signature is > copied as abstract method into the interface > - default method may stay in the interface (if supported) > - reference to the interface constructor (meta: that's why it's the wrong > name) are changed to reference to the inline class constructor. > - Foo$val is denotable as Foo.val, but it can only appear in non public > context (local variable, parameter type/return type of a private method, > private field) and it can not be a type argument or a bound of a generic > class/method. > > With that, i think we may not need null-default inline class anymore. > > For value based class, we have the issue that those are classes and not > interfaces. > My hope here is than we can teach the VM that we can retrofit invokevirtual > and invokeinterface to work on both classes and interfaces. It will also make > the transformation from any class to an interface binary compatible which > will be a nice tool if you want to grow a library. > > For LW100, we will enable the support of public constructors wich will make > Foo$val visible denotable. > > Obviously, it's just a proposal and i hope i'm not too far in my description > of what we have discussed. > > Rémi
