Properties

Nick Sabalausky a at a.a
Thu Jan 8 07:52:56 PST 2009


"Michiel Helvensteijn" <nomail at please.com> wrote in message 
news:gk4oi2$14tv$1 at digitalmars.com...
> dsimcha wrote:
>
>> Yeah, this has been mentioned in the past before.  The most obvious way 
>> to
>> make it work w/o any breaking or significantly bulk-adding changes would
>> be to define foo.length += 8 to mean foo = foo.length() + 8, or
>> foo.length++ mean foo =
>> foo.length + 1.  This would be pure syntactic sugar, as it is when 
>> working
>> with primitives.
>>
>> One problem that comes to mind is if, instead of length, which is
>> presumably some kind of integer, you have a property for some user 
>> defined
>> type with operator
>> overloading.  This user-defined type could define opAdd to do something
>> arbitrarily different from opAddAssign.  Even if we assume that no
>> reasonable programmer would do this and treat this as a "who cares?"
>> corner case, there's still the problem of opInc and opAddAssign being 
>> much
>> cheaper in some cases than
>> opAdd.  For example, in some cases opAdd might require copying of a whole
>> bunch of stuff, where opInc or opAddAssign just increments a single
>> primitive under the hood.
>
> I've always thought properties should work somewhat like this:
>
> property int length {
>    get() { return this.len; }
>    set(newLen) { this.len = newLen; }
> }
>
> The return-type of get is automatically int, as is the parameter-type of
> set. These two functions are automatically called when the property is
> used.
>
> int a = length;
> // int a = length.get();
>
> length = 10;
> // length.set(10);
>
> In cases where read/write access is needed, the compiler can do this:
>
> length++;
> // int temp = length.get();
> // temp++;
> // length.set(temp);
>
> This can work for any user-defined type, since we're using the same
> operator. If you want it done faster 'under the hood', you can use
> operator-overloads inside the property:
>
> property int length {
>    get() { return this.len; }
>    set(newLen) { this.len = newLen; }
>    void opIncrement() { this.len++; }
> }
>

Agreed. The current way is just sloppy and it bothers me constantly. *gripe* 
*gripe* *gripe*

I would make two modifications to your suggestion though:

1. Like in C#, you shouldn't need to define paramater lists for "set" and 
"get". They're always going to be the same. In the case of "set", it's 
always going to be just the one param, and it'll be the new value, so just 
make a special predefined var. Something like:

get { return this.len; }
set { this.len = value; } // "value" (like in C#), or "$" or something like 
that

2. You shouldn't have to manually define a private var to go along with the 
property. In languages with real properties, the following idiom is used 
constantly:

private int _var;
public property int var {
   get { return _var; }
   set { _var = $; }
   void opIncrement() { _var++; }
}

Why should that be needed? It should be like this:

public property int var {
   // int internalValue; // Automatically created (but named better)
   get { return internalValue; }
   set { internalValue = $; }
   void opIncrement() { internalValue++; }
}

In the minority of cases where a property doesn't need this variable, 
"internalValue" can just be optimized away. 





More information about the Digitalmars-d mailing list