Interfaces Library, a macro less implementation

Hi, I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/ I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not. Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO. Here's a client side example: struct foo : member_function<int(int)> {}; struct bar : member_function<int(char const*)> {}; // a baz "interface" class baz : interface<foo, bar> { public: template <class T> baz(T& x) : construct(x) {} int foo(int x) { return this->call< ::foo>(x); } int bar(char const* x) { return this->call< ::bar>(x); } }; struct some_baz { int impl(foo, int x) { return x + 1; } int impl(bar, char const* s) { return std::strlen(s); } }; struct another_baz { int impl(foo, int x) { return x - 1; } int impl(bar, char const* s) { return -std::strlen(s); } }; int main() { some_baz f; baz p = f; std::cout << "p.foo(3) = " << p.foo(3) << std::endl; std::cout << "p.bar(\"hi\") = " << p.bar("hi") << std::endl; another_baz f2; p = f2; std::cout << "p.foo(3) = " << p.foo(3) << std::endl; std::cout << "p.bar(\"hi\") = " << p.bar("hi") << std::endl; } Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net #include <iostream> #include <string> #include <cstring> #include <boost/spirit/fusion/sequence/tuple.hpp> #include <boost/spirit/fusion/sequence/at.hpp> using namespace boost::fusion; template <class Sig> struct member_function; template <class RT, class A0> struct member_function<RT(A0)> { typedef RT return_type; typedef A0 arg0_type; typedef RT(*pointer_type)(void*, A0); }; template <class F0, class F1> struct interface { typedef tuple< typename F0::pointer_type , typename F1::pointer_type> vtable_type; template <class T> struct functions { template <typename F> struct forward { typedef typename F::return_type return_type; typedef typename F::arg0_type arg0_type; static return_type call(void* p, arg0_type x) { return static_cast<T*>(p)->impl(F(), x); } }; static typename interface<F0, F1>::vtable_type const* table() { static typename interface<F0, F1>::vtable_type vtable( &forward<F0>::call , &forward<F1>::call); return &vtable; // a singleton } }; template <class T> interface(T& x) : vtable(functions<T>::table()) , obj(&x) {} typedef interface<F0, F1> construct; typename boost::fusion::meta::at_c<vtable_type const, 0>::type find(F0) const { return boost::fusion::at<0>(*vtable); } typename boost::fusion::meta::at_c<vtable_type const, 1>::type find(F1) const { return boost::fusion::at<1>(*vtable); } template <typename F> typename F::return_type call(typename F::arg0_type x) { return find(F())(const_cast<void*>(obj), x); } vtable_type const* vtable; void const* obj; }; /////////////////////////////////////////////////////////////// // // Client Code // /////////////////////////////////////////////////////////////// struct foo : member_function<int(int)> {}; struct bar : member_function<int(char const*)> {}; // a baz "interface" class baz : interface<foo, bar> { public: template <class T> baz(T& x) : construct(x) {} int foo(int x) { return this->call< ::foo>(x); } int bar(char const* x) { return this->call< ::bar>(x); } }; struct some_baz { int impl(foo, int x) { return x + 1; } int impl(bar, char const* s) { return std::strlen(s); } }; struct another_baz { int impl(foo, int x) { return x - 1; } int impl(bar, char const* s) { return -std::strlen(s); } }; int main() { some_baz f; baz p = f; std::cout << "p.foo(3) = " << p.foo(3) << std::endl; std::cout << "p.bar(\"hi\") = " << p.bar("hi") << std::endl; another_baz f2; p = f2; std::cout << "p.foo(3) = " << p.foo(3) << std::endl; std::cout << "p.bar(\"hi\") = " << p.bar("hi") << std::endl; }

"Joel de Guzman" <joel@boost-consulting.com> wrote
I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not.
"Ugly macros", here we go again ;-)
Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO.
So why a solution that clearly involves repeating things multiple times is less ugly than a macro-based approach, that allows to avoid duplication?
Here's a client side example:
struct foo : member_function<int(int)> {}; struct bar : member_function<int(char const*)> {};
// a baz "interface" class baz : interface<foo, bar> { public:
template <class T> baz(T& x) : construct(x) {}
int foo(int x) { return this->call< ::foo>(x); }
And, in a little bit more involved case: int foo(int x, string y, double z, char* psz1, char* psz2) { return this->call< ::foo>(x, y, z, psz2, psz1); } // Oops, unintended behavior!
...
IMHO, the fact that interfaces are currently built with code generators (IDL) speaks for using yet another code generator, which is a macro mechanism. And, even though I havn't really looked at the Interfaces Library close enough, I totally support the general idea of using macros for interfaces. Regards, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message news:da11a6$k4a$1@sea.gmane.org...
"Joel de Guzman" <joel@boost-consulting.com> wrote
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not. Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO.
WOW! That's very impressive! How is the run-time and compile-time performance?
So why a solution that clearly involves repeating things multiple times is less ugly than a macro-based approach, that allows to avoid duplication?
He is entitled to his opinion, Arkadiy. Your comments are disparaging and disrespectful of his contribution. Furthermore if Joel's approach pans out (I haven't studied it in depth yet) we may be able to merge the two approaches, and build a more compile-time efficient macro based IDL which maps to Joel's approach, thus leading to the best of both worlds, and the ability for the end-user to choose whichever they prefer. Structural subtyping (implicit interface implementation) is the lynchpin of the Heron programming language design, but as of yet has remained unimplemented. This may make it much easier for me to finish a Heron to C++ translator, so I am particularly interested in Joel's work! Keep up the superlative work Joel. -- Christopher Diggins http://www.cdiggins.com

"christopher diggins" <cdiggins@videotron.ca> wrote
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message
So why a solution that clearly involves repeating things multiple times is less ugly than a macro-based approach, that allows to avoid duplication?
He is entitled to his opinion, Arkadiy. Your comments are disparaging and disrespectful of his contribution.
I didn't mean to be disrespectful, and I don't think I was, but I do apologize if it sounded like this... But I am also entitled to my opinion, and this opinion is that any solution that doesn't involve duplication is, by definition, cleaner than one that does. Firthermore, I do think that the goal of eliminating macros for the sake of eliminating macros is not a right goal. Therefore, while deeply respecting the author of this proposal, I simply think, based on his motivation, that this is a step in the wrong direction. I may be wrong, of course. Regards, Arkadiy

Arkadiy Vertleyb wrote:
"christopher diggins" <cdiggins@videotron.ca> wrote
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message
So why a solution that clearly involves repeating things multiple times is less ugly than a macro-based approach, that allows to avoid duplication?
He is entitled to his opinion, Arkadiy. Your comments are disparaging and disrespectful of his contribution.
I didn't mean to be disrespectful, and I don't think I was, but I do apologize if it sounded like this...
But I am also entitled to my opinion, and this opinion is that any solution that doesn't involve duplication is, by definition, cleaner than one that does. Firthermore, I do think that the goal of eliminating macros for the sake of eliminating macros is not a right goal. Therefore, while deeply respecting the author of this proposal, I simply think, based on his motivation, that this is a step in the wrong direction.
No offense taken :) I understand your position. I am not against macros per se. I use macros all the time now if it's clearly the best solution to a particular problem. I have voted for Eric Niebler's FOR_EACH, for instance. I believe it (FOR_EACH) is the best solution given the limited tools we have for solving the matter at hand. With BIL, I am not quite sure... Here's my rationale for the macro-less Interfaces: 1) An interface is supposed to be read a lot of times. It has to be immediately understandable to the human parser. It is not an implementation detail. It is a contract. 2) I need one that can be parsable by a documentation extraction tool such as Doxygen and Synopsis. This is very important! Interfaces need to be documented. 3) You can have both! If you still insist on using macros, then by all means, use them. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Hi Joel, Joel de Guzman wrote:
Here's my rationale for the macro-less Interfaces:
1) An interface is supposed to be read a lot of times. It has to be immediately understandable to the human parser. It is not an implementation detail. It is a contract.
I totally agree.
2) I need one that can be parsable by a documentation extraction tool such as Doxygen and Synopsis. This is very important! Interfaces need to be documented.
Well, as far as synopsis is concerned I think it can be trained to understand macros quite well, in particular with its new boost.wave backend. :-) So *that* shouldn't be a reason not to use macros. Regards, Stefan

On Fri, 01 Jul 2005 06:50:36 +0800, Joel de Guzman wrote
Here's my rationale for the macro-less Interfaces:
1) An interface is supposed to be read a lot of times. It has to be immediately understandable to the human parser. It is not an implementation detail. It is a contract.
It's the human parser that's the real problem -- no question ;-) To quote myself from Feb of this year: "Also, I really hate macros for doing these sorts of things because I have to reverse engineer what the macro is doing when I need to read the code. At a minimum that means I need to go to another file, try and grok whether the macro applies to what I'm doing, mentally add in whatever functions/types it creates. I'm getting too old for these sorts of mental gymnastics -- I'd rather have the code just written out." http://lists.boost.org/boost/2005/02/21082.php I'd add to this that THE ALL CAPS STUFF IN CODE GETS REALLY TIRESOME TO READ MAKING CODE LOOK UGLY in my view. Of course macros don't technically "have to be all caps", but well they mostly are to prevent more serious problems.
2) I need one that can be parsable by a documentation extraction tool such as Doxygen and Synopsis. This is very important! Interfaces need to be documented.
These can be expanded before processing, although last I knew some debuggers have problems dealing with macros. Certainly tool vendors have said one reason they can't easily implement C++ tools (like say refactoring tools) is b/c of complications created by macros in C++.
3) You can have both! If you still insist on using macros, then by all means, use them.
Having the option is exactly the right approach -- when feasible. I'm really interested in Boost.Interfaces -- this looks like an incredibly cool design approach, but I, like you, would be put off by the need to use lots of macros in application code. So thx Joel! Jeff

Hi Joel, Joel de Guzman wrote:
I am not against macros per se. I use macros all the time now if it's clearly the best solution to a particular problem.
Allow me a curious question for that matter: What's the rationale for using huge macros in combination with REPEAT_FROM_TO in the Fusion source code (instead of using no macros and ITERATE)? Please don't get me wrong: it's not my intention to complain about one of your remarkably great (no irony) libraries here (and I don't care as its user). I'm having some difficulties to understand how the ugliest way to use macros can be the best solution to that particular problem, though. Regards, Tobias

Tobias Schwinger wrote:
Hi Joel,
Joel de Guzman wrote:
I am not against macros per se. I use macros all the time now if it's clearly the best solution to a particular problem.
Allow me a curious question for that matter:
What's the rationale for using huge macros in combination with REPEAT_FROM_TO in the Fusion source code (instead of using no macros and ITERATE)?
Please don't get me wrong: it's not my intention to complain about one of your remarkably great (no irony) libraries here (and I don't care as its user). I'm having some difficulties to understand how the ugliest way to use macros can be the best solution to that particular problem, though.
Laziness? :-) This has changes now in the new Fusion-2 now sitting in my HD. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
This has changes now in the new Fusion-2 now sitting in my HD.
Then it'll read like a novel just like the rest inside the Spirit folder... Is Fusion-1 already part of the current Boost distribution? What is the recommended phrasing when referring to it in library documentation? Is there an URL for a hyperlink? Thanks, Tobias

Tobias Schwinger wrote:
Joel de Guzman wrote:
This has changes now in the new Fusion-2 now sitting in my HD.
Then it'll read like a novel just like the rest inside the Spirit folder...
:) oh my... thanks!
Is Fusion-1 already part of the current Boost distribution?
ATM, Fusion is a sub-library under Spirit. It's been there since 1.31. I do intend to ask for a formal review as soon as Fusion-2 is ready.
What is the recommended phrasing when referring to it in library documentation?
I think it's appropriate to simply call it Fusion.
Is there an URL for a hyperlink?
Sorry, no. Let me see if I can fix that problem. For the moment, the best I have is http://www.boost.org/libs/spirit/fusion/readme.txt. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Arkadiy Vertleyb wrote:
"christopher diggins" <cdiggins@videotron.ca> wrote
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message
So why a solution that clearly involves repeating things multiple times is less ugly than a macro-based approach, that allows to avoid duplication?
He is entitled to his opinion, Arkadiy. Your comments are disparaging and disrespectful of his contribution.
I didn't mean to be disrespectful, and I don't think I was, but I do apologize if it sounded like this...
But I am also entitled to my opinion, and this opinion is that any solution that doesn't involve duplication is, by definition, cleaner than one that does. Firthermore, I do think that the goal of eliminating macros for the sake of eliminating macros is not a right goal. Therefore, while deeply respecting the author of this proposal, I simply think, based on his motivation, that this is a step in the wrong direction.
I replied to this, clicked the send button, and it vanished through thin air. I do not know why. Maybe it's early in the moring and I haven't had coffee yet :). If this is a duplicate, please pardon me. I have to re-write this again. The previous one can not be found in my sent box. Oh life!... No offense taken, Arkadiy. I understand your position. Please don't get me wrong. I am not against macros per se. I use macros all the time if it is the best solution for a given task at hand. I voted for FOR_EACH, for example. I believe it is the best solution given the limited tools we have at our disposal. For BIL, I am not quite sure. Here is my rationale: 1) Interfaces need to be immediately understandable. You read them all the time. It is a contract. By "immediately understandable", I mean something very close to plain C++ member function syntax. 2) Interfaces need to be documented. They need to be parsable by an automatic documentation extraction tool such as Doxygen or Synopsis. 3) You can have both. If you really insist on the macros, then there's no reason why you can't have them. actually, thinking about it now, there's a 4th one which is related to the implementation: 4) Introspection. The implementation allows you to inspect an interface if it has a particular member function and what it's return type and arguments are. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
2) Interfaces need to be documented. They need to be parsable by an automatic documentation extraction tool such as Doxygen or Synopsis.
I don't know about Synopsis, but with Doxygen which I use for documenting my code. In my interfaces, mentioned long ago, macro IDL I just define the appropriate macros so that during documentation parsing things expand out to simple method declarations. Is that an acceptable avenue in your view? -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - Grafik/jabber.org

Rene Rivera wrote:
Joel de Guzman wrote:
2) Interfaces need to be documented. They need to be parsable by an automatic documentation extraction tool such as Doxygen or Synopsis.
I don't know about Synopsis, but with Doxygen which I use for documenting my code. In my interfaces, mentioned long ago, macro IDL I just define the appropriate macros so that during documentation parsing things expand out to simple method declarations.
Is that an acceptable avenue in your view?
I suppose so, yes. Stefan also noted that Synopsos can also be trained to understand macros. But what about other tools? How about UML tools? Refactoring tools? Others, etc? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes:
Rene Rivera wrote:
Joel de Guzman wrote:
2) Interfaces need to be documented. They need to be parsable by an automatic documentation extraction tool such as Doxygen or Synopsis.
I don't know about Synopsis, but with Doxygen which I use for documenting my code. In my interfaces, mentioned long ago, macro IDL I just define the appropriate macros so that during documentation parsing things expand out to simple method declarations.
Is that an acceptable avenue in your view?
I suppose so, yes. Stefan also noted that Synopsos can also be trained to understand macros.
IIUC, he noted that no training is needed because the preprocessor expands the macros before the rest of Synopsis sees them.
But what about other tools? How about UML tools? Refactoring tools? Others, etc?
The all need a Wave front-end ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
Rene Rivera wrote:
Joel de Guzman wrote:
2) Interfaces need to be documented. They need to be parsable by an automatic documentation extraction tool such as Doxygen or Synopsis.
I don't know about Synopsis, but with Doxygen which I use for documenting my code. In my interfaces, mentioned long ago, macro IDL I just define the appropriate macros so that during documentation parsing things expand out to simple method declarations.
Is that an acceptable avenue in your view?
I suppose so, yes. Stefan also noted that Synopsos can also be trained to understand macros.
IIUC, he noted that no training is needed because the preprocessor expands the macros before the rest of Synopsis sees them.
<quote> as far as synopsis is concerned I think it can be trained to understand macros quite well </quote>
But what about other tools? How about UML tools? Refactoring tools? Others, etc?
The all need a Wave front-end ;-)
Ok. Fair enough :-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

David Abrahams wrote:
Joel de Guzman <joel@boost-consulting.com> writes:
I suppose so, yes. Stefan also noted that Synopsos can also be trained to understand macros.
IIUC, he noted that no training is needed because the preprocessor expands the macros before the rest of Synopsis sees them.
It all depends on what you want to do. Macros are already recognized and 'un-preprocessed' for code cross-referencing, but there is a lot more that could be done to treat macros as first-class citizens in the abstract syntax tree. There are a number of issues that I hope to be able to sort out when officially switching to wave. Regards, Stefan

christopher diggins wrote:
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message news:da11a6$k4a$1@sea.gmane.org...
"Joel de Guzman" <joel@boost-consulting.com> wrote
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not. Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO.
WOW! That's very impressive!
Hey, thanks!
How is the run-time and compile-time performance?
Run-time = same; uses the same techniques, but places the function pointers in a tuple so I can inspect them. compile-time = uses tuples. Compared to the quick prototype you wrote (based on Dave A?) for which this is based, this is definitely heavier (more abstractions). But not much, compared to, say, spirit, or phoenix.
Structural subtyping (implicit interface implementation) is the lynchpin of the Heron programming language design, but as of yet has remained unimplemented. This may make it much easier for me to finish a Heron to C++ translator, so I am particularly interested in Joel's work!
Keep up the superlative work Joel.
Oh you too of course! :) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Hi,
I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not.
I agree that the current macro-based IDL is hard to read. There have been some good suggestion on this about improving it, however. Have you looked at the template-based IDL: http://tinyurl.com/6w59y? I haven't implemented it yet, but it's at the top of my list. I've also been looking for a way to redesign the protocol so that hand-written interfaces will be resonable intelligible, but I haven't had much luck; it looks like you may have solved this.
Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO.
It looks very promising! I'll won't have a chance to examine it in detail until at least tomorrow. Jonathan

Jonathan Turkanis wrote:
Joel de Guzman wrote:
Hi,
I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not.
I agree that the current macro-based IDL is hard to read. There have been some good suggestion on this about improving it, however. Have you looked at the template-based IDL: http://tinyurl.com/6w59y? I haven't implemented it yet, but it's at the top of my list.
No I have not. That interface looks very readable indeed! I think that interface can map to the prototype I posted. It does not satisfy one of my requirements though: to be parsable by auto-documentation extraction tools like Doxygen and Synopsis.
I've also been looking for a way to redesign the protocol so that hand-written interfaces will be resonable intelligible, but I haven't had much luck; it looks like you may have solved this.
Here's another take (prototype) at a macro less implementation of the interfaces (see attached). Tested on VC7.1, g++ and Comeau. The biggest advantage is that the same C++ member function interface syntax is retained. This makes it very easy to understand and even allows documentation extraction tools like Doxygen to work as usual. A disadvantage is that there is some unavoidable redundancy-- a lesser price to pay, IMO.
It looks very promising! I'll won't have a chance to examine it in detail until at least tomorrow.
Feel free to take whatever you find useful :) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Hi,
I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not.
Have you seen the suggestions for a better macro IDL? For instance: BOOST_INTERFACE( baz, (int, foo, (int)) (int, bar, (char const*)) ) IMO that's quite readable. -- Daniel Wallin

Daniel Wallin wrote:
Joel de Guzman wrote:
Hi,
I like the idea behind the Interfaces Library: http://www.kangaroologic.com/interfaces/
I need one now. I dislike the macro-based Interface Definition Language, however. I find it utterly ugly especially because interfaces should be immediately readable. IMO, the macro-based IDL is not.
Have you seen the suggestions for a better macro IDL? For instance:
No.
BOOST_INTERFACE( baz, (int, foo, (int)) (int, bar, (char const*)) )
IMO that's quite readable.
Indeed. They're ok. Not as pretty as real C++ member functions, but ok. Is there a prototype? Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
struct some_baz { int impl(foo, int x) { return x + 1; } int impl(bar, char const* s) { return std::strlen(s); } };
With Jonathan's library this would be: struct some_baz { int foo(int x) { return x + 1; } int bar(char const* s) { return std::strlen(s); } }; A major advantage in my opinion. I think it also supports overloads. Daniel

Daniel James wrote:
Joel de Guzman wrote:
struct some_baz { int impl(foo, int x) { return x + 1; } int impl(bar, char const* s) { return std::strlen(s); } };
With Jonathan's library this would be:
struct some_baz { int foo(int x) { return x + 1; } int bar(char const* s) { return std::strlen(s); } };
A major advantage in my opinion. I think it also supports overloads.
Oooh, I didn't notice that. For me, that's a killer. I definitely want interfaces to be compatible with existing classes, such as containers and iterators. I'm even hoping to allow interfaces to declare non-member functions and allow instances to bind to non-class types. I still haven't had time to think about Joel's proposal. However, I did spend consider effort at one point trying to support simple handwritten interfaces using ordinary member function syntax, and convinced myself that it was probably not possible. This might be because I had stronger requirements than Joel, though. Among other things, I required: 1. support for derived interfaces, including MI 2. interface instance, including those involving MI, should have the size of a struct conatining two pointers (assuming the degree of EBO currently provided by most compilers) 3. It should be possible to define a const view const_view<IBar> of an interface, in which non-const functions are disabled. (Ordinary const-qualification is insufficient, since you can make a non-const copy of a const interface instance) 4. Implicit derived-to-base and non-const-to-const conversions 5. Support for aspect oriented programming. For 2 and 5 -- at least -- I concluded that interfaces need to contain a nested rebind-like structure which allows them to be reinstantiated with different base classes. Since it's redundant to implement an interface's infrastructure twice, I put the rebind stuff in a helper class, and made the actual interface derive from an appropriate specialization of rebind. I was unable to find any way for users to write this stuff by hand without going insane. The template-based IDL looks like it is potentially the most usable. The only open question is whether compile-times will suffer unduly. Jonathan

Jonathan Turkanis wrote:
I still haven't had time to think about Joel's proposal. However, I did spend consider effort at one point trying to support simple handwritten interfaces using ordinary member function syntax, and convinced myself that it was probably not possible. This might be because I had stronger requirements than Joel, though. Among other things, I required:
1. support for derived interfaces, including MI 2. interface instance, including those involving MI, should have the size of a struct conatining two pointers (assuming the degree of EBO currently provided by most compilers) 3. It should be possible to define a const view const_view<IBar> of an interface, in which non-const functions are disabled. (Ordinary const-qualification is insufficient, since you can make a non-const copy of a const interface instance) 4. Implicit derived-to-base and non-const-to-const conversions 5. Support for aspect oriented programming.
Those are very good requirements.
For 2 and 5 -- at least -- I concluded that interfaces need to contain a nested rebind-like structure which allows them to be reinstantiated with different base classes. Since it's redundant to implement an interface's infrastructure twice, I put the rebind stuff in a helper class, and made the actual interface derive from an appropriate specialization of rebind. I was unable to find any way for users to write this stuff by hand without going insane.
The template-based IDL looks like it is potentially the most usable.
Given your requirements, I have to agree. Daniel Wallin's macro based suggestion is also quite readable. The question now is: when will they be implemented?
The only open question is whether compile-times will suffer unduly.
That will only be answered when an implementation becomes available. In the meantime, I'll see if I can get another shot at it following your requirements. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Jonathan Turkanis wrote:
I still haven't had time to think about Joel's proposal. However, I did spend consider effort at one point trying to support simple handwritten interfaces using ordinary member function syntax, and convinced myself that it was probably not possible. This might be because I had stronger requirements than Joel, though. Among other things, I required:
1. support for derived interfaces, including MI 2. interface instance, including those involving MI, should have the size of a struct conatining two pointers (assuming the degree of EBO currently provided by most compilers) 3. It should be possible to define a const view const_view<IBar> of an interface, in which non-const functions are disabled. (Ordinary const-qualification is insufficient, since you can make a non-const copy of a const interface instance) 4. Implicit derived-to-base and non-const-to-const conversions 5. Support for aspect oriented programming.
Those are very good requirements.
Okay, good.
For 2 and 5 -- at least -- I concluded that interfaces need to contain a nested rebind-like structure which allows them to be reinstantiated with different base classes. Since it's redundant to implement an interface's infrastructure twice, I put the rebind stuff in a helper class, and made the actual interface derive from an appropriate specialization of rebind. I was unable to find any way for users to write this stuff by hand without going insane.
The template-based IDL looks like it is potentially the most usable.
Given your requirements, I have to agree. Daniel Wallin's macro based suggestion is also quite readable. The question now is: when will they be implemented?
I thought it would be done by now, but as usual I'm a bit behind schedule. The interfaces library is definitely my most fun project, so I'm looking forward to working on it soon. Right now, I'm working on a book which is supposed to be done in less than three weeks.
The only open question is whether compile-times will suffer unduly.
That will only be answered when an implementation becomes available. In the meantime, I'll see if I can get another shot at it following your requirements.
I wish you the best of luck ;-) Jonathan
participants (11)
-
Arkadiy Vertleyb
-
christopher diggins
-
Daniel James
-
Daniel Wallin
-
David Abrahams
-
Jeff Garland
-
Joel de Guzman
-
Jonathan Turkanis
-
Rene Rivera
-
Stefan Seefeld
-
Tobias Schwinger