The storage hint model

John Rose john.r.rose at oracle.com
Thu Jul 21 02:34:24 UTC 2022


I’m glad to see this idea worked out in detail, and for the record.

Given we want to give users control at several points over potential 
flatness, we must choose either a separate storage classes channel or a 
variation in variable types themselves.

And my overall sense is that it’s a “pick your poison” situation.  
But I think complexifying the types goes down a little smoother than 
adding a new channel to most (but not all) variables.  Generic variables 
can benefit from a type-based solution, but not from a SC-based 
solution, as this analysis shows.

The SC-based solution shrinks the surface of the flat-vs-not choice, but 
makes it correspondingly more irregular.

One irregularity you don’t mention is signature alignment.  In order 
to link to a method or field (or override a method) you need the 
signatures aligned.  (We don’t want bridges today please.)  This means 
that the `.flat` annotations are part of the signature (since they 
compile to Q-types).  This means signatures depend on something besides 
types, surely an add to the net complexity.

Also, type inference can carry flatness in the design of record, but 
cannot do so in a SC-based design, at least not without more irregular 
hacks.  (Maybe that doesn’t matter?)

On 20 Jul 2022, at 13:05, forax at univ-mlv.fr wrote:

> Maybe you want or maybe you don't, here is an interesting 
> implementation of ArrayList
>
> public classs ArrayList<E> {
>   private E[] array;
>   private int size;
>
>   public ArrayList() {
>     array = new E.flat[16];   // ahah, flat by default !
>   }
>
>   public boolean add(E element) {  // E is not flat
>     if (element == null && !array.getClass().isNullable()) {
>       var newArray = new E[array.length];  // need to store null, use 
> a nullable array
>       System.arraycopy(array, 0, newArray, 0, array.length);
>       array = newArray;
>     }
>     if (array.length == size) {
>       array = Arrays.copyOf(array, size * 2);
>     }
>     array[size++] = element:
>     return true;
>   }
> }
>
> It starts with a flat array and if an element null is added, it 
> "unflat" itself.
> This implementation is interesting because once recompiled with the 
> new generics, a new ArrayList<Integer>() will use a flatten array by 
> default.
>
> I've no idea about the performance of such kind of implementations, 
> but using T.flat give better control on what is flattenable or not in 
> the implementation.

If we choose, we can code this trick in the design of record as well.

So it’s not an advantage of the `.flat` proposal; it’s just a trick 
that is forced on the programmer willy nilly.

Today a variable is a type, and an optional name.  If it is a local or a 
field it has a name.  If it is inside an array or a (possibly generic) 
container, there is no name.  I can refactor my variables all day long 
through named and unnamed temps, fields, arrays, and other containers.  
If some but not all of those locations accept my chosen SC, my 
refactorings have greater friction.

It seems like adding new types is less disruptive than adding a whole 
new classification for variables.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220720/5c95631f/attachment-0001.htm>


More information about the valhalla-spec-observers mailing list