@property as proposed in various DIPs, my attempted use and what I think of it

Zach the Mystic reachBUTMINUSTHISzach at gOOGLYmail.com
Thu Feb 21 17:37:55 PST 2013


On Thursday, 21 February 2013 at 23:17:53 UTC, Stewart Gordon 
wrote:
> On 20/02/2013 20:32, Jonathan M Davis wrote:
>> On Wednesday, February 20, 2013 20:41:24 Rob T wrote:
>>> The reality is that I often don't know if I'll be using one
>>> syntax over the other until usage experience is gained and the
>>> usage context determines the answer. I may even want to use 
>>> both
>>> forms depending on the use context.
>>
>> I don't understand this. You make it a property function if 
>> it's intended to
>> be used as if it were a variable. If it's not, then you don't 
>> mark is a
>> property. Done. Where's the confusion?
> <snip>
>
> I entirely agree.  I don't have as much time to read the 
> 'groups as I used to, so haven't managed to follow all the 
> discussions about it.
>
> It's hard to say what are the main advantages of @property over 
> making every function with zero or one parameter usable as a 
> property.  But I've come to like it since it was introduced.  
> And it's useful not only to programmers, but also to 
> documentation generators.
>
> In any case, some of the suggestions seem worse than what we 
> had before @property....
>
> Perhaps the only change I'd vote for is dropping the @, which 
> doesn't seem to mean anything.
>
> Stewart.

I was the author of the idea of using structs as properties. 
Description here: 
http://forum.dlang.org/thread/ririagrqecshjljcdubd@forum.dlang.org

I believe that while their advantage comes from their power and 
flexibility, their disadvantage is a slight syntactic overhead. 
With Phobos standard formatting, the following two randomly 
selected properties:

@property size_t length() nothrow pure const @safe
{
     return impl ? impl.nodes : 0;
}

@property bool empty() nothrow pure const @safe
{
     return length == 0;
}

... would become:

length struct
{
     size_t opGet() nothrow pure const @safe
     {
         return impl ? impl.nodes : 0;
     }
}

empty struct
{
     bool opGet() nothrow pure const @safe
     {
         return length == 0;
     }
}

With my syntax, a one-line getter requires the line to be longer 
by seven characters:

@property size_t length() { return impl.length; }

versus:

length struct { size_t opGet() { return impl.length; } }

Taking this into consideration, and if people have no more 
creative uses for properties than as getters and setters (i.e. 
they didn't need or want the full power of structs), I could well 
see:

@get size_t length() nothrow pure const @safe { return impl ? 
impl.nodes : 0; }

@set size_t length(size_t) { return impl.length = size_t; }

...as better looking and more precise than:

@property size_t length() nothrow pure const @safe { return impl 
? impl.nodes : 0; }

@property size_t length(size_t) { return impl.length = size_t; }

Of course, I don't want to abandon structs as properties. Of 
course I am biased, but my ideal solution would be for the @get 
and @set properties above to be syntax sugar for:

length struct
{ size_t opGet() nothrow pure const @safe { return impl ? 
impl.nodes : 0; } }

length struct
{ size_t opSet(size_t) @safe { return impl.length = size_t; } }

Unfortunately, this would cause a duplicate declaration, and 
you'd be forced to do this:

length struct
{
     size_t opGet() nothrow pure const @safe { return impl ? 
impl.nodes : 0; }
     size_t opSet(size_t) @safe { return impl.length = size_t; }
}
...when you had more than one overload. But the latter one is 
better organized and looks nicer, so I personally wouldn't mind 
converting this way.

(note: 'opSet' is intended to be a natural and better looking 
alias to the eventually deprecated 'opAssign'. 'opOpSet' replaces 
'opOpAssign', etc. This is my ideal world we're talking about 
here.)


More information about the Digitalmars-d mailing list