Category: why

  • Is anybody actually writing “Modern C++”?

    If you spend any time watching C++ conference talks, reading the standard, or skimming the Core Guidelines, you could be forgiven for thinking the industry quietly agreed to rewrite itself overnight. The code in those talks is elegant. Expressive. Composed of ranges, concepts,constexpr, value semantics, and a conspicuous absence of raw pointers.

    In college, though, C++ often shows up in a different outfit: data structures, intro systems, maybe compilers or graphics if you are lucky. It is taught as “the language you use to understand memory,” not “the language you use to write elegant libraries.” Students learn pointers early. They learn manual lifetime management. They learn to fear undefined behavior.

    Then you open a real codebase, written by a team that ships products for a living.

    And… yeah. Something is off.

    So let’s ask the uncomfortable question out loud: is anybody actually writing C++ the way C++20 suggests?

    The answer is yes. But not in the way most people mean.

    What “the C++20 Way” Even Is

    When people say “modern C++,” they rarely mean one feature. They mean a style that has emerged over the last decade: code that leans on value semantics and RAII, prefers standard algorithms over bespoke loops, uses strong types to make illegal states harder to represent, and pushes intent into the type system instead of into comments.

    In practice, “the C++20 way” usually looks like a handful of recurring moves. You see

    std::optional

    and

    std::variant

    where older code used sentinel values. You see

    enum class

    where older code used loosely-typed integers. You see concepts where older template code relied on SFINAE and error messages as a rite of passage. You see

    constexpr

    used to make compile-time decisions explicit rather than accidental.

    And, maybe most importantly, you see fewer macros, fewer raw owning pointers, and fewer surprise lifetime rules.

    None of this descended from on high with a standard release. It grew out of guidelines, talks, libraries, and hard-won experience. It is not “how C++ must be written.” It is how C++ can be written when everything goes right.

    Who’s Actually Writing C++ This Way?

    Some people really are writing the C++ from the talks. It is not imaginary. It is just concentrated in a few places.

    Library authors and C++ specialists

    If you work on standard library internals, Boost-like libraries, header-only abstractions, compilers, or tooling, this style is not aspirational. It is necessary.

    These teams spend all day living in templates. They are the reason concepts exist. They treat

    constexpr

    as a feature, not a punishment. Their code looks like the talks because they are the ones giving the talks.

    Greenfield, performance-heavy projects

    New subsystems and high-end projects are the next most likely place to find “conference C++.” Think simulation, robotics, finance, and HPC, where performance and correctness are non-negotiable and the codebase is not dragging decades of baggage.

    Even here, adoption is cautious. Smart pointers become the default, but they do not replace every custom allocator. Expressive types show up, but teams still measure every abstraction. Ranges do not replace every loop. Modules exist mostly in slide decks. Compile-time complexity is treated as a real cost.

    It is modern, but it is modern with a budget.

    Teaching environments

    Academia can produce the cleanest C++ precisely because it can ignore so many constraints. When you are not supporting four platforms, three compilers, and one vendor-patched standard library, you can teach the simpler story: avoid raw owning pointers, express intent in types, and let the compiler enforce invariants.

    Students often learn a cleaner C++ than they will see in their first job.

    That is not a bug. That is a north star.

    Who Mostly Isn’t Writing C++ This Way?

    If “conference C++” were the median, this essay would not exist. Most production C++ lives under constraints that talks rarely linger on.

    Legacy codebases

    Millions of lines of pre-C++11 code do not get magically modernized because a new standard dropped.

    Modernization is usually incremental and local. You modernize at boundaries, where it is safe. You introduce a new type here, replace a few ownership patterns there, move a subsystem toward a newer dialect when you can, and leave the rest alone unless you enjoy production outages.

    These teams live in a hybrid world: “modern where possible, old where required.” And that is often the correct choice.

    Cross-platform product teams

    If you support old compilers, niche platforms, embedded targets, or vendor-patched libraries, you cannot assume full C++20 support.

    So you end up writing C++17-ish core logic, adopting a few C++20 features where they help, and building careful fallbacks. This is not conservatism. It is survival.

    Game studios

    Games deserve special mention because they are often very modern, but almost never ideological.

    Game teams care about debuggability, build times, and predictable performance. They use RAII everywhere. They use smart pointers where they fit the engine’s ownership model. Exceptions are often banned. Heavy abstractions and ranges show up selectively, because the cost is paid by every developer who has to build, debug, and profile the game.

    Game C++ looks modern, but it does not look like a conference slide.

    And it should not.

    The Uncomfortable Truth

    The C++ standard does not describe how people do write code. It describes how people could write code if starting today, with no legacy constraints, excellent toolchains, uniform compiler support, and deeply trained developers.

    Real codebases are messier, older, and more political than that.

    What’s Actually Happening in Practice

    C++20 has not become doctrine. It has become a toolbox.

    Teams adopt what pays for itself. They take the features that reduce bugs. They take the features that clarify intent. They take the features that do not explode compile times, onboarding, or debugging.

    And they ignore the rest. Sometimes that is shortsighted. Often it is wise.

    This is not failure. It is engineering.

    A Hot Take Worth Saying Out Loud

    C++20 is not a style guide. It is a pressure gradient.

    New code drifts toward it. Old code resists it. Great engineers use it deliberately. Poor engineers misuse it and blame the language.

    The difference is not the standard.

    It is judgment.

    A Note for Educators

    If you teach C++ “the C++20 way,” you are doing the right thing, as long as you are honest about reality.

    Teach it as the ideal we aim for, not the average codebase someone will inherit. The students who understand that distinction tend to become better engineers faster, because they learn both the direction of travel and the constraints that slow it down.

    Final Thought

    The right question is not “Is anyone writing C++ like the standard suggests?”

    It is: “Which parts of modern C++ meaningfully improve this codebase?”

    That is the question professionals actually answer every day.

    And it is the real lesson C++20 teaches.

    Fair warning: I have strong opinions 😄

    Selah.

  • It’s time to fire this guy back up

    Time to start things back up with my blog. I’ve let my web presence and blog languish a bit. Been putting too much focus on the social media things, truth be told.

    So it’s time to start putting up some new content. Like what? Been having to do some work on NLP and am working on a couple of posts on setting up an environment for doing that. I’ve also been having to do some sysadmin things on Macs and have found lots of less known command-line tools that I think my notes would be helpful to someone else.

  • A New Year and A Familiar Subject

    New Year’s Day. The start of a new year… And for those of us in higher-education, the start of a new term. Like most people who teach, the first few weeks of January involve the frantic rush of getting ready to teach the Spring courses. If you’re lucky, they are courses that you have the material all configured and ready to dump back onto your employer’s learning management system. But it’s not that way for me right now as I find myself getting ready to teach Software Engineering again after some time away from the subject. So, the gap between Christmas and the start of classes is filled with reviewing the course texts, editing slide decks, and updating syllabi.

    The past few days have been reading days. And I found an interesting article in the Janurary 2014 edition of the Communications of the ACM discussing estimation in agile processes <link>. Software developers who become vocal agile proponents tend to look askance at estimation; thinking that estimation of a software project has some connection to complete definition of the requirements for a project. What is missed in this case is that you have introduced a disconnect between business and development aspects of a project.

    Agile planning focuses on workflow: how to decide what to do over the next few increments of time and how to generate the most value in that time. In the CACM article, the author points out that is very different from the business requirement for estimation: generate the information required to determine what resources are required for a project. This is key, as most software projects are capitalized projects and some sort of connection between budgetary cycles and development plans are required.

    This is an important point that is missed in instruction in agile development. Textbook discussions of agile planning focus on the workflow aspects and tend not to emphasize the connection to budgetary cycles and estimation. It’s an important point to remember when introducing novice practitioners to use of these techniques.

    Selah.

  • We’re back

    So, I’m back in the blogging business…

    For about 10 years, my web site and blog were hosted by a small web hosting provider based in Germany. They always came across as being a bit dodgy but kept their servers running, provided me the base service I needed, and generally stayed out of the way.

    Well, finally the excrement hit the oscillating device and we had a bit of a tiff over billing; they charged my card the annual renewal, turned off my access, and tried to screw me out of the refund. Sadly, it ended up with the overseas outfit locking down my old domain and refusing to provide me the transfer code.

    At this point, I’ve now switched over to the one of the large web-hosting providers and moved over enough of my content to get back on my feet. I’m still restoring content from my old blog and well be adding stuff over time. In the meantime, enjoy!

    Selah.

  • Talk to me about being effective, not being efficient

    In the course of finishing up the dissertation, I’ve been reminded about that old argument between being effective vs. being efficient. Like just about every graduate student, I was getting the “work harder, work faster” speech from my committee chair. A large part of those diatribes involved discussions about being more efficient in my work and dealing with adjusting the focus knob.

    Here’s how the words are defined by dictionary.com:

    Effective (adj.): Adequate to accomplish a purpose; producing the intended or expected result.

    Efficient (adj.): Performing or functioning in the best possible manner with the least waste of time and effort.

    Getting my head clear about the difference between these two things has been one of major roadblocks towards finishing my dissertation. I’ve become quite efficient about doing the things I’ve needed to do to get through the last semester but most of what I’ve been doing hasn’t been very effective  in moving me towards finishing.

    So, how to break the pattern? It varies from person to person but I started with a  two step plan. First, keep track of what you do during the day. This is something some people do without thinking… I’m not one of those people and a I think I’m a member of the majority in that regard. The result is that I find myself becoming very interrupt-driven. I quickly noticed just how scatter-shot my time had become.

    Second, do some “post-mortem” (and “after-death” is the right term here given how my advisor wants to shoot me) and look at how you spend your time after a few days of tracking your work. Then, prune and watch what you do.

    Selah.

  • The C++11 standard and C++ as a teaching language

    The C++ Standards Committee recently published the 2011 update to the language standard with a large body of new features. Looking over some of the changes got me thinking again about my experiences as a software developer using the language and as an instructor teaching others how to use C++. And I’m not certain that the changes in the standard bodes well for the use of C++ as a teaching language.

    A Historical Perspective

    Like many who were first introduced to computers in the late 1970s and early 1980s, I learned how to hack using BASIC and assembly language, how to program using Pascal, and finally understood computer science when I grokked LISP and Smalltalk in my first run at graduate school. My introduction to C was in the late 1980s while learning to become a UNIX system administrator while working on my Master degree and C++ in my first real job writing point-of-sale software. So,like most people in my generation I’m not a native C++ speaker; most of the time I’m really thinking in C.

    So, why comment now?

    Part of my Ph.D. experience has involved working as a part-time instructor in our undergraduate program. Our department is very old-school in many ways; one of which is that we use C++ as our primary teaching language. And we teach C++ exactly as I learned the language 20 years ago in that we first teach imperative programming using the language as more fancy version of C and then we teach the object-oriented features. In other words, for the student’s first three or four semester we teach them that “C++ is just a better C compiler” and then dump object orientation on them when they have to also struggle with all of the theory of data structures. This brings us back to some of the features in the new language standard and how people who are taught to program in C++ in this traditional manner will never think to use them.

    So what are some of these features?

    Danny Kalev is a tech blogger and consultant who served on the C++ standard committee who recently posted a blog (here) that highlighted what he considered to be important new features of the standard. Let’s take a look at a few of those features from a teaching standpoint.

    Null pointers

    One of the big problems with not only C++ but also C is the way one dealt with concept of null pointers. From day 1 in both languages, the concept has been that machine addresses were represented by an integral subtype with value of 0 indicating an invalid null address. This lead to many issues in programs with people being caviler about treating the integer value of zero as being the same as indicating a NULL pointer. You have to be diligent in teaching people the difference between the two concepts and how to avoid the problems that are introduced by this convention.

    So the convention developed that you would define a preprocessor value called “NULL” that you set to zero to indicate you were working with a null pointer value. Eventually this macro was incorporated in the set of headers mandated by the standard. Consider an example from Kalev’s post:

    void f(int); //#1
    void f(char *);//#2
    //C++03
    f(0); //which f is called?

    In both cases, very dangerous as the compiler can’t figure out which version of the overloaded function to call. Now think how to explain this concept to a neophyte programmer just learning about concepts of machine addresses, pointers, and overloaded functions.

    So, the language standard introduces the concept of “nullptr”. For example, the nastiness from Kalev’s example becomes:

    void f(int); //#1
    void f(char *);//#2
    //C++11
    f(nullptr) //unambiguous, calls #2

    A glorious and wonderful thing for the language and a feature that will help teaching. But a good illustration of the problems that exist in teaching C++ to new programmers.

    Delegating constructors

    Object orientation is one of most difficult aspects of instructing people in programing C++. The idiosyncrasies of constructors and destructors are bad enough as currently defined but the new standard is adding more complexity to the issue. For instance, the C++11 standard permits the use of delegation in constructors. Again, we consider an example from Kalev’s post:

    class M //C++11 delegating constructors
    {
     int x, y;
     char *p;
    public:
     M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target
     M(): M(0) {cout&lt&lt"delegating ctor"}
    }

     

    At last, we can now safely call other constructors, an excellent idea from an object-theroetical standpoint. However, the entire chain of teaching constructors becomes far more difficult with this feature.

    Lambda expressions

    The new standard adds the concept of lambda expressions to the language. A lambda expression lets you define functions locally at the place of the call to the function. In C++, this helps reduce some of the security risks that function objects incur in the language. Consider the following example from Kalev’s post:

    int main()
    {
       char s[]="Hello World!";
       int Uppercase = 0; //modified by the lambda
       for_each(s, s+sizeof(s), [&Uppercase] (char c) {
        if (isupper(c))
         Uppercase++;
        });
     cout&lt&lt"Uppercase&lt&lt" uppercase letters in: "&lt&lts&lt<endl;
    }

    In this case, we see an example of a lambda expression in the for_each construct where the Uppercase lambda expression defines a C++ expression for switching text to uppercase. Note the general form of the lambda expression

    [capture](parameters)-&gtreturn-type   {body}

    We see two pedagogical problems from this example: (1) the for_each construct is one that isn’t taught very well when you are inspired by the “C++ as better C” viewpoint of teaching, and (2) more critical, the entire concept of lambda expressions is one that you would not be able to teach until you have developed rather strong fundamental conceptual understanding of language design principles. Thus, not something easily taught to beginning programmers. In most undergraduate computer science programs, it’s a concept not taught until your third or fourth year in the program.

    OK, how do we tie all of these thoughts together?

    For me, the new standard makes the use of C++ as a teaching language even more problematic. Many of the concepts being added to the language to make it safer and cleaner make it more it more difficult and dangerous to use as a teaching language. Furthermore, it becomes even more problematic if your program is traditional and uses the “C++ as better C compiler” approach to teaching students just starting in their study of computer science.

    Closing thought: C++ not a good teaching language

    If we begin from the premise of C++ as being less than suited as a teaching language and becoming even more so with the introduction of the revised standard, what then should we use as a teaching language for new programmers? In my recent travels in search of a teaching position, it’s been my observation that many programs have switched to Java and C# as alternatives. These languages suffer from many of the same issues of C++. I’m beginning more and more to believe much as the teaching staff does as CMU and we should be teaching using languages such as Python.

    Selah.

    References

    Danny Kalev: The Biggest Changes in C++11 (and Why You Should Care)

    Robert Harper: Teaching FP to Freshmen

    Enhanced by Zemanta
  • A rave on the scholarship of learning

    We believe the time has come to move beyond the tired old “teaching versus research” debate and give the familiar and honorable term “scholarship” a broader, more capacious meaning, one that brings legitimacy to the full scope of academic work. Surely, scholarship means engaging in original research. But the work of the scholar also means stepping back from one’s investigation, looking for connections, building bridges between theory and practice, and communicating one’s knowledge effectively to students.
    —E. L. Boyer, 1990

    A classmate from graduate school was recently hired to teach at a small teaching-oriented institution in the Midwest. Like many newly-minted Ph.Ds, he is now finding that he’s being asked to think more about the metaphysics of teaching rather than worrying about how to teach people how to program. This person asked my opinions on the following “meta-questions” about teaching:

    1. How would you define excellence in teaching?
    2. How would you define the scholarship of teaching?
    3. How do these concepts tie together?

    They’re all very open-ended and difficult to answer. Note that the following responses are slanted towards my opinions on the subject and may differ from accepted norms. Standard disclaimers apply; your mileage may vary…

    These terms are rather well defined amongst professional educators (by which I mean people who get the “Ed.D” degree from a Department of Education who are experts in the theory of teaching). Look at some of the information that you can find on the website for the “Carnegie Foundation for the Advancement of Teaching” (yes, the same Andrew Carnegie who founded what is now US Steel Corp. and was one of the principal benefactors of Carnegie-Mellon University, go lookup his bio on Wikipedia).

    The Carnegie Foundation defines “scholarship in teaching” in three parts:

    1. Scholarship of discovery: research and performance that adds to a knowledge base and the intellectual climate of an institution
    2. Scholarship of integration: drawing together and interpreting diverse kinds of knowledge
    3. Scholarship of application: applying knowledge to practical problems

    Working from those definitions, you can define excellence in teaching by measuring, preferably in a quantifiable manner, how well an individual working within a program or a program in an educational institution addresses each of these areas. This is the equivalent of business planning in industry; you must define a set of objectives that you put in place to address these concerns and a set of goals that you must achieve to meet those objectives. Then a set of quantifiable measures are put in place that define whether or not you achieved the goals you have set for yourself.

    In a perfect world, an institution’s policies, practices, and infrastructure are aligned with these goals. An institution has to evaluate anything it does against the measures it has put in place for itself and adjust, enhance, eliminate, and/or introduce polices, practices, and structures as required.

    These are interesting questions that deserve further thought and ruminations. Look for more posts from me on this subject in the near future.

    References: