This also implies that languages and tooling with robust support for integrating with unsafe legacy code are even more desirable.
It’s the only approach that has any chance of transitioning away from unsafe languages for existing, mature codebases. Rewriting entirely in a different language is not a reasonable proposition for every practical real-world project.
It's absolutely true that you need integration and compatibility to enable iterative improvements, but Rust historically has been hostile to anything besides unsafe C ABI FFI, which is not suitable for the vast majority of incremental development that needs to happen.
Luckily, this is starting to change.
This means that "solving this" requires partial integration of a C++ compiler; it's not a coincidence that the languages with the most success have been backed by the organisations that already had their own C++ compiler.
A much easier solution is to generate glue on both sides, which is what `cxx` does.
d does support c++ abi. It seems almost dead now but it is possible.
realistically there are two c++ abis in the world. Itanimum and msvc. both are known well enough that you can imblement them if you want (it is tricky)
It's not hostile to not commit resources to integrating with another language. It might be shortsighted, though.
> d does support c++ abi. It seems almost dead now but it is possible.
That was made possible by Digital Mars's existing C++ compiler and their ability to integrate with it / borrow from it. Rust can't take the same path. Additionally, D's object model is closer to C++ than Rust's is; it's not a 1:1 map, but the task is still somewhat easier. (My D days are approaching a decade ago, so I'm not sure what the current state of affairs is.)
> realistically there are two c++ abis in the world. Itanimum and msvc. both are known well enough that you can imblement them if you want (it is tricky)
The raw ABI is doable, yeah - but how do you account for the differences in how the languages work? As a simple example - C++ has copy constructors, Rust doesn't. Rust has guarantees around lifetimes, C++ doesn't. What does that look like from a binding perspective? How do you expose that in a way that's amenable to both languages?
`cxx`'s approach is to generate lowest-common denominator code that both languages can agree upon. That wouldn't work as a language feature because it requires buy-in from the other side, too.
I don't see Cranelift ever replacing them as the main backend.
Rust has integration with the C ABI(s) from day 1, which makes sense because the C ABI(s) are effectively the universal ABI(s).
> and its C++ compatibility is a joke
I'm not sure why you would want Rust to support interoperability with C++ though, they are very different languages. Moreover why does this fall on Rust? C++ has yet to support integration with Rust!
> compared to Swift
Swift bundled a whole C++ compiler (Clang) to make it work, that's a complete deal breaker for many.
> Rust historically has been hostile to anything besides unsafe C ABI FFI
Rust historically has been hostile to making the Rust ABI stable, but not to introducing other optional ABIs. Introducing e.g. a C++ ABI has just not been done because there's no mapping for many features like inheritance, move constructors, etc etc. Ultimately the problem is that most ABIs are either so simple that they're the same as the C ABI or they carry so many features that it's not possible to map them onto a different language.
I do agree that they could do more. I find it kind of wild that they haven’t copied Zig’s cross compilation story for example. But this stuff being just fine instead of world class is more of a lack of vision and direction than a hostility towards the idea. Indifference is not malice.
Also, you seem to be ignoring the crabi work, which is still not a thing, of course, but certainly isn’t “actively hostile towards non-c ABIs”.
It seems they have, which is all to the good: the work to make custom allocators practical in Rust is another example. Rust still doesn't have anything like `std.testing.checkAllAllocationFailures`, but I expect that it will at some future point. Zig certainly learned a lot from Rust, and it's good that Rust is able to do the same.
Zig is not, and will not be, a memory-safe language. But the sum of the decisions which go into the language make it categorically different from C (the language is so different from C++ as to make comparisons basically irrelevant).
Memory safety is a spectrum, not a binary, or there wouldn't be "Rust" and "safe Rust". What Rust has done is innovative, even revolutionary, but I believe this also applies to Zig in its own way. I view them as representing complementary approaches to the true goal, which is correct software with optimal performance.
I've known Andrew for a long time, and am a big fan of languages learning from each other. I have always found that the community of people working on languages is overall much more collegial to each other than their respective communities can be to each other, as a general rule. Obviously there are exceptions.
- C ABI is good enough for any compatibility
- "Rewrite it Rust" / RESF
- Prioritize language proposals, not fundamentals
I think the attitude as changed somewhat in the last 2-3 years, with more interest in cxx and crubit and crabi, although many of those things are at least partially blocked on stalled language proposals, and largely ignored by the "core" Rust community. I would say indifference and posturing does approach hostility.
There's also consistent conflation of "compatibility with C++" and "rich compatibility with all of C++". Swift is a great example of how targeting PODs and std::vector and aligning concurrency expectations gets you extremely far, especially if you limit yourself to just LLVM.
btw, I really appreciate your Rust book.
I think indifference is very different than hostility. That there's only limited time, resources, and interest and those must be balanced and that means some projects advance before others is a very different thing than a refusal to do something.
On what basis do you make this flagrant claim? There is certainly an impedance mismatch between Rust and C++, but "kicking and screaming" implies a level of malice that doesn't exist and never existed.
Such a low quality comment.
As opposed to integrating with a whole C++ frontend? Gee, I wonder why more languages haven't done this obvious idea of integrating a whole C++ frontend within their build system.
They are talking about actually safe languages, secury by design and secure by default. Which would be a lisp or scheme without an FFI, or a beam language (Erlang, Elixir). Or pony, without the FFI. Or Concurrent Pascal, not Go.
Or a safe scripting language
I wonder if there's a "bathtub curve" effect for very old code. I remember when a particularly serious openssl vulnerability (heartbleed?) caused a lot of people to look at the code and recoil in horror at it.
Plenty of people keep putting GC languages on the same basket without understanding what they are talking about.
Then if it is a domain where any kind of automatic resource management is impossible due to execution deadlines, or memory availability, Rust is an option.
Though I like using effect systems like in Nim or Ocaml for preventing allocation in specific areas.
The point is not winning micro-benchmarks games, rather there are specific SLAs for resource consumption and execution deadlines, is the language toolchain able to meet them, when the language features are used as they should, or does it run out of juice to meet those targets?
The recent Guile performance discussion thread is a good example.
If language X does meet the targets, and one still goes for "Rewrite XYZ into ZYW" approach, then we are beyond pure technical considerations.
> The recent Guile performance discussion thread is a good example.
Sounds very interesting. Can you share a link?GC.TryStartNoGCRegion - https://learn.microsoft.com/en-us/dotnet/api/system.gc.tryst...
GCSettings.LatencyMode - https://learn.microsoft.com/en-us/dotnet/standard/garbage-co...
The latter is what Osu! uses when you load and start playing a map, to sustain 1000hz game loop. Well, it also avoids allocations within it like fire but it's going to apply to any non-soft realtime system.
Only pointing out the ones relevant in 2024, and not the whole CS history.
Such projects exist. That's fine.
Didn't something similar happened at Discord. It was Go if I recall.
But most places are small, and engineers optimize the time to market while remaining at an acceptable levels of resource consumption and support expenses, by using stuff like next.js, RoR, etc. And that saves the company money.
There is also a spectrum in between, with associated hassles of transition as the company grows.
My favorite example is that eBay rewrote their backend three times, and they did it not because they kept building the wrong thing. They kept building the right thing for their scale at the moment. Baby clothes don't fit a grown-up, but wearing baby clothes while a baby was not a mistake.
Ideally, of course, you have a tool that you can keep using from the small prototype stage to the world-scale stage, and it lets you build highly correct, highly performant software quickly. Let's imagine that such a fantastical tool exists. To my mind, the problem is usually not in it but in the architecture: what's efficient at a large scale is uselessly complex at a small scale. The ability to express intricate constraints that precisely match the intricacies of your highly refined business logic may feel like an impediment while you're prototyping and haven't yet discovered what the logic should really be.
In short, more precision takes more thinking, and thinking is expensive. It should be applied where it matters most, and often it's not (yet) the technical details.
Apparently there is unwillingness to have "high class talent", while starting from scratch in a completly different programming language stack where everyone is a junior, is suddenly ok. Clearly CV driven development decision.
Secondly, in many cases, even if all optimization options on the specific language are exhausted, it is still easier to call into a native library in a lower level language, than a full rewrite from scratch.
And totally agree about CV driven development. All these rewrite articles looks like they are trying to convince themselves instead if intelligent readers about rewrites.
However, it is impressive that from 2019 to 2023 the issues went down by almost 60% without rewriting, just by adding new code in MSLs (Rust mostly, I guess, probably a bit Kotlin). 60% is a massive achievement. I wonder why there's a plateau from 2021 and 2023. The fact that they use extrapolated number for 2024 reveals their intention to show nice numbers, but it would have been more beneficial if they'd have spent the time to analyse and explain the rise from 2022 to 2023.
I'm a bit disappointed that they don't tell us how much of the new MS code is written in which language. Seems like they're using both Rust and Kotlin. Is it 95% Rust? Or "just" 50% Rust? If the Kotlin portion is significant, in what areas do they use it instead of Rust?