The Artima Developer Community
Sponsored Link

Weblogs Forum
Polymorphism without Planning

21 replies on 2 pages. Most recent reply: Feb 9, 2005 10:08 AM by Christopher Diggins

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 21 replies on 2 pages [ 1 2 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Polymorphism without Planning (View in Weblogs)
Posted: Nov 27, 2004 9:31 AM
Reply to this message Reply
Summary
It is commonly assumed that in order to achieve some measure of run-time polymorphism we have to state in a class declaration that it it either implements an interface or it inherits from a base class with virtual functions. Not anymore ...
Advertisement
It is generally assumed that In C++ in order to achieve run-time polymorphic behaviour, we have to inherit from a base class with virtual functions. Java, and other languages also provide us with interfaces, but the classes have to explicitly state their intention to implement the interface.

This is a misconception that a lot of people understandably have when they first hear about the C++ Object Oriented Template Library ( OOTL ). In the September 2004 issue of the C/C++ Users Journal I outline a technique in C++ for implementing interface reference types without requrining changes to existing objects. This technique is used in the upcoming Boost Interfaces Library (BIL) by Jonathan Turkanis. The BIL is not yet ready for a public beta release, but a pre-release version has been included with the OOTL version 0.1.

Given two existing class such as:

  class Faz {
  public:
    int Fu() { return 1; }
    void Bar(int x) { printf("faz %d\n", x); }
  }

  class Baz {
  public:
    int Fu() { return 2; }
    void Bar(int x) { printf("baz %d\n", x); }
  }
The BIL can then be used to express an interface after these classes have been defined elsewhere as follows:
  BOOST_IDL_BEGIN(IFuBar)
    BOOST_IDL_FN0(Fu, int)
    BOOST_IDL_FN1(Bar, void, (int, x))
  BOOST_IDL_END(IFuBar)
You will have to put the blame for the ugly syntax squarely on the shoulders of the C++ design committee, not Jonathan. C++0x will surely enable improved syntax, especially if Jonathan or myself have anything to say about it ( in fact I would like to see interface references gain first class status ). The BOOST_ prefix, is a requirement for consideration in Boost, which clearly is the eventual goal of the BIL.

Once we define this interface, after the fact, we can use it to make Faz and Baz, polymorphic. Consider the following:

  int main{
    faz f;
    baz b;  
    IFuBar i;
    if ((rnd() % 2) == 0) {
      i = f;
    } else {
      i = b;
    }
    i.Bar(i.Fu());
  }
This code snippet prints out either faz 1 or baz 2.

And that's all I have to say about that.


Daniel James

Posts: 4
Nickname: danjames
Registered: Jun, 2004

Re: Polymorphism without Planning Posted: Nov 27, 2004 10:32 AM
Reply to this message Reply
> BOOST_IDL_BEGIN(IFuBar)
> BOOST_IDL_FN0(Fu, int)
> BOOST_IDL_FN1(Bar, void, (int, x))
> BOOST_IDL_END(IFuBar)
>
> You will have to put the blame for the ugly syntax
> squarely on the shoulders of the C++ design committee, not
> Jonathan.

You should probably put the blame on the preprocessor implementors. With a standards compliant preprocessor, it would be possible to do something along the lines of:
BOOST_IDL(IFuBar,
(Fu, (int))
(Bar, (void)(int, x))
)

Actually, it is possible to do that on most existing preprocessors, but it's a lot of work to make it portable.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Polymorphism without Planning Posted: Nov 27, 2004 10:55 AM
Reply to this message Reply
That is quite cool. Would you mind posting the code to do it? I am not well-acquainted with the C++ pre-processor.

Daniel James

Posts: 4
Nickname: danjames
Registered: Jun, 2004

Re: Polymorphism without Planning Posted: Nov 27, 2004 11:18 AM
Reply to this message Reply
Well, I'll have to write it first. But it won't be portable enough for Boost. I couldn't improve on what Jonathan has done.

I'll post some code soonish but it'll probably be only for standards compliant preprocessors like gcc and wave.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Polymorphism without Planning Posted: Nov 27, 2004 2:53 PM
Reply to this message Reply
Even if it isn't portable, I would like to be able to describe alternatives approaches, so this code would be a valuable contribution to the community.

Daniel James

Posts: 4
Nickname: danjames
Registered: Jun, 2004

Re: Polymorphism without Planning Posted: Nov 28, 2004 1:51 AM
Reply to this message Reply
OK, here it is:

http://www.calamity.org.uk/code/il.cpp

Just add the macro stuff to your existing library and it should work (on gcc that is). Pretty ugly though.

Here's an alternative version which uses Paul Mensonides' chaos library. It requires a fully compliant C99 preprocessor (for variadics). This allows for a much nicer syntax and a simpler implementation. Although I'm not sure whether I'm using chaos correctly.

http://www.calamity.org.uk/code/il_chaos.cpp

Chaos is available via CVS from its sourceforge project at:

http://sourceforge.net/projects/chaos-pp

Neither version deals with const functions, but I think they could be added a pretty decent manner.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Polymorphism without Planning Posted: Nov 28, 2004 3:54 AM
Reply to this message Reply
There was a series of papers about structural typing in Java in the middle 90s. Laufer's 'Safe Structural Conformance for Java' and Weck's 'Compound Types' papers are good reads.

Chris, you should put some code examples on your site. The implementation-oriented one in your article does a great job of explaining "how it works."

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Polymorphism without Planning Posted: Nov 28, 2004 9:11 AM
Reply to this message Reply
> There was a series of papers about structural typing in
> Java in the middle 90s. Laufer's 'Safe Structural
> Conformance for Java' and Weck's 'Compound Types' papers
> are good reads.

I am not familiar with structural typing, is it the same thing as what I propose?

> Chris, you should put some code examples on your site.
> The implementation-oriented one in your article does a
> a great job of explaining "how it works."

Thanks for the suggestion. Is the example such as: http://www.ootl.org/src/object-test.hpp an example of what you would be looking for?

Marcin Kowalczyk

Posts: 40
Nickname: qrczak
Registered: Oct, 2004

Re: Polymorphism without Planning Posted: Nov 28, 2004 3:24 PM
Reply to this message Reply
> It is generally assumed that In C++ in order to achieve
> run-time polymorphic behaviour, we have to inherit from a
> base class with virtual functions. Java, and other
> languages also provide us with interfaces, but the classes
> have to explicitly state their intention to implement the
> interface.

In C++ and Java - indeed. But most dynamically typed languages, and among statically typed: OCaml, Haskell, Clean and Mercury, already allow to have a common interface for multiple types with no need of declarations at the point of definition of the types. It's not a new idea.

GNU C++ used to have an extension with this property, called signatures. It has been recently removed because people weren't using it, the original author was no longer interested in maintaining it, nobody else wanted to maintain it, and interfered with further development.

Jonathan Turkanis

Posts: 3
Nickname: jdt
Registered: Nov, 2004

Re: Polymorphism without Planning Posted: Nov 28, 2004 4:27 PM
Reply to this message Reply
Right now, our target platforms are VC7.1, Intel 8.0, GCC 3.4 and Comeau 4.3.3. VC7.1 is the problem child -- not just with respect to the preprocessor.

I haven't had a chance to think about it yet, but being able to use the syntax

BOOST_IDL(IFuBar,
(Fu, (int))
(Bar, (void)(int, x))
)

may allow me to simpify the implementation considerably, since it will allow the code currently generated by the function declaration macros to dovetail.

Thanks!

I'll let you know how it turns out.

Jonathan

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Polymorphism without Planning Posted: Nov 29, 2004 12:07 AM
Reply to this message Reply
Marcin, I would ask if you would please refrain from making any more comments on my blog and discussion group. I have been very patient, but your comments are consistently negative, irrelevant and unwelcome.

Ravi Venkataraman

Posts: 80
Nickname: raviv
Registered: Sep, 2004

Re: Polymorphism without Planning Posted: Nov 29, 2004 6:10 AM
Reply to this message Reply
Hi Christopher,

Could you please let us know what blog you are referring to in the message to Marcin?

I would like to view articles and comments by Marcin to judge for myself.

Ravi

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Polymorphism without Planning Posted: Nov 29, 2004 7:40 AM
Reply to this message Reply
> > There was a series of papers about structural typing in
> > Java in the middle 90s. Laufer's 'Safe Structural
> > Conformance for Java' and Weck's 'Compound Types'
> papers
> > are good reads.
>
> I am not familiar with structural typing, is it the same
> thing as what I propose?

It is typing based on structural equivalence. class A { int a(); } and class B { int a(); } could both be passed to a context accepting something that needs an a().

A bit different from what you are proposing, but it seems to rely on it. I've long thought it was interesting that structural equivalence typing was considered very bad in the heyday of language development. I think there is even in an admonishment in K&R, but then they were talking about data predominately. Later, templates come along and 'structural equivalence' wins. The rationale is that it is okay because templates always resolve to strongly typed code in the base language, C++.


> > Chris, you should put some code examples on your site.
> > The implementation-oriented one in your article does a
> > a great job of explaining "how it works."
>
> Thanks for the suggestion. Is the example such as:
> http://www.ootl.org/src/object-test.hpp an example of what
> you would be looking for?

Actually, I was thinking of the implementation code. I see you put it up yesterday in the CodeProject? That snippet of code that shows how someone would hand-code an interface. When I first your articles, I kept thinking "okay, he has to be using function pointers. If he's not, there is some way to resolve using templates that I don't know yet." Had to wait until I got home to find your article and understand what the approach was.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Polymorphism without Planning Posted: Nov 29, 2004 7:49 AM
Reply to this message Reply
> In C++ and Java - indeed. But most dynamically typed
> languages, and among statically typed: OCaml, Haskell,
> Clean and Mercury, already allow to have a common
> interface for multiple types with no need of declarations
> at the point of definition of the types. It's not a new
> idea.

I've wondered quite a bit how aware many in the C++ template community were of the ML languages. Seems like the key difference is that people in that community seem to always bring things back to a declared type rather than allowing free structural matching like we have with C++ templates. C++ tenplates are sort of compile-time 'duck typing.'

> GNU C++ used to have an extension with this property,
> called signatures. It has been recently removed because
> people weren't using it, the original author was no longer
> interested in maintaining it, nobody else wanted to
> maintain it, and interfered with further development.

That looks like what Chris is talking about. Is that it, Chris? It would be neat to see what the author thinks of it now. It is funny. Sometimes the time isn't right or something needs to be championed differently.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Polymorphism without Planning Posted: Nov 29, 2004 9:21 AM
Reply to this message Reply
> I've wondered quite a bit how aware many in the C++
> template community were of the ML languages. Seems like
> the key difference is that people in that community seem
> to always bring things back to a declared type rather than
> allowing free structural matching like we have with C++
> templates. C++ tenplates are sort of compile-time 'duck
> typing.'

The interfaces technique now allows a more explicit and rigorous typing that can't be easily achieved with templates alone.

> > GNU C++ used to have an extension with this property,
> > called signatures. It has been recently removed because
> > people weren't using it, the original author was no
> longer
> > interested in maintaining it, nobody else wanted to
> > maintain it, and interfered with further development.
>
> That looks like what Chris is talking about. Is that it,
> Chris?

It is pretty much the same thing as far as I know, except I am doing it in compliant C++, not as a language extension. I don't know how the implementation went for the Signatures feature.

> It would be neat to see what the author thinks of
> it now. It is funny. Sometimes the time isn't right or
> something needs to be championed differently.

That is true. I think the reason the old extension was dropped for several reasons:
1) language extensions are ignored by the majority of software developers in favour of writing portable code
2) people lack the imagination to see how techniques can be used. This is a big reason why the OOTL exists, as a proof of concept of the BIL.

Flat View: This topic has 21 replies on 2 pages [ 1  2 | » ]
Topic: How to think like a Jinition Previous Topic   Next Topic Topic: Agile C++?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use