On Mon, 08 Feb 2010 00:37:53 -0500, Andrei Alexandrescu <[email protected]> wrote:

Walter has now implemented final methods in interfaces and also contracts in interfaces, both of which I think are just awesome.

We figured that essentially he artificially disallows interfaces from providing bodies for methods. I think that's a gratuitous limitation; the only distinguishing quality of an interface is that it has no state. Other than that, interfaces can always offer overridable functions that by default offer functionality in terms of existing interface functions. For example:

interface Stack(T)
{
     void push(T);
     void pop();
     @property ref T top();
     @property bool empty();
     T belowTop()
     {
         auto t = top;
         pop();
         auto result = top;
         push(t);
     }
}

The default implementation of belowTop does a fair amount of work. A particular implementation might just use that or override it with a more efficient implementation.

Many more examples can be imagined, but I'm looking for a killer one, or perhaps a killer counterexample (e.g. when would an interface-defined method be really bad?)

Your thoughts welcome.

You forgot to return result :)

Also, it should be implemented like this to prevent a problem where a stack with a single element is cleared before an exception is thrown.

T belowTop()
{
  auto t = top;
  pop();
  scope(exit) push(t);
  return top;
}

As another example (not sure if it's "killer"), here is a more useful default method:

T popTop()
{
   scope(success) pop();
   return top;
}

I can see real use for "give me the top, and pop it off at the same time." Now, if we make popTop final, it's 2 virtual function calls (popTop can be inlined), but if we make it overridable, the default implementation has 3 virtual calls, but can be optimized into 1 virtual call if so desired. I guess it's a tradeoff between whether you think most implementors will prefer to use some default implementation or most will want to optimize. But in the case you expect most to optimize, wouldn't you just provide no implementation? In the case of popTop, it's attractive to say "your stack class only needs to define these few primitives," but it's generally trivial to provide a popTop implementation that is more optimized.

I've seen places where interface documentation says "implement this function like this: ..." which is quite annoying. final functions solve most of these, I'm not sure if we need another way to do it, but I can't see any reason why it should be disallowed. The judgement call of whether to provide an overridable implementation and no implementation would be difficult. I don't see a default-but-overridable implementation being used often.

-Steve

Reply via email to