Forward declaring the identity of an object
Red IO
redio.development at gmail.com
Fri Jul 7 23:40:02 UTC 2023
You got how null and objects work slightly wrong resulting in some wrong
assumptions.
Remember all object variables in Java are just memory addresses (it's a bit
more complicated but the details don't matter here). If you assign the
object to the final field/ variable all you are doing is taking the memory
address of the thing on the right and storing it in the field. The field
itself also has an address so it would be possible to change it afterwards
but saying the field is final makes that "illegal".
The "change the variable itself afterwards" idea also is the reason you
think the keyword should be at the use site.
But this puts all the work and the track keeping to the runtime which now
has to keep a list of what fields belong to this delayed object. Something
the memory address (field) is already doing by itself in case of a valid
object.
So the simpler and more logical approach is to just set the field to the
already prepared memory location the object will be initialized to. But
mark that location so it will be treated as null if accessed through a
field. This requires only 1 note for the runtime per object instead of per
field.
I don't know if you are familiar with C but here are the 2 approaches
modeled in C:
your approach:
Foo* foo = null;
Foo* foo2 = null;
//runtime remembers fields
Foo** __foo_field = &foo;
Foo** __foo_field2 = &foo2;
// some stuff
//foo init
Foo* actual_foo = malloc(sizeof(Foo));
init_foo(actual_foo);
// setting of every forwarded declare field
*__foo_field = actual_foo;
*__foo_field2 = actual_foo;
// runtime forgetting now fully init fields.
Foo** __foo_field = nullptr;
Foo** __foo_field2 = nullptr;
My approach:
Foo* actual_foo = malloc(sizeof(Foo));
Foo* foo = actual_foo;
Foo* foo2 = actual_foo;
//Runtime remembers memory as not initialized
Foo* uninit_memory = actual_foo;
//Some stuff
//foo init
init_foo(uninnit_memory);
// runtime forgetting now initialized memory
uninnit_memory = nullptr;
As you can see your approach is taking linearly more recourses and is
harder to manage as it scales with the number of effected fields while my
approach is staying constant.
Hope this cleared up some things.
But don't underestimate the effort to implement it. It's likely to much
effort in both approaches.
Great regards
RedIODev
On Fri, Jul 7, 2023, 15:11 David Alayachew <davidalayachew at gmail.com> wrote:
> I actually just remembered this.
>
> I decided earlier on that any keyword that is used to denote this feature
> would be used where the variable is being passed in, like a "hall pass".
>
> Node a;
> Node b = new Node(__hall_pass a);
> a = new Node(b);
>
> I wanted to highlight this because your example put the keyword at the
> declaration site rather than the use site.
>
> Doing it my way is clearer because, for example in the enum example I gave
> earlier, you change things to say this.
>
> enum RPS7
> {
>
> Rock(__hall_pass Scissors),
> Paper(Rock),
> Scissors(Paper),
> ;
>
> //etc
>
>
> }
>
> Plus, in my (very ignorant and uninformed) view of how the runtime works,
> putting the keyword at the use site would more closely map to what actions
> the runtime takes, as well as where it would do it.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230708/dc5eaa7c/attachment.htm>
More information about the amber-dev
mailing list