Wednesday, September 10, 2014

The Heterogeneity of C++


This is a very general observation, and no wondrous coding revelation, but when I read what Scott Meyers had added to the beginning of The Third Edition of Effective C++, I noticed a certain parallel with the "staged" approach in Jeff Alger's C++ for Real Programmers (previously titled Secrets of the C++ Masters).

What that seemed to emphasise was the heterogeneity of C++, a characteristic of the language itself, perhaps an immaturity, but assuredly a certain "patchwork" quality in its construction, and one that endures through ISO/IEC 14882:1998, which was then amended by the C++03, ISO/IEC 14882:2003, standard, called C++0x until that standard was finalised as C++11 and what is/will be C++14.

Scott Meyers calls this variety of approaches to C++ "a federation of languages," as we see in the Third Edition's first item:

Item 1: View C++ as a federation of languages (Scott Meyers, "Effective C++, 3rd ed." ISBN-13: 978-0-321-33487-9)

The easiest way is to view C++ not as a single language but as a federation of related languages. Within a particular sublanguage, the rules tend to be simple, straightforward, and easy to remember. When you move from one sublanguage to another, however, the rules may change. To make sense of C++, you have to recognize its primary sub-languages. Fortunately, there are only four:

    • C. Way down deep, C++ is still based on C. Blocks, statements, the preprocessor, built-in data types, arrays, pointers, etc., all come from C. In many cases, C++ offers approaches to problems that are superior to their C counterparts (e.g., see Items 2 (alternatives to the preprocessor) and 13 (using objects to manage resources)), but when you find yourself working with the C part of C++, the rules for effective programming reflect C’s more limited scope: no templates, no exceptions, no overloading, etc.

    • Object-Oriented C++. This part of C++ is what C with Classes was all about: classes (including constructors and destructors), encapsulation, inheritance, polymorphism, virtual functions (dynamic binding), etc. This is the part of C++ to which the classic rules for object-oriented design most directly apply.

    • Template C++. This is the generic programming part of C++, the one that most programmers have the least experience with. Template considerations pervade C++, and it’s not uncommon for rules of good programming to include special template-only clauses (e.g., see Item 46 on facilitating type conversions in calls to template functions). In fact, templates are so powerful, they give rise to a completely new programming paradigm, template metaprogramming (TMP). Item 48 provides an overview of TMP, but unless you're a hard-core template junkie, you need not worry about it. The rules for TMP rarely interact with mainstream C++ programming.

    • The STL. The STL is a template library, of course. but its a very special template library. Its conventions regarding containers. iterators, algorithms, and function objects mesh beautifully, but templates and libraries can be built around other ideas. too. The STL has particular ways of doing things, and when you’re working with the STL, you need to be sure to follow its conventions.

Keep these four sublanguages in mind, and don’t be surprised when you encounter situations where effective programming requires that you change strategy when you switch from one sublanguage to another. For example, pass-by-value is generally more efficient than pass-by-reference for built-in (i.e., C-like) types. but when you move from the C part of C++ to Object-Oriented C++. the existence of user-defined constructors and destructors means that pass-by-reference- to-const is usually better. This is especially the case when working in Template C++, because there, you don’t even know the type of object you’re dealing with. When you cross into the STL, however, you know that iterators and function objects are modeled on pointers in C, so for iterators and function objects in the STL, the old C pass-by-value rule applies again. (For all the details on choosing among parameter-passing options, see Item 20.)

C++, then, isn’t a unified language with a single set of rules; it’s a federation of four sublanguages, each with its own conventions. Keep these sublanguages in mind, and you’ll find that C++ is a lot easier to understand.

Jeff Alger speaks of varying stages of familiarity or steps along the way to mastery. It is interesting to note that what he calls "The Zen of C++" is an awareness of features in the language, in the end "idioms" that solve problems in some different or unexpected way:

The Zen of C++ (Jeff Alger, "C++ for Real Programmers," ISBN 0-12-049942-8)

C++ is a language learned in stages. Only when the last stage is reached does it all finally start to make sense, to combine into a Zen that unifies the otherwise scattered tricks and syntax. I think of learning C++ as being like rising up in an elevator. Ding! Second floor. C++ is a more reasonable C, strongly typed as long as you don’t fool around too much and, hey, how about those nifty // comments? All those C programmers who didn’t want to go into management needed a career path, and Bjarne Stroustrup, bless his soul, dreamed up a doozy.

Ding! Third floor. C++ is a decent-but-not-great object-oriented programming language. It’s not Smalltalk, but hey, what do you expect from a language that runs so blindingly fast? C++ is the COBOL of the 1990s, politically correct and sure to get your project funded by top management. Heck, they might even double your budget if you mention C++ often enough in your proposal. That’s just as well, because no one really knows how to estimate and manage C++ projects, and as to tools, say, lot of weather we’re having, isn’t it? Ding!

Top floor, everybody out. Hey, where did everyone go? Sure is drafty up here. C++ is really yacc++, not so much a language as a way of creating your own languages. It is elegant not for its simplicity like jumbo shrimp, the terms C++ and simple grate on the ears when used in the same sentence but for its potential. Lurking behind every gnarly design problem is a clever idiom, a nice twist to the language that makes the problem melt away like the Wicked Witch of the West without her umbrella. That idiom solves the problem as elegantly as a real language like Smalltalk or Lisp would, but without causing smoke to rise from your CPU and the stock of companies that manufacture memory chips to rise on Wall Street. C++ isn’t a language -- it’s an experience, a mind-altering drug.

This is also reminiscent of what Scott Meyers says about James O. Coplien's Advanced C++ Programming Styles and Idioms (ISBN-13: 978-0201548556) being a psychedelic book because it's purple and expands your mind.

Maybe the range of approaches is just a patchwork in paisley.