Will Carbon Replace C++?
semaphoreci.com
semaphoreci.com
So based on the article's own observation: no, of course not. The more interesting question is "will it stand on its own?" to which the answer is "only if it actually solves so many problems with the thing it's trying to supplant that it makes sense to give it a serious try".
And C++ just... doesn't have that many real problems. It has a lot of irks, but the problems people run into are problems that others already solved, a thousand times, over the last half century, in many different ways for many different iterations of the language.
Pretending you can replace C++ is like pretending you can replace cars. Not just "create EVs" but straight up replace cars. Good luck, you won't succeed if that's your goal, so hopefully you realise you need to focus on making a decent language that some folks might consider using instead of C++ for some of their work, instead of creating "the successor to C++".
As "Unix haters handbook" says: C++ is to C, what lung cancer is to lung.
As they compile their C code using a compiler written in C++. (GCC and Clang are both written in C++).
I like C++ and Rust. If I meet a dev who likes Go, I can guarantee we won't agree on much.
From Carbon's README:
> C++ [...] is struggling to improve and meet developers' needs, as outlined above, in no small part due to accumulating decades of technical debt. Incrementally improving C++ is extremely difficult, both due to the technical debt itself and challenges with its evolution process. 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.
Carbon will face the same issue as Dlang. Everyone agrees that Dlang is an improvement over C++ in many significant aspects, and a very impressive one at that, but in order to gain meaningful adoption the benefit has to be high enough to justify the pain of swimming upstream against the rest of the ecosystem. D never quite made it above that threshold, though perhaps in an alternate history where Google picked it up instead of pushing Go, it could have.
1. Being "C++ but nicer" is an awkward niche. It's not differentiated enough to overcome switching costs for C++ users. It's hard to justify risks of a new language, costs of hiring and/or code rewrites just for quality of life improvements.
At the same time being similar to C++ is a turn off for users who don't like C++ and look for something different.
2. D with a GC is not really competing with C++ in its core niche where C++ is irreplaceable, but rather with many many other GC languages for programs that can use almost any language. The idea of GC being optional is a hard sell, because it's an obvious switcheroo — without the GC you don't get all of the nice features, so GC-less D is even less differentiated from C++.
Carbon at least avoids the second problem. I'm not sure if Carbon's new syntax and semantic tweaks are different enough.
One unnoticed feature of D's GC is it enables safe memory allocation when doing CTFE (Compile Time Function Execution). This can be used even when the code being compiled for runtime does not link in the GC. It greatly increases the power of CTFE.
That is to say, if I want to use a third-party library, and that library was written to use the GC, and I want to _not_ use the GC, can I use said library? Or does using it require that I enable the GC for my code as well?
(Lots of D users use a mix of GC and explicit allocation. Each has their best use cases.)
May I ask what your concern is?
Hence, if you don't do GC allocations, or at least do not do them in your realtime loop, it will not pause.
D is not a GC language. It's a language with an optional GC. (It also does not have the code gen compromises that fully GC languages rely on, such as write gates.)
As soon as you disable the GC in D, you end up with a really awkward to use language, no closures, no exceptions, no dynamic arrays, I think you can't even use the common string in D without the GC.
People arguing that D can be used without a GC are just trying to sell you on something.
There is a flag to allocate them with malloc, and use RC.
> no dynamic arrays, I think you can't even use the common string in D without the GC.
Totally not true. You can't concatenate arrays (string are just arrays of char) with `arr1 ~ arr2` and you can't `new` them, but you can do pretty much anything else.
> People arguing that D can be used without a GC are just trying to sell you on something.
Of course, but C++ people have an unnatural aversion to GC also the D GC only ever collects if you allocate from it. No allocations == no collections.
For the most part, GC is a productivity enhancer, you can roll your own allocators, use malloc, etc. if you need to. You can statically ensure that some or all of your code doesn't use the GC and as expected there is a productivity/code maintenance price you pay for doing so.
If anything, D should stop pretending that it doesn't have a GC and stop trying to appeal to people who don't want a GC, it's a losing battle. D should just accept the fact that it is a GC'd language and start making the argument for why it's a better GC'd language than Java or C# or the host of other GC'd languages.
The vast majority of C++ developers do not want a GC'd version of C++, but it's possible that Java developers could be interested in a C++-like language that has a GC and good C compatibility.
GC is just one of the styles.
Yes, if you use "new" you get a GC allocation. But nobody makes you use "new". If you use the array concatenation operator, it uses the GC. But there are many ways to concatenate an array that don't use it.
As for closures, they get allocated on the GC only if they escape the stack frame. This is detected, and if you want to be told about it, annotate the function with @nogc.
What is that flag? Do you have a link to the documentation? I do remember talk about adding a feature that would allow exceptions to be allocated in @nogc code, but that was never ultimately implemented and looks to be postponed (to the best of my knowledge).
D is free to use for any purpose, being Boost licensed. We don't even keep track of who downloads it. Not that such info would do any good anyway, as anyone can host the distributions for download.
So yes, you can secretly use D at work, and we won't be able to tell on you!
To me optional GC is a major downside. Because the option to use the GC exists, I don't believe that the language and the library ecosystem will have first-class support for the no-GC users. For example, DUB's website doesn't have an option to search only for no-GC packages. I don't want to be restricted to the worse half of the language.
Doing everything that C++ can do is not a reason to switch away from C++. C++ can already do everything that C++ can do.
D has some nicer syntax, and neat little features like universal function/method call syntax, unittest blocks. But I can't go to my boss and say "Hey, we should rewrite our product in D. Why? Because the unittest block is a really cool idea".
Indeed, you should not change languages based on only one thing. It's also pedantically true that one can do anything in any Turing-complete language.
A much more interesting point is how productive one can be in different languages.
A little over a decade ago the industry (of people that cared about C++) were psyched about C++11. Today people don't really give a crap about C++20 other than checking that their code still compiles and people barely know what's in C++23. The air has been let out of the balloon, since other ecosystems have grown up and are easier/better to use than C++.
I know of multiple shops that would have "never" moved off C++ that have switched to C# or Go. The performance is there and the headaches aren't.
And frankly, C++ doesn't have an ecosystem. There's boost, abseil, folly, and to an extent Qt. Everything else is C and wrappers around C. Moving off C++ means adopting a language with a good standard library and/or an actual ecosystem that does useful things - which C++ massively lacks.
Rust is definitely in the wings and growing, it's just a shame that so much of the industrial use turned out to be crypto. Once C++ developers get over their irrational fear of generic programming and package management, Rust and it's ecosystem become extremely compelling.
C and C++ don't have a fear of package management. On the contrary, they're packaged in more ecosystems than probably anything else: gems, wheels, rpms, debs, nix, conan, vcpkg, you name it. The hard part of C and C++ packaging is making it easy for projects to integrate in all those ecosystems.
If carbon goes the same route as Rust, Go, etc. by standing up yet another hermetic ecosystem, it will be very clear that it's not really trying to replace C and C++; it will merely be trying to carve out a new niche.
I think one thing that Carbon has going for it is that it's bidirectionally compatible with C++, in the same way that Kotlin is with Java (or Swift with ObjC). If you have a massive C++ codebase, you're supposed to be able to just add new Carbon code, without changing any of your existing codebase. This should allow gradual adoption at whatever pace you want, which should help adoption a lot.
I'm waiting for some other shoes to drop here. There's some fine print in this promise that isn't widely grokked yet.
Code migration is part of the Carbon language requirements. Carbon is being designed because other existing langages didn't focus on this aspect.
The specific details and edge cases are probably to be determined.
It's clear that compatibility is a goal but it's clearly not a feature yet, so we should be careful to talk about carbon as if it has that feature, especially given how hard that feature will be to implement and support.
I'm more confident that Google will be able to meaningfully use carbon in its monorepo than I am that it will be a good replacement for C and C++ for any given non-Google project.
In practice, none of this really matters. For example, generics are just one way to do code organization, you can write codebases that are clear, maintainable, and reliable, without ever touching generics once.
This had very little to the discussion. Of course it can't be replaced. Code is created by humans, and as long as we have opinions nothing gets truly replaced. Just decreased usage over time.
> C++ and Switft just became "more dominant".
Yup, like this. Of course a general statement is no.
I have very little interest in this topic. But I seen this SAME comment a million times on anything thats new that attempts to challenge something. And as usual whether something "dethrones" something is less interesting than what changes or ideas that it offers.
Just like ALL those you listed, they didn't replace any of those, but they definitely challenged the ecosystems, or improved the old ones.
Naunce discussion is far more interesting.
For example, why do you think Carbon won't be able to gain dominance over time? I mean I think thats a huge hurdle too.
70% of security bugs are memory safety issues. That's a lot of real problems.
> It has a lot of irks, but the problems people run into are problems that others already solved, a thousand times, over the last half century, in many different ways for many different iterations of the language.
People run into memory safety issues more often in new C++ code.
https://www.chromium.org/Home/chromium-security/memory-safet...
https://security.googleblog.com/2021/09/an-update-on-memory-...
https://github.com/microsoft/MSRC-Security-Research/blob/mas...
https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
https://media.defcon.org/DEF%20CON%2030/DEF%20CON%2030%20pre...
https://advocacy.consumerreports.org/research/report-future-...
https://alexgaynor.net/2020/may/27/science-on-memory-unsafet...
https://github.com/google/sanitizers/blob/master/hwaddress-s...
https://security.googleblog.com/2022/12/memory-safe-language...
Run your code in a WASM sandbox or on a GPU, problem solved.
- WASM will be available even more places than the JVM
- way more languages will target WASM than ever did the JVM
Personally, I cannot wait for a WASM future.
Being able to target WASM for the 90% of apps that it is fast enough for and being able to use the same language and libraries to target native when required….is going to be awesome.
I really like the CLR. A more widely adopted version of something similar ( WASM ) is attractive.
https://en.wikipedia.org/wiki/List_of_Java_virtual_machines
https://en.wikipedia.org/wiki/List_of_CLI_languages
And this ignoring all the bytecode environments that have existed since the 1960's.
Assuming your WASM sandbox is airtight, that would work. But there are still ways to break out or cause damage because within the sandbox, its like a flat address space with 0 modern protections like ASLR, stack canaries, page protection, etc. (unless you manually compile it in yourself). See [0]
* [0]: https://www.usenix.org/conference/usenixsecurity20/presentat...
I do think more things running in WASM or WASM-like VM's could help a lot, but I'm not sure what the GPU part is supposed to mean.
Are these really real enough problems, though? If you're defending against state level attackers it's a problem. But how much do these really impact Joe Schmoe average computer user?
People targeted by state level actors are people too, and software should protect them if it can, and not having mem related bugs is definitely possible :)
You don't have to be the final target to be a botnet node... you don't even need to be a specific target to get a keylogger that tracks your logins for financial websites.
Yes... it is REALLY REAL ENOUGH,
Because I think the answer is all of us.
Also, the targets of state level actors are using the same software as the rest of us. If ours is insecure, theirs is too. Have you seen the list of Open Source vulnerabilities the US Gov has not patched?
If you oppose change so much that you just shrug in the face of free 70% reduction of risk I don't know what to tell you.
It does not have many, but it has one and it's big. It's not memory safe.
Check out this talk by Herb Sutter, around minute 43:
This is the first time a government [see note] has actually issued guidance to industry broadly that was the barest paraphrase away from "where possible don't use C and C++"
[ Note: in this context, the "government" is the US Department of Commerce and NIST, which, according to Herb, have issued a detailed guidance in response to the Executive Order on Cybersecurity [2]. While I couldn't find that guidance, I found one by the NSA [3], which saw quite a few comments here on HN in December last year [4] ].[1] https://www.youtube.com/watch?v=ELeZAKCN4tY
[2] https://www.whitehouse.gov/briefing-room/presidential-action...
[3] https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
Modern C++ has made big inroads into removing memory safety issues though. Memory safety bugs are relatively uncommon in modern C++ compared to pre C++11 times.
You could argue that C++ is still "unsafe by default" and you'd be right. But most C++ programmers use smart pointers and unique pointers rather than raw pointers now, vectors instead of raw arrays, etc.. And it does make a big difference.
Note that std::vector's at() predates C++11, whereas std::span was added in C++20. It's a myth that C++ is getting more memory-safe; in many aspects it's actually regressing.
In a greenfield project where you control every line of C++ code, you can easily achieve very good safety using nothing but ancient C++ features.
Not just memory safety. I mean, you can make your own numeric types that do overflow checks and throw exceptions or whatever. It probably won't be very fast, but it will be solid.
People have used C++ (ancient C++) to make numeric types with units, where you can't add "kilograms per second" to "meters". I remember that from some talk thing I went to in 1999.
All three major C++ standard library implementations have an option to enable assertion checks in both std::vector and std::span operator[]. Enable them unless you are in such a resource limited environment that you can't afford the checks (unlikely). The only reason the standard doesn't require the checks is to allow C++ to be usable in those resource limited environments. You could argue the checks should be enabled by default, but that's not something for the standard to decide, complain to your standard library vendor.
std::string foo = "foo";
const std::string foo2 = absl::StripAsciiWhitespace(absl::AsciiStrToUpper(foo)); // in Python: foo2 = foo.upper().strip()
std::cout << foo2; // garbage
Yeah, all technically the user's fault, but it gets pretty tiring worrying about this stuff when you're writing a high-level application and the few CPU cycles you save don't really matter. No matter how good you are, you will make mistakes, and the chance of one bug corrupting memory in your whole process increases exponentially with the LoC written. Also I have to point out the irony in a language being type-safe but not memory-safe.
Also, I didn't expect Java-looking class syntax to leave member variables uninitialized (garbage) if you don't set a default. That should at least be a compiler warning, I mean how often do you actually want that?
Misnomer aside, there is no contradiction. Type safety is much easier to reason about at compile time than memory management. So, it shouldn't come as a surprise. You need a rust like "borrow checker"-by-default functionality.
The contradiction is when the veteran SWEs I work with say we use C++ instead of Python for the added safety of compile-time type checks, treating dynamic typing like a bigger risk than memory trampling (never mind that Python has type-checking too if you really want it).
C++ does have issues. However few languages can handle complex problems well. (Rust is very intriguing for the possible ability to do things at the same scale)
If you use the wrong type in Python, you get an unhandled exception failing to find a property or something, that's about it. Maybe there's a contrived scenario where it'll succeed in a wrong way, but again that's a smaller blast radius
C++ has exceptions too, but I've never used them, so idk. The abseil statuses end up being used like DIY exception handling, and it's ok but a bit easier to mishandle something than in Python. And a segfault cannot(? or shouldn't) be caught and will crash the whole program.
For short programs Python works great, but it doesn't scale to large programs.
The problem is C++'s priorities. Priority #1 is performance, and if you look closely, nearly every single instance of this buggy-program hostile attitude comes down to the language and libraries absolutely refusing to do any kind of dynamic safety checking by default. UB can be traced directly from "it's too hard to reason about the implications of buggy programs" to "well, don't do that, stupid programmer".
I'm no expert in this, I'm just a guy who's sick of writing web backends in C++ for no reason.
No. It's not. It's designed by committee -- impossible to deprecate old misfeatures, trying to entertain everybody but please nobody.
<source>: In function 'int main()':
<source>:6:54: error: conversion from 'absl::string_view' {aka 'std::basic_string_view<char>'} to non-scalar type 'const std::string' {aka 'const std::__cxx11::basic_string<char>'} requested
6 | const std::string foo2 = absl::StripAsciiWhitespace(absl::AsciiStrToUpper(foo)); // in Python: foo2 = foo.upper().strip()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
This is gcc with c++20, curious what the garbage is you're describing.The garbage comes from AsciiStrToUpper returning a new std::string which StripAsciiWhitespace takes as a string_view (implicit conversion). By the time you print foo2, the string is already freed.
For those downvoting, please explain why you think string_view should take ownership of an rvalue string
I didn't downvote, btw. I don't do that in general.
Just turn people loose on your codebase without supervision and be really surprised that the hackers make off with your data?
You, sir, are arguing from bad faith as your obvious mission is to promote “rust in all the places”.
But sure, you can still make the error with expiclit types.
But "Herb Sutter says you should use it, he even gave it a catchy name/acronym" is as good as it gets. And he does so AFAIK in the same place he created the "Almost Always Auto" name: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style...
Notice that he says "the main reasons to declare variables using auto are for correctness, performance, maintainability, and robustness—and, yes, convenience, but that’s in last place on the list.". He is arguing literally the opposite of what you do, that using auto avoids bugs ("for correctness").
I'm not going to argue in favour or against "Almost Always Auto". But I see no problem calling it "Modern C++".
* Herb Sutter being the convener of ISO WG21
Even if you use string_view on the LHS instead of auto, pretty easy to miss the bug here.
It's even better if your language has a way to express "the return value points to data from the input argument, so it's a compile error to pass a rvalue string to this function". The second we got a language able to do that, usable everywhere where C++ is, (yes, that one) the incapacity of C++ to express this became "a problem with C++". Our expectations have just increased.
Surely it can be catched via static analysis if you suppose the common case that the return value is a function of the argument, and not pointing to some static global data. But you will get false positives when somebody does the uncommon case. There is a lack of expressiveness in C++ here.
Last I remember, the lifetime profile stuff was there, but there was still no way to add your own annotations. For some reason, I didn't hear too much about any of this, it was
- clang is working on it
- clang is working on it
- clang is working on it
- Visual Studio has it
- clang is working on it
- Silence
gcc still has nothing, right?
There are so many details you need to keep track of, and eventually you make a mistake. Now, yes, i know what all of that does, and how they are supposed to be used, but it does not remove the cognitive load.
Many languages have a substantially lower cognitive load when doing something trivial, such as ToLower().ToUpper(), etc.
Let’s not make this a language war, there has to be some programming language that does low-level memory operations without batteries included for some types of technologies. When I write code in C++ and I want something like garbage collection or ref counting I can reach for a shared_ptr.
If you don’t want to concern yourself with types, values vs references, or manual memory management don’t choose C++. The default handling is sane if not necessarily intuitive. You shouldn’t create a ref or pseudo-ref (string_view) to data that is not on the heap and no longer allocated to the stack - seems sane. This problem could be easily caught by breaking function calls into separate lines and explicitly specifying the types at each step.
From Xerox point of view, yes. Unfortunely they lost to the UNIX workstation market.
Interlisp-D, Smalltalk and Mesa/Cedar.
Believing that one size fits all is a sure way to alienate a lot of people who don't fit that size. Right tool for the right job and giving the freedom for people to solve their problems in the best way is a better way to win people over.
Nothing to do with the technology.
Hence why I love why Android is so locked down to native code, and Apple is doubling down on Swift.
Google also has a lot of stuff in the middle where they're fine with sacrificing a little speed for a lot more safety, but Java etc are too slow. Golang was supposed to satisfy that, but I'm guessing it was too big of a leap from C++.
Is Cpp systems-level language? As I see, the problems arrives from the fact that Cpp is a multi-paradigm language, and as such contains a near endless wealth of features to combine. Also modern Cpp takes a clear direction away from low level to (relatively) more high-level language. The problem really comes from the combination of low level and high level paradigms in the same language/codebase, where the expectations of the behavior of each piece of code can vary wildly.
> ... will have these sharp edges handled differently
Perversely, plain C, often has a lower cognitive load than Cpp. This is because you must always manually handle pointers, types, object lifetimes, etc. Now, this does result in a high cognitive load, BUT, the cases as in Cpp where you might combine auto, with a temporary, with a pointer inside, referring to some unseen resource, cannot happen, because you cant do that in C. So the worst case in cognitive load is never as bad as in Cpp. The lack of features means less possible combinations to shoot yourself in the foot. (Though C does still have many, nor is C an ideal language)
> Let’s not make this a language war
Discussing the problems of Cpp is not language war. Nor is understanding the merits and problems of the Design of Cpp.
> If you don’t want to concern yourself with types, values vs references, or manual memory management don’t choose C++
But IF YOU DO write Cpp, there is no escaping them. Which is my point.
Now, if you wrote absl::string_view foo2 = etc., you'd have a dangling view for sure. In practical industrial usage, you'd build with an address sanitizer (it's built into clang: -fsanitize=address), which should catch that issue.
We use an address sanitizer in tests but not in production. IIRC we had one untested log output line like this that caused corruption in prod.
Modern C++ adds new features that allows you to write code that doesn't have as many memory safety problems, but all the unsafety (is that a word?) that existed in the past still exists.
Removing features that allows memory unsafety will probably never happen, because one of the main reasons people use C++ is all the legacy code will still be used for decades.
It's great that you can write C++ using only the newest features, and that does increase safety. But that doesn't offer the same guarantees of languages designed to simply not have these kinds of problems, or that by design flag the points in the code where safety can't be guaranteed by the compiler.
If the code is small and doesn't change or doesn't have to last for too long, that's OK. But when it's changed over the years, it's pretty much impossible to guarantee that the unsafe parts are kept small and contained, especially as programmers leave and new ones come in.
So is there a compiler flag or external linting tool that can generate warning messages when you're using an older memory-unsafe technique where a safer and more modern technique could replace it?
I remember when people said the same thing about C++03. Plus ca change.
In C++98 you could develop a program with some unsafe core of whatever resource management you wanted, and then wrap it with the right classes so that it can't be misused.
After circa 1995, anyone struggling memory safety issues in greenfield C++ code that was completely under their control (no legacy) had to be a supreme goofball not to be leveraging the language to make that sort of thing go away.
The "Ragel" tool they used evidently generates C that uses raw pointers:
> The Ragel code is converted into generated C code which is then compiled. The C code uses, in the classic C manner, pointers to the HTML document being parsed, and Ragel itself gives the user a lot of control of the movement of those pointers. The underlying bug occurs because of a pointer error.
The bug in these Ragel-generated parsers was somehow hidden or compensated for by some buffering strategy, which they tweaked when introducing some new kinds of parsers "cf-html". Those didn't have the bug, but the different buffering turned on for them exposed the bugs in the Ragel based parsing.
https://web.archive.org/web/20170223233000/https://blog.clou...
I'm looking at the Ragel State Machine Compiler user guide. Chapter 5 (Interface to Host Program) makes it quite clear what sort of thing the Cloudfare people chose to grapple with. Ragel will write code for you planted into middle of any C function anywhere; you must provide numerous predefined variables, under prescribed names, some of which are pointers to data, and so it goes. For some languages, there are safer interfaces: for Java and Ruby there is a buffer and instead of a pointer there is an index into it. Ragel could have been upgraded to have actual C++ support of some kind.
Cloudbleed was found out in C code, with the usual issues dealing with bounds in C.
The effort needed on tooling would be significant though. I don't see that happening and overtaking Rust.
(btw the correct spelling is Achilles, Achilleus, Akhilleus, Ἀχιλλεύς)
VC++ has some annotations on that sense, problems are two fold, get the vendors to agree, and the C subculture that security actually matters.
Thanks for the correction.
For example, with -Wold-style-casts you can diganose every use of the (TYPE) EXPR casting notation, which is often seen in the lower-level C-like C++ code for punning memory.
Somewhere in some commonly included header for the project you can write declarations for C functions that should not be used, marking them deprecated. Then if people introduce strcpy or malloc or whatever you don't want, that can be diagnosed (and can fail compilation, if desired).
> It does not have many, but it has one and it's big. It's not memory safe.
It's not as big as a deal as c++ opponents make it out to be. The ratio of memory bugs to other bugs at work is basically zero. The problems that are holding our product back have nothing to do with memory safety. Of the long list of problems we need to solve, that just isn't one of them. If the only thing a new language offered over c++ was that I don't have to think about that 0.01% of bugs anymore, but in exchange I get either a garbage collector or a borrow checker to fight with, I would not switch.
Enough of this already. Not going to discuss ancient code. I currently using modern C++ and it has enough features to keep one's code reasonable safe if that was the goal. And frankly I do not remember any reported bugs in my production caused by "memory unsafety". Just plain old logic errors every once in a while.
The computer isn't "memory safe." If you want a language that can express every function of the hardware it runs on, you expose this fact as well.
Careful management of "unsafe" blocks might be an answer, but I suspect we're going to have to dig way deeper until we find a truly "safe" solution. At that point, would it actually matter which language you use?
https://www.chromium.org/Home/chromium-security/memory-safet...
https://msrc.microsoft.com/blog/2019/07/a-proactive-approach...
You can see the clear conflict in the mentality of these new languages. "Fast and, somehow, safe!" It's missing the forest for the trees, much like your retort.
People are. Like on Android.
> In Android 13, about 21% of all new native code (C/C++/Rust) is in Rust. There are approximately 1.5 million total lines of Rust code in AOSP across new functionality and components such as Keystore2, the new Ultra-wideband (UWB) stack, DNS-over-HTTP3, Android’s Virtualization framework (AVF), and various other components and their open source dependencies. These are low-level components that require a systems language which otherwise would have been implemented in C++.
> To date, there have been zero memory safety vulnerabilities discovered in Android’s Rust code.
> We don’t expect that number to stay zero forever, but given the volume of new Rust code across two Android releases, and the security-sensitive components where it’s being used, it’s a significant result. It demonstrates that Rust is fulfilling its intended purpose of preventing Android’s most common source of vulnerabilities. Historical vulnerability density is greater than 1/kLOC (1 vulnerability per thousand lines of code) in many of Android’s C/C++ components (e.g. media, Bluetooth, NFC, etc). Based on this historical vulnerability density, it’s likely that using Rust has already prevented hundreds of vulnerabilities from reaching production.
Source: Memory Safe Languages in Android 13 https://security.googleblog.com/2022/12/memory-safe-language...
But sure, keep telling yourself that it’s possible to write C++ code of this quality by being more careful or using some magical sanitizer or by hiring better developers or whatever.
Linus Torvalds - 2022
Even in my comment I quoted a passage that said "we don’t expect that number to stay zero forever". This is important. Although it has been successful so far, there will be bugs in it, even the odd memory safety bug.
That's still progress! Fewer bugs than before is progress, (mostly) eliminating a class of bugs is progress. I only addressed a person who was saying "there will still be some bugs, so there's no point tackling this at a language level". They're unable to grasp the idea of progress.
I can honestly say I've never known anyone who has written a lot of code in both C++ and some other language who has this opinion. I'd say, to the contrary, that almost every feature and characteristic of C++ is a problem - it's either a complete disaster in terms of programmer ergonomics or it makes it way too easy to create terrible bugs. It's _all_ wrong.
Once you understand lifetimes well C++ is a joy to write. 99% of all the complaints about C++ are 1. lack of automatic bounds checking, which is trivial to implement yourself 2. memory management problems because people have a poor mental model of how it works, which can be learned.
Well, so is Rust. You even have usable macros and templates that are't cancer to write.
While not a shot at your choice, a C++ dev that I follow a bit is the creator of SerenityOS. Many times and in many of his YouTube videos he has sung the praises of C++ and called it his favourite language. Presently, he is writing his own language, Jakt, to replace it. I find that interesting.
or memory management problems because Qt uses a different string type than glib uses a different string type than std, each with different ownership semantics, and by the way some of these claim to be thread-safe while others don’t say clearly one way or the other in the docs, except actually Qt’s copy-on-write implementation claims to be thread safe but assumes that the compiler inlines the mutation operators so if you forward-declare `struct QString` instead of #include <QString> then the operations might not be thread-safe…
i think the CoW problem might have been with Qt’s set type, not its string type, but you get the idea. it’s not just the language: it’s the library ecosystem too. it’s that any time i dive into contributing to a new C++ project i have to learn potentially a new memory model, one which is likely assumed instead of documented.
RAII presented an opportunity to normalize all this stuff; i’m not sure how significantly it’s unified things: i suspect it’s effective primarily in greenfield projects.
That is true for any language, even C, so your complaint is with those libraries not the language - and glib isn't even a C++ library at all while Qt is an ancient library that cares more about source-compatibility with its earlier versions than modern C++ (or even any version of C++ with a std::string).
> except actually Qt’s copy-on-write implementation claims to be thread safe but assumes that the compiler inlines the mutation operators so if you forward-declare `struct QString` instead of #include <QString> then the operations might not be thread-safe…
That doesn't make any sense. How is inlining going to affect thread safety? And (only) forward declaring a type won't let you do any mutations since at that point it's just an opaque name withoutout any known members.
> it’s not just the language: it’s the library ecosystem too.
And a new language won't fix that - especially when your idea of the library ecosystem for C++ already includes C libraries.
glibmm
i’m sorry that i’m fuzzy on my Qt CoW issue. it was 8 years ago or so, i could probably dig up the ticket about it but the point was that thread-safety is just a thing you’re guessing at whenever you’re using C++. other languages have radically reduced that guesswork.
>> it’s not just the language: it’s the library ecosystem too.
> And a new language won't fix that - especially when your idea of the library ecosystem for C++ already includes C libraries.
that doesn’t match my experience. taking the C++ codebases i’ve contributed to, more use a non-std string type than do. e.g. LMMS uses QString, Stepmania uses its “rage” rstring type. neither of these are small projects, both have download counts in the multi-millions.
new languages do address these problems. when i see a project in Rust (or Go, Typescript, …) that i’m thinking of contributing to, i can be fairly confident it’s using the standard String type and that i can come up-to-speed on its memory model instantly — when i see that same project written in C++ i don’t know if it’ll take 10 minutes or 10 hours to understand its memory model, and believe me that uncertainty does impact which projects i choose to contribute to today.
But that has to be learned for each CPP file separately.
I wrote plenty of code in Qt and C++ (up to around C++11) and I don't think it was that bad. I then moved on to JS / PHP (purely for money) and now Rust.
C++ is not that bad. Templates can be a bit hairy and slow.
Now that we have Rust to compare, having safety would be nice. It wasn't an option back then. You were either shooting yourself with undefined in scripting languages or with null pointers in C/C++. Having a dependency manager a-la npm or cargo would be nice, but it was never an option in the past.
But things are mostly fine.
Be careful with that, because it only takes government to decide to heavily tax something or simply phase out something for it to go away. Eventually the minority cost rises so it becomes a self full-filling prophecy.
That, will not apply to C++ or languages in general.
Could countries that currently don't really have cars? Yeah, probably. In the same way that a market segment that doensn't use C++ can decide not to use C++. Could a country like Vietnam? Doubtful, but maybe. A market segment with low C++ penetration can probably decide they want to collectively move away from C++. Could China? Not anymore, no. C++ drives too much software in the market segment to make sense to replace, even if the grass is greener on the other side of the language fence. Could the US or the EU ban cars (and again: not ICEs, but cars, full stop)? Let's all try not to laugh.
How much ALGOL do you see out there?
There will be almost no Objective C at some point.
There will be almost no Visual Basic.NET at some point.
A C++ replacement may take longer than the rest of my life.
It is possible though that we may not be that many years away that, for new projects, it may be uncommon to choose an “unsafe” language.
Give it time. Unlike the other examples one company (Apple) has full control here. There is basically zero demand for Objective-C outside of development for Apple platforms.
Apple is already making Swift only features and APIs and is deprecating older things. Obj-C is arguably legacy already, but still works fine.
I’ll bet plenty of money there will find a day when Apple says “This is it, next release it’s out of the toolchain”.
Existing developers often have Obj-C code (I do), but the biggest user is Apple. So they can’t kill it tomorrow. But its days are numbered.
No one is in that kind of position with C/C++/JS/Java.
Just like Kotlin hardly matters outside Android.
For those that don't use C++, Herb is chair of the ISO C++ standards committee, and holds the position of "native languages architect" at Microsoft.
https://twitter.com/herbsutter/status/1609307537261617154
This is a good introductory talk on cpp2 by Sutter at CppCon three months ago, where he demonstrates cppfront, the cpp2 -> C++ transpiler. One of the things I like about it is that the code it generates is human-readable and fully backwards-compatible with C++. If you use cpp2 in your project and end up not liking it, you still have the same (very reasonable) C++ code that you'd write by hand today if you followed the guidelines you're supposed to already.
https://www.youtube.com/watch?v=ELeZAKCN4tY
I think this is very promising, and I'm interested in using it my next project. We don't need a total replacement for C++, we just need to let out the awesome language that's always been hiding inside it.
Google threw the weight of their top C++ engineers behind Carbon. It's happening. That's really what matters in the world of programming languages. Not how good it is.
In summary, Google can do what it wants, but I'll just keep using C++ no matter what it does. I spend all my time in and on HaikuOS now, so for me C++ here here to stay :)
I like the ideas Fuschia is trying to implement, but unfortunately it still looks like a small experiment with an uncertain future.
And who knows, just like it happened with Singularity and Midori having an impact on .NET design since WinRT, some Fuchsia ideas can be brought into Android in that case.
Best of luck with your project, I look forward to seeing it released one day.
Thanks! I'm working on a port of Solvespace to Haiku. My goal is ultimately to give it a native UI and some new features, but I'm still early in the process. The latest thing I got working was some pixels in the screen from a replacement 2D renderer that uses AGG instead of Cairo. I post screenshots to Twitter as I go (@realtaraharris).
Also being dismissive of Fuchsia being a dead end despite contributing to Haiku seems a bit ironic.
Google has a notoriously short attention span.
Google throws their weight behind a lot of projects. You can find a list of 282 of those projects here: https://killedbygoogle.com/
So it's too early to say that "it's happening". Right now, it's just an experiment.
Maybe once Carbon reaches a stable 1.0 release and has seen some success in production (~2026 maybe?), that point won't be as important, but especially in the beginning it seems to me a deciding factor.
Non-intelligent converters just make a mess. Here's c2rust.[1]
Classic C++ to modern C++, plus a compiler flag to lock out all the old unsafe stuff, would be an achievement.
I like Rust well enough, but I'm simply not interested in abandoning C++ and all of the incredible stuff written in it just for the sake of theoretical purity and safety.
Carbon is an experiment to solve Google's challenges with C++, which look very different to, say, the challenges of the games industry or those of embedded software development. C++ is widely used enough that it would take decades of sustained development specifically targeting replacing it across all the areas it is used to make a dent.
It's a bit like Fortran has been displaced by C, C++, Julia, even Python (with Numpy / Scipy) from the realm of numeric code where it used to reign supreme. It does not mean that important Fortran code does not exist any more, or even that new Fortran code is not written every day. It just means that Fortran is no longer dominant, and in many areas is definitely not the first choice.
Same is happening to C++.
(Well, new Cobol code gets written.)
Golang only accepts one way of doing things and it looks like Python. It makes assumptions to replace complexity so you don't need to think too deeply in many cases. I would never pick it for any serious project, but as a quick one-off tool, especially if you're planning on networking it, Go can get the job done easily and painlessly enough.
Now, Dart, on the other hand, that's a language that doesn't need to exist in my opinion. It's ES5/ES6 with some tweaks but IMO TypeScript has since easily surpassed it at a language level. I don't know why Dart still exists, but we're stuck with it now that Flutter uses it.
I will be very surprised if a C++ successor will be a new language. I think it will be a frontend to C++ that cleans up the syntax, has much stricter rules around UB, and can rely on C++ as its unsafe counterpart. C++ itself will never be safe - it can’t be while maintaining backwards compatibility, and even modern features (ranges, coroutines) provide a wide range of new lifetime nightmares.
A new frontend could solve a lot of that, while allowing unsafe “trust me bro” code to be written in C++.
There’s the “enable new features in a file with pragmas” idea, too, which could be promising. But I’m not convinced.
To give perspective: CompCert (a C compiler with formally-proven semantics, arguably one of the largest formally-proven programs to date) has been developed for decades and still does not support all C99 features; it and sel4 (a formally-verified safe microkernel) are both single-core because proving properties in complex multicore interactions has basically not been done (sel4 actually does have a multicore implementation, but it's not yet formally verified).
Safety, performance, ease-of-use: pick two. If we really care about safety, the easiest solution for many is to just use a language like Java or Python where everything is boxed and checked and there is no truly unsafe code. Safe Rust strikes a really nice balance of being almost formally-proven safe, almost as performant as unsafe Rust/C++, and almost as easy to use as more general-purpose-languages (the extent of the third "almost" varies widely among developers).
You're looking for Herb Sutter's CppFront: https://github.com/hsutter/cppfront
As Cfront was to C, Cppfront is to C++.
However, I’d like to have seen more emphasis on safety by design, rather than safety by excluding things.
I think it’s definitely easier to get it in at this stage of cppfront’s development than it would be of Carbon, but that’s because the implementation is incredibly simple and the technical debt is low.
I have high hopes for cppfront, though. I hope it grows into a full frontend rather than a preprocessing step.
Interoperability with C++ is a very nice and useful thing but the language still needs work. Andreas' video on writing code that actually does stuff in Jakt made it clear that there are still places where the language needs to be improved (which is fine, it's not finished) and at its current state I think it'll be a while before the language gains any adoption.
The language reminds me of Zig in a way, which also featured a "transpile a language into another" approach up until recently. Unlike Zig, Jakt actually seems to have usable syntax highlighting and IDE support beyond "highlight these specific keywords". I've never found any IDE that works well with Zig, and the people I asked told me to use an older, buggy highlighter and ignore the errors or program without any IDE support.
Despite its immaturity, it's already nicer to just work with than the language behind Bun, a JS runtime mentioned here on HN a lot. That's very promising for the future of Jakt at the very least.
"interface" seems a step forward, amongst other things. I'd like to see Sumtypes (aka Algebraic Data Types) without the pain. And recursive data structures. And co-routines for mortals.
I'd be tempted to check out Carbon at some point. I am mistrustful of Google, though, what with their whole telemetry idea in Go.
A good outcome would be if Carbon pollinated some ideas into C++, acting as a testbed.
I think that C++ has steered itself exceptionally well, actually. It has aimed at stability rather than "move fast and break things". It has avoided the missteps of Raku (Perl 6), Python 3. The fact that people "hate" C++ is on balance more of a feature than a bug. The newer languages have projects which sometimes mandate nightly builds (I'm looking at you, Rust and Zig). It feels that you're trying to build a house on a sandbank.
I hope that C++ never gets a package manager/build system. I'm not convinced that they've ever really been done properly or stably (Python seems to have a plethora of install methods, for example), and it leads to the mentality of kitchen-sinking dependencies.
It is unclear to me what missteps you are referring to?
Isn't Dart a compiled language that can be compiled to JS via dart2js and not "on top of JavaScript"?
Was never built on top of V8 in any shape of form. Dart VM does not even share any code with V8.
Dart 1 was designed by people who originally started V8 (Lars Bak and Kasper Lund), that's the only connection.
It can run on ARM32, ARM64 and x84_64 natively as machine code through the Dart runtime when compiled AOT and performance is of course much better than compiling to JavaScript so you can see why it's a really interesting option for the development of Flutter which targets web, desktop, and mobile. You write the code once and get to have JIT for development with hot reloading, debugging and live metrics, and AOT compilation for your desktop and mobile targets while also getting a JavaScript bundle for your web target.
[0]: https://haxe.org/
Google could focus on making C++/Rust interop as smooth as Carbon's instead.
Betteridge's law of headlines
why do I need to type "let" and "fn", etc?
why not make the syntax very similar if you actually want to make it easy to migrate?
Personally I think it's great that most new languages seem to move in roughly the same direction when it comes to syntax.. like
"x: int" instead of "int x" for variable declaration, and something similar on functions "fn", "fun" or "function" prefix before functions "let"/"const" for constants and/or single assignment variables "var" for variables etc.
I think there's a reason so many language designers are making similar decisions on these things.
what is the advantage of type int fn foo versus int foo() {} ?
why type var in front of a variable when int x makes it clear its a variable?
It is simpler to parse, and degrades better with type inference. That’s 90% of it, I’d imagine.
By making big changes to syntax, you are just making it less likely this ever gets truly adopted.
Optimizing for character count is dead.
// Returns the smallest factor of `n` > 1, and
// whether `n` itself is prime.
fn SmallestFactor(n: i32) -> (i32, bool) {
This is so unlike C++ I cannot see how anyone can consider it a successor language. It might, in fact, be a much better language, but it is not a successor when you're going to change syntax this much, and in a way that will be hard to automate (precisely because of the "most vexing parse" problem(s).auto SmallestFactor(int32_t n) -> std::pair<int32_t, bool> { ... }
In the more general case, having the return type follow the function name means that it can reference parameters in sizeof(), decltype() etc.
auto time_keeper = TimeKeeper(Timer());
this is nice and clean
(Also, I would take var over auto any day, to be honest; but no, they had to override the old useless keyword for some mysterious reason.)
On top of that, the best keywords - e.g. in this case "let" or "var" - are also the ones most likely to clash with identifiers in existing code.
let time_keeper = TimeKeeper(Timer());
Which is one less character to type.
I’d suggest learning a couple more languages - after you’ve learned a few, you get used to it - you don’t even see the code. All I see is assignment, variable, parameter…
(But seriously, the vast majority of imperative languages have syntax which is near-enough the same that it really doesn’t matter - much like two spaces vs four spaces, you can spend days, weeks, months arguing about which is better… or you can flip a coin, pick one, and after 5 minutes of using it you’re used to it, freeing up your brain to worry about more useful things :) )
Also pointer/multiplication ambiguity: https://medium.com/@bartobri/exploring-the-ambiguous-nature-... , https://softwareengineering.stackexchange.com/questions/1245... , https://stackoverflow.com/questions/41331871/how-c-c-parser-...
Unless `int x` is followed up by an opening parenthesis, in which case it suddenly is a function definition and not a variable. Which also means a parser now needs lookahead for one of the most common statements in the language.
`let` means variable, always. Not only that but in most cases (>90%) you can omit the type as it's obvious. Now you just have to type `let s` instead of `String s`, with the difference that `let` also tells you this variable is immutable, which isn't even possible in many languages in the first place.
> involves typing one more character
Who cares. 99% of devs don't, otherwise they'd use APL or its relatives, where the entire Conway's Game of Life is a single line. There are more important factors than the number of symbols on screen.
The only that really has a chance.
However, Carbon's syntax makes technical sense, and is in line with many contemporary languages (Rust, TypeScript, Swift, Kotlin). It is easier to parse, which is important for tooling and IDEs. `fn name` is easy to grep for. `let` works well with type inference and destructuring assignment, which are becoming standard features in modern languages (although Carbon still supports C-style aggregate initializers, which is not so great).
Carbon could be a great SxS language with enough inertia building up over time: still never aim to replace C++ (a fool’s errand) but always work in conjunction with large C++ codebases.
It’s such a great pleasure to write things in TS while always being able to use mix-match JS libraries and tooling and debugging. I hope Carbon achieves a similar result moving the industry and engineers forward without resorting to “languages are religions” tediousness.
> Note that we don't expect to finish the 0.1 language work in 2023. Our goal is to make sufficient progress that we can complete it in 2024, but there are still many things that can go wrong and cause significant delays.
https://github.com/carbon-language/carbon-lang/blob/trunk/do...
So while an interesting experiment, and it can even get an ecossytem of its own, provided it doesn't go out of steam, it is still quite far from that.
The JavaScript part is a factual error. Dart can compile to js. Dart can also soon compile to wasm, but most of dart code runs on the dart VM and has nothing to do with JS.
If only there were a way to write new code in a new language, mostly unconstrained by the long history of C++, but let the two languages share a toolchain, and maintain a logical interface compatibility layer. Not just linking the same ABI, but compatible types, functions, meta-functions (templates), etc.
Then you could implement all of the features and static checks of your dreams, and modify the language and its implementation to make those features/checks more powerful and easy to implement.
My guess is that's the idea. If you weren't a huge company with zillions invested in countless lines of C++, you wouldn't need to consider this. And, regardless, it's a neat idea.
Apple has a LOT of C/C++/Obj-C/Obj-C++ code. And they certainly have the resources/need for such a thing.
I wonder if what they’re doing could be extended to make integrating new Swift code easier with all the existing non-Swift stuff as it slowly got rewritten.
I’m not suggesting everyone switch to Swift, merely that someone may already be doing something like you’re talking about.
Seems like converting a native python extension to the new language will just break all the downstream users of that package who do not already have the new toolchain set up. That's exactly what happened with the cryptography package when it converted to Rust. And that's just an example. What about all the projects shipping to embedded systems, tiny Linux distros, specialty proprietary OSs, and so on?
Maybe my comment was too harsh. It's great someone's trying to make the C++ situation better. I hope they succeed. I just think they won't and C++ should go the way of C and stop "evolving", while this thing is very similar in spirit to blowing it up even further. (I've actually liked working with C++ for the past 15 years, but not because it's productive but for the stockholmy "challenge" of it)
But I'd also assume that much (all?) of that cleanup would be stuff that would be worth doing anyways, even if you sticked to c++, but that you keep postponing...
In my opinion all these things have failed. The language is old, has insane amounts of legacy beurocracy and process tied to it, has terrible unchangeable defaults, unchangeable ABI, and is insanely complicated to "get right" (write a function that adds two signed integers and returns the result, that has no undefined behavior) to the point where there is an established tradition not to try to get it right. Yes, smart pointers are nice, concepts are also nice, but this patchwork does not work well with other features, and what this "improvement" process does is make it more complicated. Almost noone really understands it anymore.
It's time to retire it and start over completely, as well as reconsider if all the things that C++ has been traditionally used for warrant such a language. Things like GC languages or Rust/Zig should fill that space. They have decent interop where needed. Meanwhile C++ is not going away for a very long time. I see this project as building another language into C++ that makes it even more complicated.
Javascript -> Typescript is just a different domain, one where things move fast, break and are suddenly replaced or thrown away. This C/C++ stuff is slow. The industry is too big, backwards and fragmented to do anything other than start over with a completely new language where possible, and where it's not possible and just keep cleaning the dust from the antiques and hope.
There's huge C++ projects that should be in e.g. Java if started now (I really dislike Java). On the other hand, there's an ongoing effort (been there for decades!) by a cult-like group of C++ programmers, convincing themselves that they can write memory safe code, and trying to convert embedded C programers and convince them to stop dereferencing volatile hex addresses copied from decades old pdf manuals (e.g. because that's UB). These people still don't use compiler optimizations because who knows what that might do. I've used "modern" embedded C++ and mostly gotten reactions along the lines of "C is better, this new stuff is no good, abstractions obscure stuff, how are we supposed to debug which of those hex adresses don't match the pdf?" What do you do with that? It's not unreasonable: the old way worked well enough, changing things are costly and dangerous.
I believe this mess is not a technology problem that can be solved by adding more language features or dialects to C++.
What impressed me about carbon (apparently so much that I sound like a embarrassing fanboy even to myself, heh) is how determined they seem in trying to avoid scope creep: usually it's quite the opposite, every field of programming that's not entirely ruled out gets declared home turf that will eventually get revolutionized by the language (because a prototype exists and it looks pretty because it's still in that cute puppy stage when all the gnarly bits are conveniently left out)
That is what happens when languages stick around for decades
It all just seems like a band-aid (adhesive plaster for non-native speakers).
I wonder if having a stable ABI wouldn't be better. Specifically the CXX project shows how this kind of capability is extremely powerful.
Seems to me languages that focus on backward compatibility end up with a great modern core but it kinda gets lost because how do you know that the modern core? Developers learning can’t know what’s new and best and recognize what’s old noise.
It has to be said though that googles reputation for killing projects overshadows anything they do.
That's probably the reason why there is a new language created every second day. Curious to see if one will "win", though.
If Carbon ever goes beyond an experiment it will be for Google's own internal purposes.
What's wrong with that? All of my gripes with Java, other than the way they did their generics, are at the language level. The bytecode and underlying VM are works of art. Kotlin adds reification to the JVM and adds explicit nullability annotation as a compile time error rather than a warning, which solves my worst annoyances with Java. I'd still use Kotlin if all it did was transpile itself into .java files and call the compiler for me.
Kotlin also decided to become a platform of its own, just like every guest language.
It is also the reason why despite my C rants, if there is no alternative, that is what I use.
I rather use the tools that ship in the box than adding additional layers to configure and debug.
The overwhelmingly negative comments here on HN remind me of the pushback that Rust Linux kernel modules received on HN when they were first announced around 2015/2016. Now they’re seen a much loved feature (I understand they solve different problems so the analogy isn’t perfect). I’m not confident that Carbon can be used to solve the issues that arise in large C++ projects as I’ve never tried it but that’s very different from pretending C++ is some kind of perfect language that doesn’t have these flaws and doesn’t need fixing.
2. exception handling ... meh, i can't take this seriously. There's no ideal exception handling and if this is what is grinding your project to a halt, you've got bigger problems.
3. dependency handling ... if you mean "prepackaged libraries" then I'll repeat again that I don't want solutions to this baked into the language
If we can teach AI to program in C/ASM will language features matter?
then create a profile for whatever Google needs instead.
and also please create a C profile off C++ that is safer than C, and make C a true subset instead of diverging them even further.
That is, they’ve already been doing what you ask. Yet here we are.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p21...
Carbon has a few interesting ideas which I hope survive in at least some weird niche languages even if the Carbon experiment fails, because they deserve to be known to people who invent programming languages - some future Rust replacement might find a use for them for example.
But the most important thing Carbon got right that most of these C++ Successor languages did not, was that it understood why Rust is safe. Rust's safety is not primarily about the technology, although of course the technology is important, it's about the Culture, and Carbon understood that.