properties

Steven Schveighoffer schveiguy at yahoo.com
Tue Jul 28 08:47:05 PDT 2009


On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Steven Schveighoffer wrote:
>> On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu  
>> <SeeWebsiteForEmail at erdani.org> wrote:
>>
>>> I think inferring meaning from the presence or absence of "()" is  
>>> rather dicey.
>>  Really?  Then why name your functions things like empty, why not  
>> ex245, to make them look it up, making *sure* they know what the  
>> meaning is before they use it.
>
> I didn't say not to infer meaning from the name.

No, you're saying inferring meaning from parentheses is not a good idea.   
I think it's the same thing as saying that inferring the meaning from a  
function/field name is not a good idea (just in a more sarcastic way...).   
When you see parentheses, you infer function.  When you don't you infer  
field/property.  Note that I'm not just pulling this out of a hat, it's  
the way people already think, you should acknowledge that.

>
>> As one other person stated, they thought empty() emptied a range.
>
> Well it doesn't.

Exactly, so why do you think he thought that?  Let's take someone who's  
used a language that uses () do denote a function, and no parens to denote  
a field (there are a few of them out there).  Would that person ever think  
that

x.empty;

means "empty the contents of x"?  The answer is no, not ever.  Whether you  
like it or not or think it's dicey or not PEOPLE WILL INFER MEANING FROM  
PARENTHESES.  I even do it, even though I *know* that it's dicey.  I hate  
having to look up usages of things that make no sense because I have no  
idea what the code is doing.  It's so much better when the meaning is  
clear from the code itself.

>
>> Being able to read code and understand what it means without resorting  
>> to documentation is the sign of a good choice of symbol names.
>
> Sure.
>
>> The presence or absence of parens is a hard-coded accepted meaning of  
>> field vs. function.
>
> I understand how some people want to derive meaning from obj.foo()  
> versus obj.foo. I think they shouldn't in D. I mean D has had for years  
> the behavior that you could drop the trailing empty parentheses.

And for years, there have been complaints about it.  This will  
continuously be a thorn in the side of D adoption until it is resolved.

>> Properties build on this notion by making a virtual field that actually  
>> resolves to a function (but behaves like a field, and this is an  
>> important accepted meaning).
>
> Not quite. C# has allocated a language feature for properties. Yet they  
> allow you to write write-only properties, which do NOT behave at all  
> like fields

I'll give you that one, but that's an uncommon "because we can" case.

> and also read-only properties, which also don't behave like fields.

Ever heard of readonly fields?  Yes, they exist in C#.  Besides, that's  
one of the benefits of properties, you can do things that you can't do  
with fields, otherwise why have them?

> Guess what - they both behave like functions. So their properties are an  
> elaborate mechanism that is actually thoroughly unchecked, thus going  
> back to what you could do by calling functions. So why the hell did they  
> define the feature in the first place? Oh, for allowing people to write  
> a.foo() instead of a.foo. You know what, that's a bit disappointing for  
> an entire language feature.

No, they did it to *force* you to write a.foo instead of a.foo(), to make  
it more defined that foo is a field-like entity.  There's a subtle, yet  
very important difference.  They saw the implementation of properties in  
Java as a good thing, but Java relied on a social standard that a method  
that begins with get is a getter, a method that begins with set is a  
setter, and a method that begins with is is a boolean.  C# provides a  
better way to convey that contract via properties.

D's implementation looks to me like a quick hack so D can say "look, we  
have properties!"  They don't provide any of the interface benefits that  
true properties do.  Might as well go back to Java style, where you have  
to name your properties getX, setX or isX.  But now, normal functions are  
corrupted with the ability to use them as properties.

>>> Well I don't think so. To repeat what I wrote elsethread: foo = bar is  
>>> rewritten into foo(bar) if and only if auto __x = foo, __x = bar  
>>> works. This means, a setter only works if there's a corresponding  
>>> getter. (Write-only properties be damned.)
>>  This is a band-aid fix, easily broken.
>>  int select(int timeoutMS = -1); // method on a socket, for example
>>  Hell, even my TimeSpan problem would still fail.
>
> Well maybe you could change TimeSpan.

Lovely.  Force the developer to rename his functions because D is too weak  
to allow defining a correct interface.  You didn't even address the select  
example, I think that's a very compelling example of something that breaks  
your rule.

My point is that your rule only works if you write code in a certain way,  
and I don't think that should be a determination of whether something is a  
property or not by the compiler, because the naming of functions is  
supposed to be up to the developer, not the spec.  It's like a prejudice  
against certain coding styles without any good reason.

>
>> Also you are forgoing the ability to have overloaded setters, which  
>> could be useful.  Not to mention getters for delegates.
>
> Wait, overloaded setters do NOT make the thing behave like a field, but  
> you were stating how nice that is a few paragraphs ago! So what is it  
> that you think is good?

Yes they do.  It makes them behave like a variant field.

e.g.

x.timeout = 5.5; // set timeout to 5.5 seconds
x.timeout = TimeSpan.seconds(5); // set timeout to 5 seconds exactly

And what about getters for delegates?  That problem is still unresolved by  
your rule.

-Steve



More information about the Digitalmars-d mailing list