[fpc-devel] "Default" discussion for SmartPointers etc

Jonas Maebe jonas.maebe at elis.ugent.be
Wed Jul 27 15:33:12 CEST 2016


Michael Van Canneyt wrote on Wed, 27 Jul 2016:

> On Wed, 27 Jul 2016, Maciej Izak wrote:
>
>>
>> TNullable<T: record> = proxy record
>> ...
>>
>> looks good for me, even better than pure record, the context is more clear.
>
> Yes. Exactly what Jonas wanted to achieve, I suppose.

A bitpacked or packed record still behaves like a regular record. If  
does not behave like a record, it should not be called a record.

Additionally, the @@/@ operator thing is inconsistent with how e.g.  
ansistrings or dynamic arrays work: @ansistringvar does not get you  
the address of the first character, but of the variable itself.  
Similarly, there is no @@ansistringvar to get the address of the  
ansistring variable itself rather than of the first character, even  
though the 'value' of an ansistring starts at that first character.

Procedure variables in Turbo Pascal (and Delphi) are the only type for  
which this approach was ever was used, and given that they didn't use  
it anymore later on may indicate that they also thought it was not a  
very good idea in hindsight. Let alone that we would also start  
accepting @@@-expressions  
(https://github.com/maciej-izak/PascalSmartPointers/blob/master/tests/tdefault21.pp  
).

The fact that you want this operation so the proxy can be transparent  
in most cases and then be intransparent in some other cases, indicates  
that there may be something wrong with the way the concept is  
designed. It's a bit like having a pointer type that you always want  
to be implicitly dereferenced, so then you add @pointer to get the  
value of the pointer and @@pointer to get the address of the pointer  
variable itself.

It would seem better to me that you do have to add something after  
your proxy object (specify a field, call a method, use proxyobject[x],  
...)  to get the proxied value. Just like with a class, where  
"instance" by itself can never refer to the default property (it's  
always "instance[x]").

The discussion about var-parameters similarly worries me. I think it  
is a desirable feature that you cannot pass such a proxy object  
directly as a var-parameter to a routine expecting a plain value. Just  
like you, indeed, can never pass a property as a var-parameter, even  
if it maps directly to a field. You should not be able to implicitly  
strip away the proxy object, since it obviously changes (possibly in a  
very invasive way) how that value can be manipulated (the value could  
be strict private and only gettable/settable via methods normally, so  
it is limited to certain values). It breaks the contract if you can do  
such direct manipulations anyway.

One possible alternative is to severely restrict such a proxy object  
at the language level: make sure its definition cannot add any  
additional functionality beyond what is strictly necessary for  
read-only proxying (except possibly for implicit conversion operators,  
which then also must be forbidden from changing the value). In that  
case, passing the proxied value directly by reference is no problem  
because after returning, the proxied object will be guaranteed to  
still be in a valid state (since the proxy object has no ability to  
restrict what value could be assigned to the proxied object field if  
it were done via the proxy).


Jonas



More information about the fpc-devel mailing list