properties
Steven Schveighoffer
schveiguy at yahoo.com
Tue Jul 28 10:20:30 PDT 2009
On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> Steven Schveighoffer wrote:
>> 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.
Yes, I agree. But there is also a subtle problem we can solve at the same
time. You keep missing the point.
Let me come at another angle. You can't view properties as some sort of
enforcement by the compiler. The compiler is not guaranteeing that if you
call something without parentheses, it doesn't execute arbitrary code, it
has nothing to do with what the compiler guarantees. But the *meaning*
that the author of the function wishes to convey is available via the
requirement of parentheses or lack thereof. The author of the code is
saying "I wrote this function as if it were a field."
It's the same thing as function names. The compiler allows you to name
your functions how you wish, and enforces that foo is different than bar.
Why is this important? Because foo does something different than bar.
And to a user, that's obvious, because in english foo means something
different than bar. What if the compiler allowed you to call functions as
long as what you typed was an unambiguous prefix of the function name.
For example:
struct S
{
int foo();
int flu();
int bar();
}
This is valid code:
S s;
s.fl();
s.b();
// s.f(); // doesn't compile because its not unambiguous
Why is this advantageous? Well, it saves you from having to type the
whole function name. It's unambiguous, so there is no problems as far as
the compiler is concerned, so its easily implemented. But why don't we
have a wonderful time-saving feature like this? Because it would be a
nightmare to read. You can change the implied english meaning of the
function by just using its prefix. But the compiler doesn't care, because
it has no idea what the english meaning of the words are, and it's
satisfied that you made an unambiguous decision.
Back to our problem at hand, by allowing one to call functions with or
without parentheses you are not only changing the implied meaning of the
function, but you have removed the ability of the author to convey that
meaning with simply the requirement of parentheses. He has to explain
"this is a property" through by making the function name reflect that
fact, or be an ass and say "well you shouldn't assume things based on
parentheses, look it up dummy!"
Yes, if we solve the problem of setters, we have killed a huge wart on D,
but why ignore the other warts?
>>> 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.
Just like D!
struct S
{
const int readonlyfield;
int readonlyproperty();
}
Yes, that's right. readonly is analogous to const.
>>> 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!
I explained this above. I'll reiterate: The enforcement of "field-like"
by the compiler is not the point of properties, the ability given to the
author to document that fact is the point.
>
>> 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?
It's less verbose, makes the code read better, allows you to avoid using
functions to do everything. As another example, Java doesn't have
operator overloading, so BigInteger is horrific to use, calling functions
for each operation. So would you argue that C# or D with operator
overloading isn't better because operators are just functions, why call
them something else?
>> 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.
No. The interface benefits are explained above.
>>> 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.
I want to use the parentheses or lack thereof as part of the human meaning
for the function/property. Making them optional means I can't do that.
>
>> 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.
I would be pleased, how can it be solved?
>> 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.
But my way is orthogonal to writing normal functions. Your rule
mistakenly identifies normal functions as properties.
>
>> 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.
Yes, and it is well established that opXxx shouldn't be used for arbitrary
function names. But you are expanding that rule to basically any function
name, which means all functions are subject to being misinterpreted by the
compiler, no matter what you name them.
>> 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.
It's a sacrifice in the name of clarity.
>>>> 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.
I can live without overloading setters, I don't think it's a requirement,
but it would be possible with my method. That's the only point I was
trying to make.
-Steve
More information about the Digitalmars-d
mailing list