<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">I’m glad to see this idea worked out in detail, and for the record.</p>
<p dir="auto">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.</p>
<p dir="auto">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.</p>
<p dir="auto">The SC-based solution shrinks the surface of the flat-vs-not choice, but makes it correspondingly more irregular.</p>
<p dir="auto">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 <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">.flat</code> 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.</p>
<p dir="auto">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?)</p>
<p dir="auto">On 20 Jul 2022, at 13:05, <a href="mailto:forax@univ-mlv.fr" style="color: #3983C4;">forax@univ-mlv.fr</a> wrote:</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Maybe you want or maybe you don't, here is an interesting implementation of ArrayList</p>
<p dir="auto">public classs ArrayList<E> {
<br>
private E[] array;
<br>
private int size;</p>
<p dir="auto"> public ArrayList() {
<br>
array = new E.flat[16]; // ahah, flat by default !
<br>
}</p>
<p dir="auto"> public boolean add(E element) { // E is not flat
<br>
if (element == null && !array.getClass().isNullable()) {
<br>
var newArray = new E[array.length]; // need to store null, use a nullable array
<br>
System.arraycopy(array, 0, newArray, 0, array.length);
<br>
array = newArray;
<br>
}
<br>
if (array.length == size) {
<br>
array = Arrays.copyOf(array, size * 2);
<br>
}
<br>
array[size++] = element:
<br>
return true;
<br>
}
<br>
}</p>
<p dir="auto">It starts with a flat array and if an element null is added, it "unflat" itself.
<br>
This implementation is interesting because once recompiled with the new generics, a new ArrayList<Integer>() will use a flatten array by default.</p>
<p dir="auto">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.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">If we choose, we can code this trick in the design of record as well.</p>
<p dir="auto">So it’s not an advantage of the <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">.flat</code> proposal; it’s just a trick that is forced on the programmer willy nilly.</p>
<p dir="auto">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.</p>
<p dir="auto">It seems like adding new types is less disruptive than adding a whole new classification for variables.</p>
</div></div></body>
</html>