new DIP5: Properties 2
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Fri Jul 31 13:16:43 PDT 2009
Steven Schveighoffer wrote:
> On Fri, 31 Jul 2009 13:34:13 -0400, Marianne Gagnon <auria.mg at gmail.com>
> 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
More information about the Digitalmars-d
mailing list