C++, the successor to the C programming language, is unarguably one of the most relevant languages of the modern day. C++ powers Python machine learning, JavaScript libraries, game development, and many other tools used in modern programming languages.
For every Grand Challenge, if you get a solution, you’ll find some C++ somewhere on the bottom where you can’t see it. – Bjarne Stroustrup
C++ is also one of the older object-oriented programming languages with an adaptable design, versatility, and wide range of compatibility. C++ has inspired newer languages like Java, making the language viable for developing games, medical devices, AI and control systems, and many other applications.
Many modern programming languages like Rust and Golang have sprung up and allowed developers to write clean, safe code flexibly and with fewer hassles than their predecessors. However, older programming languages still power many codebases that run in our daily lives.
We’ve also seen programming languages roll out that proffer solutions to older ones like C/C++. In today’s world, they’re JavaScript, TypeScript, Objective-C, Swift, Java, and Kotlin.
In the recently concluded CPP North conference, Google announced that they’ve worked on a successor for C++: the Carbon programming language. In this article, we’ll go over what Carbon is, its features, how it differs from C++, how to set it up, and more.
Let’s get started!
Within C++, there is a much smaller and cleaner language struggling to get out. – Bjarne Stroustrup
Carbon is an open source, statically-typed, compiled programming language initially built by Google to succeed C++. Carbon offers developers modern programming practices, such as generics, modular code organization, and simple syntax.
Carbon hopes to match C++’s performance and scalability. The language is designed for bidirectional interoperability with C++ for migration and adoption. This means you can transpile C++ codebases to Carbon and vice versa, as well as use existing C++ libraries.
Carbon is also very friendly and has a gentle learning curve for C++ developers, offering more expressivity and support for existing software design and architecture.
Carbon is still an experiment and is in its development phase. With that said, many features to help you write the Carbon code you’ll love haven’t been added yet.
Carbon shares some strong similarities with C++. It’s infused with modern programming practices, support for C++, interoperability, memory safety, and generics. These are a few notable features of the Carbon programming language and we’ll go over some of them now.
Logically, a successor language like Carbon needs to be compatible with its preceding language. Carbon is bidirectionally (two-way) compatible with C++, and you can use any of the languages with the other. Let’s take a look at its interoperability in action:
// Source code by the authors of the Carbon programming language // C++ code used in both Carbon and C++: struct Circle { float r; }; // Carbon exposing a function for C++: package Geometry api; import Cpp library "circle.h"; import Math; fn PrintTotalArea(circles: Slice(Cpp.Circle)) { var area: f32 = 0; for (c: Cpp.Circle in circles) { area += Math.Pi * c.r * c.r; } Print("Total area: {0}", area); }
In the example above, the Carbon code uses the circle.h
C++ library to print the area of a circle.
// Source code by the authors of the Carbon programming language // C++ calling Carbon: #include <vector> #include "circle.h" #include "geometry.carbon.h" auto main(int argc, char** argv) -> int { std::vector<Circle> circles = {{1.0}, {2.0}}; // Carbon's `Slice` supports implicit construction from `std::vector`, // similar to `std::span`. Geometry::PrintTotalArea(circles); return 0; }
The above C++ code uses the geometry.carbon.h
library to print the area of a circle with the provided parameters. Notice how the Carbon code is more readable and intuitive.
Generics is one of the many great features you’ll find in modern programming languages, including Rust and Go. Carbon features a modern generics system with checked definitions and opt-in templates for seamless interoperability with existing C++ code.
Carbon’s generic system is one to look out for. It’ll ensure type checks for generic definitions to avoid the cost of definition checks at compile time. It’ll also ensure robust checked interfaces to reduce accidental dependencies on implementation and create significant explicit contracts.
Memory safety is a big tasking point of using C++. Carbon aims to address memory safety by tracking uninitialized states, increasing initialization enforcements, and discouraging initialization bugs.
Carbon will feature fundamental APIs and idioms to support dynamic bound checks in debugging. It’ll also support hardened builds with a comprehensive default debug mode. Carbon’s safety strategy could also feature some guaranteed memory safety programming models.
You can run Carbon programs in debug, performance, and hardened modes depending on your preference for memory safety. You can read more on Carbon’s safety strategy in the GitHub documentation.
Since Carbon is new and the language is not production-ready, you can only compare Carbon with C++ based on their shared features. C++ has existed for some time and developers have been able to share their frustrations concerning the language. Hopefully, Carbon will minimize the numerous C++ issues in the same way TypeScript did for JavaScript.
Here’s a brief comparison between Carbon and C++:
Carbon
|
C++
|
|
Object-oriented
|
Yes
|
Yes
|
Learning curve
|
Gentle
|
Hard to grasp
|
Expressiveness
|
Very expressive
|
Hardly expressive
|
Type systems
|
Strongly–typed; statically–typed
|
Strongly–typed; Statically–typed
|
Generics support
|
Yes
|
Templates; Similar to generics
|
The probability of Carbon successfully succeeding C++ is relatively high in my opinion, especially considering the state of C++ and the company behind the language. Further considering the bidirectional interoperability between both languages, developers won’t necessarily have to miss out on C++ features.
Go and Dart have seen massive adoption across their intended fields, and Carbon could be quite successful.
Carbon is still in experimental mode so the language is far from production-ready. However, you can still play around with the current state of the language and consider contributing to its growth!
Now, we’ll go over how you can use Carbon’s explorer to check the codebase and play around with the language.
You’ll first need to have Homebrew installed on your computer. You can check out these installation instructions to install Homebrew on Linux and macOS.
Start by installing Bazelisk with the Homebrew package manager:
brew install bazelisk
Next, install llvm
and export the PATH
variable:
brew install llvm export PATH="$(brew --prefix llvm)/bin:${PATH}"
Clone the Carbon repository and move into its directory on your machine:
git clone https://github.com/carbon-language/carbon-lang cd carbon-lang
Finally, build and run the Carbon explorer:
bazel run //explorer -- ./explorer/testdata/print/format_only.carbon
And that’s it! Now you can begin experimenting with Carbon and checking out how the language works.
Carbon’s syntax is actually quite similar to the syntax of Rust and a few other languages. Let’s take a look into an overview of Carbon’s syntax, including variables, loops, conditionals, functions, and classes.
You can declare variables with the var
keyword. Carbon is statically-typed, so you’ll have to specify a data type.
var hello: auto = "Hello, world!";
The auto
data type is a general data type you can use on any variable. Just like C++, every statement has to end with a semicolon.
Carbon employs c-style for loops with a range of for loop functionality included.
for (var name: String in names) { // names is an array Print(name); }
The for loop iterates over an array and prints the elements of the array.
Carbon’s functions are very similar to Rust’s, with the exception that you have to declare the parameter variables explicitly.
fn Sum(var a: i32, var b: i32) -> i32 { return a + b; }
The Sum
function returns the sum of the arguments on call.
Carbon also uses the c-style conditional statements.
fn check(var value: i32) -> i32 { if(value == 7) { Print(value); } else { Print(0); } }
The check
function checks if the argument input equals 7
and either prints the value
if it does or prints 0
if the if statement is invalid.
Carbon provides a keyword for defining classes with their identifiers and fields of any type.
class Human { var phone: i32; var age: i32; var name: String; }
The Human
class has the phone
, age
, and name
fields. You can declare any number of fields for your operations.
Google and Carbon’s teams envision Carbon as a fast, scalable language that evolves and supports performance-critical software running on modern operating systems, hardware, and environments. Carbon would also sail towards backward or forward compatibility and a stable application binary interface (ABI) for the language.
An experimental but working version of Carbon is slated to be public by the end of 2022, and a full release will be available by 2024–2025. You can check out a detailed overview of the language goals.
In this article, we covered an overview of Carbon and its features, compared Carbon to its predecessor, C++, looked at how to install Carbon and how its syntax works, as well as looked into where Carbon is hoping to go in the future.
Carbon is taking a batteries-included approach to developing the language. The repository is live on GitHub, where you can contribute to the discussion and development towards building a C++ successor everyone would love.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.