The Case for Rust (in the base system)

Seeking for opinions from Rust/C experts: how does readability of the two languages compare?

It doesn't.

C has readability of assembler. If it is written well, it's very succinct. If it isn't, it can be hard to follow.
Rust has readability of OO-style C++, it is mostly scaffolding. This allows programmers to navigate to parts of true logic easily, but only if they know how the scaffolding works.

E.g. this is queue manager for spotify CLI client in Rust - https://github.com/hrkfdn/ncspot/blob/main/src/queue.rs
As you can see, this absolutely looks nothing alike what good queue manager would end up looking in C.

Rust is not a C-compatible replacement, I'm not so sure why on earth anyone thinks so.

Now one thing I really despise about Rust is the syntax, it doesn't have a C/C++ syntax yet they claim to take over them, I see a lot of Pascal influence. let keyword is an useless piece of 1960s turd. It is completely redundant. I have used this keyword when programming below age of 10. When I moved up to my third programming language, this is what the online documentation had to say on it :

Use of the optional LET keyword is not recommended. The variable=expression assignment statement performs the same action with or without LET.

So since the latter 90s I haven't used this keyword ever.

Like most of the stuff creeping into programming languages today, the reasoning is not technical merit. It is commercial. It is all about introducing not-yet-able new programmers to projects and making their work easier. Stuff like let/var apparently allows them to 'grasp' the scope of the variable. Same thing with Cargo. In C++ world Conan exists yet it is nowhere near massively adopted. But there are a ton of hireable programmers that do web languages and 'easier' languages, all of them supported by one-shot package management and build systems.
 
Two thoughts,
- A rust transpiler like cppfront would be welcome
- Rust and the freebsd-kernel freebsd-userland using all the same compiler & version. Forget it.
 
Rust uses the 'let' keyword to distinguish between binding and assignment. A statement like 'let x=5' creates an immutable variable x with a value of 5, while 'x=5' would assign the value 5 to an existing mutable variable x.

I'd agree with the idea that 'let' is pointless for languages that always declare a variable as mutable. The same annoying feeling came over me in 1980's BASIC dialects where I was also happy to skip it. In Rust, I get why it's there. Things like 'if let' do take some getting used to.
 
Let's compare to F#. There every variable is immutable unless you explictly say so. Except for scripting languages most languages differentiate between const & variable. I think they even have a different segment in memory space when compiled.
 
let keyword is an useless piece of 1960s turd. It is completely redundant.
In Scheme it has a clear meaning. (let ((x 1) (y 2)) <expr>) == ((lambda (x y) <expr>) 1 2). That is, x & y are respectively bound to 1 & 2 during the evaluation of <expr> -- the same as if you defined an anonymous function with two args x & y and the body of this fn evaluates <expr>, this anon. is applied to values 1 & 2. Unfortunately languages with static types complicate a lot of things unnecessarily all in the name of performance and security.
 
There once was a discussion on the fpc mailing list about replacing the memory allocator of the compiler for speed reasons. I did, as a test, do a dumb replacement that had a big pool and only returned slices from that, never freed. Fastest way to allocate, only two operations. There was no real speed up. Then I measured a bit deeper and came to the result that in a self compile, about 2% of the runtime were in the original memory management. And cutting that out had put more work on the system page allocator, eating that up again.

TL/DR, or as was said before "the morale of the story" - benchmark and measure. Get hard facts before declaring a feeling a problem. And remember Amdahl's law.

Speaking of memory allocators, you might enjoy the HEXACON 2025 keynote presentation by Ivan Krstić of Apple. He describes the process of implementing the memory tagging architecture Apple calls Memory Integrity Enforcement which first shipped in iOS 26 (fall 2025) after five years in development. One of the fascinating challenges was merely *finding* all the custom memory allocators!

Of course Apple's memory-safe systems programming language of choice is Swift, but their approach is fascinating and would apply to other operating systems projects and languages. Notably, by working at the level of the compiler, kernel, and memory allocators, MIE is able to provide protection for the large parts of their codebase which are not yet refactored into Swift.
 
The problem with garbage collecting C and C++ is that objects are not allowed to move. So there is no compaction for better cache and TLB hit rates and you still have to fill fragmentation holes, Worst of all worlds, really.

I've wondered if Rust might see less resistance if it had instead been named "C+++" or something. By the way, have you noticed the Google Carbon language project? It's not as mature as Rust, but the project goals might put it on the radar for migration of FreeBSD to a memory-safe future.
 
I've wondered if Rust might see less resistance if it had instead been named "C+++" or something. By the way, have you noticed the Google Carbon language project? It's not as mature as Rust, but the project goals might put it on the radar for migration of FreeBSD to a memory-safe future.

I know nothing about Carbon except some politics.
 
Carbon recently added the possibility to print a string, yes a string. Are you kidding. This is pre-pre-pre-pre-alfa. When will it reach beta ? In 10 years ?
I think Brian W. Kernighan and Dennis M. Ritchie didn't take that much time to print a string :)
 
Rust uses the 'let' keyword to distinguish between binding and assignment. A statement like 'let x=5' creates an immutable variable x with a value of 5, while 'x=5' would assign the value 5 to an existing mutable variable x.

let is contextual depending on the language. We have mentioned three languages, Rust, Scheme and BASIC and the keyword has three different meanings.

I'm also not a fan of type inference. I believe a programmer should know what types he's programming around.

A variable isn't immutable, I don't know how and when this clash of nomenclature happened, variable is totally opposed to immutable constant.
To have to write two keywords in order to declare an inferred variable for me is very strange.
 
Functional paradigm. I'm a fan of F# language, every variable by default is IMMUTABLE expect otherwise specified.

F#,
Code:
// Declare a mutable integer with an explicit type
let mutable counter: int = 0
// Reassign a new value using the <- operator
counter <- counter + 1
printfn "The current value is: %d" counter
 
I've wondered if Rust might see less resistance if it had instead been named "C+++" or something. By the way, have you noticed the Google Carbon language project? It's not as mature as Rust, but the project goals might put it on the radar for migration of FreeBSD to a memory-safe future.
Carbon is interesting. I would keep watching it. And not get as frustrated with it as Alain is, because I suspect that it is actually much more advanced and production ready than people outside of its internal development know. Remember: The tao that you can see is not the real tao.
 
I took a quick look at Carbon. Doesn't seem particularly interesting.

Just consider something simple like this: for (n: i32 in Core.InclusiveRange(2, 999)) { .. } -- why not just for n: i32 in 2..999 { .. } which is pretty clear. The only excuse is they want Carbon to be *the successor language* to C++, so they will carry along most of the baggage. And yet, they dropped C style declaration in favor of Pascal style! Probably a designer's favorite style! A successor language to a very complex language C++ is bound to be even more complicated, or "successor" is just a marketing speak. Most of their "goals" seem more like motherhood and apple pie. Not sure how they will drive the language design -- goals should be specific enough such that you can define steps to achieving them.

The goals that make some sense are: 1) there should be a way to translate correct C++ code to C6 as faithfully as possible 2) it should not be too hard to train a C++ programmer to write C6 code. But very hard to achieve these along with 3) code that is easy to read, understand and write.

The problem (IMHO) is this: Ideally a new language would provide simpler building blocks from which C++ abstractions as well as other better abstractions can be built. This simpler language would be ideally meet 3) above. But C++'s existing abstractions (features) are not well designed at all & it would be very difficult to come up with simpler building blocks for them. That is why they've left in templates (as opt-in support?) so there goes 3)!
 
After catching up with most of the comments in this thread, I'm developing the sense that there's quite a bit of skepticism about the need for memory-safe programming languages at all, and also about the very concept of a successor language.

Folk interested in the question might appreciate the perspective of John McCall of Apple. In this presentation he describes the need for a memory-safe successor language, and Apple's approach to migrating a large code base to a successor language, in their case mostly Swift (at all layers).

Introducing a Memory-Safe Successor Language in Large C++ Code Bases - John McCall - CppNow 2023
 
I do not have a dog in this event.

Just curious.
What does Rust, Ada or F# etc have to offer that main stream languages do not, other than being “different” ?
 
Functional F# ,
Code:
// Define a Record type for a Product
type Product = { Name: string; Price: float }

// A list of products (Immutable by default)
let cart = [
    { Name = "Book"; Price = 15.0 }
    { Name = "Pen";  Price = 2.5 }
    { Name = "Lamp"; Price = 45.0 }
]

// Functional transformation using the pipe operator (|>)
let calculateTotal items =
    items
    |> List.filter (fun p -> p.Price > 10.0) // Filter: items > $10
    |> List.map (fun p -> p.Price * 0.9)    // Map: Apply 10% discount
    |> List.sum                            // Reduce: Sum everything up

let finalPrice = calculateTotal cart
printfn "The discounted total for premium items is: $%.2f" finalPrice
 
Back
Top