Google Carbon vs Apple Swift
Can Carbon replace C++ the way Swift replaced Objective-C?
The Carbon programming language is actually some pretty cool news! An early experimental version just got dropped recently on the 19th of July 2022. I will not repeat the typical press release stuff, but focus instead on what I think about this new language from Google.
Carbon is following in a trend in programming we have seen play out multiple times now, which is to take an established industry language and make a modern version of it with minimal impedance mismatch. Basically, that means that the new language keep important semantics from the legacy language, so you can easily reuse all existing code. Here are some of the languages combinations which are examples of this approach:
Swift — A language implemented on top of the Objective-C runtime with modern type safety and functional programming support.
Kotlin — A JVM language which integrates smoothly with Java. Surprising number of syntactic similarities with Swift.
Elixir—Language with Ruby syntax on top of the Erlang Virtual Machine, allowing you to reuse Erlang code effortlessly.
Zig — Drop-in replacement for C. Same layout of data as C. Similar memory management model and binary interface. C can call Zig code.
We could also add the multitude of transpilers (source-to-source compilers) which exist for JavaScript, such as TypeScript.
All these languages are designed for tight integration with another language, beyond just having some barebones foreign function interface. Java and Python, for instance, can call C code, but that does not make them drop-in replacements for C. There is quite a lot of glue code which needs to be written. Further, you don't want C to call Python or Java code. That will end up yucky.
Apple tried for a while to get people to migrate to Java and Ruby away from Objective-C. Neither approached worked. A massive investment existed in quality Objective-C libraries, which simply could not be used from Objective-C and Ruby in a way that wasn't clunky in one way or the other. The simple reason was because neither of those languages were ever designed with Objective-C in mind. There was an honorable attempt called Ruby Motion which built Ruby on top of the Objective-C runtime for much righter integration.
In the end, what really worked was creating a modern language from scratch, specifically designed to integrate tightly with the Objective-C runtime. That approach is what led to Swift.
As a long-time Objective-C developer, I got to say that really paid off. In fact, the experience was wonderful. I could split out individual methods on Objective-C classes, rewrite them to Swift code, recompile, run and see everything work just as well as before. Normally, a rewrite is a big, carefully planned project with a lot of pain.
With Swift, you could move almost as fast or slow as you wanted. You didn't even need to do a full port. You could leave half the code rarely edited alone and not port it.
Going through this experiencing porting a couple of iOS applications to Swift, I made many positive observations regarding benefits of moving to a more modern language. I have gone over the language specification of Carbon, which has led me to conclude that anyone porting their C++ code to Carbon will experience very many of the same positive benefits I experience in going from Objective-C to Swift.
Let us go over some of those benefits.
Benefits of Introducing Carbon in a C++ Project
You got to read this as educated speculation based on my experience with Swift and the features I see Carbon offers relative to C++. When I read the feature set of Carbon, it is hard to not notice the striking similarity to Swift:
No more null pointers. Use optional types instead.
Pattern matching
Tagged unions or alternatively enums on cocaine, also known as sum types.
Data must be initialized properly
There are also numerous syntactic similarities. Here is an example of Carbon code:
// Carbon code
import Console;
// Prints the Fibonacci numbers less than `limit`.
fn Fibonacci(limit: i64) {
var (a: i64, b: i64) = (0, 1);
while (a < limit) {
Console.Print(a, " ");
let next: i64 = a + b;
a = b;
b = next;
}
Console.Print("\n");
}
Notice how similar it is to the Swift code, which does the same thing:
// Swift code
import Foundation
// Prints the Fibonacci numbers less than `limit`.
func fibonacci(limit: Int64) {
var (a, b) : (Int64, Int64) = (0, 1)
while a < limit {
print(a, " ")
let next: Int64 = a + b
a = b
b = next
}
print("\n");
}
Both Carbon and Swift use keywords such as var
and let
to start declaring a variable, and use colon :
to separate the variable name from its type.
// Carbon variable
var x: i64 = 42;
// Carbon constant
let y: f64 = 13.31;
// Swift variable
var x: Int64 = 42;
// Swift constant
let y: Float64 = 13.31;
Bottom line is that there are plenty of similarities, which means it helps me gauge how it would feel to program Carbon relative to C++. I already know how Swift feels relative to C++ and Objective-C.
Catching Bugs By Porting to Carbon
When I ported Objective-C code to Swift, I got a massive amount of help from the strict Swift type checker. At times, I felt the Swift type checker was like a Nazi camp commander, but it was brilliant in uncovering sneaky bugs which the more cavalier Objective-C type checker passed by. That was not merely a question of using the wrong type. A lot more involved catching variables which had not been initialized or initialized in the wrong order. It could be code which had rarely taken code paths which the type system would warn would cause failure.
Once you start seeing these benefits, you get hooked on porting. I suspect many C++ developers once they try Carbon will get enticed by a similar experience. By seeing how a new language can help catch bugs and improve the quality of their code, they will be won over.
NOTE: If you are already a Medium subscriber you can read the full article there.
Keep reading with a 7-day free trial
Subscribe to Erik Explores to keep reading this post and get 7 days of free access to the full post archives.