February 25, 2007
> 
> class Base
> {
>    int foo(int) { ... }
> }
> class Derived : Base
> {
>    // Is this "error: override keyword required"
>    // Or is it ok -- not an override but a distict overload leaving
>    // foo(int) in tact.
>    int foo(float) { ... }
> }
> 

In this case it would compile without error. You did not provide 'override', so you say: make overload.

If 'override' is required, it would be obvious, that it is missing. So I think it would be much easier to find this error (if override was meant). And it is documented for a later reader. This is an improvement of readability.


February 25, 2007
Frank Benoit (keinfarbton) escribió:
> My point is, i want this strange rules to be removed.
> And I want the override keyword not to be a useless thing.
> 
> I propose:
> 1.) make an overload not hide base implementations
> 2.) make the override keyword required, to make it useful.
> 3.) remove the interface reimplementation rule.
> 
> What do you think?

I also agree with the three points.

Number 2 is especially useful if a function in a base class is removed. Inmediately you can tell which classes need to remove the overriden functions because they are no longer in use, and can lead to bugs.
February 25, 2007
Frank Benoit (keinfarbton) wrote:
>> class Base
>> {
>>    int foo(int) { ... }
>> }
>> class Derived : Base
>> {
>>    // Is this "error: override keyword required"
>>    // Or is it ok -- not an override but a distict overload leaving
>>    // foo(int) in tact.
>>    int foo(float) { ... }
>> }
>>
> 
> In this case it would compile without error. You did not provide
> 'override', so you say: make overload.
> 
> If 'override' is required, it would be obvious, that it is missing. 

I'm not so sure.  I try to live by the 'mark all overrides' policy myself but still I often forget.

> So I
> think it would be much easier to find this error (if override was
> meant). And it is documented for a later reader. This is an improvement
> of readability.

Any improvement of readability comes from 2) -- making 'override' required.  Not from 1) -- making all overloads propagate.  1) saves typing but does not necessarily improve readability.  What could be more clear than an explicit list of all the base class versions of foo()?

Also -- does this() get special treatment?  Or do constructors all automatically propagate too?

And in general how do I hide super.foo(int) if I _don't_ want it? (private assert(0) re-implementation of every method I don't want perhaps?)

I guess I would be happier with something that required explicitly declaring that base class overloads should be forwarded.  Like
   alias super.foo foo;  // bring forward all base class foo's
or
   alias super.foo(int) foo; // bring forward only the int version.


Another thought -- making override required could make life difficult for some code generators.  Imagine an automatic class wrapper that creates a derived class of the form:

class foo(Base)  : Base
{
   int someMethod(int x) { ... }
}

That will always work now, but if override becomes required, then that template will have to do some static if mojo to figure out if Base already has a someMethod(int) implemented or not and if so stick in the 'override'.

--bb
February 25, 2007
Ary Manzana wrote:
> Frank Benoit (keinfarbton) escribió:
>> My point is, i want this strange rules to be removed.
>> And I want the override keyword not to be a useless thing.
>>
>> I propose:
>> 1.) make an overload not hide base implementations
>> 2.) make the override keyword required, to make it useful.
>> 3.) remove the interface reimplementation rule.
>>
>> What do you think?
> 
> I also agree with the three points.
> 
> Number 2 is especially useful if a function in a base class is removed. Inmediately you can tell which classes need to remove the overriden functions because they are no longer in use, and can lead to bugs.

Already works that way if you just use override religiously.

--bb
February 25, 2007
Bill Baxter escribió:
> Ary Manzana wrote:
>> Frank Benoit (keinfarbton) escribió:
>>> My point is, i want this strange rules to be removed.
>>> And I want the override keyword not to be a useless thing.
>>>
>>> I propose:
>>> 1.) make an overload not hide base implementations
>>> 2.) make the override keyword required, to make it useful.
>>> 3.) remove the interface reimplementation rule.
>>>
>>> What do you think?
>>
>> I also agree with the three points.
>>
>> Number 2 is especially useful if a function in a base class is removed. Inmediately you can tell which classes need to remove the overriden functions because they are no longer in use, and can lead to bugs.
> 
> Already works that way if you just use override religiously.
> 
> --bb

But who in this days believe in programmers? :-P
February 25, 2007
> Another thought -- making override required could make life difficult for some code generators.  Imagine an automatic class wrapper that creates a derived class of the form:
> 
> class foo(Base)  : Base
> {
>    int someMethod(int x) { ... }
> }
> 
> That will always work now, but if override becomes required, then that template will have to do some static if mojo to figure out if Base already has a someMethod(int) implemented or not and if so stick in the 'override'.

No, it will not work.
Today you also need to know the base class methods, and add aliases in
you generated class, if needed. The problem is exactly the same. TioPort
actually implements this.

For generated code, it is probably easier this way with override. Because if you generate code, you most of the time know, that you do a override.

To the ambiguity issue of the alias:
Override is always/already precise, because it *is* bundled with the
complete method signature.
February 25, 2007
> I'm more concerned about redability when the lines get to long than typing. And I also don't think that enforcement of overload/override is that important, no other language I have used does this and if a class have so many methods that they cant be kept track of is probably missdesigned.

Delphi has, for example, and the thing with the "override" keyword is extremely useful when you have huge class hierarchies!
February 25, 2007
votes++

I'd really like to have it the way you propose. Every time you override a method, you should definitely have to write override so anyone actually knows what you're doing. In teams it's too often that you have to have a look at someone else's code and it's very useful to know which method is overridden and which not.

To the interface part:
I'm used to Delphi but didn't use interfaces in D yet, so I'm kind of
shocked to get to know that your little example won't work... I think of
an interface of a kind of contract - the interface defines some methods
and the object implementing the interface provides the method in a way
the interface does not have to know of (why should it?) - just that the
object _has_ this method. This means, if a base class of your object
implements the method, the interface should use this method. Well,
there's another problem: What if your base class has a method that looks
exactly the same an interface declares a method - so both collide (read
the comment in "MyRealObject" for a better explanation)


interface ISomeInterface
{
    int thisMethod();
}

class MyBaseObject
{
    int thisMethod() {
        return 123;
    }
}

class MyRealObject : MyBaseObject, ISomeInterface
{
    // as you're not the author of MyBaseObject, you may not change
    // MyBaseObject's thisMethod to something else, or you just can't
    // change the method because it is used elsewhere, and so on.
    // You still want to provide MyBaseObject's implementation
    // Then you've got the following problem:
    //
    //  * you want to provide ISomeInterface.thisMethod
    //  * you want to provide (not override) MyBaseObject.thisMethod
    //

    // if the declaration that you implement ISomeInterface means that
    // the compiler looks into superclasses, simply leaving the method
    // out (because you inherit it) will conflict with your first point

    // the following will conflict with the second point because
    //
    // MyRealObject obj = new MyRealObject();
    // obj.thisMethod();
    //
    // will return 321 instead of 123
    //
    override int thisMethod()
    {
        return 321;
    }

    // you need to tell the compiler which method implements the
    // interface's thisMethod. In Delphi, you may do this with the
    // "implements" keyword, but I don't think this will fit into the
    // D language. consider the next few examples: which one do you more
    // like?

    // first one: delphi style
    int someMethod() implements ISomeInterface.thisMethod
    {
        return 321;
    }

    // second one, perhaps more D-ish
    int someMethod() : ISomeInterface.thisMethod
    {
        return 321;
    }
}


Perhaps another example will show where the problem may occur, too: If you have to implement two interfaces that have two methods that are looking the same but have to return different values:

IFirstInterface
{
    char[] getInterfaceName(); // shall return "IFirstInterface"
}

ISecondInterface
{
    char[] getInterfaceName(); // shall return "ISecondInterface"
}

class MyObject : IFirstInterface, ISecondInterface
{
    char[] getInterfaceName()
    {
        return "so what?";
    }
}

At the moment, it is not possible to solve this problem in D.

I don't know if something like that is possible at the moment, but if you have this kind of "delegating an interface function", you could even delegate the implementation of an interface to another object:

class MyObject : IFirstInterface
{
    MyOtherObject obj : IFirstInterface;
}

This would mean that not MyObject implements IFirstInterface but MyOtherObject (well, that would be real information hiding *g*).


best regards,
Nicolai
February 26, 2007
On Sun, 25 Feb 2007 16:13:01 +0200, Frank Benoit (keinfarbton) <benoit@tionex.removethispart.de> wrote:

>
> My point is, i want this strange rules to be removed.
> And I want the override keyword not to be a useless thing.
>
> I propose:
> 1.) make an overload not hide base implementations
> 2.) make the override keyword required, to make it useful.
> 3.) remove the interface reimplementation rule.
>
> What do you think?


I, also, don't like that an overload or override will hide base functions. I think
requiring the 'override' keyword would make code more readable. But what if
other cases (see below) would also require explicit syntax? (I don't know what
the full implications of this would be, etc; just some quick thoughts.)


Ok, there are the following five cases:

1) Define a new function (i.e. the base class doesn't have one with the same name).

2a) Override a function; don't hide other functions with the same name.
2b) Override a function; hide other functions with the same name.

3a) Add an overload for a function; don't hide other functions with the same name.
3b) Add an overload for a function; hide other functions with the same name.

(I think I haven't ever wanted/needed to use the cases 2b and 3b, though, but I guess
that's just me.)


New rules would be:

A) The 'override' keyword is required for the case 2a.

B) A new keyword 'overload' is required for the case 3a. (I don't know if 'overload'
is a right word for it because it's similar to 'override'. I use it here though.)

C) A new keyword 'renew' (or something) is required for the cases 2b and 3b.


For example:

  class Base {
    int foo();
    int foo(int);
  }

  class Derived : Base {
    int bar();                //ok

    int foo();                //error; 'Base' has 'int foo()'
    renew int foo();          //ok (hides 'int foo(int)')

    override int foo();       //ok
    override int foo(float);  //error; 'Base' has no 'int foo(float)'

    overload int foo();       //error; 'Base' has 'int foo()'
    overload int foo(float);  //ok
  }


For templates, there should also be extra keywords to allow easy code generation.
For example, <X> == override || overload, <X> is some keyword.
February 26, 2007
Kristian Kilpi wrote:
> C) A new keyword 'renew' (or something) is required for the cases 2b and
> 3b

I like this idea making the uncommon case explicit. I have never felt any need for either 2b or 3b possibly as I learned to think about extends as an "is a" relation ship and that implies having all the behavior of the base class.