Another Properties Proposal
Chad J
gamerChad at _spamIsBad_gmail.com
Tue Aug 21 15:46:35 PDT 2007
OK how about this:
Type _foo;
Type getFoo() { return _foo; }
void setFoo(Type val) { _foo = val; }
property Type foo(getFoo,setFoo);
// or &getFoo and &setFoo if you prefer
// also for readonly and writeonly:
property Type foo(getFoo,void);
property Type foo(void,setFoo);
In this incantation, properties are a compile-time construct.
It just tells the compiler that we have something called "foo" which is
really a pair of functions, but we want it to behave exactly like a data
field.
Also note the typing, this is to ensure that the property has a uniform
type, since data fields don't have different types for when you read and
write to them. The getter and setter functions must have types that are
the same as or implicitly convertible to/from the property's type.
Thus the following is correct:
int _foo;
short getFoo() { return cast(short)_foo; }
void setFoo(long val) { _foo = cast(int)val; }
property int foo(getFoo,setFoo);
// calling code might work like so
int bar = foo; // works, since int bar = getFoo(); works
foo = bar; // works, since setFoo( bar ); works
But if getFoo had been written this way:
float getFoo() { return cast(float)_foo; }
Then the compiler would give an error.
Another possible syntax (without new keywords, almost looks better too):
in Type foo(getFoo); // RO property
out Type foo(setFoo); // WO property
inout Type foo(getFoo,setFoo); // RW property
So far this is pretty much what Ender KaShae suggested in the original
thread.
There is also the possibility to trap certain operations on the property:
inout Type foo(getFoo,setFoo)
{
Type opPostInc()
{
scope temp = getFoo();
temp += 4; // Different behavior
setFoo( temp );
return temp;
}
}
thus opPostInc() would override the default language-defined opPostInc()
for the property.
I'd also suggest that taking the address of a property returns a pointer
to a delegate or function pointer to the setter.
Another thing that would be useful then is to allow the setter to
(maybe) return a value. That way the setter can act as a getter when in
a pinch.
Now we can write template and generic code that take addresses of
members and be mostly unaware of the difference between properties and
data fields:
// baz is just some function. This is on the user's side of the prop.
T baz(T)(Bar arg)
{
auto ptr = &arg.foo; // foo is a property, a data field works too
T val = *ptr; // calls foo.setFoo(typeof(foo).init);
return val;
}
Where "T val = *ptr;" expands to the following:
typeof(foo) delegate(typeof(off)) temp = *ptr;
T val = temp; // same as T val = temp(); by implicit properties.
- Not supplying a return type for the setter function would make taking
the address of the given property into a compile-time error.
- The return type for the setter function would be under the same
type-strictness scrutiny as the return type for the getter function.
Also note that the above use of delegates plays on the current property
syntax. Without implicit properties, the example would look like this:
T baz(T)(Bar arg)
{
auto ptr = &arg.foo;
T val = *ptr(typeof(foo).init); // fails if foo is a data field.
return val;
}
If the setter of the property does not have a return value, it would be
a compile time error to take the address of said property. Should a
user want to have the address operation return something else, like a
pointer to the data underlying the property, then perhaps there should
be an "opAddressOf" operator overload that is available only for
properties.
Alternatively, we could just do what I found C# to do and make it a
compile time error to take the address of a property.
Another issue might be whether or not to let properties override each
other. This is in the case of classes with inheritance.
Initially, I'd say no. It is more likely that the getter and/or setter
function(s) are what should be overridden.
Well I'm soaking up my time and I need to pack for D con, so I'll cut it
short on describing what these beasts should expand to. They should
expand to whatever makes them behave as closely to data fields as
possible from the property user's perspective.
- Chad
More information about the Digitalmars-d
mailing list