Google Launches Carbon, an Experimental Replacement for C++
thenewstack.io
thenewstack.io
I would say the number one weakness of C++ is its model of copy by default and often by surprise. For example: f(std::move(x)) will copy x if x is const or f takes its value by const ref - rather than a compiler error as you might reasonably expect (if you don't know the C++ reference model inside out).
In Rust, moves are destructive (which simplifies implementions - you don't need an "empty" state) and always bitwise (which is usually fine, so long as they're destructive); and copies are always explicit so you don't have the above problem. I personally think that is all more useful than the borrow checker.
If Carbon has the same bizarre move/copy rules as C++ then the effort is wasted IMO.
Without the borrow checker, this "move-by-default, move is memcpy" semantics would break all hell loose. Dangling pointers/references would be everywhere. I like this part of Rust, but I'm not sure if it can work in a non-GC, no-borrow-checker language.
It seems to me that would be enough, but maybe I haven't thought it through properly, or maybe you'd end up having to copy a lot more often than you want to (or use optional half the time, which might defeat the point a bit).
If you can track whether or not a variable has been (definitely) initialized, you can track whether or not a variable has been moved from. It's the same basic logic. And there are languages without full borrow checkers that can do that--Java is the first one that comes to mind.
fn main() {
let x = [1, 2, 3];
println!("{:?}", x);
let y = x.map(|x| x % 2 == 0);
println!("{:?}", y);
}
x is borrowed by println (or rather by code that println expands to) and then it is moved by array::map. The compiler needs to know that before x.map(), x is not borrowed anymore. Otherwise it could be that println actually stored a reference to x somewhere and now you have a dangling reference possibly breaking type-safety (referring to an array of bools through a reference to array of ints, if the map is implemented as an in-place operation). void foo() {
if (true) {
Foo f;
stores_a_reference_to_foo(&f);
}
uses_stored_reference_to_foo();
}
I see that destructive moves would in theory introduce more opportunities for that, but I don't really see it making a big difference in practice - routines that take a pointer/reference and hold onto them (without taking ownership) already need a lot of care in C++. template<class T> T std::move(T&& t) {
return T(static_cast<typename std::remove_reference<T>::type&&>(t));
}
But it would have had performance implications.Given fn(const Foo&) (or fn(Foo&)), your implementation would stop fn(move(x)) from compiling.
But given fn(Foo) and const Foo x, your implementation would still allow fn(move(x)) to compile and perform a copy.
The plain Foo case won't do any copies because of NRVO and temporary elision (both optimizations are now guaranteed by the standard); again x will be moved from.
The upside of this implementation is that x is always moved from. The downside is that sometimes more objects are created (for example in the const&) than the pure cast case and can't always be reliably optimized out.
Not true. Both Foo& [1] and const Foo& [2] parameter types fail to compile (in gcc 8.5, I also tried gcc 10 with same result).
Bizarrely, in more modern compilers, including gcc 11, both Foo& [3] and const Foo& [4] do compile, even with the language version forced to C++11. I'm very curious to know why; presumably there's some defect report that got retroactively applied to all standards, but I can't find anything relevant. In any case, this illustrates how cryptic the C++ rvalue rules are.
[1] https://godbolt.org/z/97Yse4jWY
[2] https://godbolt.org/z/Gsj83zes6
[3] https://godbolt.org/z/xWhG9cxKn
[4] https://godbolt.org/z/xadn7Txh4
> Const foo& will as temporaries can bind to const references; this is desirable and x is still moved from.
Well that (it's desirable) is your opinion! In my view, in an ideal world, f(move(x)) would not mean there is at least one move... it would mean there are at most zero copies.
I forgot remove reference for the T in the result type and in the return statement.
Interestingly it compiles with gcc-12 for some reason.
In generic code you do want to copy if T is not movable (for example when implementing a container). The annoying thing with the existing std move is that it might or might not move from the x depending on the implementation of the sink. This implementation will always move from if x is movable.
Different tradeoffs.
Now can we make a move with your requirements (only move no copy?) I think so. Let me think about it.
Rust has implicit copies too, e.g. if you do:
let v = 2u16;
foo(v);
then v is being copied. What Rust does not have is implicit deep copies. The auto-copying depends on the type and is only done for types that don't have a custom destructor, or to be more precise, implement the Copy trait. So a big array of integers gets copied (because it implements the Copy trait), but a Vec gets moved (because of its custom destructor there is no Copy trait implementation).What's important about Copy is that, since you said you want to permit Copy here, it's OK if Rust keeps both identical bit patterns alive after the bits are copied. Just keeping both alive is obviously better for trivial types like u32, but on modern hardware it's also true for somewhat more complicated types like &str (which is a pointer and a count) or SocketAddrV6 (an IPv6 address, a port number, flow label and so on).
Thus, in your example, v is being bit copied (at least notionally) in both cases to become the parameter of this foo function, but because v is Copy, we can nevertheless use v again on the next line, the bits in v are still alive. If v was not Copy (e.g. an owned String) then foo(v) consumes v, it's moved into foo and now it's gone, we can't access v on the next line.
The fact that foo(v) consumes v, is why core::mem::drop() is so trivial: https://doc.rust-lang.org/core/mem/fn.drop.html
struct Foo;
impl Copy for Foo {}
impl Drop for Foo {
fn drop(&mut self) {
// ...
}
}
It gives the error: error[E0184]: the trait `Copy` may not be implemented for this type; the type has a destructor
--> src/main.rs:3:1
|
3 | impl Copy for Foo {}
| ^^^^^^^^^^^^^^^^^^^^ `Copy` not allowed on types with destructors
See also the "When can't my type be Copy?" section of the Rust documentation: https://doc.rust-lang.org/1.62.0/std/marker/trait.Copy.html#...I read the documentation and had the very same question. My notes from the announcement thread had this line in it:
> * Not clear from the main design document is how the distinction--if any--between trivial/nontrivial copy/move types work. There appears to be an explicit move operator (with obvious syntax ~x), so support for nontrivial move or immovable is better than Rust already, but the avoidance of a NRVO setup still makes me wonder what the actual story is here.
Given that Carbon copies the signed-no-overflow/unsigned-may-overflow distinction from C/C++, it wouldn't surprise me if they also copy the move/copy rules from C++, as those are both rather fundamentally baked into C++ (which means you have to deal with it for automatic translation), even if they are pretty objectively confusing.
it's kitchen sink language.
choose what features you want.
choose your own style. you wanna do OOP | DOP suit yourself.
that versatility is why C++ is unmatched in terms of where it's deployed.
Safe Rust doesn't have classes, inheritance, copy constructors, move constructors, header files, preprocessor, textual substitution macros, code executing before main(), exceptions, global variables, pointer arithmetic... Looks radically simpler to me.
I agree that Rust is simpler than C++ and I think a lot of people mean that Rust isn't easier (up front). Given how new and different it can be, that makes sense.
And by the way, Rust does have pointer arithmetic.
It's not clear to me that either is simpler or easier. The big point of Rust is really memory safety, not ease of use or simplicity.
Now, that "everyone" there has a bunch of social consequences, like you're going to see a bunch more diversity in Rust's community than we've traditionally seen in this sort of endeavour. But it also means technically there's work put in to actually deliver on the slogan by making it easier for everyone to use the language.
This is how Rust has those excellent compiler diagnostics. That's not an accident, it's part of "empowering everyone". Experts could manage with a compiler that outputs terse errors like "Syntax error, line 14" but that's not going to empower everyone.
Rust has a heck of a lot of features, but it’s got nothing like the “too perfect forwarding” problem of the language behaviour just being plain hard to predict.
Rust lacking some of these makes it a somewhat unfriendly language to write libraries in.
You can have multiple inheritance. You can have as many levels of partially implemented, partially abstract classes as you like provided you eventually have a concrete class, and these abstract classes can have member data. You can have static methods, which I've seen abused as namespaces so often. You can have static methods and non static ones in a class hierarchy. Finally you can mix templates into this.
In an ideal world the developers of a project in a company would collaborate to keep this from getting out of control and enforce a relatively consistent philosophy. However in practice people have their quirks and specific not always rational views, and programmers are in general not always the best at dealing with other people, programmers included.
So a strong personality is determined to do it one way and refactors a bunch of code to their liking, and on and on, and now a variety of features have been used in different ways.
No language is immune to this as it is fundamentally a human problem, but taking out features generally helps. Since we can get by without inheritance most of the newer languages have done away with it.
I think that Carbon is not meant to be 100% backward compatible at least at this point, so they can iteratively try to smooth the rough edges of the language.
The Github Page[1] says this: "The best way to address these problems is to avoid inheriting the legacy of C or C++ directly, and instead start with solid language foundations like modern generics system, modular code organization, and consistent, simple syntax."
It is also important to separate C++ the language from its standard library.
As C++ the language has modernized, it has dramatically reduced the lines of code to express a given thing. And the more modern way of expressing the thing has stronger type safety, more flexibility, and better composability. Things that used to require a lot of template metaprogramming magic to pull off are now clean one-liners. Particularly in C++20, which is probably the biggest step-change since C++11, metaprogramming is simultaneously much more powerful and much more readable. A lot of code that used to be written is now metaprogrammed. Previous use cases that required C macros largely have native C++ equivalents at this point.
The major issue that makes C++ seem complex is the standard library, which was largely designed and written for legacy versions of C++. If you use the standard library heavily, it tends to want to be used in the style of C++ for which it was originally written. If you built a standard library for C++20 from first principles, it would look quite different from the one we have. Hence the proliferation of non-standard "standard" libraries for C++.
That said, I like the idea of rewriting old C++ code with modern C++. That'd be also a good way to learn modern C++ in a practical way and having legacy code serves well for this context ;-)
Any examples for this? My knowledge stopped at boost and I guess there are more.
Not sure if you've missed this, but this is a number one reason many consider C++ absurdly complex. To actually know C++ is to know many different similar languages based on the year the code was written. C++20 is very different than C++03 as noted. Now compare this with C, or Go, Java, etc. which in comparison have barely changed.
[1]. https://www.wired.com/2015/09/google-2-billion-lines-codeand...
> Introduces yet another non standardized, corporately backed Rust look-alike language.
What's gonna happen when we have 5 of these things crawling around, are they going to be compatible with each other?
Rust has none of these. For every line of Rust code in the world, there are likely 10e3 - 100e3 lines of C++. You can either label it all "legacy code" and pretend your employer has the budget or time to rewrite it all, or you can find something in between writing new "legacy code", or throwing away your (for a company like Google) absolutely huge investment.
FWIW projects that build for interoperability have a much higher chance of long term success than those that don't. This is true for everything in software, not just programming languages. For this reason alone you can't easily compare Carbon and Rust. Carbon sounds something a little closer to Vala (C compatibility) than anything like Rust
Also your Vala comparison would imply this language compiles to C++.
That's a big "if" of course, and time will tell whether they manage to pull it off, but at least that seems to be where they want to go.
The way I see it, Carbon has C++ compatibility as a requirement, adding as much safety, performance etc. as possible on top, while Rust seems to start from a safe-by-default approach and building its way from there.
I like the ability of Carbon to seamlessly integrate with existing C/C++ code and libraries.
If the thing(s) that you're looking to "better" about C++ are its atrocious compile times and/or the C++ culture's even more atrocious shared aesthetics, then the answer is "no".
However, because it's meant to compile and interop with both C and C++, I'm hopeful that it'll be an easier switch for more projects. It doesn't provide the safety checks that safe Rust does, but safe Rust requires a rewrite IIUC.
As it is, Google can't make changes to C++ that it wants in a timely manner (if at all). Having a C++g edition where there are slight changes to the language for the Google flavor rather than the latest standard makes things even worse.
From Google's perspective, the same can be said of Rust.
What Google does see is Swift where there are significant evolutionary changes to the language over the time.
So, Google has created their own language to fit into a similar space as C++ and allows them to make changes to the language at a much more rapid pace than the C++ standards committee would have.
My crystal ball says "this language will diverge further and further from where it started as Google changes it to solve Google Problems."
This shouldn't be a "Oh! Neat! Everyone start coding in Carbon - it's the next C++!" Yes, it's interesting in that there are some interesting ideas in it and refinement of ideas that aren't practical elsewhere. However, this is a language created to solve Google's problems - not the world's.
What exactly does this language solve in Google’s problem domain that can’t be enforced through guidelines?
The Google C++ style guide is longer than the Carbon language design (though I will note a large number of sections that are "TODO").
(working from guesswork here)
Given the codebase that Google currently has in C++, the amount of effort to continue enforcing those style guides through human "this needs to change before I can approve it" to (in Google's eyes) more reasonable code with Carbon ultimately results in less developer time being spent reviewing style guide issues. At that scale, this may become a significant savings even when taking into account creating a new language.
I’m aware a language that enforces better coding styles is more efficient, I’m asking how and why does Carbon do this.
Reading the design document for Carbon and looking at the samples, it appears that many of these are not as easy to access.
Things such as "not using the preprocessor for meta programming" by itself is a significant advantage.
https://github.com/carbon-language/carbon-lang
Helps with quick auto-completion, and someday when I get to dictate code, fewer mistakes.
also programs aren’t proofs so we certainly shouldn’t name keywords after them
I wonder if `var`/`let` is easier because the words aren't as close as `var`/`val`? Or maybe it just gets easier with experience?
The number of current and former Google employees that transitioned from being Gophers to being Rustaceans that I know of is basically a 100% conversion rate. Nobody at Google will use Carbon, nobody outside of Google will use Carbon.
It's going to be worse than the Swift implosion.
The linked article explains this: classes defined in C++ can be used in Carbon and vice-versa. It even suggests you stick to Rust if that's not what you need.
Edit: Oops, I assumed that the "linked article" was the github page[1] for Carbon, which is a lot more useful.
[1] https://github.com/carbon-language/carbon-lang#why-build-car...
What's wrong with Swift? It's a replacement for Objective-C, that nobody besides macOS/iOS devs used anyway, therefore it's no big deal if nobody uses it outside of macOS/iOS development, as it's not a regression
The number of pure-Swift projects I've seen per tempus is far less than pure-ObjC, which I think is the best measurement to comprehend Swift uptake. Nobody wanted an ObjC replacement, Apple misread the room.
[1] https://survey.stackoverflow.co/2022/#technology-most-popula...
For an analogy, imagine using a workbench and being forced to put each tool back into it's respective drawer once I am done using it - even though I will certainly need to use the tool again very soon. Whereas other IDEs let my workbench be as customized and cluttered as I want it to be.
And also, as most apple dev tools, it is the only modern language whose compiler failed under me (other than being slow as hell) - I have never gotten a type inference timed out error in other languages, even though it has been around for a time :D
As for growing a language, this is a must watch (bear with the presenter for the bit, you will soon understand why he talks strangely in the beginning): https://m.youtube.com/watch?v=_ahvzDzKdB0
So why "compete" with Rust? Because C++ compatibility was never a design goal of Rust, so gradual, painless migration from C++ to Rust is a non-starter. The best you can hope to do is rewrite entire subsystems where the API is narrow enough. This new language is obviously going to allow something more like Kotlin or even Swift where codebases will be mixed and new code will be written in Carbon.
The problem with Rust is that it does not have this built directly into the language and relies on third party libraries. That doesn't really scale properly and some of the solutions are half-automated and needs lots of fine tuning, flag toggles and other configuration for it to work.
Carbon, Swift and D have a different approach in integrating the interop capability directly into the language which does sound like an easier way to automate this use it for existing C++ libraries. But I guess that this approach is not easy, but it seems with D lang, it paid off.
Go is a bigger language than Rust, it's not surprising to see people move over, that doesn't mean it's going to get used.
You're also vastly underestimating the number of people who otherwise like C++ and wish there was just an easier to use version.
For example - if 'Magic Carbon' somehow got rid of the ugly parts of C++, integrated smart pointers into the syntax, made the tooling, builds more robust, and somehow made it possible to integrate with C/C++, it'd be my new favourite language.
The article addresses this directly and is clear that Carbon is not designed to 'compete with Rust', and instead targets a much narrower use-case:
> Carbon is for those developers who already have large codebases in C++, which are difficult to convert into Rust.
I don't have a large C++ codebase to maintain so I don't currently have any use for Carbon, but I could see it being interesting for those who do.
So which way is this gonna go? Or do they have some other way to do memory management that nobody's thought of yet? If they had that, it'd be much more impressive than anything else they've said so far.
I thought Linux was C only and Linus is actively hostile against cpp for some good reasons.
It won't be for long (Rust) https://thenewstack.io/rust-in-the-linux-kernel-by-2023-linu... .
But I don't expect C++ to be added.
> It won't be for long (Rust)
To be pedantic, it already isn't; a small but very important part of Linux is written in assembly (it used to be more, but most of it was ported to C; what's left is a small core which simply cannot be expressed correctly in C).
While the memory safety aspects of Rust is good for security, its still an evolving language and doesn't have the same stability as C. Its the same reason why C++ hasn't been adopted.
Among the reasons C++ hasn't been adopted for Linux:
* Nobody actually did the hard work. The Rust for Linux people have spent a lot of time actually making this possible. C++ proponents tend to just drive past "Ha, you should use C++" which they presumably think makes them seem clever but it doesn't.
* C++ doesn't have a coherent "freestanding" subset. In theory (and according to the ISO document) there's freestanding C++ but in practice you quickly find you need lots of custom runtime stuff, it's not really part of the C++ standard at all.
* Linus is trying not to be an asshole and that's not going to be helped by introducing a C++ culture where you'll routinely see sentiments like "This has a Code of Conduct so it's for fucking snowflakes".
* C++ loves implicit allocation and Linus hates implicit allocation, especially infallible allocation. Now, you could sort of fix this if you rewrote a lot of stuff, and indeed in the Rust for Linux implementation of alloc (Rust's allocation library) there are a lot of places where it does fallible allocation and doesn't offer implicit allocation.
The example of the latter which won't affect most kernel programmers but I think is easiest for a typical programmer to understand is this: In C++ or Rust, if I have a string called adjective (maybe it's "Fast") and a string called noun (maybe "Cheese", and I write phrase = adjective + noun; then we're going to get the resulting word from concatenating the two strings ("FastCheese"), right? Is this abuse of the + operator? Maybe. But it works. In Rust for Linux that won't compile. Because it's an implied, infallible allocation. To put that concatenated string somewhere there's an allocation, which could fail, and how could the + operator "fail" ? Where does the error go if this happens?
I guess it hasn't as good interoperability with existing C++ as Carbon is aiming for (I don't think, could be wrong) and wouldn't give Google as much control of it as it probably will have over Carbon.
How long before they pull the rug out, or do any of their other dirty shenanigans?
Out of all the projects where you could trot out this tired "killed by google" shit, this is literally the worst one. What is your thought process here? "I don't know anything about the subject, but let me repeat a lame joke that people will surely find hilarious despite it being the thousandth time it gets posted to HN this year. Surely it will play to the crowd."
Not controlled by Google in that Google literally owns at most half of it?
What, exactly, would they need to do to satisfy you?
But how this is accomplished, article does not go into detail in this. Is there going to be ABI compatibility with C++? What are the features that make Carbon a better porting target than Rust?
This is quite smart as you are basically getting ABI compatibility for free. Assuming you have the source code to the C++.
I'm not sure how it will work with dynamic or proprietary libraries, but as I understand it that is already a technically unsolved ABI problem with C++.
I think Carbon will be a much better choice for extending a C++ project.
Rust might be a good choice if you are able to start from scratch or the project has C bindings.
(The idea with Carbon is you could replace specific C++ classes or headers.)
I think already the very first sentence is already wrong.
1998 ISO/IEC 14882:1998 C++98
2003 ISO/IEC 14882:2003 C++03
2011 ISO/IEC 14882:2011 C++11
2014 ISO/IEC 14882:2014 C++14
2017 ISO/IEC 14882:2017 C++17
2020 ISO/IEC 14882:2020 C++20
Where C++11 and C++20 are huge major upgrades.This is both a strength and a weakness of C++. It's a very old language and it has been keeping that backwards compatibility promise for a very long time. The result is that certain portions of the language are effectively unchangeable as a result. This is the key thing that Rust's editions are trying avoid.
> Where C++11 and C++20 are huge major upgrades.
They seem significant by the standards of C++ but they're rather less impressive in the bigger picture.
var r : i32;
How is this any better than int32_t r;
?
all I see is additional, unnecessary keyword to type.The type omission version isn't very useful, as this type of code is difficult to read later. Generally end up regretting using auto, and end up converting it to the actual type, except with iterators or nasty templates.
For example "if the compiler can inherit the type" should read "if the compiler can infer the type".
abc * xyz;
Depending on what abc is (variable or type name) it can be either a multiplication or pointer variable declaration. With the new syntax ambiguity is reduced.This might not be a huge issue for people reading code (because in context it should be pretty obvious), but for compiler it means that type information is required to parse code and compiler stages get mixed together.
let foo : & fn(&[MyType], i32) -> String = ...
(a reference to a function that takes a slice and a 32bit signed integer as arguments and returns a string)is dramatically simpler than the C/C++ equivalent.
More subjectively, I find `var` or equivalent makes code much easier to read, because you can scan for variable declarations much more easily. With C++ code, almost any token could be a variable declaration and you have to think about the type even if you wouldn't otherwise care about it. It also allows you to have inferred types without a separate auto keyword.
let foo : & (&[MyType] -> i32) -> String = ...
Like in Haskell? Seems having both `fn` and `->` is unnecessary? fn foo_bar(foo: &[MyType], bar: i32) -> String { ... }
so probably to match that.I believe Haskell does something clever such that there is no difference between a function that takes two parameters, and a function that takes one parameter and returns a function that takes the second parameter. This isn't the case in Rust. Those would be distinct types and the latter would be called differently to the former. So I'm not sure that the Haskell syntax would work for Rust.
On that note, is there any recently created programming language decided to go with that type before name?
Not to mention the weird appearance of uppercase letters in function calls (Print ?)
The benefit that C++ and Carbon can run together is a nice feature. It is like Objective-C++ (using ObjC + C++ together) or Swift/ObjC that worked well in gamedev as well when you needed to wire in a C/C++ game engine into iOS. For Android the NDK.
I think any C++ replacement has to be compatible with C++ but at that point isn't C++ still the root? C++ will never go away and it is actually a great language that is powerful. Then again I have spent lots of time in gamedev where that matters and most libs are going to be C/C++ for the foreseeable future.
Just learn C++.
You'll probably need to learn C++ to understand integrations with Carbon anyways. Carbon seems like yet another language you'll have to learn that is built on and tries to replace C++.
Fun fact: Fun fact: Objective-C was made in 1984, one year before C++ (1985).
the hate is pretty simple:
- compile times
- vague compiler errors
- template syntax is incredibly hard to read, especially when using techniques like sfinae, or trying to write functional interfaces
- really bad names for idioms (raii, sfinae, pimpl)
- really bad names for standard library types & functions
- truly arrogant community (notice how the boost website doesn't advertise that it's the easiest to use library -- it's the "most expertly designed")
- class member function declaration is out of control (`virtual const foo bar(const baz& x) const override`)
- defaults are unsafe (mutable by default)
- package management is a nightmare (i've only used conan, which is starting to mature, but still has a limited selection of packages, and seems to constantly break how they do things...because package building for an ecosystem as wide and unstructured as c++ is an intractable problem)
- cmake is the worst dsl ever. the program itself is fine, but the dsl is the worst.
- footguns everywhere (auto vs auto&...but auto* exists, and isn't necessary)
- N different ways of initializing
- it's incredibly hard to teach
- inconsistencies w/ C (brace initialization w/ named fields)
- incredibly subtle things can have a huge impact (class member variable declaration order)
- no standard way to document classes & functions
there are still certainly use cases where it's worth using, but the hate is pretty straightforward to me: it's just more hassle than it's worth most of the time. and there is some inner language struggling to get out that's probably nice to use. There are some nice things about it: notably static destruction.
and yes, some of those are more ecosystem based / my own opinions / not necessarily "the language" -- and there are reasons for why many of the warts are the way they are (backwards compatibility, control over construction order). it's still a giant pain in my ass.
C++ is one of those things that when you grok it and can ship with it, everything else is easier. The years I have spent on C++ I have enjoyed because everything else looks easier and how performant it is. It is fun to code in as well. There are many ways to do things in C++ and that is a feature. I also feel like people use less dependencies and do more custom code in it but that may just be a gamedev thing. I like that style over using thousands of dependencies and less ability to control memory. While maybe it can be unsafe if done incorrectly, it surely has less attack vectors at the dependency level like other software today.
Additionally, it seems like C++ is still a language where programmers/developers control the products over all the middle layers that control modern software, like the hellscape that is project management of software today.
- https://chromium.googlesource.com/chromium/src/+/refs/heads/...
- https://security.googleblog.com/2021/09/an-update-on-memory-...
Would carbon be a variation of "making C++ safer" mentioned in that blog post?
It's not as bad as Microsoft though, with the word "Unity" - both a game development platform and an IOC container. Had loads of fun googling help for the IOC container when 90% of the results were about the game dev platform - also in C#.
Interesting tact, and at face value that concession might undermine adoption given that Rust has a big head start and not hinged to a corp with a well-earned reputation for killing projects.
I see this about exceptions, for instance:
"Carbon may not provide seamless interoperability support for C++ exceptions. For example, translating C++ exceptions to or from Carbon errors might require annotations or bridge code, and those translations may have some performance overhead or lose information. Furthermore, if Carbon code calls a C++ function without suitable annotations or bridging, and that function exits with an exception, the program might terminate."
https://github.com/carbon-language/carbon-lang/blob/trunk/do...
So they are already not using that feature in their C++ code today.
https://google.github.io/styleguide/cppguide.html#Exceptions
This is a team of people with serious C++ backgrounds, who explicitly are interested in this as a successor to C++. Some of these are people who worked on P2137 which is the "Goals and priorities" paper that the committee explicitly rejected for C++ 20, so they know what they think C++ should be, and they know WG21 doesn't want that, so if they do want it they're going to need a separate vehicle to get there.
Also they're far from finished, so there's the attraction that Carbon could be whatever it is you want, while something like Rust has decided what it is.
If Carbon can convert existing C++ code, still be human readable and have way faster compile speeds, then yeah it can kill C++.
I think I’ll wait couple more years before trying though.
Is this a retention activity, or do they honestly think that creating their own programming languages and tooling will help them meet their goals?
Carbon was one of two primary C-based application programming interfaces (APIs) developed by Apple for the macOS (formerly Mac OS X and OS X) operating system.
Compare also keywords or key terms:
Carbon will be built on a foundation on modern programming principles, including a generics system, that would remove the need to check and recheck the code for each instantiation. Another much needed feature lacking in C++ is memory safety. Memory access bugs are one of the largest culprits of security exploits. Carbon designers will look for ways to better track uninitialized states, design APIs and idioms that support dynamic bounds checks, and build a comprehensive default debug build mode. Over time, the designers plan to build a safe Carbon subset.
Versus...
Carbon libraries are extensively cleaned up, modernized and better "protected". While the Mac OS was filled with APIs that shared memory to pass data, under Carbon all such access was re-implemented using accessor subroutines on opaque data types. This allowed Carbon to support true multitasking and memory protection, features Mac developers had been requesting for a decade.
https://en.wikipedia.org/wiki/Carbon_(API)
Go Get 'Em!
You have to google explicitely for "Carbon API" for it to show up.
Whether even now, "carbon programming" or "carbon code" give results for Carbon language - and some other non-c++ libs named Carbon.
Even "carbon" by itself gives me some Carbon language links.
They just don't care.
https://docs.oracle.com/javase/tutorial/deployment/applet/in...
https://docs.oracle.com/javase/tutorial/deployment/applet/in...
Carbon (the Mac API) only existed to enable developers to more easily port Mac 8/9 applications to OS X, which was over 20 years ago. The Carbon API was officially discontinued in 2019 with Catalina.
The Carbon API served its purpose, it's now officially "dead", so I agree - I don't see much of an issue with giving a new technology the same name.
This trend of not putting any thought into what you name your language/framework/application is fairly new and shows serious laziness. Google's team should have done better. Naming things is hard but if you're going to make something worth people's time, it's worth spending a little more effort than they did.
Edit: it appears that Nitrogen and Phosphorus are already used by Lisp dialects.
Just look at how successful "golang" is.