Steven Schveighoffer wrote:
On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu
<[email protected]> wrote:
Steven Schveighoffer wrote:
On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu
<[email protected]> 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