Steven Schveighoffer wrote:
On Fri, 31 Jul 2009 13:34:13 -0400, Marianne Gagnon <[email protected]>
wrote:
I think the poll might have been skewed due to context (forget my
newsgroup poll, that was worthy of an abortion, but I also didn't
mean to
submit it :), I'm talking about Ary's)
The question was asked, what do you think this code means. In the
context
of D, where you know a symbol without parentheses can mean either a
function or a property/field, I'm certain there were several respondants
who didn't understand it was asking what they think is best, not *what D
currently does*. Ask that same questions to C++ developers and see what
you get...
It's hard to phrase the question properly without bias to a group of
people who already know the current behavior. Maybe something like:
Assume the D programming language required parentheses for normal
parameter-less functions, and required no parentheses for parameter-less
functions that returned a property. For example, the following code
should imply a getter for a filter inside x:
auto tmp = x.filter;
And the following code should imply performing a filtering action
using x,
returning the result:
auto tmp = x.filter();
Do you think it's worth adding such a capability, given that you will
then
no longer be able to call ordinary parameter-less functions without
parentheses, an author of a property function must properly indicate
that
the function is a property, and the compiler must trust the author for
this implication?
IMP, the parenthesis thing is not about parameters vs function. I
think the question is about whether the function can modify my object
or not.
e.g. if I call
foo = object.x;
I assume 'object' was not modified. But if x can be like a function,
disguised as a parameter, I can modify my object without knowing.
In C++, I'd say this behaviour is ok for 'const' functions. Now I
haven't taken the time to study D constness, so I can't readily tell
what is the direct equivalent, but I guess you understand what I mean.
In short, IMO everything that can modify my object should require ()
to stress that this is an action with possible side effects, not
merely a getter.
Hm... this is somewhat similar to const, be we already have const in D.
I think you and I or on the same page -- parentheses implies action, no
parentheses implies no action (and therefore, no change to the object).
However, I can envision properties that do take actions (such as
logging) and may even change the object (such as caching), and functions
that perform actions but do not modify the object. I wouldn't say
modification of the object is a direct 1-to-1 mapping with parens or
lack of parens, but I'd definitely say that lack of parens implies no
"public" modification.
However, none of this would be enforcible via the compiler. For that,
we have const. A const property would make loads of sense, but
unfortunately, it modifies the contract you have with the object members
when calling it (see DIP2
http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP2).
So to sum up, with this feature lack of parentheses would imply no
action, but would not be enforced. However, it would be considered
incorrect logic if the rule was not followed, similar to naming your
functions something other than what they do.
I am leery of such a feature. It essentially introduces a way to define
conventions that are in no way useful to, or checked by, language rules.
In my experience this has been a bad idea more often than not. Of
course, simple conventions such as capitalized types, camel case values,
and so on, are useful and easy to follow. But as soon as complexity of
conventions becomes only a bit higher, their usefulness becomes a
downward step function.
In C++ there were two ways to define a template:
template <class T> ...
and
template <typename T> ...
The existence of "typename" as a keyword has an interesting history of
its own, but in here it was allowed for the reason that T may be any
type, not a class type. So, people thought, it would be less confusing
if people wrote "typename" for type template parameters.
So far so good. When I wrote Modern C++ Design, I decided to make a bold
move and use "typename" in code samples wherever it could have been any
type, and "class" wherever the type was indeed restricted to a class
type. I documented that convention in the introduction and off I went.
The experiment was an unqualified failure. First of all, people got
confused. Then some found actual "bugs" because I used one keyword when
I had promised to use the other. Of course I had bugs - there's plenty
of template code and no automated means to check it! If I could turn
back in time, I'd just use "class" everywhere.
There are similar cases in other communities, probably Perl being a
prime example because it allows most everything to mean something, so
conventions are very important. My reading of the experience on
espousing complex, unchecked, and unused reified conventions? Don't.
Andrei