
A rat. For reasons. The subtitle is a quote from Bjarne Stroustrup. Suffice to say, he was not
thinking of Carbon when he uttered these words. At least since this quote is already thirty
(30!!!) years old.
Toggle original/dithered image
In case you’ve not heard of it, Carbon is Google’s experimental
open-source “C++-successor
language”. As a very rough first approximation, think Objective-C/Swift, Java/Kotlin, C/C++, C++/Carbon.
It is also frequently mentioned in the same breath as Herb Sutter’s Cppfront and Sean Baxter’s Circle (and
Rust, surprise surprise).
Like with any ‘successor language’, the overall goal includes (at the bare minimum) near-seamless
interoperability, as well as significant improvements over the original language.1
(Otherwise it can hardly be called a successor, duh.)
If you’ve clicked on the article, you’re probably waiting for me to admit that I’m lying, and to tell you
that (in fact) Carbon is a programming language.
And yes, it’s true! Carbon is a programming language. (Or rather, it’s aspiring to be a
programming language. Carbon is an experimental project and hasn’t hit its 0.1 release milestone yet. The
Carbon developers are very transparent about this.)
But in my humble opinion, thinking of Carbon as a ‘programming language’ is kind of missing the point. Let
me tell you how I think about Carbon, and why I think that it’s more interesting than most people give it
credit for:
Carbon is a concentrated experimental effort to develop tooling that will facilitate automated
large-scale long-term migrations of existing C++ code to a modern, well-annotated programming language
with a modern, transparent process of evolution and governance model.
The entirety of Carbon (the language, as well as the project) is built around making this goal possible.
(Disclaimer, I don’t speak for Carbon, take my words with a grain of salt.)
Why?
In this post, I want to convince you of the following points:
-
Carbon is a project to investigate the possibility of a large-scale reduction of C++ technical debt via
automated code migration.2 -
Many so-called ‘successor languages’ are nothing like this. They don’t make
automated code migration an explicit goal, and generally build a layer of abstraction on top of
or rely on their host language. -
All of this is downstream of Google’s disagreements with the C++ Standard Committee. In fact, while all
of this is about reducing technical debt, it’s also about reducing the organizational costs involved in
having to coordinate migrations and language evolution with the committee. - Developing a new programming language is probably necessary to achieve the goals of the project.
I’d like to bring special attention to the point about governance: This isn’t just a technical issue. It’s
a governance issue. It’s a “We just straight-up disagree on the future direction of the C++ programming
language.” sort of issue. I already went over these cultural disagreements in
a previous post.
(The astute reader will note that you can evolve and govern your own programming language however you
want, without needing to deal with WG21 (aka the C++ Standard Committee, aka the authority that decides
what C++ is3.))
At this point I’d love to reach for the Herb Sutter “We must minimize the need to change existing
code.” quote4 again,
but I’ll instead just state the obvious:
A large-scale migration to a different programming language is the opposite paradigm. As far as
changes to existing code go, it’s uncompromising. It’s an approach that’s only going to work for a subset
of people, and in fact,
Carbon’s goal document
lists “We consider it a non-goal to support legacy code for which the source code is no longer available”.
In other words, the language is not for everyone. That’s fine! I am still very interested in it. I care
about Carbon since I believe that it’s trying to solve the hardest problem C++ is currently facing.
This isn’t any single technical issue (there are many, many of those), no, and it’s not even a
broad concern such as memory safety.
It’s the problem of C++ slowly calcifying and struggling to modernize. It’s about ABI, about dozens of
tools but no agreed upon standards, and it’s about backwards compatibility. It’s about allowing existing
C++ code to evolve, modernize and change, in spite of decades of technical debt, multiple
implementations, and many different users with different expectations and requirements.
This is, in other words, an incredibly hard problem, and a long-term project.
If you believe that certain multi-million line C++ codebases are still going to exist in twenty years,
then you should understand the business case for Carbon.
A short lesson in history
Let’s briefly summarize the backstory for those who haven’t kept track. You could (very roughly) say that
Google is developing Carbon due to conflicts with WG21, and disagreements about the future of the C++
language.
What matters is that Google contributed to WG21 for many years, and that it has a vested interest in the
future of the language, due to owning many, many million lines of C++ code. It’s hard to
overstate how critical C++ is for Google’s infrastructure, and for modern technology in general.
The short summary is that Google’s developers (not just Google’s, mind you) disagreed with other parts of
the committee about the
future direction of the C++ language. There are a lot of reasons for this, and
a lot of ink has been spilled on the
topic. Eventually, after trying to work with WG21 for many years, Google basically threw in the towel.
(You cannot blame them. They tried hard, and the WG21 process is notoriously slow and frustrating.)
At this point, a lot of people might think that the core disagreement between Google and WG21 was about
‘memory safety’, or something like that.
It wasn’t!
The current memory safety hype is a pretty big deal for C++, but the ball was already rolling several
years ago. All of this started with concerns about C++’s complexity5
and performance.6
It turns out that fixing certain issues would require backwards incompatible changes (bad!). Coordinating
this across the entire C++ ecosystem would be more or less impossible.
I’ll not get into the details and instead point at Chandler Carruth’s
‘There are no zero-cost abstractions’
for an example: It pins down how first of all, std::unique_ptr
has a runtime overhead, and
second of all, how fixing this would require an ABI-break and a language change.
(That doesn’t mean Google doesn’t care about memory safety, of course. They do. But memory safety isn’t
what started the whole conflict, even though it’s currently carrying the torch. That’s why memory safety
is still relevant to all of this, especially since making C++ memory safe without compromising the vision
of the standard committee looks more or less impossible.)
Migration & Language Evolution
First of all, that Carbon has automated code migration as one of its goals should be clear. The
Carbon people are
very explicit about this. It’s also a common theme in
their talks.
This is, first and foremost, about moving away from the “We mustn’t break existing code, so we
had to squeeze in this new feature/syntax in some awkward way somehow.” approach to language
evolution. (co_await
and the (proposed) reflection operator (^^
) are sending
their regards.7)
This approach to language evolution kind of sucks. It’s not like the committee doesn’t
understand the problem, or doesn’t want to evolve the language. The committee is not
evil, and it’s not your enemy. C++ is just incredibly hard to evolve for all sorts of reasons, which would
honestly justify an article on their own (ABI, multiple implementations and the committee process, no
unified ecosystem, no editions or epochs system, no unified migration tooling, widespread dynamic linking,
etc.)
Carbon’s goal is to move away from that.
How? Via automated t
13 Comments
DashAnimal
As someone who uses C++ daily, very excited for Carbon. I really align with the goals they have set. Its a shame communities like r/cpp block any discussion of successor languages but I hope once this language starts gaining more momentum and nearing release, it will begin to market itself and get more attention.
Mond_
Oh hey, that's my post.
HI HACKER NEWS! Excited to see you!!! Ping me if you find typos.
(Also jeez, writing this took way too long and I spent too much time editing it trying to cram everything from Cpp2, the Google governance issue, member access operators as a case study, some historical bits, etc. into the post.)
EDIT: One of the most interesting things for me is that (so far) no one complained about the lack of Carbon code examples.
atribecalledqst
Have to say, it bothers me a little bit that they named it Carbon. I associate that term strongly with the old Carbon API from Apple.
Carbon was officially removed with 10.15 Catalina in 2019 – what's the statute of limitations on reusing a name like this?
noelwelsh
What I've seen of Carbon looks really good. I feel they're trying to do something that is hugely ambitious, and so perhaps unlikely to succeed, but I love the vision.
As I don't have a massive C++ codebase I have no stake in Carbon's success, but I think language improvements are some of the most significant steps we, as an industry can take (language improvements are basically the only way we can rule out entire classes of bugs) and I want our industry to improve.
adrian_b
I have no idea whether Carbon will be successful, but this is the only right way of evolving a programming language when incompatible changes must be made: by providing tools that guarantee a completely automatic migration of the legacy programs.
Hopefully Carbon will succeed to achieve this goal.
hatwd
Interesting language – its syntax looks like a mix of Rust and Go, with a few of its own idiosyncrasies to distinguish it from those languages.
> Carbon is a concentrated experimental effort to develop tooling that will facilitate automated large-scale long-term migrations of existing C++ code to a modern, well-annotated programming language with a modern, transparent process of evolution and governance model.
This is probably where Go and Rust fail to be C/C++ "successor" languages, as interop between those languages doesn't seem to be as seamless as Carbon aims to be.
Will keep an eye on its development!
rednafi
I haven’t written C++ since I graduated and hopefully won’t have to, but this looks really good.
While I love Go, I feel like languages like Go and Rust didn’t become C++ killers because they expected everyone to jump on the bandwagon and abandon all their legacy code. That didn’t happen.
This approach of keeping the interop intact might just work.
steveklabnik
This is a great post! I'm very intrigued to see how Carbon ends up. I've also enjoyed reading about some of their implementation choices, being more data-driven.
habitue
This immediately suggests what you want is a gradual migration process from one language through several intermediate languages to your target language.
i.e. instead of a big bang C++ -> Carbon migration, instead you want something like:
C++ -> C+++ -> Carbon– -> Carbon -> Carbon++ -> Rust
(Basically fake names for more gradual transitional intermediate languages, assuming Google would like to have everything in Rust eventually.)
The key idea of "targeting automated migrations" makes this kind of thing feasible
rvense
I know enough C++ to understand that "member access operator" example, but not enough to have ever seen that before, and my first thought is just "big yikes".
I'm sure there are cases where this will mean you can write more general and flexible library code, but is it really worth the cost? C++ just seems so full of this three-starred nonsense.
mhh__
I highly doubt I'll ever use Carbon but I'm really enjoying their statements of their ideology and choices on various matters in the github repo.
comex
I like the idea of Carbon and I hope to use it in the future. But wow,
> We consider it a non-goal to support legacy code for which the source code is no longer available
is such a pejorative way to talk about ABI stability.
Yes, supporting code you lost the source for is one use case for ABI compatibility. I guess it’s a real need that some people have. But it’s by far the most unsympathetic use case. It reeks of antiquated development practices. Plus, binaries with lost source are inherently a ticking time bomb since you won’t be able to port the code to new platforms or make any fixes.
But what about all the other use cases for ABI stability?
What if your vendor has the source code but doesn’t want to give it to you?
What if you do have the source, but you want to be able to update libraries without rebuilding every executable that depends on them? Especially valuable if you’re building an operating system, Linux or otherwise. (There’s a reason that Swift spent so much effort on ABI compatibility.)
What if you want to let people build dynamically-loadable plugins? (This one at least gets a brief mention in the Carbon goals document, albeit under the "legacy compiled libraries" section.)
What if you just want to save build time via pre-built libraries?
Don't get me wrong, I'm not against Carbon's decision to make ABI stability a non-goal. There are real tradeoffs in making ABI stability work. I'm just saying, if you're going to explain why you don't support it, don't dismiss the use cases for it by picking such a poor exemplar.
Remnant44
I thought this was a well written and fair article. My preference would be that C++ is not "forked", but I understand the reasons for the impasse and consequences.
I found the part about member access operators interesting.
I've written C++ for 25 years, and although I've used "pointer"-to-member(function/fields) ability many times (indeed, this is how you bind signals to your member slots statically in QT!), I had no idea that it could both be null, and that -1 was used for a 'null' 'pointer' in this instance.
Good example about how large the language is, with so many weird dark darks. The number of air quotes needed above is pretty illuminating on its own.