properties
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Tue Jul 28 09:30:00 PDT 2009
Steven Schveighoffer wrote:
> 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.
I acknowledge that in C, C++, and Java, you must add () to call an
argument-less function. I also acknowledge that in C# a.b could mean
either a field access or execution of arbitrary code.
>>> 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.
I acknowledge that some people infer meaning from parentheses. I mean,
there's at least one :o).
>>> 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.
Again, most complaints have been directed towards writeln = 5. I think
that's the major problem to be 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.
I acknowledge that you give me that one.
>> 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?
So now C# has two ways of providing a readonly field. Doesn't quite look
like an example to follow.
>> 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.
Which is not, because it can execute arbitrary code that is not
restricted in any way. How good a design is that? Back to semantics by
convention?
That's what I'm saying: if it could do anything, at least don't pretend
it's anything special. It's a function!
> 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.
Why is C#'s way better?
> 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.
What are the interface benefits that "true" properties do? What is a
"true" property? Something that could do anything. Surprise, that was
already the charter of functions. Well thank you very much.
> 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.
Yum.
>>>> 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.
Or maybe because her use of name was too ambiguous.
> You didn't even address the
> select example, I think that's a very compelling example of something
> that breaks your rule.
I agree that that example reveals a problem. I also think that that
problem could be solved, but I doubt that you'll be pleased.
> My point is that your rule only works if you write code in a certain
> way,
Your rule also 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.
opXxx are up to the spec.
> It's
> like a prejudice against certain coding styles without any good reason.
I don't see that. I more see a prejudice against dropping "()" when
calling a function.
>>> 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.
Then write a function that takes a variant instead of overloading.
> 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.
I believe it's a minor problem that does not impede people from getting
work done.
Andrei
More information about the Digitalmars-d
mailing list