[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