So the Rust library you write is fully self sufficient without calling into any Rust stdlib functions or without using any runtime initialization mechanisms like ctors and dtors? That sounds too good to be true - If I am calling Rust then I am getting the Rust runtime just like if I can strlen I am getting the C library.
You can use a significant portion of Rust with only libc (i.e. no different to C) and this will be increasing. Things like "constructors" and destructors do not need the support of a runtime at all, they're entirely just conventional static function calls.
That is to say, the only overhead/problem with calling using C vs. using C and Rust is the increased binary size of having additional code included. There's no loss of flexibility (as long as you're not trying to run on a tiny microcontroller).
That does sound great overall - and I will take a deeper look at Rust - but this thread is about rewriting the core Linux utilities in Rust - if I had to do that with full featured Rust it would be hard enough. But if I had to restrict myself to a subset to avoid the "runtime penalty" for programs embedding my Rust shared library implementation of libbfd - then the rewrite just went from nearly impractical to completely impractical in terms of the efforts required.
> But if I had to restrict myself to a subset to avoid the "runtime penalty" for programs embedding my Rust shared library implementation of libbfd
The point is there is no 'runtime' penalty with Rust†. It doesn't have a compulsory garbage collector, it doesn't have a compulsory complicated IO manager, it doesn't have a compulsory multiplexed threading system. In some circumstances lacking any of those will be a downside, of course, but not having it built-in and compulsory means Rust gains flexibility. In several ways, there's actually lower overhead with Rust, because it is a modern language designed around the advances and research that has happened, e.g. dynamic (de)allocation can be faster due to putting some sizedness requirements on the very lowest level APIs (which one rarely calls directly, so the programmer will never notice the restrictions, just the improved speed).
My comment was trying to address the Go <-> C <-> Rust bridge, pointing out that C and C <-> Rust are essentially the same, other than the extra code one must have from writing in two languages rather than one. If one was to forgo the C (which is possible, Rust can easily be used to write a library directly exposing a C ABI), there won't be much difference at all between C and Rust.
In summary, in future, any restrictions required would not be very significant, and, even now before Rust's runtime has been excised, the restrictions will be things like "no network IO", one still gets access to all sorts of fancy iterators and data structures without requiring any runtime.
†Strictly speaking, this isn't quite true right now, but there is a concrete plan currently being executed to make it true.
Wow, in that case Rust is looking like it could be hell of a lot better C replacement! If I could just write all my libs in Rust using the full power of the language and then just call them easily from any language without ungodly overhead or complexity like in case of say Java/JNI, that's nothing short of fascinating!
It's not all brilliant though, there's still a lot of useful tooling that Rust needs to develop to make it really nice, e.g. there's no nice way to create a C header file describing a Rust library (since C headers are the lingua-franca of FFI libraries, in many ways), https://github.com/rust-lang/rust/issues/10530 .
And, being a young language, it's not too hard to be doing something no-one else has ever done, especially with this low-level stuff. :) (Meaning compiler bugs and some "I don't know" answers.)
You can use the core library to get standard functions with no runtime. I'm not sure what you're saying about constructors and destructors. There's nothing special about calling strlen that adds overhead.
So we would need to write Rust libraries without using Rust stdlib? Not exactly a great advantage in that case. Especially so when you are rewriting a ton of C code.
It's about the context - rewriting ton of code that is in C libraries right now. If that had to be done using Rust without its runtime libs it is an huge disadvantage to solve the issue at hand.
How high is that penalty, relative to, say, loading a variety of C shared libraries? At some point safety and security trumps saving a few kilobytes of memory...in a server environment, that point probably has already been passed a decade ago. Of course, if the penalty is hundreds of megabytes, then the equation might add up differently.
But, we already have a huge number of system tools and utilities running in a huge number of languages. Python has become the lingua franca of Linux management tools; Perl was in that role in the past, and still exists in a lot of places; bash and shell are integral. All have separate runtimes, and sometimes interact with system-level C libraries, either directly or through command line interfaces.
Is it really that big of a deal to have a Rust or Go shared library in a system that already has a half dozen different languages and a variety of shared and unshared libraries existing at once? I suspect it would be unnoticeable on a modern system. I'd choose safety over shaving a few kilobytes of memory used.
There would be a cost in having that interface friction for developers...and we'd be paying that cost for years. But, it seems like both Rust and Go have planned for the languages to be integrated with C libraries from the beginning, so it seems less of a problem. If I were going to attempt such a thing, I'd probably start with the front end utilities that use the libraries and then work my way down to converting the libraries (even though the libraries, in this case, are where the problems lie). But, maybe it's possible to make Go or Rust code that provide the same C interface as the existing libraries...I don't know enough to even guess.