Does D have too many features?

Jacob Carlborg doob at me.com
Sun Apr 29 08:43:49 PDT 2012


On 2012-04-29 04:32, Francois Chabot wrote:
>> - properties - another incredibly convenient feature. I think a more
>> sexy implementation of properties are in order, but the construct is
>> great. It would be nice to have properties as a language type, rather
>> than a attribute:
>
> To me, properties are much more than a convenience. The important part
> of it comes from its existence, not its usage. Quite simply, having
> properties mean that using public member variables does not break
> encapsulation (as long as having them part of the public interface is
> intentional).
>
> Without properties, you MUST write accessors for all of them on the off
> chance that you might want to refactor/delegate them in the future. This
> adds a huge amount of boilerplate code that ends up wasted time 98% of
> the time.
>
> In short, properties existing, even if not used, end up improving both
> my efficiency and the legibility of my code.

In principle I agree with you. But in practice this doesn't always work. 
Take this for example:

struct Point
{
     int x;
     int y;
}

class Widget
{
     Point point;
}

void main()
{
     auto w = new Widget;
     writeln(w.point.x);
     w.point.x++;
     writeln(w.point.x);
}

Prints "0" and "1" as expected. If we now change "point" to a property 
like this:

class Widget
{
     //Point point;

     Point point_;

     @property Point point ()
     {
         return point_;
     }

     @property Point point (Point point)
     {
         return point_ = point;
     }
}

It will now print "0" and "0". This is a silently breaking change. Sure 
you can change "point" to return by reference:

class Widget
{
     Point point_;

     @property ref Point point ()
     {
         return point_;
     }

     @property ref Point point (Point point)
     {
         writeln("foo");
         point_ = point;
         return point_;
     }
}

Which will print "0" and "1" again. But it won't print "foo", meaning 
you bypassed the getter. To solve this the compiler would need to 
perform some kind of property rewriting. Translating:

w.point.x++;

To:

auto __p = w.point;
__p.x++;
w.point = __p;

Also you might need to just as well use properties from the beginning 
because you need virtual properties. It would help if this was allowed:

class Widget
{
     @property Point point;
}

Which would translate to:

@property Point point ()
{
     return point_;
}

@property Point point (Point point)
{
     return point_ = point;
}

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list