www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - ref on hidden this param

reply TwoOfCups <TwoOfCups notreal.com> writes:
I am guessing I'm not the first person to think of this.

But allowing ref to be applied to the hidden this on member 
functions would be nice.
could be used for lazy init of objects, reassigning the lvalue 
and stuff.

Seem like a very easy thing technically so idk if there is some 
ideological reason not to?

right now we can do
```
class C{}
void foo(ref C c){...}
C c;
c.foo();

```

Which is pretty good, but an un-attached floating function can 
often get lost from the type they are meant to be attached to 
during certain import scenarios or certain template  scenarios so 
its actually not a robust solution.
Oct 04
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/10/2025 6:28 PM, TwoOfCups wrote:
 I am guessing I'm not the first person to think of this.
 
 But allowing ref to be applied to the hidden this on member functions 
 would be nice.
 could be used for lazy init of objects, reassigning the lvalue and stuff.
 
 Seem like a very easy thing technically so idk if there is some 
 ideological reason not to?
 
 right now we can do
 ```
 class C{}
 void foo(ref C c){...}
 C c;
 c.foo();
 
 ```
 
 Which is pretty good, but an un-attached floating function can often get 
 lost from the type they are meant to be attached to during certain 
 import scenarios or certain template  scenarios so its actually not a 
 robust solution.
This cannot work. Methods are stored in the vtable which is accessed from the this pointer. You would be jumping to a function pointer which is acquired after a null dereference.
Oct 04
parent reply TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 05:35:24 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 On 05/10/2025 6:28 PM, TwoOfCups wrote:
 This cannot work.

 Methods are stored in the vtable which is accessed from the 
 this pointer.

 You would be jumping to a function pointer which is acquired 
 after a null dereference.
ok so mark it final, still i think such a thing would be useful
Oct 04
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/10/2025 6:39 PM, TwoOfCups wrote:
 On Sunday, 5 October 2025 at 05:35:24 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 On 05/10/2025 6:28 PM, TwoOfCups wrote:
 This cannot work.

 Methods are stored in the vtable which is accessed from the this pointer.

 You would be jumping to a function pointer which is acquired after a 
 null dereference.
ok so mark it final, still i think such a thing would be useful
This is indeed possible. Walter would like to make the this pointer optionally explicit. However to support ref on it, there should be reasoning beyond "it could be useful".
Oct 04
parent reply TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 05:45:19 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 On 05/10/2025 6:39 PM, TwoOfCups wrote:
 On Sunday, 5 October 2025 at 05:35:24 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 05/10/2025 6:28 PM, TwoOfCups wrote:
 This cannot work.

 Methods are stored in the vtable which is accessed from the 
 this pointer.

 You would be jumping to a function pointer which is acquired 
 after a null dereference.
ok so mark it final, still i think such a thing would be useful
This is indeed possible. Walter would like to make the this pointer optionally explicit. However to support ref on it, there should be reasoning beyond "it could be useful".
Well in my case I am wanting it for a specific templated serialization scenario where the serializer has the ability to use a proxy type to serialize as a proxy type instead of serializing it directly. And i was wanting to serialize objects as a uuid and on deserialization do a look up to find it but would need to reassign the lvalue to make it work.. i will probably figure out some other way to do it but it will just make my serialization code more complicated and its already very complicated.. so "it could be useful" is all i got for you cus its what prompted me to make this thread.
Oct 04
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/10/2025 6:55 PM, TwoOfCups wrote:
 Well in my case I am wanting it for a specific templated serialization 
 scenario where the serializer has the ability to use a proxy type to 
 serialize as a proxy type instead of serializing it directly. And i was 
 wanting to serialize objects as a uuid and on deserialization do a look 
 up to find it but would need to reassign the lvalue to make it work..
A small example of this, where the proposed feature is used would be very welcome. I'm having trouble picturing the types and their interaction to each other.
Oct 04
parent reply TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 05:58:10 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 On 05/10/2025 6:55 PM, TwoOfCups wrote:
 Well in my case I am wanting it for a specific templated 
 serialization scenario where the serializer has the ability to 
 use a proxy type to serialize as a proxy type instead of 
 serializing it directly. And i was wanting to serialize 
 objects as a uuid and on deserialization do a look up to find 
 it but would need to reassign the lvalue to make it work..
A small example of this, where the proposed feature is used would be very welcome. I'm having trouble picturing the types and their interaction to each other.
``` class C { int uuid; int toSerial(){ // int is the proxy type return uuid; } void fromSerial(int i){ // do uuid lookup and assign this if this could be ref } } ... during serialization check if type has a toSerial and call that instead of serialized directly, in this case uuid will be written instead of the class contents. the actual class contents will be serialized else where ```
Oct 04
next sibling parent TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 06:49:16 UTC, TwoOfCups wrote:
again probably i will figure out some other way out of it.. but i 
just figured i would drop a post
Oct 04
prev sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/10/2025 7:49 PM, TwoOfCups wrote:
 On Sunday, 5 October 2025 at 05:58:10 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 On 05/10/2025 6:55 PM, TwoOfCups wrote:
 Well in my case I am wanting it for a specific templated 
 serialization scenario where the serializer has the ability to use a 
 proxy type to serialize as a proxy type instead of serializing it 
 directly. And i was wanting to serialize objects as a uuid and on 
 deserialization do a look up to find it but would need to reassign 
 the lvalue to make it work..
A small example of this, where the proposed feature is used would be very welcome. I'm having trouble picturing the types and their interaction to each other.
``` class C {         int uuid;     int toSerial(){ // int is the proxy type         return uuid;     }     void fromSerial(int i){             // do uuid lookup and assign this if this could be ref     } } ... during serialization check if type has a toSerial and call that instead of serialized directly, in this case uuid will be written instead of the class contents. the actual class contents will be serialized else where ```
Okay so the class is memorized (somehow, doesn't matter). You have the ability to access and reflect upon the class at compile time. Why not use a static method instead? ```d class C { ... static C fromSerial(int i) { C self = ...; // lookup i for C return self; } } ```
Oct 04
parent reply TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 06:56:27 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 Why not use a static method instead?
yeah i was thinking about doing that but like i said the serialization code is already a fucking mess of weird little special cases. so now i have to add checks for if the proxy functions are static and handle in a different way.
Oct 05
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Sunday, 5 October 2025 at 07:40:25 UTC, TwoOfCups wrote:
 On Sunday, 5 October 2025 at 06:56:27 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 Why not use a static method instead?
yeah i was thinking about doing that but like i said the serialization code is already a fucking mess of weird little special cases. so now i have to add checks for if the proxy functions are static and handle in a different way.
I use a static method for (de)serialization, it works pretty well. You should require static methods IMO, this is the right abstraction. Because you are creating a new instance, and that requires different semantics than just overwriting an existing one. -Steve
Oct 05
parent TwoOfCups <TwoOfCups notreal.com> writes:
On Sunday, 5 October 2025 at 21:34:01 UTC, Steven Schveighoffer 
wrote:
 On Sunday, 5 October 2025 at 07:40:25 UTC, TwoOfCups wrote:
 On Sunday, 5 October 2025 at 06:56:27 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 Why not use a static method instead?
yeah i was thinking about doing that but like i said the serialization code is already a fucking mess of weird little special cases. so now i have to add checks for if the proxy functions are static and handle in a different way.
I use a static method for (de)serialization, it works pretty well. You should require static methods IMO, this is the right abstraction. Because you are creating a new instance, and that requires different semantics than just overwriting an existing one. -Steve
My original design was to just disallow classes completely. It was fully oriented towards basic types, sum types, structs and ranges. And it is pretty nice as just that. I just didn't want to do a type registry to make class inheritance in deserialization possible. But time passes and the desire for inheritance in my serialization became too tempting. So I added a class registry and now I'm trying to go the next step of being able to properly serialize arbitrary graphs of object references where the correct references could be restored on deserialization.. so some kind of uuid gets written when an aggregate has an object of a special type of class. For general objects I just make a new object and serialize/deserialize the data in place. But for a special type of object (the base class for all entities in a game) I want this uuid lookup system. it is made more messy because I want the serialization code to handle top level serialization calls to these objects directly, aka serialize the data no uuid stuff, but then if this type is seen to be a member then we do the uuid behavior. so my system has been evolving from one design decision to the next. I am trying to work with what I already have without needing to redesign large parts.
Oct 05
prev sibling parent Tim <tim.dlang t-online.de> writes:
On Sunday, 5 October 2025 at 05:28:49 UTC, TwoOfCups wrote:
 I am guessing I'm not the first person to think of this.

 But allowing ref to be applied to the hidden this on member 
 functions would be nice.
 could be used for lazy init of objects, reassigning the lvalue 
 and stuff.
This has previously been implemented here: https://github.com/dlang/dmd/pull/15389 It caused different problems, so it has been reverted here: https://github.com/dlang/dmd/pull/15637
Oct 05