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

Reply via email to