You don't need metaprogramming to have this problem.
True, in fact it was an example of a more general idea.

There was also the complaint from some developers that C is
"superior" to C++ because in C++, a method call in a complex class hierarchy can theoretically end up "anywhere", whereas in C, you at least know exactly which function will get called, since there is no
overloading.

That's an extreme opinion, tools are tools, it's not that we always have to operate in the strictest ways possible, but yes I'd say you have to be conscious of the consequences. Nowadays my rule of thumb is to ask myself -do I need this- when thinking of grabbing a given language feature for a given implementation. Do I need a class? What would it give me? If it ends up with considerable savings then go ahead.

Now you discover a bug somewhere in this function. How would you go about finding where it is? Well, since this is C, which allegedly doesn't have any polymorphism, that should be trivial, right? Just trace through all of the function calls and narrow it down. Except... all of those ops.xxx() calls are function pointers. So OK, we need to find out
where they point to.

Yeah... That decision was quite bad (especially today!), as you point out they didn't avoid polymorphism really, just re-implemented it in a language that doesn't support it natively in its type system, and that is often trouble.

That's why I actually am wary of certain forms of metaprogramming, I don't think it's often a good idea to try to extend a language beyond what its syntax natively supports, not only because it surprises people, but also because it will surprise tools and so on...

[...] you only
need to remember add and delete, and the abstraction takes care of itself by resolving to the correct overload based on the argument types.

That is not really OO though or well not what I mean with OO/OOD. The OO that I would avoid is the "thinking in objects" mindset. Associating functions with types is the simplest form of polymorphism and it's totally fine, you don't even need classes for that! But even if you face a problem where you do actually need interfaces over objects, go ahead, I'm not saying it's never useful. But it shouldn't be the "default" state of mind and certainly how to split computation in objects shouldn't be the way we think about solving problems, that's the bad of OO mentality that degenerated into horrors like "patterns". Computation is algorithms that change bits of data.

Metaprogramming goes one step further and lets you reduce boilerplate --

True, I just wanted to show the tradeoff that are entailed in that. Then it can still be useful, but a lot of times is just abused, and many, many times we would be better served by a better type system than having to hack features via metaprogramming.

I would be much more open to generics if we had in C++ bounded parametric types (concepts... or C# style generics) rather than templates. And I would use C++11 lambdas, even if I wouldn't have touched with a mile-long pole the Boost::lambda stuff, and so on...


At the end of the day, *all* tools must be used with care. Even in C, a language with neither OO nor metaprogramming support, you can code yourself into a nasty mess by using built-in language constructs like function pointers, like I showed above. Just because you *can* cause serious injury to yourself with a hammer, doesn't mean that hammers
are inherently evil.

Right, but we live in a world where it seems to me lots of people are hammer happy :)

Reply via email to