Toward LW10, the inline interface proposal

Remi Forax forax at univ-mlv.fr
Fri Aug 2 14:58:37 UTC 2019


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


More information about the valhalla-spec-observers mailing list