Negative views on Rust ( not mine! )

I just came across this, via "This Week in Rust"
https://chrisdone.com/posts/rust/

Regarding his negative points:

(1) I would agree that compiler errors can get very mysterious, but honestly it has not been a serious problem for me.

(2) The section titled "Fetishization of Efficient Memory Representation" I think he is referring to the borrow checker. Again, my personal experience has not been negative at all. Yes, you have to learn the borrowing rule, and how to live with it, but that has not been a problem for me at all.

(3) "The use of unsafe is a little disturbing" I don't find it disturbing. What Rust has done is make a clear distinction between code that is "safe" ( cannot cause memory corruption, undefined behaviour ) and code that is not. This is entirely reasonable and an excellent idea in my view!
[ Maybe he has some negative views on how people are using Rust, I guess pretty much any technology can be mis-used. I am not really aware of such mis-use, but it's possible unsafe is over-used ]

(4) Skipping on to " Async is highly problematic". I don't see it. As far as I am concerned Async is absolutely fine.

Anyway, what do you make of this article?

11 Likes

In the "Fetishization of Efficient Memory Representation" section it sounds like he simply wants a garbage collected language with everything on the heap, all arrays containing pointers, etc.

He's wrong that this "will never make a difference". It doesn't make a difference if performance doesn't matter to you, but sometimes it matters and having a stack and arrays of inline objects is great for performance. C++ wouldn't be so popular if it didn't make a difference.

However I tend to agree that there may be space for such a new language -- taking some other good ideas from Rust but with garbage collection instead of lifetimes.

10 Likes

Ehh... You can't please everybody :man_shrugging:

There is no such thing as the "perfect language", and different languages have their own way of doing things and their own language-specific quirks.

Rust's type system and values happen to align very well with the way I approach problems so I find it very enjoyable to use, even if there are some rough edges. For similar reasons I like TypeScript when doing frontend stuff and loath having to interact with JavaScript or the JavaScript quirks that leak into TypeScript. We all have our preferences regarding syntax or resource management or inheritance, and that's okay.

I personally don't think any of the points raised are a big deal, and actually view things like understanding your app's ownership story and caring about memory as a good thing!

I agree with the author regarding "Rewrite it in Rust" or the "we rewrote X in Rust and it got faster" circlejerk - that attitude pisses me off. A lot of it comes from people who elevate their preferred language to an almost religious level without having used it too much in the real world. That said, often if you've got a piece of crap code you will need a reason to justify the time spent rewriting it in another language to management, and performance is a convenient excuse that is hard to shoot down.

10 Likes

I am currently trying to make up my own mind w.r.t moving from Rust to C++, so I find it interesting.

I like the sentence on the "rewrite fallacy". It is very hard to say one language is faster than another. When you rewrite something you learn new ways to think about the problem. Especially when you try a language that thinks differently about things, like Rust.

It is very likely that my C++ code will be faster if I rewrite it in C++.

But Rust code is so much safer :slight_smile:

13 Likes

The main critiques I strongly disagree with are those around having runtime-systems built in (garbage collection, async). It's not a triviality; it's a deliberate, conscious decision. Sometimes you want one, sometimes you want to avoid one. I'm happy not to be fighting GC pause demons in my Rust programs. I'm also happy to have garbage collected languages at hand when it doesn't matter.

I fail to see why Rust programs should be confined to or excluded from any particular bucket (webapp, cli, ...) as well.

Finally, I think they have a misunderstanding in their conclusion. Preferring to avoid Rust due to the lack of garbage collection (say) is perfectly valid, but I think here

I wouldn’t mind using it as a replacement for single-threaded C if I just use the standard library.

they may have confused async with being multi-threaded. One of the beautiful things about Rust's ownership model is that it applies to concurrency and not just memory safety.

The other critiques I either at least partially agree with, or aren't fleshed out enough for me to judge. (One last clarification since I feel strongly about it: rustc's errors are the best I've ever seen. Newcomers from other languages often have to be told that they're actually helpful. But there is the occasional gnarly one.)

15 Likes

Typical result of Rust being too good for it's own good.

Rust is, essentially, a better replacement for C/C++.

But C and C++ are low-level (well, kinda-sorta), dangerous and scary languages, which can not be really fixed. Languages you try to avoid and ask everyone to stop using and which are used, ideally, only when you have to, not when you want to.

Rust, in comparison, is pretty modern language with many niceties of other modern languages for managed platforms (heck: it doesn't have UB in safe subset… that's quite an achievement by itself) thus people try to use it like any other high-level sloppy language for managed platform.

And become unhappy, because, well… Rust is not designed for that!

And, indeed, after reading the whole article we finally reach the most important part of it, lurking at the very end: it’s used at my job, so I’m sort of forced to have an opinion about it.

Rust is the best language within it's niche (low-level system language). But the more you move out of it the more problematic choices made by it become. If you really want GC-based language and can tolerate unpredictability which GC, invariably, brings to latencies then why are you even contemplating Rust in the first place?

I'm 200% sure Rust wouldn't ever regain tracing GC because lack of GC coupled with safety is what makes it unique! There are bazillion other languages which can serve you if managed environment is acceptable for your needs!

P.S. I have actually seen similar discussion related to C++ and Ada, quarter century ago, when they were new. It was, actually, part of both languages since the beginning (although rarely implemented by actual compilers) and people also predicted that GC would become popular and people would start using it instead of manual memory management, etc. Even before that happened the whole CPU architecture of the future was developed with hardware support for the GC! The final state of all these predictions? P2186R2: Removing Garbage Collection Support. C++23. Nuff said.

10 Likes

I'd argue Rust is very useful for those so-called higher level application niches, perhaps moreso than languages ostensibly designed for them.

Edit: Sorry if it looks like I pulled your quote out of context. I just used it for emphasis, not that I think you believe Rust isn't useful for such things. :grinning:

5 Likes

It depends. It does suit more applications than C++, but definitely not everything Java or C#, not to mention JavaScript and Python are used for.

If you write your app in C/C++, Rust is perfect to you (and this means much more apps than just operating systems and browsers! GNU utilities, for example, git, etc.).

If you write, or can write, or plan to write, your app in Go, then Rust can be an option, sometimes. Not always. A good example is Discord rewriting of some of their servers in Rust.

In general, if you care about safety/correctness/performance a lot, then Rust suits your needs. And it doesn't need to be those three together. Even one is enough.

But bussiness apps are just not what Rust was designed for. Yes, you can write them in Rust, but it'll be costlier than just writing them in managed lanuage X and fixing bugs as they appear.

1 Like

I 101% agree with this. It's stupid to to say that rewriting anything in Rust will make it faster, because in general, rewriting anything in anything will make it faster... It's a rewrite!

The "X... written in Rust" attitude is annoying too. So many times I have seen open source projects that are just clones of some other open source application, but in Rust. That's literally the only change in the project - it's in Rust. Just because it's in Rust shouldn't make me drop all alternatives and go to that clone - I need hard proof that using that clone of some project is actually worth it, for whatever reason. Putting "written in Rust" as the first line in your project shouldn't convince anyone.

6 Likes

Note that it's common for these to be "I'd optimized this in $OtherLanguage for a few days, and then my first naive version in Rust was actually faster". And that is impressive. (Well, at least for can-be-pretty-fast languages like Java. Certainly it's more common for a rewrite in a faster language to be faster than the python version, or something, but then the actual thesis of those posts is more "I'm surprised how little of an annoyance it was to do in rust".)

13 Likes

I'm likely to choose the Rust version if it doesn't use unsafe. If it does, then I agree with you.

5 Likes

Unsafe in and of its own is neither good nor bad - it's the gratuitous use of unsafe to get around the borrow checker or because "that's how we do it in other languages" that you need to be wary of.

Malware and bugs can be written just as easily in safe code, too :wink:

That's not to say I don't agree with you - it's just that people tend to demonize unsafe, which promotes superstition and fear around it, when the culture should be more about having a "healthy level of respect" for unsafe code.

5 Likes

I keep hearing this. After two years of Rust usage I still don't understand what it means.

Certainly one can do "low level" things in Rust. Like access hardware registers and so on. Typically the domain of assembler or C or C++.

I have no idea what "system language" is supposed to mean (Above and beyond that low level stuff I mention above that is required to write operating systems and such).

As far as I'm concerned all my programs are a system or more often part of a system.

Also as far as I can see Rust has enough "high level" conveniences that it can do whatever you might do in Javascript or Python or whatever.

The only "low level" thing then is that it is not so easy for a beginner to programming to get started with Rust as it might be with Javascript or Python or whatever.

Perhaps this "high level" vs "low level" or "system vs non-system" are not really useful classifications.

Anyway, never mind. I have just been reading that data centres in Ireland are consuming about 10% of the nations electricity generation capacity and the Irish power grid is under strain.

Scale that thought up around the world and we see that is a huge amount of power consumption. No doubt resulting in a huge amount of C02 emissions and hence global warming.

Given that programs written in PHP, Javascript, Python, Java etc are so inefficient, using more CPU cycles and hence energy, I conclude it is a moral imperative not to use them on such scale.

So, use Rust. Efficient and safe.

:slight_smile:

5 Likes

Wikipedia includes pretty good definitions. System programming language is is a programming language used for system programming. And then system programming is the activity of programming system software.

That's precisely what system programming is. Programming where you may need to care about every allocated byte and every nanosecond (when you are programming low-speed controllers you may only care about milliseconds but if you CPU speed is measured in low single megaheartz not gigahertz milliseconds are a big deal too).

Just to show the difference between applications development world and system programming world: each Linux thread have 16KiB of stack storage (it used to be 8KiB on 32bit platforms but 64bit prompted increase from 8KiB). For everything: TSS data structures, all the deeply nested function calls and many other things. That's system software world. As was way of comparison: in app development world 12KiB of stack are reserved just to handle “Stack overflow” exception!

That is also true and it's certainly true that sometimes it's hard to distinguish. But consider that recent discussion about why using async function pointers requires quite complicated dance in Rust.

This is directly related to the desire to allow to use of async in an environments where you couldn't just go and allocate memory on the whim (this is not just a simple desire: if you program a hard realtime system then you would, natuarally, want to have both async and zero memory allocations in the critical path).

Yes. And as I have said this is both blessing and a curse. It's blessing because it's easier to use language which includes certain high-level features.

It's a curse because it makes language easy enough to use that people are trying to use in places where JavaScript or C# may have been more appropriate choice.

They hit limitations embedded in Rust to serve system software development needs and try to push for the crazy things like addition of GC (which is absolute no-go for system level language).

P.S. And it would be fascinating to know just how and when Rust have become a systems programming language. Because initially it wasn't planned as such: it had a GC, green threads, non-trivial runtime, etc. Yet somehow it ended up being system language first everything else second. Why this switch happened and when?

1 Like

Rust’s use of magical sugar constructs, where the compiler will automatically insert dereferences and copies and clones and drops for you has an initial appealing “it’s all simple underneath” quality to it, but in practice this leads to bad compile errors: The worst kind of compile error is the one where the compiler is complaining about something that it generated for you, rather than something you explicitly wrote.

Fair enough. Rust's error messages are great though, have been getting better all the time. Maybe one day they can get good enough that this won't be an issue anymore.

In practice, people just want to be able to write a tree-like type without having to play Chess against the compiler. I predict that garbage collectors will become popular in Rust eventually.

Fair enough. If you're not already very experienced with Rust, and don't need performance, it may be rational to use Python or something instead.

The use of unsafe is a little disturbing, because every library features it. But it’s not much different to using an FFI. I don’t see this is a big downside.

I have to assume that by "every library features it" they simply mean that many do. But this is not a fair comparison. The only reason Rust has unsafe blocks at all is because it achieves something that other systems languages don't even try to (compiler-guaranteed memory safety). In, for example, C or C++, literally all code is unsafe, in the sense of "unsafe" meant by Rust.

I see a lot of “we rewrote X in Rust and it got faster” posts. I think that if you rewrite anything from scratch with performance in mind, you’ll see a significant performance improvement. I’m suspicious of how much Rust itself is needed versus the developers having some performance discipline.

I'm skeptical of this claim, you're not going to microoptimize pure-Python data processing to be anywhere near the level of half-reasonably written Rust code unless you use a completely different algorithm. But I agree that RiiR is a bit of a bad trend, but for a different reason: rewriting something from scratch is extremely time consuming. Which is why I like to send people How to not RiiR (which is about how to create Rust bindings for existing codebases).

I’ve seen this play out for Haskell. Around 2007, when I started with Haskell, the community was friendly as anything, evangelic, open. People praised it for this. Everyone just felt blessed to be able to use this exciting language. Today, it’s more like any other community. What happened? People started using Haskell for real, that’s all.

Meh, I don't find it too convincing that language communities teleologically become more toxic as they start being "used for real." We'll see though.

Rust’s choice to exclude a runtime/scheduler blessed and built-in to the language means they had to develop alternative strategies in the language itself. This is not turning out well.

Nah, this was the right decision. There's a thread somewhere I can't find that explains better than me why this is. But basically, code "built-in to the language" is just libraries that everybody's stuck with forever, even if it was designed badly, even if they don't need it. And at the scale of complexity Rust operates at, it's basically impossible not to get things wrong. That's why the model of "have de-facto official libraries, and if a library is very essential and completely stable for several years, merge into the stdlib" works so well. And the presence of multiple competing async runtimes isn't just an artifact of decentralized figuring out of what's the best design, they serve different incompatible goals which different people need in different contexts.

I feel like Rust is self-defined as a “systems” language, but it’s being used to write web apps and command-line tools and all sorts of things.

This is a little disappointing, but also predictable: the more successful your language, the more people will use your language for things it wasn’t intended for.

That's true, Rust's popularity is resulting in people using it to write things like web apps which eg. Python is just fine for. I'm not convinced this is a bad thing though. I think that largely the reason for this is neither performance nor pure mass of popularity, but rather that, in ways unrelated to performance, Rust is just a really well designed language. Even if its commitment to being systems-level adds some complications that eg. Python can avoid.

5 Likes

The more Rust gains footing in the industry, more devs will "have to use it because of work", and they will complain about it. It's actually a good thing:

13 Likes

The developers views on languages are not all irrelevant because it could eventually lead to a situation where a language would become the "most dreaded" language which than would lead to the massive code rewrite just to port the code back to a language that more developer dislike less. Just like Python rewrites of Perl code. Which then would be the beginning of the end.
According to this quote languages might evolve from "languages nobody knows about" to "languages people complain about" and eventually end in "languages nobody uses".

As a new Rust user, what I find I like about the language are things like pattern matching, and Result/Option for error handling. The borrow checker is really secondary. The language just works well for the kinds of things it tackles. This is what makes it appealing to me for jobs like creating web services - the code just feels better put together.

I wanted to like Go - I have a preference for staticly typed/compiled languages coming from a C/C++/Java background - but the ever-present "if err == nil" just grates on me.

The memory safety of multi-threaded programs is under-rated - that world can be very hard and tricky, I'm happy to get all the help I can when wading in those waters.

Rust isn't perfect - nothing is. But I appreciate the new features it brings to the task at hand.

8 Likes

The point about "Efficient Memory Representation" is somewhat true that it is confusing for developers used to think in terms of Stack and Heap that you can't export data out of a function because Rust did place it into the Stack for performance reasons while you think it is in the Heap.
And that is actually the point where I can't consider Rust a Low Level Language because it does to many stuff behind the scenes that is difficult or impossible to avoid.
On the other hand by doing the Memory Management behind the scenes it is able to construct aggressive Memory Micro Optimizations that a normal developer never would even consider implementing just to get the most performance out of the code.
This then leads to the situation that your Rust code always will be faster than the rewritten counter part in a different language. And this advantage will be seen much bigger when handling big data. On big data those Micro Optimization will evolve into clearly measurable advantages.

Thus on disciplines where performance really matters Rust certainly can be a big player and the efforts to work with Rust will be rewarded.

About the "Efficient Memory Representation"
I found an example in a post about Rust FFI
https://www.greyblake.com/blog/2017-08-10-exposing-rust-library-to-c/
When I saw the way Rust stores the Languages Array in an endless string I understood clearly where the performance advantages come from

the output was the entire massive of static data:

RussianRundiRomanianPortuguesePolishPersianPunjabiOromoOriya....

No sane developer would ever even think of a way to store a static Array of Strings in 1 single String just to save memory.
To recover the different languages in the correct order and correct length is just a nightmare for the human mind.

And these constructs are only Micro Optimizations that only give an advantage when used millions of times.

But that is the advantage of abstracting memory management and letting it to the compiler.

1 Like