On 02/17/2012 04:23 AM, Jonathan M Davis wrote:
On Thursday, February 16, 2012 18:49:40 Walter Bright wrote:
Given:

      class A { void foo() { } }
      class B : A { override pure void foo() { } }

This works great, because B.foo is covariant with A.foo, meaning it can
"tighten", or place more restrictions, on foo. But:

      class A { pure void foo() { } }
      class B : A { override void foo() { } }

fails, because B.foo tries to loosen the requirements, and so is not
covariant.

Where this gets annoying is when the qualifiers on the base class function
have to be repeated on all its overrides. I ran headlong into this when
experimenting with making the member functions of class Object pure.

So it occurred to me that an overriding function could *inherit* the
qualifiers from the overridden function. The qualifiers of the overriding
function would be the "tightest" of its explicit qualifiers and its
overridden function qualifiers. It turns out that most functions are
naturally pure, so this greatly eases things and eliminates annoying
typing.

I want do to this for @safe, pure, nothrow, and even const.

I think it is semantically sound, as well. The overriding function body will
be semantically checked against this tightest set of qualifiers.

What do you think?

No. Absolutely not. I hate the fact that C++ does this with virtual. It makes
it so that you have to constantly look at the base classes to figure out what's
virtual and what isn't. It harms maintenance and code understandability. And
now you want to do that with @safe, pure, nothrow, and const? Yuck.


Whether a function is virtual or not has far-reaching semantic consequences in C++ (overriding vs hiding). Whether a function is pure/nothrow/const/@safe does not, because those are just annotations that give some additional guarantees, which *ought* to be clear from what the function actually does. It is not like anyone would look up the signature before using some method inside a pure function if what it does seems to be pure.

I can understand wanting to save some typing,

:o)

Seriously, the average programmer is exceedingly lazy. Any language feature that might reduce the annotation overhead is a plus. Annotations are for the compiler, not for people.

but I really think that this
harms code maintainability. It's the sort of thing that an IDE is good for. It
does stuff like generate the function signatures for you or fill in the
attributes that are required but are missing.

An IDE can also fill in the attributes that are not required but missing if this is implemented, or directly display only the interface to some class, so that is simply not a valid point. Having all the proper annotations can become an IDE style warning for those who like IDEs.

I grant you that many D developers don't use IDEs at this point (at least not 
for D) and that those
sort of capabilities are likely to be in their infancy for the IDEs that we
_do_ have, but I really think that this is the sort of thing that should be
left up to the IDE. Inferring attribtutes like that is just going to harm code
maintainibility.

It makes re-factoring a lot easier which helps maintainability: The programmer can annotate some method with pure, hit compile and he will immediately see all the non-pure overrides if there are any and may fix them.

It's bad enough that we end up with them not being marked on
templates due to inferrence, but we _have_ to do it that way, because the
attributes vary per instantiation. That is _not_ the case with class member
functions.

Please, do _not_ do this.

- Jonathan M Davis

I think you are severely overstating the issues. What is the most harmful thing that might happen (except that the code gets less verbose)?


Reply via email to