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
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to