Proposal: interfaces

112 views
Skip to first unread message

christopher diggins

unread,
Apr 9, 2004, 10:45:03 AM4/9/04
to
Motivation
==========
C++ designs that inherit from multiple pure abstract base classes introduce
multiple vtables that cause rapid bloating of objects that is uneccessary.
The current solution is an unacceptable "just don't do that".

Proposed Solution
=================
- interface reference type (fat pointer which points to object and to
interface function table)
- implements interface declarations

class FuBar {
implement IFuBar;
...
};

- instantiable interface declaration semantics i.e.

interface SomeInterface {
FuBar1();
...
};

- a downloadable example and demonstration is available at :
http://www.heron-language.com/heronfront.html

Advantages of Proposal
======================
- no code bloat when compared to comparable ABC design
- faster than comparable designs using ABC's
- introduction of proposal requires virtually no changes to other parts of
language standard

--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Larry Evans

unread,
Apr 9, 2004, 11:49:19 AM4/9/04
to
christopher diggins wrote:
> Motivation
> ==========
> C++ designs that inherit from multiple pure abstract base classes introduce
> multiple vtables that cause rapid bloating of objects that is uneccessary.
> The current solution is an unacceptable "just don't do that".
>
> Proposed Solution
> =================
> - interface reference type (fat pointer which points to object and to
> interface function table)
> - implements interface declarations
Hi christopher,

I'm just guessing, but also hoping that what you're proposing might
help in something akin to dynamic inheritance. I've wanted to
create something like a "base" class heirarchy and then "decorate" it
with different "views". An example of what I'm trying to do is at:

http://groups.yahoo.com/group/boost/files/regexp_first.zip

it implements inheritance of T via superclass smart_ptr<T>; however,
this obviously requires the inheriting class to forward all calls to the
superclass. But the inheriting class would need to have a virtual
function table whose only purpose would be to provide forwarding functions.

Can you tell me how this interface feature would help in the
regexp_first code?

I'd be happy to email you the code directly if that would help.

Regards,
Larry

Larry Evans

unread,
Apr 9, 2004, 6:38:21 PM4/9/04
to
Larry Evans wrote:
> christopher diggins wrote:
[snip]

> with different "views". An example of what I'm trying to do is at:
>
> http://groups.yahoo.com/group/boost/files/regexp_first.zip
>
Another example of where interfaces MAY be useful is with the code at:

http://groups.yahoo.com/group/boost/files/managed_ptr/overhead_referent_vals.zip

The Overhead will contain a virtual DTOR in order to be able to call the
Referent DTOR, but this causes the "bloat" of another VFT. Could this
interface feature avoid that?

Alberto Barbati

unread,
Apr 10, 2004, 2:50:20 AM4/10/04
to
christopher diggins wrote:
> Motivation
> ==========
> C++ designs that inherit from multiple pure abstract base classes introduce
> multiple vtables that cause rapid bloating of objects that is uneccessary.
> The current solution is an unacceptable "just don't do that".

This motivation is valid in several problem domains, yet it's not valid
in general. I still can imagine examples where abstract base classes are
necessary and where the overhead of current implementation is
acceptable. Whether your motivation is sufficient to justify a language
extension, I cannot tell. Keep in mind that linkers are getting smarter
and smarter and link-time code generation may (if not now, in the
future) greatly reduce the code bloat that you are worried about.

> Proposed Solution
> =================
> - interface reference type (fat pointer which points to object and to
> interface function table)
> - implements interface declarations
>
> class FuBar {
> implement IFuBar;
> ...
> };
>
> - instantiable interface declaration semantics i.e.
>
> interface SomeInterface {
> FuBar1();
> ...
> };

You suggest to introduce two new keywords but for sure you know how the
committee is reluctant to add those. The "implement" keyword is
unnecessary, IMHO. I don't see any problem in using the common syntax:

class FuBar : public IFuBar
...
};

As for the "interface" keyword, a replacement could be:

class SomeInterface = 0 {
FuBar1();
...
};

as "= 0" is already used for abstract virtual functions, the meaning
should be clear. Alternatively, one could overload the keyword "virtual":

virtual class SomeInterface {
FuBar1();
...
};

> - a downloadable example and demonstration is available at :
> http://www.heron-language.com/heronfront.html

The fact that you can provide one implementation that gives good results
doesn't demonstrate anything. See below...

> Advantages of Proposal
> ======================
> - no code bloat when compared to comparable ABC design
> - faster than comparable designs using ABC's
> - introduction of proposal requires virtually no changes to other parts of
> language standard
>

Your "solution" looks just like a syntax to me. It's not self-evident
how the advantages that you are claiming are obtained and, even more
important, why similar advantages cannot be obtained in another way.

Exactly I would like to understand:

1) precisely what code won't be generated w.r.t. the ABC syntax

2) how your proposed syntax helps to eliminate such code

3) why your proposed syntax is essential to eliminate such code (i.e.:
does it provide an essential information about the code that couldn't be
obtained in other way programmatically, possibly at link-time?)

--
Alberto Barbati

Dave Harris

unread,
Apr 10, 2004, 12:10:32 PM4/10/04
to
cdig...@videotron.ca ("christopher diggins") wrote (abridged):

> - instantiable interface declaration semantics i.e.

How does an interface differ from an abstract base class? Can an interface
have non-pure virtual functions? Non-virtual functions? Static member
variables? Or are they just like in Java?

Your motive seems to be performance. I suspect the Java model is more
restrictive than is necessary for performance, for ideological reasons. I
think that the killer problem with implementing ABCs is dealing with
non-static instance variables.

But I could be wrong. I would like to see a much more detailed analysis
than that you show on your web site. I'd like to see exactly where the
overhead of ABCs comes from. Have you considered other implementation
techniques for ABCs, eg thunks, or cached searches? Can you prove that the
only way to get performance is by using the restricted form of interfaces?

-- Dave Harris, Nottingham, UK

John Nagle

unread,
Apr 10, 2004, 3:11:45 PM4/10/04
to
Could you arrange to host your files on an openly accessable
website? Thanks.

John Nagle
Animats

Larry Evans wrote:

> Larry Evans wrote:
>
>> christopher diggins wrote:
>
> [snip]
>
>> with different "views". An example of what I'm trying to do is at:
>>
>> http://groups.yahoo.com/group/boost/files/regexp_first.zip
>>
> Another example of where interfaces MAY be useful is with the code at:
>
> http://groups.yahoo.com/group/boost/files/managed_ptr/overhead_referent_vals.zip
>

---

christopher diggins

unread,
Apr 11, 2004, 1:16:47 AM4/11/04
to
"Dave Harris" <bran...@cix.co.uk> wrote in message
news:memo.20040410131032.2400A@brangdon.m...

> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > - instantiable interface declaration semantics i.e.
>
> How does an interface differ from an abstract base class? Can an interface
> have non-pure virtual functions? Non-virtual functions? Static member
> variables? Or are they just like in Java?
>
> Your motive seems to be performance.

My motive is performance in so much that I want to have the freedom to write
a class that implements multiple interfaces without having to worry about
being hit with ever-increasing size and speed penalties that are
uneccessary.

>I suspect the Java model is more
> restrictive than is necessary for performance, for ideological reasons. I
> think that the killer problem with implementing ABCs is dealing with
> non-static instance variables.

I think the killer problem is the overwhelmingly common misconception that
an interface is the same as an ABC and that the functions should be virtual.

> But I could be wrong. I would like to see a much more detailed analysis
> than that you show on your web site. I'd like to see exactly where the
> overhead of ABCs comes from.

I would have thought that was relatively common knowledge.

> Have you considered other implementation
> techniques for ABCs, eg thunks, or cached searches?

No, I am not concerned with ABC's specifically but how they are a poor
substitute for an interface.

> Can you prove that the
> only way to get performance is by using the restricted form of interfaces?

I can't prove that because it isn't true. There are lots of ways improving
performance.

> -- Dave Harris, Nottingham, UK

--

---

David Abrahams

unread,
Apr 11, 2004, 7:03:45 PM4/11/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Dave Harris" <bran...@cix.co.uk> wrote in message
> news:memo.20040410131032.2400A@brangdon.m...
>> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
>> > - instantiable interface declaration semantics i.e.
>>
>> How does an interface differ from an abstract base class? Can an interface
>> have non-pure virtual functions? Non-virtual functions? Static member
>> variables? Or are they just like in Java?
>>
>> Your motive seems to be performance.
>
> My motive is performance in so much that I want to have the freedom to write
> a class that implements multiple interfaces without having to worry about
> being hit with ever-increasing size and speed penalties that are
> uneccessary.
>
>>I suspect the Java model is more
>> restrictive than is necessary for performance, for ideological reasons. I
>> think that the killer problem with implementing ABCs is dealing with
>> non-static instance variables.
>
> I think the killer problem is the overwhelmingly common misconception that
> an interface is the same as an ABC and that the functions should be virtual.

Has anyone suggested the "good-old CRTP" yet?

// base class template for all interfaces
template <class Derived>
struct interface
{
protected:
Derived& self()
{ return *static_cast<Derived*>(this); }

Derived const& self() const
{ return *static_cast<Derived const*>(this); }
};

// a specific interface - requires that Derived supports foo and bar
template <class Derived>
struct foobar : interface<Derived>
{
void baz()
{
this->self().foo();
this->self().bar();
}
};

// A specific implementation of the foobar interface
struct my_foobar : foobar<my_foobar>
{
void foo();
void bar();
};

Look, ma, no virtual functions!

Cheers,
Dave

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

vze2...@verizon.net

unread,
Apr 12, 2004, 2:44:48 PM4/12/04
to
>
> Has anyone suggested the "good-old CRTP" yet?
>
> // base class template for all interfaces
> template <class Derived>
> struct interface
> {
> protected:
> Derived& self()
> { return *static_cast<Derived*>(this); }
>
> Derived const& self() const
> { return *static_cast<Derived const*>(this); }
> };
>
> // a specific interface - requires that Derived supports foo and bar
> template <class Derived>
> struct foobar : interface<Derived>
> {
> void baz()
> {
> this->self().foo();
> this->self().bar();
> }
> };
>
> // A specific implementation of the foobar interface
> struct my_foobar : foobar<my_foobar>
> {
> void foo();
> void bar();
> };
>
> Look, ma, no virtual functions!
>
> Cheers,
> Dave
>

Is't there a problem when using different classes implementing foobar?
I would have to declare my_foobar and your_foobar like this:

foobar< my_foobar > & foobar_1 = *new my_foobar;
foobar< your_foobar > & foobar_2 = *new your_foobar;

Then references foobar_1 and foobar_2 would have different types
which is not what happens for interfaces in Java, for example, which is
a limitation since I won't be able, for instance, to define a function i
that has a parameter of type "interface foobar" unless I want to
templatize everything that deals with that interface.

Regards,

--
Aleksandr Morgulis
aleksandr...@verizon.net

christopher diggins

unread,
Apr 12, 2004, 11:29:13 PM4/12/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:ur7uuo...@boost-consulting.com...

> cdig...@videotron.ca ("christopher diggins") writes:
>

<snip>

> Has anyone suggested the "good-old CRTP" yet?

<snip>

> Look, ma, no virtual functions!

The CRTP(?) approach does indeed have no virtual functions but is lacking of
polymorphism on the interface because every "implementation" would have a
different base type.

---

christopher diggins

unread,
Apr 12, 2004, 11:33:05 PM4/12/04
to
"Alberto Barbati" <Alberto...@libero.it> wrote in message
news:HVGdc.118593$Kc3.3...@twister2.libero.it...

> christopher diggins wrote:
> > Motivation
> > ==========
> > C++ designs that inherit from multiple pure abstract base classes
introduce
> > multiple vtables that cause rapid bloating of objects that is
uneccessary.
> > The current solution is an unacceptable "just don't do that".
>
> This motivation is valid in several problem domains, yet it's not valid
> in general. I still can imagine examples where abstract base classes are
> necessary and where the overhead of current implementation is
> acceptable. Whether your motivation is sufficient to justify a language
> extension, I cannot tell. Keep in mind that linkers are getting smarter
> and smarter and link-time code generation may (if not now, in the
> future) greatly reduce the code bloat that you are worried about.

This was a big error on my part in the presentation of the proposal. I don't
propose to replace ABC's but rather introduce interfaces as being an
appropriate alternative for certain design scenarios which call for them
(i.e. behaves-like and looks-like object relationships). I agree that ABC's
are a perfectly acceptable and balanced solution in many cases and shouldn't
be replaced. Linkers do nothing to deal with the larger problem of object
bloat when implementing large numbers of ABC's.

> > Proposed Solution
> > =================
> > - interface reference type (fat pointer which points to object and to
> > interface function table)
> > - implements interface declarations
> >
> > class FuBar {
> > implement IFuBar;
> > ...
> > };
> >
> > - instantiable interface declaration semantics i.e.
> >
> > interface SomeInterface {
> > FuBar1();
> > ...
> > };
>
> You suggest to introduce two new keywords but for sure you know how the
> committee is reluctant to add those. The "implement" keyword is
> unnecessary, IMHO. I don't see any problem in using the common syntax:

The committee prejudices don't concern me at this point with regards to the
syntax. But in general, I have confidence that they measure each proposal
carefully and separately without preconcieved notions.

> class FuBar : public IFuBar
> ...
> };
>
> As for the "interface" keyword, a replacement could be:
>
> class SomeInterface = 0 {
> FuBar1();
> ...
> };
>
> as "= 0" is already used for abstract virtual functions, the meaning
> should be clear. Alternatively, one could overload the keyword "virtual":
>
> virtual class SomeInterface {
> FuBar1();
> ...
> };

Your syntax proposal is interesting and clever, I credit you with it in the
rewrite of my proposal.

> > - a downloadable example and demonstration is available at :
> > http://www.heron-language.com/heronfront.html
>
> The fact that you can provide one implementation that gives good results
> doesn't demonstrate anything. See below...

I am demonstrating the technique as opposed to proving things. Some people
need to see tangible work before they take theoretical notions into
consideration.

> > Advantages of Proposal
> > ======================
> > - no code bloat when compared to comparable ABC design
> > - faster than comparable designs using ABC's
> > - introduction of proposal requires virtually no changes to other parts
of
> > language standard
> >
>
> Your "solution" looks just like a syntax to me. It's not self-evident
> how the advantages that you are claiming are obtained and, even more
> important, why similar advantages cannot be obtained in another way.

It is more than syntax I am trying to propose. It is the fact that an
interface is not an ABC. See http://www.heron-language.com/abc-iop.html.

> Exactly I would like to understand:
>
> 1) precisely what code won't be generated w.r.t. the ABC syntax

Virtual functions and dynamic dispatch of functions within the object
implementing an interface would not be generated.

> 2) how your proposed syntax helps to eliminate such code

Becaue an interface is clearly not an ABC there is no point to using virtual
functions as it conflicts with the intent.

> 3) why your proposed syntax is essential to eliminate such code (i.e.:
> does it provide an essential information about the code that couldn't be
> obtained in other way programmatically, possibly at link-time?)

The proposed syntax differentiates the notion of implementing an interface
from inheriting an ABC. The main difference is that implementing an
interface does no imply virtualization of the functions. This fact can by
easily leveraged by an implementation to create a more efficient usage of
interfaces compared with the naive comparable implementation using ABC's.
The intent of using ABC as an interface is not easily knowable to a
compiler/linker and having the compiler have different representations of an
ABC depending on context would probably not be a practically possible
option.

Thanks for your comments Alberto

---

David Abrahams

unread,
Apr 12, 2004, 11:35:56 PM4/12/04
to
vze2...@verizon.net writes:

> Is't there a problem when using different classes implementing
> foobar?

It depends on your requirements. Please re-read the part of my post
that you snipped:

-----


cdig...@videotron.ca ("christopher diggins") wrote:
> My motive is performance in so much that I want to have the freedom to write
> a class that implements multiple interfaces without having to worry about
> being hit with ever-increasing size and speed penalties that are
> uneccessary.
>
>>I suspect the Java model is more
>> restrictive than is necessary for performance, for ideological reasons. I
>> think that the killer problem with implementing ABCs is dealing with
>> non-static instance variables.
>
> I think the killer problem is the overwhelmingly common misconception that
> an interface is the same as an ABC and that the functions should be virtual.

-------

> I would have to declare my_foobar and your_foobar like this:
>
> foobar< my_foobar > & foobar_1 = *new my_foobar;
> foobar< your_foobar > & foobar_2 = *new your_foobar;
>
> Then references foobar_1 and foobar_2 would have different types
> which is not what happens for interfaces in Java, for example, which is
> a limitation since I won't be able, for instance, to define a function i
> that has a parameter of type "interface foobar" unless I want to
> templatize everything that deals with that interface.

Of course. You can't have it both ways: either you get type erasure,
dynamic polymorphism, and you pay the runtime cost of virtual
functions, or you preserve type distinctions, use static
polymorphism, and avoid the runtime cost of virtual functions. In
C++, it's up to you to choose.

--
Dave Abrahams
Boost Consulting

http://www.boost-consulting.com

Pete Vidler

unread,
Apr 13, 2004, 10:58:46 AM4/13/04
to
christopher diggins wrote:
[snip]

> The CRTP(?) approach does indeed have no virtual functions but is lacking of
> polymorphism on the interface because every "implementation" would have a
> different base type.

CRTP = Curiously Recurring Template Pattern. The compile-time
polymorphism is gained through the use of templates whenever you need to
take different "interfaces".

-- Pete

David Abrahams

unread,
Apr 13, 2004, 10:59:12 AM4/13/04
to
da...@boost-consulting.com (David Abrahams) writes:

> Of course. You can't have it both ways: either you get type erasure,
> dynamic polymorphism, and you pay the runtime cost of virtual
> functions, or you preserve type distinctions, use static
> polymorphism, and avoid the runtime cost of virtual functions. In
> C++, it's up to you to choose.

Sorry, I obviously didn't read the proposal carefully. The proposal
wants to trade object size for increased (interface) pointer size.
That's not available in C++, at least, not with a nice syntax. I
think the proposal misses that you also need fat references, in order
to allow

(*interface_pointer).foo()

Cheers,
Dave

Dave Harris

unread,
Apr 13, 2004, 3:32:10 PM4/13/04
to
cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > How does an interface differ from an abstract base class? Can an
> > interface have non-pure virtual functions? Non-virtual functions?
> > Static member variables? Or are they just like in Java?

I would still like to see this answered. In my view you have not yet made
a case for your new feature.


> > Have you considered other implementation techniques for ABCs,
> > eg thunks, or cached searches?
>
> No, I am not concerned with ABC's specifically but how they are a poor
> substitute for an interface.

Why are they are poor substitute? It seems to me Java interfaces have
restrictions which make them less useful than C++ classes.


> > Can you prove that the only way to get performance is by using
> > the restricted form of interfaces?
>
> I can't prove that because it isn't true. There are lots of ways
> improving performance.

You just said your motivation was performance. If you can get the
performance of interfaces with ABCs, why do you want the new feature?

Maybe in, say, 5 or 10 years time, when all the compiler vendors have
"export" working properly and they have turned their attention to
optimisation, they will find better ways of implementing ABCs. Then
interfaces will not be necessary. Do you have any good reason for thinking
this cannot happen?

-- Dave Harris, Nottingham, UK

---

vze2...@verizon.net

unread,
Apr 13, 2004, 4:19:46 PM4/13/04
to

I have been thinking about the ways of implementing interfaces within the
framework of C++ while preserving all the features of the original proposal,
but have had no success so far. However I am still not convinced that features
offered by the proposal are valuable enough to warrant the language change.

The implementation that you suggested suffers one more disadvantage as compared
to OP's proposal. Interfaces, as proposed, would allow for the implementing
class to be very light weight, e.g. having no virtual methods or being POD.

With your implementation the class implementing an interface derives from
the interface class which means that the interface class must provide a
virtual destructor.

Also, it is natural to expect that a if A implements an interface and
B is derived from A, then B implicitly implements the interface. I can
not see how one can easily achieve it with your implementation. On the
other hand with the OP's proposal it can be done.

Anyway, some sort of polymorphysm can be achieved by adjusting your example in
the following way:

template< typename T > class if_base
{
public:

T & self() { return *static_cast< T * >( this ); }
const T & self() const { return *static_cast< const T * >( this ); }
};

template< typename T > class if_foo;

template<> class if_foo< void >
{
public:

virtual void foo() = 0;

virtual ~if_foo() {}
};


template< typename T >
class if_foo : public if_base< T >, public if_foo< void >
{
public:

void foo() { self().foo(); }
};

class foo_class : public if_foo< foo_class >
{
public:

void foo();
};

Unfortunately this requires foo() to be virtual (which actually
matches the default behavior in Jave, but Java provides "final"
modifier which, as far as I know, can not be implemented in C++).

The above implementation solves one problems with ABC's that is mentioned
in the proposal: the object size increase. In fact if foo_class has
virtual functions in the beginning, it actually saves memory, since
interface pointer is just an ordinary pointer rather than a fat pointer.
Otherwise it just adds one vtable pointer to the class which makes
it equivalent to a fat pointer.

Here is another possibility to implement interfaces, this time
using composition instead of inheritance:

template< typename T > class if_foo;

template<> class if_foo< void >
{
public:

virtual void foo() = 0;
virtual ~if_foo() {}
};

template< typename T >
class if_foo : public if_foo< void >
{
public:

if_foo( T & t ) : t_( t ) {}

void foo() { t.foo(); }

protected:

T & t_;
};

class foo_class
{
public:

void foo();
};

This would allow foo_class be as simple as necessary, and it solves
the problem of inheritance:

class foo_class
{
public:

virtual void foo();
virtual ~foo_class() {}
};

class derived : public foo_class
{
public:

void foo();
};

derived D;
foo_class & fc = D;
if_foo< void > * ifp = *new if_foo< foo_class >( fc );
ifp->foo(); // calls derived::foo()

But now ifp points to an object if_foo< foo_class > which contains a vtable ptr
and a reference to D which effectively makes it 3 pointers instead of 2 as in
fat pointer proposal.

Regards,

--
Aleksandr Morgulis
aleksandr...@verizon.net

---

christopher diggins

unread,
Apr 14, 2004, 8:38:02 PM4/14/04
to
"Pete Vidler" <pvi...@mailblocks.com> wrote in message
news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...

> christopher diggins wrote:
> [snip]
> > The CRTP(?) approach does indeed have no virtual functions but is
lacking of
> > polymorphism on the interface because every "implementation" would have
a
> > different base type.
>
> CRTP = Curiously Recurring Template Pattern. The compile-time
> polymorphism is gained through the use of templates whenever you need to
> take different "interfaces".
>
> -- Pete

The term "compile-time polymorphism" is misleading. Historically the term
polymorphism is used to refer to objects taking different forms at runtime.
Calling the CRTP approach "compile-time polymorphism" is misleading,
especially in the context of implying that it is comparable to real
polymorphism.

---

christopher diggins

unread,
Apr 14, 2004, 8:38:15 PM4/14/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:uk70k3...@boost-consulting.com...

> da...@boost-consulting.com (David Abrahams) writes:
>
> > Of course. You can't have it both ways: either you get type erasure,
> > dynamic polymorphism, and you pay the runtime cost of virtual
> > functions, or you preserve type distinctions, use static
> > polymorphism, and avoid the runtime cost of virtual functions. In
> > C++, it's up to you to choose.
>
> Sorry, I obviously didn't read the proposal carefully. The proposal
> wants to trade object size for increased (interface) pointer size.
> That's not available in C++, at least, not with a nice syntax. I
> think the proposal misses that you also need fat references, in order
> to allow
>
> (*interface_pointer).foo()

Sorry that I forgot to mention that in the proposal.
I would also propose not using interface reference types to have the same
semantics as pointers, but rather as a struct. This is because the idea of
dereferencing would be redundant.

interface_pointer.foo()

I would find that syntax preferable, but this is a minor point.

---

christopher diggins

unread,
Apr 15, 2004, 1:03:38 AM4/15/04
to
"Dave Harris" <bran...@cix.co.uk> wrote in message
news:memo.20040412231942.236A@brangdon.m...

> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > > How does an interface differ from an abstract base class? Can an
> > > interface have non-pure virtual functions? Non-virtual functions?
> > > Static member variables? Or are they just like in Java?
>
> I would still like to see this answered. In my view you have not yet made
> a case for your new feature.

I am currently proposing interfaces that contain only member functions. Your
other suggestions (static member variables, non-pure virtual functions,
non-virtual functions) could all be potentially introduced later. I like
them all and see no reason not to include them, except that at this point it
would be perhaps premature to consider them.

> > > Have you considered other implementation techniques for ABCs,
> > > eg thunks, or cached searches?
> >
> > No, I am not concerned with ABC's specifically but how they are a poor
> > substitute for an interface.
>
> Why are they are poor substitute? It seems to me Java interfaces have
> restrictions which make them less useful than C++ classes.

I confused the issue from the beginning because of my poor introduction of
the proposal, for which I apologize. I meant to say that using ABC's as
interfaces is very inefficient. ABC's by themselves are useful and
important. I don't mean to compare interfaces with classes as such.
Interfaces have a very specific and useful purpose, to model certain kinds
of looks-like and behaves-like object relationships.

> > > Can you prove that the only way to get performance is by using
> > > the restricted form of interfaces?
> >
> > I can't prove that because it isn't true. There are lots of ways
> > improving performance.
>
> You just said your motivation was performance. If you can get the
> performance of interfaces with ABCs, why do you want the new feature?

Sorry, I wasn't sure to what performance you were addressing. My position is
that using an ABC to emulate an interface is inefficient.

> Maybe in, say, 5 or 10 years time, when all the compiler vendors have
> "export" working properly and they have turned their attention to
> optimisation, they will find better ways of implementing ABCs. Then
> interfaces will not be necessary. Do you have any good reason for thinking
> this cannot happen?

The whole problem stems from the fact that a implementing an interface is
not an implicit agreement to make those functions virtual (as it would be
when inheriting from an ABC). This problem can not be resolved by simply
making ABC's more efficient. Virtual functions by definition require more
time and memory than non-virtual functions.

---

Alberto Barbati

unread,
Apr 15, 2004, 11:16:37 AM4/15/04
to
christopher diggins wrote:
> I am currently proposing interfaces that contain only member functions. Your
> other suggestions (static member variables, non-pure virtual functions,
> non-virtual functions) could all be potentially introduced later. I like
> them all and see no reason not to include them, except that at this point it
> would be perhaps premature to consider them.
>
> [snips]

>
> The whole problem stems from the fact that a implementing an interface is
> not an implicit agreement to make those functions virtual (as it would be
> when inheriting from an ABC). This problem can not be resolved by simply
> making ABC's more efficient. Virtual functions by definition require more
> time and memory than non-virtual functions.
>

Those two sentences looks in contradiction to me. The first one suggests
that interface methods should be pure virtual by default (you said that
"non-virtual function could be potentially introduced later"). The
second sentence suggests that implementing an interface does not make
the methods implicitly virtual. Could you clarify your thought?

In fact, you have stressed several times in this thread that interface
member functions need not be virtual (you even said that "there is no
point to using virtual functions as it conflicts with the intent"). This
points strikes me. If you define an interface as:

---begin example
interface Runnable
{
void run();
};

class Base
{
public:
implement Runnable;
void run();
};

class Derived : public Base
{
public:
void run(); // does it override Base::run()?
};

int main()
{
Derived d;
Runnable rd = d; // or whatever syntax you have to get
// an interface reference from an object

d.run(); // Derived::run()
rd.run(); // which one? Base::run() or Derived::run() ?

Base& b = d;
Runnable rb = b;
rb.run(); // which one? Base::run() or Derived::run() ?
}
---end example

In this scenario, the most obvious thing, IMHO, is that run() should
behaves as-if it where implicitly declared as virtual, that is
Derived::run() should be called in all three places. A different
behaviour would violate the least-astonishment principle (for most Java
programmers at least ;)

Please notice that implementing non-virtual methods in interfaces is
more difficult than implementing virtual ones. Correct me if I'm wrong,
but to implement a non-virtual method correctly, the interface reference
should contain a pointer to each non-virtual method, thus each method in
the interface increases the size of the reference. As interfaces
references are meant to be passed by value, this looks like a nightmare
to me. On the other hand, to implement virtual methods, the size of a
reference would be exactly equal to two pointers (one to the object, one
to the vtable) regardless of the number of methods.

Even in case I'm missing something and there's a valid reason why
interface methods need not be virtual, my example shows that virtual
methods still have a reason to be and should be included in the proposal
right from the beginning.

Alberto

Bob Bell

unread,
Apr 15, 2004, 1:09:45 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") wrote in message news:<3rafc.164007$KE5.2...@weber.videotron.net>...

> "Pete Vidler" <pvi...@mailblocks.com> wrote in message
> news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...
> > christopher diggins wrote:
> > [snip]
> > > The CRTP(?) approach does indeed have no virtual functions but is
> lacking of
> > > polymorphism on the interface because every "implementation" would have
> a
> > > different base type.
> >
> > CRTP = Curiously Recurring Template Pattern. The compile-time
> > polymorphism is gained through the use of templates whenever you need to
> > take different "interfaces".
> >
> > -- Pete
>
> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,
> especially in the context of implying that it is comparable to real
> polymorphism.

Not exactly. The term "polymorphism" simply means "many bodies".
Historically, polymorphism refers to the effect of having a single
syntactic construct that can be executed in multiple ways depending on
some kind of context. The term "polymorphism" got co-opted by the
object oriented programming movement, so now everyone thinks that
polymorphism mean some kind of run-time message dispatching scheme. A
consequence is that polymorphism at compile time gets a special name:
"compile time polymorphism".

A simple (and historical) example is "+".

x = y + z;

can execute different instructions depending on the type of y and z.
This is also an example of compile-time polymorphism since the
decision about which code to execute is made at compile time.

Bob

Pete Vidler

unread,
Apr 15, 2004, 1:47:44 PM4/15/04
to
christopher diggins wrote:
[snip]

> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,
> especially in the context of implying that it is comparable to real
> polymorphism.

From the dictionary definition of polymorphism (from www.m-w.com):

"the quality or state of being able to assume different forms"

I see this as applying to static (compile-time) polymorphism just as
well as it does to dynamic (run-time) polymorphism.

The two are comparable -- please explain what you mean when you say they
are not? They accomplish essentially the same thing (but at different
times).

-- Pete

llewelly

unread,
Apr 15, 2004, 1:48:48 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Pete Vidler" <pvi...@mailblocks.com> wrote in message
> news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...
>> christopher diggins wrote:
>> [snip]
>> > The CRTP(?) approach does indeed have no virtual functions but is
> lacking of
>> > polymorphism on the interface because every "implementation" would have
> a
>> > different base type.
>>
>> CRTP = Curiously Recurring Template Pattern. The compile-time
>> polymorphism is gained through the use of templates whenever you need to
>> take different "interfaces".
>>
>> -- Pete
>
> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,

'compile-time' is clearly distinct from 'runtime'. It is thus obvious
that 'compile-time polymorphism' refers to a different property
than 'polymorphism'.

You are saying it is misleading to refer to a red rose as a 'red rose'.

> especially in the context of implying that it is comparable to real
> polymorphism.

Compile-time polymorphism and runtime polymorphism have overlapping
areas of use. Therefor they can be compared, within the area of
their overlap. It is not an apples-to-apples comparison; it is an
apples-to-pears comparison. Nonetheless both are fruits, so to
speak.

christopher diggins

unread,
Apr 15, 2004, 3:48:28 PM4/15/04
to
"Bob Bell" <bel...@pacbell.net> wrote in message
news:c87c1cfb.04041...@posting.google.com...

I am aware of the greek roots of the word as well the standard English
defintion. English definitions of words often have little meaning when
referring to programming techniques and concepts.

> Historically, polymorphism refers to the effect of having a single
> syntactic construct that can be executed in multiple ways depending on
> some kind of context.
>
> The term "polymorphism" got co-opted by the
> object oriented programming movement, so now everyone thinks that
> polymorphism mean some kind of run-time message dispatching scheme. A
> consequence is that polymorphism at compile time gets a special name:
> "compile time polymorphism".

I was not aware of the common usage of the term polymorphism predating the
object oriented movement. If this is the case then I withdraw my objection.

> A simple (and historical) example is "+".
>
> x = y + z;
>
> can execute different instructions depending on the type of y and z.
> This is also an example of compile-time polymorphism since the
> decision about which code to execute is made at compile time.
>
> Bob

I was under the understanding that this was commonly called operator
overloading. My relative youth in the field of computer science perhaps
betrays me in this discussion.

This discussion, while being very interesting and educational, does not
detract from my original point that bringing up the compile-time
polymorphism of CRTP in comparison with the run-time polymorphism of
interfaces is not a fair and accurate comparison because they are different
techniques which can not be used interchangeably.

I was perhaps wrong in attributing this error of comparison with what I may
have mistakenly perceived as a poor choice of terms.

---

Matthew Collett

unread,
Apr 15, 2004, 7:09:39 PM4/15/04
to
In article <%Cafc.573$uc7....@weber.videotron.net>,

cdig...@videotron.ca ("christopher diggins") wrote:

> The whole problem stems from the fact that a implementing an interface is
> not an implicit agreement to make those functions virtual (as it would be
> when inheriting from an ABC). This problem can not be resolved by simply
> making ABC's more efficient. Virtual functions by definition require more
> time and memory than non-virtual functions.

If I have understood correctly what you are after, it seems to be a
special case of something rather simpler and more general, namely the
ability to say that a virtual function is no longer so (or rather, can
no longer be overridden). In effect, the job could be done by giving
C++ something like Java's 'final' for functions. Assuming the notation
'~virtual' to avoid introducing another keyword:

class AnInterface { //Just an ABC, as at present
public:
virtual void aFunction() = 0;
}

class AnImplementation: public AnInterface {
public:
~virtual void aFunction(); //Prevents further overriding
}

Anything which has a pointer/reference to AnInterface then uses the
usual virtual dispatch mechanism (and despite what you say above, I
cannot see how interfaces can be implemented without something
effectively equivalent to virtual dispatch), while anything which has a
pointer/reference to AnImplementation could use direct (non-virtual)
dispatching instead.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle

christopher diggins

unread,
Apr 15, 2004, 8:46:21 PM4/15/04
to
"Alberto Barbati" <Alberto...@libero.it> wrote in message
news:3vtfc.3575$Qc.1...@twister1.libero.it...

> christopher diggins wrote:
> > I am currently proposing interfaces that contain only member functions.
Your
> > other suggestions (static member variables, non-pure virtual functions,
> > non-virtual functions) could all be potentially introduced later. I like
> > them all and see no reason not to include them, except that at this
point it
> > would be perhaps premature to consider them.
> >
> > [snips]
> >
> > The whole problem stems from the fact that a implementing an interface
is
> > not an implicit agreement to make those functions virtual (as it would
be
> > when inheriting from an ABC). This problem can not be resolved by simply
> > making ABC's more efficient. Virtual functions by definition require
more
> > time and memory than non-virtual functions.
> >
>
> Those two sentences looks in contradiction to me. The first one suggests
> that interface methods should be pure virtual by default (you said that
> "non-virtual function could be potentially introduced later"). The
> second sentence suggests that implementing an interface does not make
> the methods implicitly virtual. Could you clarify your thought?

You are correct, the sentence which refers to virtual functions is wrong.
Perhaps inserting "virtual-like" would clarify its intent.

> In fact, you have stressed several times in this thread that interface
> member functions need not be virtual (you even said that "there is no
> point to using virtual functions as it conflicts with the intent").

I stand by this statement.

> This points strikes me. If you define an interface as:
>
> ---begin example
> interface Runnable
> {
> void run();
> };
>
> class Base
> {
> public:
> implement Runnable;
> void run();
> };
>
> class Derived : public Base
> {
> public:
> void run(); // does it override Base::run()?
> };

Not according to the proposal.

> int main()
> {
> Derived d;
> Runnable rd = d; // or whatever syntax you have to get
> // an interface reference from an object

That is exactly the syntax I was thinking of.

> d.run(); // Derived::run()
> rd.run(); // which one? Base::run() or Derived::run() ?

Base::run because Derived doesn't implement Runnable, but Base does. Derived
could implement Runnable as well if it wanted to have its own implementation
executed.

> Base& b = d;
> Runnable rb = b;
> rb.run(); // which one? Base::run() or Derived::run() ?

Base::run again for the same reasons above.

> In this scenario, the most obvious thing, IMHO, is that run() should
> behaves as-if it where implicitly declared as virtual, that is
> Derived::run() should be called in all three places. A different
> behaviour would violate the least-astonishment principle (for most Java
> programmers at least ;)

If any implementation of Java performs in that manner it is incorrectly
implemented according to the java virtual machine specification of
invokeinterface bytecodes:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface

I would venture to say that the reason the implicit virtual behaviour is
obvious to you (and many others) is because as C++ programmers we are used
to working with virtual functions. I would argue that from a more naive
standpoint, an interface behaving as virtual itself violates the
least-astonishment principle.

> Please notice that implementing non-virtual methods in interfaces is
> more difficult than implementing virtual ones.

Not difficult really, I banged out an implementation in a few days
(http://www.heron-language.com/heronfront.html )

> Correct me if I'm wrong,
> but to implement a non-virtual method correctly, the interface reference
> should contain a pointer to each non-virtual method, thus each method in
> the interface increases the size of the reference.

I use an extra pointer in the interface reference to a static table of
method pointers. You only need one table for each class/interface pair.

> As interfaces
> references are meant to be passed by value, this looks like a nightmare
> to me. On the other hand, to implement virtual methods, the size of a
> reference would be exactly equal to two pointers (one to the object, one
> to the vtable) regardless of the number of methods.

I use the same approach to implementing the proposed non-virtual interfaces
in HeronFront.

> Even in case I'm missing something and there's a valid reason why
> interface methods need not be virtual, my example shows that virtual
> methods still have a reason to be and should be included in the proposal
> right from the beginning.

That is correct and the original proposal was very badly written. I
shouldn't have suggested in the proposal that interfaces would replace
ABC's, but rather they would replace using ABC's as interfaces.

By the way have you looked at the most recent proposal where I take into
account your syntax suggestions? http://www.heron-language.com/cpp-iop.html

---

llewelly

unread,
Apr 15, 2004, 8:51:31 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Bob Bell" <bel...@pacbell.net> wrote in message

[snip]


>> A simple (and historical) example is "+".
>>
>> x = y + z;
>>
>> can execute different instructions depending on the type of y and z.
>> This is also an example of compile-time polymorphism since the
>> decision about which code to execute is made at compile time.
>>
>> Bob
>
> I was under the understanding that this was commonly called operator
> overloading. My relative youth in the field of computer science perhaps
> betrays me in this discussion.

[snip]

Overloading is a kind of polymorphism.

Adam H. Peterson

unread,
Apr 15, 2004, 10:38:02 PM4/15/04
to
> I meant to say that using ABC's as
> interfaces is very inefficient. ABC's by themselves are useful and
> important. I don't mean to compare interfaces with classes as such.
> Interfaces have a very specific and useful purpose, to model certain kinds
> of looks-like and behaves-like object relationships.

From a functionality stand point, it looks to me like ABC functionality
is are a proper superset of interface functionality. From a performance
standpoint, I don't see how ABCs have an obvious asymptotic performance
hit. They look to me like they are pretty equivalent in terms of
performance (if that). That may not be true, but I feel it needs to be
demonstrated more conclusively to justify the addition of a reduced
functionality version of a language feature because of performance concerns.


> Virtual functions by definition require more
> time and memory than non-virtual functions.
>

Which definition of virtual functions are you using? I've never heard a
definition for virtual function that included a performance hit as a
criterion. Perhaps a performance hit can be deduced from the
definition, but I'm not convinced of that either.

Matt Austern

unread,
Apr 15, 2004, 10:38:25 PM4/15/04
to
pvi...@mailblocks.com (Pete Vidler) writes:

> christopher diggins wrote:
> [snip]
> > The term "compile-time polymorphism" is misleading. Historically the term
> > polymorphism is used to refer to objects taking different forms at runtime.
> > Calling the CRTP approach "compile-time polymorphism" is misleading,
> > especially in the context of implying that it is comparable to real
> > polymorphism.
>
> From the dictionary definition of polymorphism (from www.m-w.com):
>
> "the quality or state of being able to assume different forms"
>
> I see this as applying to static (compile-time) polymorphism just as
> well as it does to dynamic (run-time) polymorphism.

You don't have to resort to dictionary definitions to show that: you
can point to the computer science literature! For example, you can
point to the famous paper by Cardelli and Wegner, "On Understanding
Types, Data Abstraction, and Polymorphism". They distinguish between
"universal" and "ad-hoc" polymorphism (where "ad-hoc" includes things
like overloading), and, within universal polymorphism, they
distinguish between parametric and inclusion polymorphism.

C++ templates are a perfectly good example of parametric polymorphism.

Bart van Ingen Schenau

unread,
Apr 16, 2004, 11:27:04 AM4/16/04
to
On Fri, 16 Apr 2004 00:46:21 +0000 (UTC), cdig...@videotron.ca
("christopher diggins") wrote:

>"Alberto Barbati" <Alberto...@libero.it> wrote in message
>news:3vtfc.3575$Qc.1...@twister1.libero.it...
>> christopher diggins wrote:
>
>> In this scenario, the most obvious thing, IMHO, is that run() should
>> behaves as-if it where implicitly declared as virtual, that is
>> Derived::run() should be called in all three places. A different
>> behaviour would violate the least-astonishment principle (for most Java
>> programmers at least ;)
>
>If any implementation of Java performs in that manner it is incorrectly
>implemented according to the java virtual machine specification of
>invokeinterface bytecodes:
>
>http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface

That is not how I interpret that specification.
The invokeinterface opcode has as parameter a reference to an object,
and the method to invoke is first looked up in that object and after
that, if it wasn't found, in any base-class of that object.

This suggests to me that an implements relation is inherited by
derived classes in Java.

Bart v Ingen Schenau

christopher diggins

unread,
Apr 16, 2004, 1:39:34 PM4/16/04