Collapsing the requirements

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Aug 6 13:17:07 UTC 2019


----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Lundi 5 Août 2019 23:47:48
> Objet: Re: Collapsing the requirements

> On Aug 5, 2019, at 4:08 AM, forax at univ-mlv.fr wrote:
>> 
>> if we have a public method like "id" that takes a Foo or return a Foo it means
>> that you are providing a public API that doesn't play well with inference
>> (because Foo can not be a type argument for T).
>> Any user codes that will want to use a Stream, an Optional, List.of(),
>> Arrays.asList(), etc will not work.
>> So you are transferring the problem of generic over inline classes being not
>> supported in LW10 from the library developer to the users of those libraries.
>> 
>> So the question is should we do something to help library developers to avoid
>> them to publish public API with inline classes in their signature or do we
>> think that library developers will discover by themselves that having an API
>> with an inline class is the middle is not user friendly.
> 
> I would prefer to make the inline classes work well with libraries, including
> generic inference, so that the companion box type is require as rarely as
> possible, only for instantiation.
> 
> So, List<V.Box> is required, but if you say List.of(V.default) inference should
> pop up to List<V.Box>, just like List.of(1) pops up to List<Integer>.
> 
> As Brian suggests, this is the sort of detail that needs to be worked out.  I’m
> hopeful it can work at least as well as today’s int/Integer rules.

A long term objective is to get ride of boxing, if we are introducing more boxing in LW10, we may cripple our own future.
So i don't think LW10 should introduce rules for inline class that works "as well" as boxing conversions, it should work well enough.

By example,
  List.of(V.default) being typed as a List<V.Box> is perhaps too much
but
  List.of(V.default) being typed a List<V> *and* List<V.Box> list = List.of(V.default) being valid should be Ok.

The difference may be subtle, but in the second case, the assignment to List<V.box> works because a target type is specified.
This will ensure that the support of specialized generics in LW100 will also work and is the preferred mechanism.


Here are the rules, i propose:
- we should doesn't allow inline classes in signature of public methods (the confinement rule),
- there should be an opt-in mechanism to have the box (the eclair interface) derived automatically by the compiler,
  this default derived interface is empty (unlike Integer), you have to unbox it to call a method in the bytecode,
  but as part of the desugaring mechanism, when invoking a method on the box, the compiler will invoke the corresponding method on the inline class (or a NPE is thrown).
- the autobox rule should be derived from the handshake between an interface and it's sole permitted implementation being an inline class
  (so it works for the generated Box classes but also any eclair interfaces)

So for a value based class like Optional,
Optional will have an hand-crafted box (Opt), the autobox rule works and calling a method on Optional is a plain old interface call.

for an inline class like Complex with a Box provided by the compiler,
Complex.Box is an empty interface, the autobox rule works and calling a method on Complex.Box is equivalent to a inserting a cast like this: ((Complex)box).method()

Rémi


More information about the valhalla-spec-observers mailing list