FreeBSD considers Rust in the base system
lwn.net
lwn.net
Rewrite everything C++ is not a small undertaking with (maybe?) not allot plus-sides, and even then you still need C++ because of LLVM. LLVM and GCC are both C++, and you have to compile the Compiler (self-hosting), and even if your a 100% Rust or C OS, you still need C++ because of LLVM/GCC....well if you want a modern compiler ;)
Not important, you have to compile your Compiler fini, btw for Linux (just the Kernel) you need Perl ;)
I am guessing that performance of current standalone C compiler is not as good as the one produced by compiler suit.
Following the conversation thread, rust also use llvm under the hood, but a customized one. Which would force the base system to have two versions of llvm.
These words are doing a lot of work.
(The proxy I use for this is the ratio of years spent programming to insane acronyms known. C++ has given me SFINAE, CTAD, SIOF, etc. so far, while Rust has only given me RPIT.)
As someone who has extensive experience in C++, Haskell, and Rust, I can confidently say that none of them is simple, it’s just that C++ has a mountain of legacy / technical debt that Rust has to deal with. If C++ were to be invented today, it would look a lot more like Rust.
I'm not sure about this, because the world without C++ would have been quite different from today. The main complication comes from the fact that C++ was considered a much higher-level language than today, so its absence would have made other alternatives evolve differently.
https://www.youtube.com/watch?v=CWiz_RtA1Hw
Return Position Impl Trait is Existential Types, but Argument Position Impl Trait is just a simpler syntax for some Generics, same syntax, different meaning. This is actually one of the places where Rust is probably easier to pick up in use than to understand in theory. APIT and RPIT both "feel" right, but in type theory these are radically different features.
In that way it's like some natural languages, native English speakers don't notice a bunch of the grammar rules they learned as kids, those rules just "feel" right and not formally taught.
However, I can today easily write clean C++ that’s easy to understand, and using containers, algos and smart pointers is also robust. This is what the C++ community has settled on, while pushing complexity into libraries.
The Rust community has settled on async, moves and references (with the lovely lifetime annotations) and other cognitive overhead, because they think that getting errors at compile time offsets all the mental overhead of those constructs. Then they gaslight all the beginners which complain about that mental overhead.
So in theory Rust may be simpler, but idiomatic Rust isn’t. It’s differently complex.
This is orders of magnitude simpler than c++ overloading of copy/move assignment and constructors, even when you follow the rule of 0 (not least of which is that you don’t to teach people about it or how to keep code exception safe).
It’s kind of amusing to claim that c++ is simpler than Rust when it’s demonstrably not true - a new person to Rust is more productive after 6 months than a person new to c++. That implies the bar to getting proficient is low. A person can reach intermediate more quickly implying the bar to the next levels is lower. And it’s easier to maintain a rust project due to cargo meaning a usable easy build system out of the box that the entire community uses vs opinionated choices each project has to do, and macros that are easier to manage than preprocesser mess. So easier to maintain and easier to jump into any project. Oh and tests and mictobenchmarks out of the box and a very rich ecosystem of supporting libraries.
Idiomatic rust is simpler than idiomatic c++ and it’s clearer what constitutes idiomatic rust whereas c++ in practice is rarely idiomatic and there are going to be conflicting ideas on what is idiomatic.
This is ignoring the very real benefits of rarely to never dealing with a whole class of difficult to debug bugs (threading and memory safety) in the vast majority of code you’ll write .
References are not at all simpler, they're memory-safe, which in conjunction with lifetimes makes them significantly more complex to understand and write. This is a known problem... In C++ I copy by default and move if I want to optimise. Moves also happen behind the scenes as an optimisation, this is how things should be, don't push the work on the programmer!
I don't agree with your claim that a new person to Rust is more productive. What's that based on? In my experience, a new person to Rust will write memory-safe code by default, which is good, but they pay the cost of Rust's lack of ergonomics forever. See https://news.ycombinator.com/item?id=40172033 which covers async, refactoring and design issues that plague even experienced programmers.
> Idiomatic rust is simpler than idiomatic c++ and it’s clearer what constitutes idiomatic rust whereas c++ in practice is rarely idiomatic and there are going to be conflicting ideas on what is idiomatic.
It's really not, because C++ copies by default which is typically both memory-safe and very easy. If using smart pointers and clone was idiomatic in Rust, you'd have a point, instead references and lifetimes are idiomatic.
Modern C++ has a pretty clear definition, albeit it's evolving as new things are added to the standard. C++ is moving too fast recently, but then again so is Rust.
> This is ignoring the very real benefits of rarely to never dealing with a whole class of difficult to debug bugs (threading and memory safety) in the vast majority of code you’ll write .
That, cargo and lack of historical baggage are the only real benefits of Rust compared to C++. The lack of ergonomics, slow compile times and to some extent the aggressive community make it far from a clear choice.
Is this true? I ask because I've seen it mentioned that a C++ co_await suspends that call frame alone (thus the call returns to the caller and resumes immediately), where as Rust's .await suspends the entire call stack (all frames up to and including the caller). If true, in what sense are these mechanisms same?
> The Rust community has settled on async, moves and references (with the lovely lifetime annotations) and other cognitive overhead
The rust community has settled on async in the same way that the C++ has - it's an optional keyword that is some syntactic sugar over compiler-generated stuff. The main unique "cognitive overhead" is that Rust forces you to write down lifetimes when they can't be inferred, but the rest is the same or worse in C++.
As for the async mechanism, I don't believe there's magic in Rust that suspends the entire call stack. It walks up the stack the same as in C++. If you don't await an async function call or one returning a future, then there's no suspension and the inner function is executed until the first suspension point if I recall correctly same as in C++. There's nuances in differences but at a high level they're very similar in that it's generating a state machine and nothing more; Rust does require a runtime whereas C++ can do without since the Rust picked generic futures that work on all runtimes whereas in C++ you have to have the runtime provide the future implementation (or have the future not be part of any runtime).
> Rust doesn’t have the backwards compat baggage that C++ has, so it’s simpler.
C++'s "compat baggage" is mostly self-imposed, because it didn't have any working isolation system (including module systems) for a very long time, and the current C++ module system is still not fully isolating.
> [T]hey think that getting errors at compile time offsets all the mental overhead of those constructs.
This complaint might be true for some (but not all) people, but even in that case Rust will give a full memory safety (with some specific but reasonable definition). You can always use other languages if you don't find the memory safety that important---after all, there are many other axes of safety to consider and balance. But if you do need the memory safety for many good reasons, Rust is definitely a better language than C++ to achieve that.
Also C++ might be forgiving, but it takes much time to learn C++ to avoid many pitfalls and yet I regularly got tripped up by things that I do know but didn't have in mind at the time. I hate the "modern C++" argument; such argument is only reasonable when you are forbidden to write any legacy code without explicitly overloading. (Again, C++ has no real isolation to allow such mode switching.)
https://www.phoronix.com/news/Rust-Linux-Maintainer-Step-Dow...
'''
Hey folks,
This is as short a series as one can be: just removing myself as maintainer of the Rust for Linux project.
I am retiring from the project. After almost 4 years, I find myself lacking the energy and enthusiasm I once had to respond to some of the nontechnical nonsense, so it's best to leave it up to those who still have it in them.
To the Rust for Linux team: thank you, you are great. It was a pleasure working with you all; the times we spent discussing technical issues, finding ways to address soundness holes, etc. were something I always enjoyed and looked forward to. I count myself lucky to have collaborated with such a talended and friendly group.
I wish all the success to the project.
I truly believe the future of kernels is with memory-safe languages. I am no visionary but if Linux doesn't internalize this, I'm afraid some other kernel will do to it what it did to Unix.
Lastly, I'll leave a small, 3min 30s, sample for context here: https://youtu.be/WiPp9YEBV0Q?t=1529 -- and to reiterate, no one is trying force anyone else to learn Rust nor prevent refactorings of C code.
Thanks, -Wedson
'''
Having another maintainer completely shut down your talk by somewhat angrily shouting out irrelevant and fundamentally incorrect complaints and comparisons is incredibly disrespectful.
"You're not gonna force all of us to use Rust!"
However, I do think that the "other side" also raises a valid point in that they can not reasonably be expected to maintain the semantics on the C side so that the Rust bindings (which does make assumptions in order to create clean and powerful bindings to use the Rust type system) do not break. Pre-Rust, the onus is indeed on them to ensure that the entire codebase conforms with any semantic changes, but now, if we say get a new filesystem entirely written in Rust that relies on the bindings, who is responsible and how will the coordination happen?
Again, I am not a kernel developer and only a mediocre (at best) systems programmer. Thus, I could have misunderstood the discussion.
From the sounds of it, some of them consider this request unreasonable.
They are uncalled and should not be tolerated.
We had a colleague in my last job that was good technician but nobody wanted to talk to him or ask for help or anything because frankly, he was an asshole.
They simply have a fundamental difference of opinion. And I actually understand the C person is suggesting. Although may be he wasn't clear in explaining it. It is not the responsibility of C maintainer to spend additional time to explain their code. Especially in a way that Rust people understands. And may be in order for them to do that, without all the Rust context, they might as well learn Rust. And if Rust blinding is even set as a priority then all C maintainers would now have obligations, one way or another to work well with rust. Which neither does the C maintainers want to spend time on or have the interest to spend time on.
The Rust people on the other hand saw their move as common good and want everyone to work together. Unfortunately most developers would only discover very late in their carrier, you can only make that happen when everyone 's interest are aligned.
Color me shocked.
I don't get this fixation rust proponents have to try and force-jam it into pre-existing projects, instead of writing their own rust software.
Making existing, well-used OS kernels safer is probably a lot easier than writing a new kernel from scratch, porting drivers, marketing it, and gaining a larger user base.
Not saying that's not a worthwhile endeavor, but it's up to everyone to decide what they want to do.
Ultimately the maintainers of a non-Rust project will decide if they want Rust in there. No amount of "force-jamming" is going to make it happen without their considered consent.
It means that rewriting part of something in rust has chances to reduce the overall security of the software
I find my use of force-jam was entirely appropriate, after careful consideration informed by the How rust proponents push rust into pre-existing projects.
As well as the drama they bring alongside them, and their propensity to resort to personal attacks.
Firefox (and many other projects) was already a mix of multiple languages - it uses C, C++, Javascript, ... and now Rust. And while there is value in having less languages to deal with, there is equally value to use multiple languages and apply them where you see major benefit. For example, replacing exposed and high-risk components (image/file parsers for example) with a language that de-risks those implementations. Like all of the things in software engineering, this is a tradeoff. It may not make sense for your application, but it can make sense for others.
Using the "Code" column to ignore comments and blanks.
This is based on the mozilla-central-78a5d30a370f bundle.
(Also, holy crap it took tokei 10m to run this analysis).
If you find the time and urge I'd be interested to know the results.
Because the BSDs and Linux are actually used in hundreds of millions of systems and provide clear value to lots of people. Redox is cool, but it's in an entirely different league. It's not surprising that some people prefer to work on brand new stuff (like Redox), and some people prefer to work on improving old stuff that is actually in widespread use.
> I don't get this fixation rust proponents have to try and force-jam it into pre-existing projects, instead of writing their own rust software.
I take it you prefer to always demolish your house and build a new one whenever any renovation, nomatter how small, involves a significant change in materials or methods or technology?
When such an analogy is put forth, I cannot believe there is any intent to discuss the subject in good faith.
Where I work, we have some open source C code that is also in the FreeBSD base system. We have decided to create new code in Rust and look into deprecating the C code. Obviously, the FreeBSD project can just take over maintenance of the C code, but that will be burden to the project.
Note the 'may' and 'long term'. But for a project like FreeBSD it is good to look at Rust before it becomes an issue.
A more silent problem, it is quite possible that Rust programmers are less likely to contribute to a project that is based on C and C++ where Rust is not welcome. Certainly when new code is needed, that group will wonder why it needs to be written in C or C++.
Personally I'd prefer if it stays out of FreeBSD. All languages with package systems turn into a horrible quality over time. PHP Composer, Python Pip, node NPM and so on, initially it seems effective but the version dependency/issue hells are true nightmares. And I fear rust with cargo is going to be the same. Maybe I'm wrong, and in case it does go into base, I really hope I'm wrong so the quality of FreeBSD doesn't go down...
As an OS vendor, FreeBSD could do something like that with Rust. If a Rust application is developed inside the FreeBSD source tree, make it so that it can only use the Rust standard library plus whatever libraries exist inside the FreeBSD source tree.
And non-UNIX OSes, where by definition C library belongs to the compiler it is shipped with.
There's even a precedent for this, check out DragonFly BSD if interested in reading more.
If a new package manager (or the existing one, cargo) tries to fetch packages and doesn't fetch it correctly, the users will be faced with thousands of compilation errors in a moments notice. The new package manager will be abandoned, or the users will revert the existing one to a previous version in which it worked as expected.
I also don't see reason to declare npm to be a failure, and frankly pip was never good. Cargo is excellent. I don't see why it would decline.
This is all so vague, and that confuses me. Language package managers are "destined to decline in quality" for unstated reasons. Language package managers are "don't work well" because there are multiple languages (and I presume you also mean multiple operating systems/distributions). That argument would seem to apply equally well to any package manager (including those maintained by OSs), so why are we singling any of them out?
(Cargo does have a build script mechanism, with a major use case being integrating with other languages at compile time. Eg, running `make`. The other package managers I'm familiar with have similar mechanisms. I would assume they all do, since it's a problem they all have.)
> Cargo does have a build script mechanism, with a major use case being integrating with other languages at compile time
I already use cmake and my own custom build environment manager. While there are warts it is setup and works well enough that I don't want to switch. But rust wants me to forget about all that and use cargo. While in theory I can use something else, they don't bother documenting those workflows (I'm not convinced they will keep them working if I do get it working)
I would be very surprised if changing the arguments to rustc (or the equivalent in any language) wasn't considered a breaking change, so I'm not sure how well founded your skepticism is. If it's poorly documented, that is a shame.
I wrote some small games in Zig, I made some money writing Go. I dabbled in Elixir, Erlang, some Lisps, it goes on. I love programming. After my 9-5 C# Job nowadays I usually spend a few hours programming with my friends.
I was extremely skeptical of Rust, due to the hype and some very obnoxious Rust proponents. I learned Rust, I'm still learning it, but I've shipped a few smaller backend apps and worked on a few larger projects now.
The main reason why I think that Rust should replace C++ in all new projects is actually very simple: Tagged unions, pattern matching, reflection, no OOP and the toolchain. There is a lot of syntax in Rust that is beautiful, but besides that, those are the most useful features. They save hundreds to thousands of lines of code per codebase, compared to C++. The Option<T> alone is a simple
enum Option<T> {
Some(T),
None,
}
Whereas in C++, std::optional<T> is a massive class with edge cases, weird implicit conversions ({} = std::nullopt, beware), and don't even start with differences between different STL implementations. What about `std::make_optional`? At least C++23 adds monadic operations like `.and_then()`, but with the "let's capture by reference why not" lambdas in C++, you easily have dangling references in your lambdas if you do anything multithreaded.In Rust, I just write code, and if it compiles, it runs and does *exactly* what it says. I don't have to run the code to see if it crashes just because I'm using multiple threads, or a bunch of tokio async tasks. In C++, sure, if it compiles you cleared the first hurdle, but about 60% of the time the code has edge cases you're not considering. Most if not all C++ code I've seen makes assumptions about the lifetimes of things, and/or uses globals, and/or happily uses shared pointers in ways that they were not designed. Anything using `boost::asio` is a gigantic clusterfuck of "make sure you pass by value, by rvalue reference, or as a shared pointer" that, of course, not a single linter or compiler will tell you about if you don't. They don't have to tell you, because that's UB, and that probably crashes horribly, but maybe not!
I can't wait for more people to use Rust so their ecosystem matures a little more.
Hit a multithreaded C++ server with 20k users a day alone and you would not believe the edge cases and weird states they will generate for you.
> I was extremely skeptical of Rust, due to the hype and some very obnoxious Rust proponents.
...is obviously a very biased way of gauging anything. As mentioned upthread in another comment of mine, every single community has the minority of loud bad apples and it's not fair to judge Rust because its community is literally like any other on this planet.
You did the right thing, you ignored the emotional responses and went to check for yourself, factually and objectively. I'd be honored to call you my colleague.
Bravo.
> You did the right thing, you ignored the emotional responses and went to check for yourself, factually and objectively.
I'm currently talking to lots of other C and C++ developers I know, and trying to convince them to give it an honest shot. The first thing I say is pretty much "Hey, I know this thing is overhyped and you're probably fed up, I thought so, too, but ...", and then follow that up with tagged unions, pattern matching and showing the toolchain. That sells most of them on it. Error handling also is a huge plus if they're also big error-handling nerds.
Also note how I never mention memory safety -- the reality is barely anyone gets really excited about that. We'd all use @safe Dlang[0] if it was that exciting to us all.
That's a different approach, thanks for describing it. I've tried it as well but apparently I spoke with some very bone-headed people because they hand-waved it away immediately with "meh, C unions are fine, you're a noob if you need Rust to hold your hand". :(
I'll remember to bring those up next time, because I found myself caring about exhaustive pattern matching / enums more lately, compared to memory safety (which I do care about a lot still).
C++ wasn't put into critical dependency in the kernel in FreeBSD either. If you think it's just a dialect of C (I don't) then that speaks to the strength of opposition.
Lua was put in the kernel. Perhaps because "it's just forth" and has less risk of drift from a critical dependency.
When the pace of change of Rust moves to less-than-annual, I think it might be valid but frankly I think RustBSD is a better model: fork the code, write a rust kernel, maintain an ABI which C can live with, move forward.
A person could reasonably argue that this is redox. It's different in that it's a new OS rather than a rust-ified version of an existing thing, but still, it's a microkernel unix-ish OS in rust.
What I care about is getting an interactive shell prompt and a filesystem with . and .. and / and BOURNE shell compatible semantics, and an ability to run vi and emacs. (I am less sure plan9 people care about shell btw they went rc and then into some place I don't understand up in the 5th dimension)
MINIX is dead for multiple reasons, including technical ones [1]. Simply put, its design and implementation are no longer fit for purpose on modern systems. At this point, starting over from scratch would probably be more effective than trying to address all of its issues.
Doubt: https://blog.rust-lang.org/2014/10/30/Stability.html#will-ru...
> Will Rust and its ecosystem continue their rapid development?
> Yes! [...] and we expect this will only accelerate.
Emphasis mine.
The codebase is bsd-license, it's as good (fork-wise) as it can be.
So go ahead, fork it and explore your ideas... If they're good, they can still be merged back into upstream.
People in the FLOSS scene nowadays are too much fork-a-phobic in my opinion.
Without the support from upstream, just _syncing_ your fork with upstream can be a massive pain, as your changes conflicts with the new upstream changes. It's even more debilitating when you realize your efforts may not even be rewarded -- the upstream can simply decide to refuse to merge your fork.
This happens if you don't fork often, post your changes once in a very long time, and don't rebase your work very often.
If you rebase often enough you shouldn't have the mergeability problem.
> It's even more debilitating when you realize your efforts may not even be rewarded -- the upstream can simply decide to refuse to merge your fork.
The alternative is letting people greenlight you to even go and do a proof of concept. It smells like bureaucracy to me.
Having a fork and a working proof of concept can back your argument about feature development. The implementation is just a detail and can be adjusted or reworked as necessary.
Otherwise you risk your ideas getting stalled (or worse, completely rejected) by people that don't even fully understand what you're talking about.
"Can still be merged back into upstream" is a huge uphill battle. I understand the people who want to skip it.
Actually this has been proven wrong in the real world. Bryan Cantrill in his talk about OpenSolaris (and its sad ending) talked specifically about how being fork-a-phobic was an issue.
> Who needs 100+ more UNIX almost-clones?
Who needs 100+ GNU/Linux distros? and yet here we are and 100+ GNU/Linux distros is one of the strength of GNU/Linux.
Other than this, 100+ more "UNIX almost-clones" are only an issue if they are long lived. If the clone serves the purpose of showing a PoC implementation you can get the PoC reworked and merged into mainline and just kill the fork (see my other comment)
How so? TL;DR it for me and future readers, please?
> Bryan Cantrill in his talk about OpenSolaris (and its sad ending) talked specifically about how being fork-a-phobic was an issue.
Nobody is "fork-a-phobic", this is childish talk and completely misses the otherwise clear point that I think I presented. Again, if you can TL;DR it meaningfully people could be interested, otherwise it looks like plain old gatekeeping.
I did, you keep missing the point.
True gatekeeping is preventing people from exploring ideas by saying people should not fork. Quite literally, you’re the one pushing for the gate to be kept closed.
I can’t help you with text comprehension, I’m sorry. Since you keep missing the point I won’t be replying any further, it’s wasted time.
Good luck with everything.
I get that you want to emerge the "winner" here but it's not going to work, HN readers are fairly well-educated. I asked for a summary, you refused it by also reaching for an ad hominem.
It's very visible who is who in this situation.
Good luck indeed.
To be frank, I think most of us just see two people failing to communicate.
Can you point out what did you perceive as snark, btw?
I'm saying that as one who knows little about the language.
- Has the memory safety of Java
- But is as fast as C/C++
The thing you have to pay to get that combination, is a LOT more time and frustration fighting the borrow checker, and getting things to compile.But for a kernel (and a few other cases like network servers, browsers, foreign data decoders), I think that trade-off is perfect.
As someone who works in Rust professionally, I've only found this to be true in the initial learning curve (which is admittedly steeper than many other languages). But once that up-front cost was paid, I actually find myself more productive in Rust than in other languages.