25 years ago, when I was trying to write some sort of library to
go with Walter's C++ compiler, I had a wish, and it still pops
into my head from time to time.
What I wanted was functions that were declared in a base class as
'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify the
extra code. The compiler would then automatically add a call to
the same function in whatever base class last defined or extended
the method.
extend void foo() // Declared in base class as cumulative void
foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a light
bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed to
to it.
Does this make any sense?
Steve

25 years ago, when I was trying to write some sort of library
to go with Walter's C++ compiler, I had a wish, and it still
pops into my head from time to time.
What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.
extend void foo() // Declared in base class as cumulative
void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a
light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed
to to it.
Does this make any sense?
Steve

Sorry, I had two foo()s in the 'example'. What I meant was
extend void foo() // Declared in base class as cumulative
{

25 years ago, when I was trying to write some sort of library
to go with Walter's C++ compiler, I had a wish, and it still
pops into my head from time to time.
What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.
extend void foo() // Declared in base class as cumulative
void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a
light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed
to to it.
Does this make any sense?
Steve

What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived
class that wanted to do something extra - as opposed to
something different, would simply define an 'extend', and just
specify the extra code. The compiler would then automatically
add a call to the same function in whatever base class last
defined or extended the method.

This exists but it's not automatic.

I think the point is that the super.foo() call is enforced.
Is it possible to write a cumulative annotation to detect
missing calls? Example:
class Base {
cumulative void foo() {}
}
class Bar : Base {
void foo() {} // compile error, no super.foo() call
}
It should probably get another name like overrideExtends.

25 years ago, when I was trying to write some sort of library
to go with Walter's C++ compiler, I had a wish, and it still
pops into my head from time to time.
What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.
extend void foo() // Declared in base class as cumulative
void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a
light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed
to to it.
Does this make any sense?
Steve

Sounds a little like the :after mechanism of the Common Lisp
Object System (CLOS). They also have :before, if your extra code
should run before the super-call. The third variant is :around,
which is like the default overwriting in D et. al.

Sounds a little like the :after mechanism of the Common Lisp Object
System (CLOS). They also have :before, if your extra code should run
before the super-call. The third variant is :around, which is like the
default overwriting in D et. al.

Yes! - and CLOS came from my all time favorite playland, the Symbolics
Lisp Machine with its version of OOP called Flavors.
See page 25 section 1.12 Method Combination and you will see a zoo of
ways to combine methods from a class ineritance hierarchy.
ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-602.pdf
A fun read. I wonder what David Moon is doing today?
--
Dan

25 years ago, when I was trying to write some sort of library
to go with Walter's C++ compiler, I had a wish, and it still
pops into my head from time to time.
What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.
extend void foo() // Declared in base class as cumulative
void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a
light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed
to to it.
Does this make any sense?
Steve

This is something that I have wished for as well. If it was
automatically inserted, it would only make sense for it to be
useable on functions with no return and no arguments. If it was
just enforcement then it wouldn't matter.
Something that does do this currently is default constructors.

extend void foo() // Declared in base class as cumulative void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class function to
return on behalf of the derived method as opposed to to it.
Does this make any sense?

I've often wished for something like that when working on OO-heavy
stuff. Some virtual funcs are intended to always be called by all
overriding functions, but without a way to enforce that, it becomes a
scary error-prone choice of API design. And trying to design your way
around that limitation can be a pain.

Maybe:
----
extend void foo() { ... }
----
would force you to use super.foo() and otherwise gives an error?
----
class Foo {
void foo() {
// ...
}
}
class Bar : Foo {
extend void foo() {
// compiler will force you (opposed to override) that you
call super.foo() but it isn't important where. You can call it at
the end or at the start or wherever you wish.
}
}
----
Maybe we could also reduce the super.FUNCTION with "super" as for
base class constructors. Or to distinguish we could name it
"base":
----
class Foo {
void foo() {
// ...
}
}
class Bar : Foo {
extend void foo() {
base(); /// will be rewritten to super.foo();
}
}
----
The latter is of course for the "lazy" people. :)

Maybe:
----
extend void foo() { ... }
----
would force you to use super.foo() and otherwise gives an error?
----
class Foo {
void foo() {
// ...
}
}
class Bar : Foo {
extend void foo() {
// compiler will force you (opposed to override) that
you call super.foo() but it isn't important where. You can call
it at the end or at the start or wherever you wish.
}
}
----
Maybe we could also reduce the super.FUNCTION with "super" as
for base class constructors. Or to distinguish we could name it
"base":
----
class Foo {
void foo() {
// ...
}
}
class Bar : Foo {
extend void foo() {
base(); /// will be rewritten to super.foo();
}
}
----
The latter is of course for the "lazy" people. :)

This is not good enough, this makes the "extend" optional on
overridden functions. What it needs to be is a way to ensure that
if your function is overridden by a base class that it is
guaranteed to be called by the new function.
Something like this
class A
{
extendable void foo(){}
}
class B : A
{
override void foo(){}// compilation error, super.foo not
called
}
This makes it non-optional. You have to call super.foo if you
want to override foo.
Also, in some cases it is not enough just to ensure that it is
called, some times you will want to make sure that it is called
at the beginning or end of the function. Though this is harder to
get right, not really sure how it would work with returns.
Also I think it would make sense for something like this to be
transitive. For instance in the above example, the new foo should
also be extendable or else the guarantee breaks.

Also, in some cases it is not enough just to ensure that it is
called, some times you will want to make sure that it is called
at the beginning or end of the function. Though this is harder
to get right, not really sure how it would work with returns.

In the case where it would be needed to be called at the
beginning or the end of the new method. The compiler might be
able to implicitly add it in itself, similar to how super(); is
implicitly added to the beginning of overridden constructors.

Also, in some cases it is not enough just to ensure that it is called,
some times you will want to make sure that it is called at the
beginning or end of the function. Though this is harder to get right,
not really sure how it would work with returns.

In the case where it would be needed to be called at the beginning or
the end of the new method. The compiler might be able to implicitly add
it in itself, similar to how super(); is implicitly added to the
beginning of overridden constructors.

So far as I'm understanding this thread, Steve Teale is asking for a
way to inject code before and after a call to a function from other
places in the program. E.g. Write some function foo, write some
function bar, and specify that any time foo is called, bar should be
called immediately after *automagically*.
The reason this hasn't been done in any language I'm aware of is
because you can solve the same problem using existing polymorphism, and
it's a horribly awful design practice to have hidden code like that.
-S.

So far as I'm understanding this thread, Steve Teale is asking
for a way to inject code before and after a call to a function
from other places in the program. E.g. Write some function
foo, write some function bar, and specify that any time foo is
called, bar should be called immediately after *automagically*.
The reason this hasn't been done in any language I'm aware of
is because you can solve the same problem using existing
polymorphism, and it's a horribly awful design practice to have
hidden code like that.

It's a bit more specific than 'from other places in the program',
and anyway, once you've accepted virtual functions, you've
accepted 'automagic' ;=)
I'm writing a little example program that illustrates what I'm
getting at, and I'll post it somewhere when I'm through.
Steve

So far as I'm understanding this thread, Steve Teale is asking for a
way to inject code before and after a call to a function from other
places in the program. E.g. Write some function foo, write some
function bar, and specify that any time foo is called, bar should be
called immediately after *automagically*.
The reason this hasn't been done in any language I'm aware of is
because you can solve the same problem using existing polymorphism, and
it's a horribly awful design practice to have hidden code like that.

It's a bit more specific than 'from other places in the program', and
anyway, once you've accepted virtual functions, you've accepted
'automagic' ;=)
I'm writing a little example program that illustrates what I'm getting
at, and I'll post it somewhere when I'm through.
Steve

If I was understanding properly, you were suggesting that the code
should be executed even for instances of the base class. There's
some automagic that's good, that sounds like a vile thing to have to
debug when you take over for somebody else.
-S.

I'm writing a little example program that illustrates what I'm
getting at, and I'll post it somewhere when I'm through.

OK, it's at britseyeview.com/cumulative.txt.
I think enforcement of the call to super.handleCommand() would
get most of the way down the road. More could be done if the
compiler inserted the super call, and maintained an implicit
class member equivalent to my 'cmdResult' that could be tested in
override implementations of handleCommand(). But I think that is
OTT.
Steve

OK, it's at britseyeview.com/cumulative.txt.
I think enforcement of the call to super.handleCommand() would get most
of the way down the road. More could be done if the compiler inserted
the super call, and maintained an implicit class member equivalent to
my 'cmdResult' that could be tested in override implementations of
handleCommand(). But I think that is OTT.
Steve

I'm writing a little example program that illustrates what I'm
getting at, and I'll post it somewhere when I'm through.

OK, it's at britseyeview.com/cumulative.txt.

However, I now realize you can do better in D. The base class
needs to define an array of delegates. It appends its handler to
the array, then derived classes each append their handler. The
append is done like:
handlers ~= &Red.handleCommand;
Am I right in thinking that this makes the calls non-virtual?
Anyway, the result is I think exactly what I wanted.
The example is at britseyeview.com/cum2.txt.
Steve

When I've had a need for base classes to call super class functions, I
certainly wanted a way to enforce it. I just don't know if it would
just lead to other OOP design problems.

Sounds like a good reason to use unittests to me. The compiler can't
possibly deal with all the different ways you might want to enforce an
OOP pattern in a particular program. Introducing more keywords does
not seem like a fix.
-S.

When I've had a need for base classes to call super class
functions, I certainly wanted a way to enforce it. I just
don't know if it would just lead to other OOP design problems.

Sounds like a good reason to use unittests to me. The
compiler can't possibly deal with all the different ways you
might want to enforce an OOP pattern in a particular program.
Introducing more keywords does not seem like a fix.
-S.

As unit tests are optional, they are in no way an enforcement.
And for library writers(which is who this idea is mainly for I
think), writing unit tests to try and test user written code
seems a little unreasonable, especially as they don't have access
to the code :/

Hello,
I'm coming late to the discussion, but I believe that you can use the
following idiom to achieve the same results in a different way:
class C
{
// This is not overridable
public final void doStuff()
{
doSomethingWhichNeverChanges();
doExtraStuff();
}
protected void doExtraStuff()
{
// This one can be overridden
}
}
Or did I miss something?
Cheers,
LMB
On Mon, Feb 24, 2014 at 5:41 AM, Steve Teale
<steve.teale britseyeview.com>wrote:

25 years ago, when I was trying to write some sort of library to go with
Walter's C++ compiler, I had a wish, and it still pops into my head from
time to time.
What I wanted was functions that were declared in a base class as
'cumulative', or something similar. They would have been generally like
virtual functions, except that any derived class that wanted to do
something extra - as opposed to something different, would simply define an
'extend', and just specify the extra code. The compiler would then
automatically add a call to the same function in whatever base class last
defined or extended the method.
extend void foo() // Declared in base class as cumulative void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class function to
return on behalf of the derived method as opposed to to it.
Does this make any sense?
Steve

Hello,
I'm coming late to the discussion, but I believe that you can
use the
following idiom to achieve the same results in a different way:

Yes we went through that, if you go back a page you'll find a
post I did that makes the thing work better using a class
variable in the base class that is an array of delegates.
That way you don't have to do super, super, super back to root,
you just have to iterate over the delegates until you find one
that accepts the command.
It does just what I wanted to do in the first place without
compiler assistance
;=).
Steve

Hello,
I'm coming late to the discussion, but I believe that you can use the
following idiom to achieve the same results in a different way:

Yes we went through that, if you go back a page you'll find a post I
did that makes the thing work better using a class variable in the base
class that is an array of delegates.
That way you don't have to do super, super, super back to root, you
just have to iterate over the delegates until you find one that accepts
the command.
It does just what I wanted to do in the first place without compiler assistance
;=).
Steve

Actually, D has the ability to walk the object hierarchy at compile
time, and generate a function call containing all the super classes's
handleCommands. You could also even tag them with an attribute
structure to list which command #'s they accept to be able to generate
a switch, or bunch of if's to avoid function calls.
-S.

On 2014-02-26 16:05:19 +0000, Steve Teale said:
Actually, D has the ability to walk the object hierarchy at
compile time, and generate a function call containing all the
super classes's handleCommands. You could also even tag them
with an attribute structure to list which command #'s they
accept to be able to generate a switch, or bunch of if's to
avoid function calls.
-S.

25 years ago, when I was trying to write some sort of library
to go with Walter's C++ compiler, I had a wish, and it still
pops into my head from time to time.
What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.

OK, I'm back to this because I have done quite a bit of work
trying to get to what I wanted. I have converted my app so that
it conforms roughly to the above, as a test.

I've also noticed from the responses, and from responses to
associated questions, that OOP has become almost a dirty word in
the D community. It's old fashioned and slow. So if you're in
that camp, you can stop reading now.
I need to handle signals of some sort - let's say just
represented by an int.
In my base class I define a method final void handleSignal(int),
to which all signals are directed. In the same place there's a
virtual function bool signalHandler(int).
The base class also has a data member bool delegate(int)[]
handlers.
In classes Base, Intermediate, and Leaf, say, the constructor has
a statement:
handlers ~= &Base.signalHandler;
handlers ~= &Intermediate.signalHandler;
handlers ~= &Leaf.signalHandler;
The final handleSignal() method in the base class just traverses
the array, calling each delegate in turn until one returns true,
and then throws an exception or something if none of them do.
This works nicely. A lot of duplicate code in my original handler
functions is eliminated. Any particular leaf class just has to
cover the cases peculiar to it's own requirements. Intermediate
classes just deal with their generic cases, and the base class
handles all the signals that all leaves require.
The compiler doesn't help to ensure that the 'handlers ~=' bit is
present in all constructors, so I thought I would be clever, and
provide some mixin template or template function that all the
constructors in the hierarchy used, so that it was a fairly
simple thing to insist on, even if only by example.
But I have been frustrated in this desire. A member function like
final void doMyThing(string CLASSNAME)()
{
handlers ~= mixin("&"~CLASSNAME~".signalHandler;");
}
defined in the base class does not work, because the compiler
complains about the type of the this pointer being Base, despite
the fact that I am being explicit about the class name.
Attempts from other directions like calling back down the super()
chain don't work because I can't have anything but declarations
in a mixin template, and a super() call inside a template
function called by the constructor fails because the call is not
in a constructor.
Anyone have any bright ideas about how this could be regulated? I
can't say forced, because I think the compiler would have to do
that.
Steve

I've also noticed from the responses, and from responses to associated
questions, that OOP has become almost a dirty word in the D community.
It's old fashioned and slow. So if you're in that camp, you can stop
reading now.

FWIW, I don't think that's really the prevailing attitude towards OO. OO
definitely has its uses and benefits (and outside performance-critical
sections its performance is perfectly fine), it's just not the
one-size-fits-all mold to force everything into like it often got
treated as ~10 or so years ago.
Even the entity/component-based systems that I mentioned games commonly
use are still frequently employing OO, too (ex: Unity3D uses an
entity/component-based design for game objects, but the API for dealing
with the game object, components, etc is still an OO API). Entities,
metaprogramming, OO - none of these are "either/or" deals, just as OO
doesn't actually try to replace procedural programming but is rather
used together with it.

I need to handle signals of some sort - let's say just represented by an
int.
In my base class I define a method final void handleSignal(int), to
which all signals are directed. In the same place there's a virtual
function bool signalHandler(int).

[...]

Anyone have any bright ideas about how this could be regulated? I can't
say forced, because I think the compiler would have to do that.

Thanks Nick. A voice of sanity. Interestingly I'd decided on the
argument to the constructor while programming in bed last night.
The change of fashion is very noticeable though - structs for
everything seems to be a mantra these days. I have started to
wonder if the two styles could be bridged somewhat if we had the
default class method type as virtual, and then 'plain' functions
as well as final ones.
Steve

Thanks Nick. A voice of sanity. Interestingly I'd decided on
the argument to the constructor while programming in bed last
night.
The change of fashion is very noticeable though - structs for
everything seems to be a mantra these days. I have started to
wonder if the two styles could be bridged somewhat if we had
the default class method type as virtual, and then 'plain'
functions as well as final ones.
Steve

You would be able to redefine them in a derived class using
override to tell the compiler that it was intentional. Final
would remain as-is - final.
I think Walter made a good choice for the times when he chose to
have functions virtual by default, but a system programming
language should allow you to do dangerous things if you give the
compiler your permission.
Steve

I can get tantalizingly close to what I want using the extra
constructor argument.
In the base class I define a template function:
string initString(T)()
{
return "string sname =
\""~T.stringof~"\"~to!string(++nextOid);"
"HandlerDelegates[] ahdg = [ HandlerDelegates( &"~
T.stringof~".notifyHandler, &"~T.stringof~".undoHandler)];";
}
Then in the leaf class constructor I can just do:
mixin(initString!Arrow());
super(aw, parent, sname, AC_ARROW, ACGroups.SHAPES, ahdg);
Sadly the compiler does not complain if I comment out the leaf
notifyHandler()
method, cos its virtual, and there's one in its parent class.
Does contract programming to provide a way to say that some
function definition is required?
This is where I'd like to be able to say:
class Base
{
// Method is called directly, but unlike a final
// method it can be overidden in a derived class.
direct bool notifyHandler(...) { ... }
}
class Inter
{
// Kill the warning about hiding the base class method with
override
override bool notifyHandler(...) { ... }
}
As a side benefit, I think that mixing in a string generated by a
template function gives me a way of generating something
approximating a mixin template that allows more than just
declarations - insertion of parameterized code at compile time ;=)
Steve

25 years ago, when I was trying to write some sort of library to go
with Walter's C++ compiler, I had a wish, and it still pops into my
head from time to time.
What I wanted was functions that were declared in a base class as
'cumulative', or something similar. They would have been generally like
virtual functions, except that any derived class that wanted to do
something extra - as opposed to something different, would simply
define an 'extend', and just specify the extra code. The compiler would
then automatically add a call to the same function in whatever base
class last defined or extended the method.

OK, I'm back to this because I have done quite a bit of work trying to
get to what I wanted. I have converted my app so that it conforms
roughly to the above, as a test.

I've also noticed from the responses, and from responses to associated
questions, that OOP has become almost a dirty word in the D community.
It's old fashioned and slow. So if you're in that camp, you can stop
reading now.
I need to handle signals of some sort - let's say just represented by an int.
In my base class I define a method final void handleSignal(int), to
which all signals are directed. In the same place there's a virtual
function bool signalHandler(int).
The base class also has a data member bool delegate(int)[] handlers.
In classes Base, Intermediate, and Leaf, say, the constructor has a statement:
handlers ~= &Base.signalHandler;
handlers ~= &Intermediate.signalHandler;
handlers ~= &Leaf.signalHandler;
The final handleSignal() method in the base class just traverses the
array, calling each delegate in turn until one returns true, and then
throws an exception or something if none of them do.
This works nicely. A lot of duplicate code in my original handler
functions is eliminated. Any particular leaf class just has to cover
the cases peculiar to it's own requirements. Intermediate classes just
deal with their generic cases, and the base class handles all the
signals that all leaves require.
The compiler doesn't help to ensure that the 'handlers ~=' bit is
present in all constructors, so I thought I would be clever, and
provide some mixin template or template function that all the
constructors in the hierarchy used, so that it was a fairly simple
thing to insist on, even if only by example.
But I have been frustrated in this desire. A member function like
final void doMyThing(string CLASSNAME)()
{
handlers ~= mixin("&"~CLASSNAME~".signalHandler;");
}
defined in the base class does not work, because the compiler complains
about the type of the this pointer being Base, despite the fact that I
am being explicit about the class name.
Attempts from other directions like calling back down the super() chain
don't work because I can't have anything but declarations in a mixin
template, and a super() call inside a template function called by the
constructor fails because the call is not in a constructor.
Anyone have any bright ideas about how this could be regulated? I can't
say forced, because I think the compiler would have to do that.
Steve

What I wanted was functions that were declared in a base class
as 'cumulative', or something similar. They would have been
generally like virtual functions, except that any derived class
that wanted to do something extra - as opposed to something
different, would simply define an 'extend', and just specify
the extra code. The compiler would then automatically add a
call to the same function in whatever base class last defined
or extended the method.
extend void foo() // Declared in base class as cumulative
void foo()
{
(cast(BaseClass) this).foo(); // Compiler does this for you
// similar to changing a
light bulb ;=)
// the extra stuff
}
I think also that it might be necessary for the base class
function to return on behalf of the derived method as opposed
to to it.
Does this make any sense?

Yes. This is "inner virtual functions" as opposed to "outer
virtual functions" (C++). The successor to Simula, BETA
(http://daimi.au.dk/~beta/), has this. Simula has this in the
constructor of a class (which syntactically is the body), but
BETA has the concept everywhere:
somefunction:<(#
statements1;
inner;
statements2;
#)
When you specialize a function/class the extra stuff you add is
replacing the "inner" statement (and can provide it's own
"inner").
It provides for better encapsulation/enforcing invariants.

Yes. This is "inner virtual functions" as opposed to "outer
virtual functions" (C++). The successor to Simula, BETA
(http://daimi.au.dk/~beta/), has this. Simula has this in the
constructor of a class (which syntactically is the body), but
BETA has the concept everywhere:
somefunction:<(#
statements1;
inner;
statements2;
#)
When you specialize a function/class the extra stuff you add is
replacing the "inner" statement (and can provide it's own
"inner").

I had gone some distance along that course. A virtual function to
handle events examined the event to see if it could deal with it.
If it could not, it called a 'specificHandler' virtual function.
But that approach only works if you have a hierarchy of known
depth, when specificHandler only gets called for the leaf classes.
Later, I have had the constructors of derived classes add a
handler delegate to a list of potential handlers maintained in
the base class. The actual handler in the base class is a final
method that simply iterates that list until some derived class
handles the event, or throws if none do.
But both of these approaches are clumsy compared to what I would
like to see.
It would help if D had 'direct' class methods (as opposed to
final or virtual), as then I think it would be more
straightforward to generate the delegate list.
I'm pleased to see though that some other languages have noted
this deficiency.
Steve

But both of these approaches are clumsy compared to what I
would like to see.

Yeah, I think it would need language support to be worthwhile in
the long run. I think it makes a lot of sense for constructors
that the superclass has the first and last word in what the
object should look like. E.g. let subclasses populate an array in
their "inner-clauses" and let the superclass verify it or
compile it into something efficient.
However, it does require a sensible super class design since you
don't override virtual functions, but merely extend them.

I'm pleased to see though that some other languages have noted
this deficiency.

Yup, I am not sure if the inner clause was in Simula I in 1963,
but I believe it must have been present in Simula67. It was also
used for prefixing of blocks in Simula so that you could open
"libraries" by turning a class into a scope. E.g.
class MyToolkit begin
integer filehandler;
methods like print()
filehandler = openstuff();
inner;
closestuff(filehandler);
end
// and use it as
MyTookit begin
print() // file is open, we can print here
end
As Simula was Bjarne Stroustrup's influence for C++ he really
does not have an excuse for not adopting this stuff. ;-) Well, I
guess RAII is his version of "inner"…
If you had virtual types as class members then I guess you could
emulate inner with RAII like patterns. (By instantiating the
class rather than doing a function call and let the constructor
and destructor wrap the "inner")