-
Polymorphism and Strong Typing
2003-05-08 17:58 in /books/mcppd
A continutation from where I left off last night...
The mind-boggling nature of this (optional interface features without ugly type checks or exceptions) isn't the fact that you can do it. Perl and Smalltalk programmers are immediately familiar with this form of polymorphism (interface polymorphism) (and the associated runtime errors when you screw up). Lispers would say, "Variables don't (shouldn't) have types, values have types". However, strongly typed languages like Java and C++ usually lock you into inheritance polymorphism. (Despite Java's use of the term "interface", it does not imply the same flexibility.) The magic here is interface polymorphism with compile-time type checking.
At some point I'll have to think more about type-inferring languages like OCaml and how exactly things work there. I'm not sure if that compiler will allow you the same flexibility and safety as the C++ template technique.
(Side note to all this: When did I become a language geek?)
-
Modern C++ Design
2003-05-08 00:06 in /books/mcppd
I'm starting to read Modern C++ Design as part of the ALACPP group. It's a bit of an adventure given that my C++ experience is limited to a couple quarters in school.
We're reading the first chapter for tomorrow, which is an intro to advanced generics/templates using the concept of policies. I haven't quite grokked it fully, but I'm starting to get an idea of where this technique fits in.
The shortcomings of simple multiple inheritance are well-known. It's brittle and doesn't scale well, nor is it flexible enough to really deal with non-trivial interweaving of the constituents.
Standard pattern-based OO design generally prescribes composition rather than inheritance to acheive flexibility and scalability. At a first glance, policies look a lot like the Strategy pattern. However, the differences are the interesting bit.
First, and probably least importantly, the syntax is more concise for templated policies that for setting a bunch of strategies. Also, C++ typedefs can simplify your life, although factory methods are essentially semantically equivalent, if a litte more verbose.
Second, templates provide compile-time type safety, which isn't present with a strategy. This means that you can't accidentally assign a single-threaded instance of your class where you really needed a multi-threaded design, because the compiler will give a error. Also, because templates provide compile-time binding, there are performance benefits. The tradeoff is a slight loss of flexibility aas you can't change a policy in the course of execution the way you can a strategy. (Actually, this is not quite true. Alexandrescu talks a little bit about how to specify allowed type conversions between policies, but I haven't managed to absorb that section yet.)
The most intriguing difference to me at this point is way that you can deal with optional features of the policy. In a language like Java (pre-generics) you have to deal with this in one of two ways. Either you include optional methods in your policy interface and permit the hated UnsupportedOperationException, or you stick the optional methods into a subinterface and deal with a lot of "instanceof" checks, which also tend to make people ill.
However, two features of C++ make another option availible. First, the enhanced compile-time typing means that the runtime UnsupportedOperationExceptions turn into compiler errors. Second, the compiler doesn't actually enforce type-checking on methods which are never used! So, you can include methods which rely on optional features of a policy, but if a user of your class configures it with a policy that doesn't support them but doesn't use those methods of your class either, the compiler doesn't complain! Conversely, if they use a methods which relies on a feature their choice of policy doesn't allow, that is a compile-time error.
That's pretty wild. I'm not sure if I like it, but it's definitely a little mind-boggling.
Leave a comment
Please use plain text only. No HTML tags are allowed.