Foo / Foo.ref is a backward default; should be Foo.val / Foo
Dan Heidinga
heidinga at redhat.com
Tue Apr 26 18:37:09 UTC 2022
Where is a B3 (.val) instance preferable to a B2 (B3 .ref) instance?
What are the criteria that would make an API designer expose a B3
(.val) instance in their method descriptors?
The primary benefit of a B3 (.val) instance over a B2 instance is
memory density. This relates to the containers holding the value.
The benefits are most evident when dealing with larger numbers of
flattened instances or arrays that live in the heap. The B3 (.val) is
primarily a benefit for backing storage. Agreed?
For API points, the .val instance ensures that nulls are impossible
and the methods can avoid null checks but may need special handling
for the all-zero value. There are potentially performance benefits
from the calling conventions knowing a priori that null isn't in the
value set. The impact of this is TBD. Alternatively, the default
.ref has the benefits Kevin pointed out in his original email (not
repeating them here).
Tearing only comes into play when writing to storage. It's a
non-issue for API points. Anything controversial here?
The question again is what's the primary reason(s) for exposing a B3
(.val) vs B2 instance in APIs? What guidance would we give API
designers around the use of B3 .val instances?
My initial attempt at this:
* Use B3 .val instances for backing storage - so instance variables,
arrays, and static fields (Flattening of statics tbd).
* Use B3 .val instances for internal private API points - so private
methods or package private methods where the instance has already come
through some front door
* Use B2 (B3 .ref) in most public APIs for migration, avoiding bad
default values, etc as per Kevin's initial email - at the risk of
slightly worse performance?
* Use B3 .val instances for the small set of public APIs where every
inch of performance matters (and only after proving it matters)
With this kind of guidance, a focus on the density of storage, and a
good way to spell ".val", I can see the benefit of Kevin's approach.
Still not 100% on board but persuadable.
In the B3 defaults to .ref model, what does the constructor return?
An L or Q? Can the user control that?
Remi's "new Complex(r, i)" example left me wondering do users say:
Complex.val c = new Complex(1, 2);
or
Complex.val c = new Complex.val(1, 2);
Does the Complex class author decide by providing one or the other
form of constructor:
Complex.val(int r, int i) { /* Return QComplex */ .... }
and
Complex(int r, int i) { /* Return LComplex */ .... }
The instance itself doesn't change but there may be conversions
(checkcast) needed one way or the other.
--Dan
On Tue, Apr 26, 2022 at 1:56 PM Dan Smith <daniel.smith at oracle.com> wrote:
>
> On Apr 26, 2022, at 8:45 AM, Kevin Bourrillion <kevinb at google.com> wrote:
>
> I think I would insist that `.val` be spelled with only one additional character... or even that the value type be generated as the snake_case form of the name!
>
>
> Okay, this is a meaningful refinement that I find less objectionable.
>
> If it's '#Integer128' or 'Integer128!' instead of 'Integer128.val', we've trimmed away a chunk of the typing/reading overhead (though it's still there, and I think some of the overhead is directly in service of what you find attractive—the idea that the value type is something unnatural/a departure from the norm).
>
> If it's 'integer128' and 'Integer128', well now there is no "default" type, and I think we're talking about something categorically different. There are some new (surmountable?) problems, but my earlier objections don't apply.
>
More information about the valhalla-spec-experts
mailing list