Hacker News new | ask | show | jobs
by mattnewport 3152 days ago
Major influential figures in the C++ community (notably Bjarne Stroustrup and Herb Sutter) are very explicit about having a goal of simplifying everyday usage of C++ (make simple things simple). Watch any of Bjarne's talks over the last few years to see this is one of his main focuses. It's also recognized that backwards compatibility / not breaking existing code are very important however. Yes, that's a hard set of requirements to meet but I find it bizarre when I keep seeing people state that the C++ standards committee and the community in general don't care about simplicity and ease of use when those are literally the major topics of keynotes at every C++ conference of the last few years.
2 comments

Complexity of the language is a much discussed topic. In the trivial sense it is true that the language will inevitably get "more complex" as new features are added but backwards compatibility is largely maintained. I don't believe that is a very relevant metric for usability however. Higher level features are generally added to languages to make them simpler to use but they also make that language more complex by some metrics. You can argue that assembly language is "simpler" than C++ because it lacks "complex" higher level abstractions but I'd rather wrote code in C++98 than assembly most of the time and I'd rather write code in C++17 than any previous version of C++ because it continues to get more usable and simple things get simpler.
Complexity doesn't come from abstraction, but rather from the lack of simultaneously short and precise descriptions of how things work. C++ isn't complex because “it's flexible enough to support several programming styles” or whatever nonsense. It's complex because its features are all bolted on, rather than parts of a coherent design from the ground up.
C++ has a standard which contains extremely precise descriptions of how things work which is more than can be said for many languages. How many other languages are there that have three major compiler and standard library implementations with almost no common code yet which all manage to be largely compatible (able to compile the same code and agree on the meaning)?

Some of the complexity of C++ comes from it doing hard things, some is in part a consequence of heroic efforts at backwards compatibility. There are areas of the language that most people stay away from or use in very constrained ways like multiple inheritance that are unlikely to be deprecated for backwards compatibility reasons but in my many years of professional C++ development multiple inheritance has never caused practical difficulties for me precisely because everybody stays away from it except for pure abstract interfaces.

>> but rather from the lack of simultaneously short and precise descriptions of how things work.

> C++ has a standard which contains extremely precise descriptions of how things work which is more than can be said for many languages.

(0) Most programming languages don't set the bar very high.

(1) You missed the “short” part. The C++ standard is already pretty long, and it isn't even written in a form that makes it possible to prove things about C++ programs by consulting the standard.

> How many other languages are there that have three major compiler and standard library implementations with almost no common code yet which all manage to be largely compatible (able to compile the same code and agree on the meaning)?

I can think of at least four: Standard ML, Common Lisp, C, Java.

> Some of the complexity of C++ comes from it doing hard things,

In unintelligent ways. For example:

(0) Macro, pardon my French, template expansion as a generic programming tool is super dumb. Better alternatives were known in the 70's.

(1) C++ classes are very poor abstract data types: You need arcane language design hacks like `friend` to abstract over two or more types at once.

(2) C++ classes are also very poor object constructors: The language has no type for “all objects that have methods foo, bar, qux” (à la OCaml or Go).

> some is in part a consequence of heroic efforts at backwards compatibility.

Most of it.

> (0) Macro, pardon my French, template expansion as a generic programming tool is super dumb. Better alternatives were known in the 70's.

And yet C++ has better support for generic programming than most mainstream languages and it continues to improve. What's a language you think does generic programming 'right'?

> (1) C++ classes are very poor abstract data types: You need arcane language design hacks like `friend` to abstract over two or more types at once.

I don't really understand this comment. C++ has good support for static / compile time ADTs (the STL is very much built around the idea) and also supports 'runtime' ADTs through interfaces. In neither case is friend needed to abstract over types.

> (2) C++ classes are also very poor object constructors: The language has no type for “all objects that have methods foo, bar, qux” (à la OCaml or Go).

Static polymorphism in C++ currently relies on duck typing but this is what the Concepts TS is addressing. A major benefit of that will be improved error messages and a better generic programming experience.

> What's a language you think does generic programming 'right'?

The most obvious examples are ML and its derivatives.

> C++ has good support for static / compile time ADTs (the STL is very much built around the idea) and also supports 'runtime' ADTs through interfaces. In neither case is friend needed to abstract over types.

The STL is built around ADTs in spite of the language's lack of support. If C++ had an actual notion of abstract types, then templates could be type-checked against ADT specifications (so-called “concepts”), rather than having to wait until instantiation time.

> In neither case is friend needed to abstract over types.

You can't encapsulate a single abstraction providing two or more ADTs without using `friend`. That's a fact.

> Static polymorphism in C++ currently relies on duck typing but this is what the Concepts TS is addressing.

This is a reply to the wrong thing. Concepts are ADT specifications, not object specifications.

Simplifying every day usage is entirely a different thing than simplifying the language. I’m not denying the inprovement in usage, just that you should expect the complexity of the language to continually increase because that’s the needs of the c++ community.
My question then is why should I care about "increased complexity" by this definition more than about "simpler usage"? Adding well thought out language features that simplify my every day usage is a good thing and the sense in which it increases complexity is not a sense that particularly concerns me. I think C++ is generally making good choices about what features to add. Generic complaints about new features tautologically "increasing complexity" are not interesting. Specific concerns about particular features not carrying their weight in terms of simplifying usage are interesting (and a big part of what the C++ standards process is engaged in).
Agreed. You have to choose between "large scale removal of features from the language" vs "30+ years of back-compat". You can't have both. A huge strength of C++ is it's legacy and the maintainers would be foolish to throw that away in a C++ 2.0 movement.

Instead, they add new features that lets new code be written in new ways without requiring you to toss out your old code. Your old C code is full of mallocs and frees. Your old code still works when you partially update it using the newest features. But, once C++ added new and delete, you rarely ever needed to type malloc or free any more unless you were overloading new and delete. Your old C++ code is full of news and deletes, but new language features added in C++11 made unique_ptr and shared_ptr possible. And, now you rarely need to type new or delete unless you are making your own unique_ptr/shared_ptr variant.

Why would you care? Well the complexity makes tooling difficult, the engineers expensive, and arguably ongoing development could be slower depending on how many c++ features they have to deal with in one code unit. Are these any strikes against the language itself? No, of course not, but one can see why e.g. using go instead might afford more flexibility if the underlying c++ distinguishing features aren’t necessary. The language complexity is still something to consider even if c++ is sufficient.

I am by no means arguing that C++ committees are making any mistakes.

I don't think we disagree on much. Jonathan Blow is of the opinion that what games programmers need is a new language designed from scratch, in part because he believes the most viable (and dominant) language used for games, C++, is irredeemably complex. I recognize that there are complexities to C++ but I'm of the opinion that it's been getting better and will continue to do so for games development and that the new features in practice are making the language simpler to use even if technically they are making it "more complex" in the sense of having more features. The tooling is also getting better, despite the complexity, and Clang has played a big part in that. The case for switching to a different language is not compelling to me, especially to a completely new language rather than something with some track record.