[fpc-devel] "referenced properties" vs "value properties"
Skybuck Flying
skybuck2000 at hotmail.com
Tue Sep 20 14:21:05 CEST 2011
I think the Delphi language has a little problem when it comes to
"properties".
I consider C/C++ to be a "value language" or maybe even a "const language"
where addresses of classes and fields are constant or hard coded into
instructions.
While Delphi is more of a "reference language" or "pointer language" where
addresses of classes are stored in data pointers which are used via
instructions.
The closest thing to a c++ class is a record in Delphi.
Delphi classes are different from a c++ class, in Delphi a class when
instantiated returns a pointer to a class in memory.
This "referenced" design of Delphi is pretty handy, it allows code to refer
to the same memory via different pointers which all point to the same
memory.
However I do consider "properties" in it's current design to somewhat break
with this "referenced design".
Properties in Delphi are more like a "value type", they/the properties also
works on "values", the read/write values or records or even entire arrays.
This more or less seems like a design mistake. Perhaps properties should
have been always "referenced" as well just like Delphi classes.
(Think of a referenced property as a "var parameter" versus a "copy
parameter"
The var parameter would allow changes, while the copy parameter does useless
changes.)
The problem with properties currently is that it does not allow partial
modification of records or arrays, when a property is of type record or
array it's a everything or nothing situation, either the entire record/array
is overwritten/returned or nothing at all, this is very inconvenient and
also bad for performance.
Delphi programmers have to fall back on pointer types for value types to be
used with properties. So Delphi programmers would need to create pointer
types again and turn properties into pointer types.
One example of somewhat bad programming is record operator overloading which
also requires two values apperently, this means the properties will have to
be dereference for example: C = A^ * B^
The operators themselfes do not seem to work with pointer types, so pointers
will have to be deferenced, quite a mess.
The solution could be to introduce "referenced properties". These properties
under-water always work with pointers to fields, records, arrays and so
forth.
This frees the programmer from having to deal with pointers and pointer
types and pointer dereferencing and reduces coding mistakes and also makes
coding more efficient/faster/less code needed.
A possible syntax could be as follows:
type
TSomeClass = class
private
protected
mMyArray : TSomeBigArrayType;
public
referenced property SomeBigArray : TSomeBigArrayType read mMyArray;
end;
(a write mMyArray would be superflous but could also be allowed for easy
changing between referenced and non-referenced/value properties, but simply
ignored by compiler).
The above syntax would treat access to SomeBigArray via a pointer under
water.
So writing:
SomeClass.SomeBigArray[100] := 500;
would automatically retrieve a pointer to the array and apply the index
operator on the dereferenced pointer, instead of reading the entire array
onto a stack copy and then overwrriten entire 100 and then dumping the
entire array into obvlious with the code having no effect as it would in
Delphi, where this to be a static array ;)
The code might happen to work for dynamic arrays, since those are too
pointers underneath, however for static arrays or for example records, the
useless behaviour would be there.
Other problems with properties as already indicated:
property MyRecord : TRecord read mMyRecord
MyRecord.SomeField := 100 <- currently leads to useless code, the record
would be copied onto stack, modified and dumped.
Again the programmer has to write:
property MyRecord : PRecord read GetMyRecordPointer;
MyRecord.SomeField := 100; // now it would work via a pointer, because the
programmer programmed it like that.
Delphi's referenced properties would do away with this extra code and do it
automatically as follows:
referenced property MyRecord : TRecord read mMyRecord;
MyRecord.SomeField := 100;
An alternative syntax could also be:
property MyRecord : TRecord access mMyRecord;
or as I already wrote a long time ago:
property MyRecord : TRecord address mMyRecord;
or perhaps:
property MyRecord : TRecord reference mMyRecord;
Anything to solve the current situation would be nice, how would you solve
the problem and automate it ?
For now it seems best to avoid "records" as the plague and always use
"classes".
There is one catch22/drawback, classes don't have operator overloading.
However somebody wrote "record operators" are slow so perhaps it's for the
better.
Bye,
Skybuck.
More information about the fpc-devel
mailing list