Revisiting .ref and .value

Paul Bjorkstrand paul.bjorkstrand at
Tue Jul 21 11:38:37 UTC 2020

I don't find it that confusing, but I have been following this project for
years now. I do see how it can get confusing with all the new terminology.
Fwiw, I believe the syntax is not yet set in stone (or if I am wrong please
let an expert correct me).

Question: if you make a new, numeric type, that fits inside a machine word,
would you really want to be forced to always say 'inline' at every use to
get all the benefits of the inline type?

I'm not against this idea; I see the allure of the simplicity. I had to ask

On Tue, Jul 21, 2020, 03:12 Gernot Neppert <mcnepp02 at> wrote:

> If I've got this right, the way for specifying which variant of an inline
> class to use, one would have to use one of the suffixes .ref or .value.
> Existing classes refactored as inline classes could somehow specify that
> .ref was the default, whereas new inline classes would have .value the
> default.
> What strikes me as odd is the fact that we are now having 4 new terms that
> would have to be understood by the developer:
> - the keyword 'inline' that declares a class that represents a value-type.
> - the keyword-suffix '.val' that says "At this point, use the inline
> representation of a class".
> - the keyword-suffix '.ref' that says "At this point, use the regular
> non-inline representation of a class".
> - the Standard interface "IdentityObject" that probably most often will be
> encountered as a type-bound for a generic function or class.
> This makes me think: do we really need to learn so many different terms
> when they are so closely related?
> Couldn't we do without the '.val' and '.ref' suffixes if we shifted towards
> decorating the *type-use* instead of the *type* itself?
> Which leads me to this idea:
> 1. A declaration "inline class Bar" would always declare a 'ref-default"
> class. The purpose of 'inline' here would be simply to enforce certain
> restrictions, such as final fields etc.
> 2. inline classes would not implement the interface "IdentityObject".
> 3. In order to make use of the "inline characteristics", one would have to
> specify "inline" again:
> class Outer {
> Bar byRef; // ref-member, may be null.
> inline Bar embedded; // inline member, mandates the same
> definite-assignment rule as that for final fields.
> }
> // inline return-value and inline parameters will copy by-value.
> inline Bar calculate(inline Bar bar) {
>     inline Bar temp = bar; // inline local var, will copy by-value.
>    // inline array. Must use an initializer-instance that will be used for
> all array-members.
>     inline Bar[] arr = new Bar[10] { new Bar("") };
> }
> // ref-return-value and ref-parameters
> Bar calculate(Bar bar) {
>          Bar temp = bar; // local var, assigns the reference only.
> }
> // generic function requires inline-class, so copy-by-value may be used
> <C> void foo(inline C) {
> }
> // normal generic function for any ref-type. Will use implicit
> reference-projection if an inline-value is passed
> <C> void foo(C obj) {
> }
> // generic function that explicitly requires non-inline class.
> // By requiring IdentityObject, we know that 'obj' cannot be the result of
> a reference-projection, so we can safely synchronize on it!
> <C extends IdentityObject> void foo(C obj) {
>   synchronized(obj) {
>   }
> }
> // Conflicting declaration, will be rejected by compiler
> <C extends IdentityObject> void foo(inline C obj) {
>   synchronized(obj) {
>   }
> }

More information about the valhalla-spec-observers mailing list