Which problems? That's a genuine question: the way I see it, C++'s niche is shrinking by the year, as new languages and more powerful computers arise. So, what's left?
It is still the dominant language for large-scale low-level systems. Critical software driving submarines, power plants, financial exchanges and medical devices is likely written in C++. The code on most of SpaceX's spacecrafts is in C++. Most of Google's infrastructure is written in C++.
With the constant increase of low powered computing devices we are likely to see that "niche" increase.
I think it is rather embarrassing that most code written in modern languages performs worse on today's computers than native code running on 1980s machines.
Performance is what makes computing magical.
"In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal and I believe the same viewpoint should prevail in software engineering" - Donald Knuth
Sadly, people only cite his other quote about premature optimization being evil, leading to a generation of computer programs written with no consideration of speed and user experience.
Funny how "critical" software often uses wildly unsafe languages. They should take advantage of paranoid type systems instead, that would prevent the occasional crash upon integer overflow, or SI/imperial incompatibility…
In established engineering disciplines, specification is a relatively small part of the work. In software, specification is everything (compilers and interpreters do the heavy duty for you). In established engineering discipline, a 12% improvement in a meaningful dimension (such as construction costs, or interior volume, or…) is easily worth doubling the specification effort. In software, a 12% cut in specification effort is easily worth a 50% worsening of another dimension, such as runtime speed or compilation speed (though of course we must not overdo it http://xkcd.com/303/ ).
This very much depends on what you care about. If you are running a 100,000 machine datacenter, a 12% efficiency improvement may save you millions of dollars in computing and energy costs a year. That is certainly worth a doubling of specification effort.
I don't think so. In established fields of engineering, optimization takes up as much, if not more time, than design.
Computing is a new enough field that so far that hasn't been the case, but I think with the increase of media processing and large scale data processing, a 10000 machine computer will be the new norm. And just like most other fields of engineering, optimization will be a major concern, if not the primary concern.
You are glossing over a fundamental difference between computing and other fields of engineering: copy & paste.
You don't get to just copy a bridge. You have to build another. With software, it is harder to justify building something anew, even if it's a bit different: you could re-purpose the old thing at very little cost (provided the old thing was well written and close to your mark to begin with, which is often not the case…).
Then there's the systematic automation of everything we understand sufficiently deeply. Garbage collection. Compiler optimizations. Libraries, some of which are freakishly fast. Databases.
When faced with a new project, you will increasingly not care about performance, because you will just reuse the incredibly fast infrastructure the system folks wrote for you. Don't get me wrong, performance is likely to become more and more important over time (as you said). It will just take less and less programming effort, as everything will increasingly be put in common —well, as long as we have the internet and Free Software.
More and more, the path to freakishly good performance will be simple, elegant, and obvious code. Algorithms will still matter, but you will hide most of them behind libraries. And you certainly won't do micro-optimizations.
If the compiler is not enough, you can have a team rewrite your hot spots using computer assisted semantic preserving transformations, in a tiny fraction of the effort it took you to write elegant code in the first place. Should you need to modify this code, no problem: just re-run the special set of optimization they devised in the first place. Worst case, the compiler just tells you it can no longer run the specialized optimization on your new code, leaving you with slow code until the optimization team amends its optimization.
Sure, but none of this points to high-performance languages being a shrinking niche. They will continue to dominate low-level code and library code.
Less low-level code will be written each year than high-level code, but it'll still be tremendously important. And as machines change, the underlying libraries will keep changing.
On the one hand, we have required effort. On the other hand, we have impact. To take an extreme example, Web browsers are a tiny niche in terms of development effort. Their impact however is something else entirely.
This is what I predict with low-level stuff. It will grow in terms of impact, but shrink in terms of development effort (at least in relative terms).
> as machines change, the underlying libraries will keep changing.
Increasingly, no they won't. What will change will be the optimization technique that we will need to operate on otherwise clean, elegant, obvious, and slow code.
Take a C library for instance. If it is written in a portable fashion, you only need to write a new C back-end to port that library to another machine. The same goes for semi-manually optimized code. You don't need to change the specification (I mean, the source code) to port the thing to another platform. You only need to change the optimization strategy. It's still an effort, but that's much less effort than a complete rewrite.
> It is still the dominant language for large-scale low-level systems.
He didn't say it wasn't the least dominant. He asked why it was to be considered the best. Dominance is a thing of legacy and you have to take into account a bunch of reasons that have nothing to do with how good a language is to assess why that's so.
Being the best tool is something completely different. I think the commenter has a good point and I think it's clear that a lot of the areas C++ has been used for have been taken over by better languages that offer more without conceding much. In that regard, he is spot on in saying that C++'s niche is indeed shrinking.
C++, like most other languages, is the best tool for some problems and areas, but those are growing smaller and smaller as we identify exactly what we need and create new languages to escape the rest of C++.
> I think it is rather embarrassing that most code written in modern languages performs worse on today's computers than native code running on 1980s machines.
Ok, let's play ball.
> After the Cray-1, the Cray Corporation developed another giant named Cray-2. It remained the world’s fastest Supercomputer between the years 1985 to 1989, capable of performing 1.9 gigaflops.
( Source: http://infotology.blogspot.be/2012/04/super-computer-timelin... )
So that's tha fastest of the fast in the '80's. According to Intel, a i7-3770k consumer CPU gets 112 gflops and a Q6600 quad core, which was released in Q1 2007, has 38.40 GFlops. That's a factor 58+ faster on the i7, or a factor 20 for the Q6600.
I picked the bench config x86 quad core because this had the highest peak. Also, if you take these languages, which are more commonly used:
* C#/Mono: Worst 9x, median 2x
* Go: Worst 7x, median 3x
* Haskell: Worst 3x, median 2x
* Java: Worst 3x, median 2x
* PHP: Worst 109x, median 36x
* Python 3: Worst 129x, median 37x
* Ruby: Worst 239x, median 53x
* JRuby: Worst 115x, median 34x
But keep in mind that:
* Current CPU integer performance, cache speeds, memory bandwidth and general i/o would completely destroy the Cray-2
* GFlops are a real bad indicator of how fast a computer is. Current computers are even faster. Current GPU's are floating point optimized and run circles around any general purpose CPU when it comes to GFlops.
* These are CPU-bound artificial language comparison benchmarks.
* Native code means nothing. Bad slow code will always be slow, whatever language you use. Some of the languages included do compile to 'native code' (Go and Haskell), and a lot of the interpreted/byte code compiled languages use a JIT to generate 'native code' too.
* We don't take into account the Cray-2's bottlenecks (mainly I/O)
* All GFlop numbers are according to the manufacturer.
* Most applications hit i/o limits before hitting CPU limits (yes there are exceptions)
* this is comparing with the fastest of the fast you could get at the end of the '80s
So in worst theoretical cases, sure. In the real world? Not even close.
> I think it is rather embarrassing that most code written in modern languages performs worse on today's computers than native code running on 1980s machines.
Are there any sources to support this statement, or are you drawing on personal experience?
I don't consider an improvement obtained switching from/avoiding a high level language that allows me useful abstractions and to avoid bookkeeping, to C++, an easy thing.
Yes, if the thing is just -slow-, optimize it. But never start out "We can't have this thing be slow; let's write it in C++!" unless you already have some metrics showing that it's -too- slow in a safer language.
Scientific computing. For my work (in particle physics) I need something that is fast, has interoperability with decades worth of C, C++ and Fortran code, runs preferable close-to-metal, and has minimal overhead. Also, it has to be something physicists (not computer scientists) can/want to work with.
There are a lot of great libraries for Python, and it's much nicer and more productive. I use it whenever possible, esp. for making graphics, or when I can use optimized stuff like in numpy. However, most of the programs I write are of the type "loop over 10 million entries, perform a simple calculation, return a number". These are mostly IO bound, and one would think that this is a case where you could use a dynamic or interpreted language. But whenever I tried, the overhead for the large loop and the variable access in tight loops was too high, and the problem became CPU bound. So, in my experience, it has to be a compiled language (or at least something more performant then Python).
I'd love to be able to use something like Haskell, as a lot of my problems are functional in nature, and it'd be able to catch a lot of stupid bugs. But it is too esoteric to be realistically adopted by the community.
The ideal language for me would be "C+". A C++ lite, where you would ban most of the complications. You would still be able to write C++ libraries, but then use them from simple C+. A C+ user, as opposed to a library writer, would not have to know about the "safe bool idiom", traits, private destructors, default methods (which are utter maddness in C++11) and template metaprogramming.
I'd then augment this simplified C+ with a powerful static invariant checker. You could say something like "guarantee x < 10; x = f()" and it could complain "you demanded x be < 10, but f() only guarantees x < 100".
"I'd love to be able to use something like Haskell, as a lot of my problems are functional in nature, and it'd be able to catch a lot of stupid bugs. But it is too esoteric to be realistically adopted by the community."
The esoteric, and what you need to do what you said, are nearly entirely partitioned from each other. Reading in a list of things, running some code over it, and spewing the results out is not that hard and will not involve anything you can't understand.
That said, even after some relatively extensive use of Haskell I still have poor intuition about how well it performs on such tasks... no, not because of "laziness", but because "naively" written Haskell still involves things getting boxed and other such performance killers that can take you halfway back to Python. I can say writing Haskell to do your described tasks isn't hard... I have a harder time promising you can write performant Haskell just by doing the obvious things. There's some promising work on doing fast numerical calculations, but it still seems like it's very easy to be doing something very fast, then change a bit of code, which silently breaks optimizations and suddenly it's slow for no obvious reason. (Note this is NOT unique to Haskell... all compiler optimizations can have this problem. It's just particularly acute in Haskell, but I've encountered it elsewhere. I've often wished for more transparent optimization feedback in many languages, or the ability to assert that I'm triggering certain optimizations so that if I do break them in the future, I find out at compile time. Alas, I've never seen such a thing.)
With C++11 you don't need the safe bool idiom anymore, you can simply define a "explicit operator bool() const". Since the conversion needs to be explicit, you won't have nasty surprises but it can still be used in an if (or while) normally as in this case the explicit conversion will be used implicitly. In other words, it works exactly like the safe bool idiom but is much easier to write.
> I need something that […] has interoperability with decades worth of C, C++ and Fortran code.
Assuming you meant more than having a good FFI…
When I judge the suitability of a language for a task in the abstract, I systematically ignore 2 very important factors: legacy code, and skill availability. I do as if everyone know every language, and we start from a mostly blank slate.
If I didn't ignore those factors, I wouldn't be judging the languages, I would be judging whole ecosystems, introducing a huge status-quo bias in the process.
---
The C+ you look for is probably possible. I bet it could be implemented a la CFront.
I write music-making software, which is one domain where C++ is utterly dominant and likely to remain so for a long time. In this world you need a language that's fast, gives you fine-grained control of memory, and allows you to operate without ever allocating or taking a lock of any kind. You could also use C for this, and some people do, but I find that the more powerful abstractions C++ provides are very very helpful here.
I think it's unlikely we'll see anything like Chrome, Ableton Live, or Photoshop written in anything but C++ any time soon.
I'm rooting heavily for you guys. I use C++ not because I love it but because it's my only reasonable option. If Rust becomes viable for the work I do I'll be on it in a flash.
I'm afraid I must insist on specificity: no specific problem means no justification. I understand the abstract reasoning if we had to plan that we might need C++ in the future. But when you're choosing a language now, you always work on a specific problem.
So, which specific problems requires you to both optimize the hell out of your CPU and memory, and mostly work at a higher level of abstraction than C?
I'll go even further: C + <high-level language of choice> already competes on that front (abstraction + performance). On which specific problems are they not enough, and C++ is required?
I'll go even further: there has been a number of C pre-processors spouting up recently. One of them does Lisp-like macros. Another does lambdas. Yet another might address templates. I predict a modern version of "C with classes", which learned from the mistakes of the past (like trying to be compatible at the syntax level).
At that point, do you think there will be any specific problem where C++ is still the best choice?
> So, which specific problems requires you to both optimize the hell out of your CPU and memory, and mostly work at a higher level of abstraction than C?
My sibling here already mentioned AAA game development. Finance is another area where top performance is often required.
Performance is the requirement. Being able to work at an abstraction level higher than C is highly desirable. C++ gives you both of those.
> I'll go even further: C + <high-level language of choice> already competes on that front (abstraction + performance). On which specific problems are they not enough, and C++ is required?
You get a boundary between the "high level" and "performance oriented" parts of the code that is arbitrary and only exists because the high level language performs poorly. There are definite costs to that approach.
> I'll go even further: there has been a number of C pre-processors spouting up recently.
Cute hacks that are probably not suitable for production use.
Let's be honest here. You're asking for problems that require the use of C++ now. The situation is surely going to be different in, say, five years from now - though I don't think it'll be a "C with classes".
I believe Jane Street does High Frequency trading with OCaml. The other examples sound valid, though I have my doubts about batch processing (compression, crypto…).
I intend to work an a serious C pre-processor this summer, after I'm finished with my Earley parser. This won't remotely resemble "C with classes". I won't aim for any syntactic compatibility, that was a silly requirement. Heck, I'll probably have Python-like mandatory indentation, reworked operator precedence, an overhauled type syntax, switches that don't fall through… But I will keep semantic compatibility, and a relatively obvious mapping to underlying C code. Coffe-C, not Clojure-C.
But even that won't satisfy me. Eventually, I want to make a source-to-source transformation framework that can turn any language into any other. With that, languages become less of a programming interface, and more of an implementation concern.
"Eventually, I want to make a source-to-source transformation framework that can turn any language into any other."
Beware. That's a pretty common programmer tarpit. I've witnessed two take this on myself. If you never hear about it online, it's because it makes "general puprose visual programming language" look easy; people at least get to the "show something off" stage with that.
It may help to observe that we technically already have an intermediate language that works with all languages, which we call machine language. If it sounds infeasible to read all machine language and convert between various programming representations especially in light of things like VMs and such... well... yeah. That's a fairly direct and accurate reflection of the difficulty in question.
My point was, HFT is possible to do with something other than C++. Jane Street does OCaml, and you have just cited Java (garbage collection and virtual machine!). Since C++ is such a Chtuloid horror, the mere fact that it is possible to use other language, let alone garbage collected languages, is extremely strong evidence that C++ simply isn't the best choice. You haven't refuted my point, you have supported it.
(Of course, I don't take legacy code nor talent availability into account. They are crucial in any real-world decision, but they don't influence the virtues of the language itself.)
> Since C++ is such a Chtuloid horror, the mere fact that it is possible to use other language, let alone garbage collected languages, is extremely strong evidence that C++ simply isn't the best choice.
Yeah, well, that's just, like, your opinion, man.
Seriously though, don't mistake your personal opinion for some objective truth. There are plenty of programmers out there who enjoy C++ and don't see it as a Chtuloid horror. What you have isn't strong evidence of anything, really.
> (Of course, I don't take legacy code nor talent availability into account. They are crucial in any real-world decision, but they don't influence the virtues of the language itself.)
And there are even more "external" factors to consider, but if you allow yourself to cherry-pick criteria then you can make any language be the optimal choice. Languages don't exist in a void.
It's not just my opinion. Do I have to resort to the nuclear option? http://www.yosefk.com/c++fqa/ Well, there you have it. C++11 and 14 made some things better, but they also have their problems.
My opinions have different strengths. This one has accumulated enough evidence that I no longer consider the possibility of its falsehood. C++ sucks, and that's the end of it. I know of the gazillion eminently reasonable reasons why C++ is what it is, but it still sucks. I know that if Stroustrup made cleaner choices for the language, it wouldn't be so popular, but it still sucks. I know that a better language that nobody use is… well… useless, but C++ still sucks. In my opinion, C++ is one of our greatest shame as a community.
> If you allow yourself to cherry-pick criteria then you can make any language be the optimal choice.
I don't cherry pick. I'm just comparing languages. Not external tools. Not backward compatibility. Not programmer availability. Just languages. The other criteria are short term considerations, and greatly increase status-quo bias. They're only interesting when I must do a small project now, with whoever happen to work with me at the moment.
For bigger projects however, the language is increasingly important. The bigger the project, the more reasonable it is to switch to use a better language, instead of a better known language.
Guys who write HFT systems in Java are basically programming them like one would in C or C++. They pre-allocate byte buffers for everything and never run the GC. If you write C-style code in Java, it's going to run pretty quickly. They aren't doing architecture astronaut AbstractMetaClassFactory stuff or using much of the provided libraries for latency-sensitive code.
FWIW, I don't think Jane Street is a competitor in the "ultra HFT" space where every nanosecond counts. AFAIK they are more of a statistical and quantitative trading group, so they may have less need for things like talking directly to hardware, keeping tight control over memory layout, deterministic latency w/o GC pauses, etc.
Almost everything that is popular has evolved over time, and making these changes once you have established users results in compromises that can be sort of ugly. C++ has patina.
> Almost everything that is popular has evolved over time, and making these changes once you have established users results in compromises that can be sort of ugly. C++ has patina.
You will note that C++ made that sort of ugly compromises from the start. Keeping a C-like syntax really wasn't necessary. (Keeping a C-like semantics, that's a different story.)
But isn't that because C++ itself evolved from C? The original "C With Classes" wasn't much more than a convenient syntactic sugar for using structs and function pointers as a poor man's object system, something that was and is common in large, abstract C programs (e.g. Linux's VFS layer, Gtk+).
I think you may be confusing is with ought here. Everybody sane knows C++ has flaws; I think Meyers even feels this way in his presentation. C++ is popular because it evolved and thus contains a lot of compromises. To draw an analogy, the Mormon Church is immensely popular in the US for similar reason--they basically said, "Hey the New and Old Testaments you spent your formative years learning are all good, but we've got some swell new stuff here too!" I'm sure Zen Buddhism is more theologically pure, but people like what's familiar to them.
Programming languages are a network effect problem first and foremost. Just like it's hard to unseat Craigslist despite its crappy UI, it's difficult to get users for a new language that may be only marginally better in terms of features, productivity, safety or convenience. Even if it's a significant improvement existing code bases, library availability, programmer availability with domain knowledge and so on matter much more for serious projects. There's a reason why Facebook took the time to write a PHP VM instead of rewriting their code.
> Programming languages are a network effect problem first and foremost.
If only reality wasn't like this. Yes, network effects are ridiculously important. And so is status-quo bias in general. I know C++ wouldn't be nearly as popular if it adopted a different syntax. I know that the ability to compile most existing C code out of the box was a big help in the adoption of the language, even though it technically doesn't matter. This is why I said erlier¹ that C++ is one of the greatest shame of our community. Stroustrup was well aware of our insanities, and he exploited them on purpose, supposedly for our own good. We as a community were simply incapable of accepting anything better. It would have been too different.
> But isn't that because C++ itself evolved from C?
It didn't. C++ did not evolve from C, it was implemented on top of C. Stroustrup didn't started by modifying the front-end of GCC, he started by writing CFront. From there, it would have been real easy to fix some of the most glaring flaws of C: switches that fall through, overly general (and verbose) for loops, the insane syntax of type declarations (ML existed at the time, and could have been an inspiration), the priority of the operators (15 levels are too much, some priorities are backwards), and maybe some operators themselves (the star for instance serves two unrelated purposes, which may be confusing). While we're at it, Stroustrup could have thrown the headers away, replacing them with a proper module system. Nothing fancy, just a nice way to package compilation units.
That was the "fixing C" part. These flaws were known at the time, it would have been easy to fix them. (Except maybe the module system. You still want an easy way to talk to existing C code.)
Then we can move on to building C++: a language with a stellar C FFI, semantics that are identical to C (except for advanced syntax sugar such as classes), but with a much cleaner, easier, and more flexible syntax. This language would have been much better than the current C++ on every possible measure, except one.
Adoption.
It seems we just can't change our syntax. No, scrap that, we just can't change, period. People love "change", but they hate change. There are few circumstances where people are willing to accept change (like this anecdote about introducing OpenOffice as "the new version of Word"). One of C++'s greatest strength (and our community's greatest weakness), was it's apparent similarity with C. It's the same, except with more features! A better syntax for C however, while more useful than a mere C-with-classes², would never have caught on.
[2]: Templates are C++'s killer feature, not classes. (OO as done with C++ and Java classes is mostly a mistake³. But that's another debate.)
(I'm not kidding about C's syntax being terrible. Experiments have shown that beginners fare no better with C than they do with a randomly generated syntax. It is that bad.)
I think C++ is a fine choice right now for a whole lot of things, though in most cases I think C is also a reasonable choice and there are tradeoffs between the two depending on the goals of the specific project (rather than the type of project).
So here's my list: A compression library, a crypto library, a numerical library, a video game, high frequency trading system, a high performance application server, a webserver, a database, a storage or caching system, an operating system, device drivers, a web browser, a VM, a programming language.
Game programming. AAA level games require high level performance which can typically not support interpreted languages. They also are complex enough that trying to program them in C would create more problems than they would solve.
Granted, many indy games can work by using an embedded interpreter for much of the game logic, but it doesn't take much to run out of computing power at that level and still maintain reasonable (and consistent) frame rates.
Statically typed i.e. without a inner loop dispatch penalty? Which others? I've considered an implementation in Fortran and OCaml as well. OCaml is attractive but doesn't cross compile to ARM officially. With C++ we can target x64, ARM and TI DSP with the same core processing module.
Cross platform applications? I know that C# apparently has cross platform support but I met with limited success on Mac OSX (perhaps I didn't try hard enough).
It is fairly easy to get a cross-platform library and use C++ to write for the main OSes (Mac OSX, Windows, Linux, in no particular order) and then you can also take the same code and compile and run it on your Raspberry Pi and ARM systems.
I know you could probably do the same with Python but I think small systems would suffer a speed penalty (I even find desktop Python applications slow so I dread to think of GUIs on an ARM written in Python). I reality I have not ever come across a piece of paid software that included a runtime of Python or some scripting language other than Perl, and that clearly wasn't for a GUI app.
What else would you write for all three platforms in? Java? I am curious.
(I suppose if you are targeting one platform only, then it might make sense to write in languages typically tied to that platform, eg. Obj-C / Swift / VB / C# (as is vastly popular in Windows land)).
The paper states that C++ must have done something right, as it is still consistently popular. If ms didn't go all in with it though, I think it would be a footnote in history.