Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

My observation is most people who suggest Rust alternative don't use Rust. People who actually use Rust known it is worth to rewrite C/C++ software in Rust, either the whole or part by part. There is a tool to convert C source into Rust too so you can retain the whole functionalities while migrating to Rust. I have done this with Lua and it work wonderfully.

The good news is Linux now adopt Rust. In the end it will be all Rust although it may take a long time to migrate from C.



> My observation is most people who suggest Rust alternative don't use Rust.

This is a very condescending statement. In fact, for most software, when given the option of a full rewrite from C/C++ to another language, Rust is usually the least reasonable option. Fully automatic memory-managed languages should be considered first.

> People who actually use Rust known it is worth to rewrite C/C++ software in Rust, either the whole or part by part.

A full rewrite is not a feasible option for many large projects, and Rust does not make it easy to rewrite C++ code piece by piece, as the linked article clearly explains.

It's not true that developers don't like full rewrites. Most often, it's the path most developers would choose if they had enough time and funding. But in reality, you don't get either of those two.

And even if you are willing to do a full rewrite, your project probably has non-trivial dependencies on large, mature C++ libraries. You are not going to rewrite those. This is why more new projects are started in C++ every day than in Rust.


> Rust is usually the least reasonable option

If the software was originally written in C/C++ based on some performance reasons (avoiding GC/being in control of boxing/being in control of when to use vtables etc.) then what would be more reasonable options?

> Fully automatic memory-managed languages should be considered first.

Those languages have existed for 20+ years so if they were ruled out as part of the original decision making then they probably still aren't applicable.


Problem was that 20 years ago some of those languages didn't had AOT compilation options, or if they did, they were commercial, priced at ways most developers would rather not bother.

Plenty of software has been written in C or C++, only because they were the only compiled languages known to the authors.

Having said this, Go, D, Swift, OCaml, Haskell, Common Lisp, C#, F#, Java (with GraalVM, OpenJ9).

All of them offer ways to do AOT compilation and use value types, granted Java is too verbose using Panama for that, and one is better of choosing one of the others.


I've been using F# and there are actually several roadblocks for AOT F# [0]. However, a self-contained .NET JIT executable is still surprisingly small (18 MB for an ASP.NET minimal API written in F#), easy to build, and easy to deploy.

[0] https://github.com/dotnet/fsharp/issues/13398


Yeah, I listed it, because it is kind of possible, even if there are issues currently.


And even if the speed and memory penalties are exactly the same as they were 20 years ago, you no longer need to support a pentium 3 with 64MB of RAM. If you write code that would have performed well 20 years ago, then bloat it 300%, it'll run just fine. I'd rather have that than just about any electron app.


In fact, in what concerns most of the languages, they scale down to computers much weaker than most of my 1990's PC desktops.

Some examples, one per language, there are others I could list.

https://www.wildernesslabs.co/

https://tinygo.org/

https://www.ptc.com/en/products/developer-tools/perc

https://www.swift.org/get-started/embedded/

https://wiki.dlang.org/Programming_in_D_tutorial_on_Embedded...


> Those languages have existed for 20+ years so if they were ruled out as part of the original decision making then they probably still aren't applicable.

There are huge C++ code bases that are 15+ years old and are still actively maintained because the cost of a rewrite is too high for something that still solves the problem well enough.

Most of the large C++ projects I've worked on were written in C++ because it was the most common and mainstream language given the CPU and memory constraints of that time. We have significantly more powerful CPUs now, especially considering multicore computing, and easily 5-10x more RAM than 15 years ago. Java/Kotlin, C#, Go, TypeScript, Swift etc., are perfectly applicable to many more problem domains where C++ once dominated. I can easily agree that many C++ projects would be better off transitioning to a fully garbage-collected language than to Rust.


> Those languages have existed for 20+ years so if they were ruled out as part of the original decision making then they probably still aren't applicable.

They were ruled out when the RAM/CPU budget per $SERVER could have been an expensive 4GB/2-core for a complex server processing transactions in real-time.

Today, that same complex server can cheaply run on a 48GB/6-cpu server. Those performance constraints for exactly the same $FUNCTIONALITY are such a low hurdle, dollar-wise, that it makes no sense in most applications of this heuristic.


> Fully automatic memory-managed languages should be considered first.

Of which none has solved concurrency. Some like Java prevents UB but garbage data will still be produced if you don’t diligently protect the access of the shared data.


Java doesn't produce 'garbage data', racing writes will never show intermediary results.


Loss of Sequential Consistency means realistically humans cannot understand the behaviour of the software and so "garbage" seems like a reasonable characterisation of the results. It might take a team of experts some considerable time to explain why your software did whatever it did, or you can say "that's garbage" and try to fix the problem without that understanding of the results.

The hope when Java developed this memory model was that loss of SC is something humans can cope with, it was not, the behaviour is too strange.


Even with sequential consistency, interweaving multiple threads produces results that go firmly into the garbage category. Even something as simple as adding to a variable can fail.

To solve interweaving, add mutexes. And once you have mutexes you'll be protected from weak memory models.


What is the end result of two threads adding +1 to the same counter 1 million times each in parallel?

Well, the result is safe but unknowable. I would call that garbage data.


> Fully automatic memory-managed languages should be considered first.

Why? If it was written in C++, there's a good chance it was so for performance reasons. You wouldn't want to throw that away with a GC.


> If it was written in C++, there's a good chance it was so for performance reasons.

I agree. But imagine that games like Doom or Quake would have been unthinkable if they weren't fully written in C/C++. Now, however, we have 3D game engines like Unity that expose a C# API for game logic scripting, and it seems to work just fine. Performance is becoming less of a concern for more and more problem domains.


With lots of Assembly, inline Assembly isn't C or C++, regardless of how many devs might pretend otherwise.

It is like saying C libraries are Python, only because they happen to be used from Python bindings.


If you want assembler Rust seems like a smarter choice because in Rust that's just part of the language whereas in C or C++ it's a vendor extension.


Assembly is never really part of the language, at most one could consider the syntax to inject a stream of opcodes being part of the language.

Both of us are old enough to remember when any useful compiled language used to allow for inline Assembly, extension or not.


True, but I would guess that projects more susceptible to rewrites would be low-level core libraries where state-of-the-art performance is always desirable.


Correct. And if those projects exposed a C++ API, then rewriting them in Rust would be highly problematic, because Rust did not prioritize C++/Rust interoperability (for well-understood reasons). So, you can either have a C API and move to Rust or have a C++ API and create a Rust version of the library for Rust developers, but your original users of the C++ library will stick with the C++ version.


You can use C++ libraries from Rust. That's a very normal thing to do. People start new projects in C++ either because they themselves don't want to learn a new thing or because they don't want their employees spending time learning a new thing.


Appart from cxx.rs. I think most binding between C++ and Rust are in fact C and Rust binding. So you need a C API to your C++ library (no template, no std etc...). So for me you can't use C++ library from Rust.


You can just use CXX? Idk what to tell you. A coworker of mine is doing it. It's not some kind of weird thing.


cxx only support a part of c++ STL container. It doesn't support template and custom container implementation. So no generic, no variadic number of argument, no automatic type déduction etc...


> You can use C++ libraries from Rust.

I doubt it. You can use C libraries from Rust, and emit C libraries in C++.

> because they themselves don't want to learn a new thing or because they don't want their employees spending time learning a new thing.

Whining about others not wanting to learn when you could have learned how Rust FFI works is, really, hilarious :-)


A coworker of mine is using CXX in a combined Rust and C++ code base. This is not exotic.


In my experience, rewriting C++ into Rust is non-trivial because idiomatic C++ expresses things that Rust cannot. This impedance mismatch breaks architecture, and that often isn’t allowed in a rewrite. I’ve seen multiple C++ rewrite attempts fail because of poor interoperability with Rust’s constraints. Language interoperability that is high quality and low friction matters to people, and in the case of C++ that is decidedly challenging.

My view at this point is that you are better off starting from a clean sheet of paper in Rust than trying to make Rust do C++ things it was not designed to do.

In the specific narrow case of performance-engineered code, Rust also seems to consistently produce slower code in my experience for myriad weird reasons, it isn’t one thing. In many cases I don’t even think it is the fault of the language per se, just a side effect of other factors. Nonetheless, customers don’t care about any of that, they won’t accept a performance regression just because you rewrote it.


Idiomatic "modern C++" as defined by the Core C++ Guidelines is very similar to Rust, it even has its own bespoke ownership+lifetime checking mechanism.


Do you know if any big public projects using the GSL or similar? I haven’t found any but I’d like to check them out.


Carbon is made for companies like Google with millions of lines of C++ using very C++ interfaces. They can't incrementally rewrite without refactoring everything to C-style headers, and that would probably involve a ton of void-pointer nonsense if its even possible.


> millions

s/m/b/ too


Carbon devs explicitly say use Rust if you can.

Non-trivial C++ programs depend on OOP design patterns, webs of shared-mutable objects, and other features which Rust doesn't want to support (Rust's safety also comes from not having certain features that defeat static analysis).

Rust really needs things written the Rust way. It's usually easier with C, because it won't have clever templates and deep inheritance hierarchies.

Even if your goal is to move to Rust, it may make sense to start with Carbon or Circle to refactor the code first to have more immutability and tree-like data flow.


> I have done this with Lua

Do you by chance work at Cloudflare, who has migrated away from Lua to Rust?

Curious to hear observations on productivity hit going from Lua to Rust.


In Cloudflare's case, Rust is much more productive.

Rust modules can handle any traffic themselves, instead of a split between native code and Lua that is too slow to do more than config (Lua is relatively fast for a scripting language, but on the critical path it was a "peanut butter" slowdown adding latency).

At the size and complexity of a server serving 20% of the Web, Lua's dynamic typing was scary. Modules in Rust can enforce many more requirements.

Rust's solid dependency management also helps share implementations and config logic across modules and even different products, instead of everything having to go literally through the same server.

https://blog.cloudflare.com/20-percent-internet-upgrade/


> instead of a split between native code and Lua that is too slow to do more than config

In case you’re not aware, Cloudflare ran on LuaJIT (not just for config) until not that long ago.

https://news.ycombinator.com/item?id=23856875


Five years ago is a pretty long time, and kornel does (or did) work at Cloudflare.


My observation is most people who mix up C and C++ use neither. How could you even automatically migrate when a lot of things you do in C++ are straight up illegal. Not to mention relying on third-party software like Qt.


It really hate libraries that call themselves C++ libraries, when they effectively are written in the common subset, with extern "C++" for C++ users.

Technically correct by ISO C++, in practice that isn't the way to write modern code.


Linux is only adopt Rust for device drivers and selective subsystems. I am not sure if it is a wide-adoption.


There are Linux targets which don't have Rust. So the drivers rule is because if we make the mm subsystem depend on Rust then a dusty architecture with no Rust can't run Linux any more. This is tolerable for userspace, realistically your Python document mangling code probably does not in fact need to work properly on a machine nobody has manufactured since the 1980s - but not acceptable to Linus Torvalds.

The expectation is that over the next say, decade, Rust gets more trusted by Linux maintainers and perhaps grows more platform support e.g. via the GNU Compiler Collection, and simultaneously some of the dustier platforms "rust out" of Linux because the few maintainers stop caring about new Linux versions. So one day you can rewrite core subsystems in Rust if that makes sense.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: