Iâm making this post after endless frustrations with learning Rust and am about to just go back to TypeScript. Looking at Rust from the outside, youâd think it was the greatest thing ever created. Everyone loves this language to a point of being a literal cult and its popularity is skyrocketing. Itâs the most loved language on Stackoverflow for years on end. Yet I canât stand working in it, it gets in my way all the time for pointless reasons mostly due to bad ergonomics of the language. Below are most of the issues Iâve encountered:
-
Cargo is doing too many things at once. Itâs a build system but also a package manager but also manages dependencies? Idk what to even call it.
-
Syntax is very confusing for no reason. You canât just look at rust code and immediately know what it does. Having to pollute your code &, ? and .clone() everywhere to deal with ownership, using :: to refer to static methods instead of a âstaticâ keyword. Rust syntax is badly designed compared to most other languages I used. In a massive codebase with tons of functions and moving parts this is unreadable. Letâs take a look at hashmaps vs json
let mut scores = HashMap::new();
scores.insert(String::from("Name"), Joe);
scores.insert(String::from("Age"), 23);
Supposively bad typescript
const person = {
name: "joe",
age: 23
}
Js is way more readable. You can just look at it and immediately know what the code is doing even if youâve never coded before. Thatâs good design, so why do people love rust and dislike typescript then?
-
Similarly, Async code starts to look really ugly and overengineered in rust.
-
Multiple string types like &str, String, str, instead of just one âstrâ function
-
i32 i64 i8 f8 f16 f32 instead of a single unified ânumberâ type like in typescript. Even in C you can just write âintâ and be done with it so itâs not really a âlow levelâ issue.
-
Having to use #[tokio:main] to make the main function async (which should just be inbuilt functionality, btw tokio adds insane bloat to your program) yet you literally canât write code without it. Also whatâs the point of making the main function async other than 3rd party libraries requiring it?
-
Speaking of bloat, a basic get request in a low level language shouldnât be 32mb, itâs around 16kb with C and libcurl, despite the C program being more lines of code. Why is it so bloated? This makes using rust for serious embedded systems unfeasible and C a much better option.
-
With cargo you literally have to compile everything instead of them shipping proper binaries. Why??? This is just a way to fry your cpu and makes larger libraries impossible to write. It should be on the part of the maintainer to build the package beforehand and add the binary. Note that i donât mean dependencies, I mean scripts with cargo install. There is no reason a script shouldnât be compiled beforehand.
Another major issue Iâve encountered is libraries in Rust, or lack thereof. Every single library in rust is half-baked. Axum doesnât even have a home page and its docs are literally a readme file in cargo, howâs that gonna compare to express or dotnet with serious industry backing? If you write an entire codebase in Axum and then the 1 dev maintaining it decides to quit due to no funding then what do you do? No GUI framework is as stable as something like Qt or GTK, literally every rust project has like 1 dev maintaining it in his free time and has âexpect breaking changesâ in the readme. Nothing is stable or enterprise ready with a serious team with money backing it.
As for âmemory safetyâ, itâs a buzzword. Just use a garbage collector. Theyâre invulnerable to memory issues unless you write infinite while loop and suitable for 99% of applications.
âBut muh performance, garbage collectors are slow!â
Then use C or C++ if you really need performance. Both of them are way better designed than Rust. In most cases though itâs just bikeshedding. Weâre not in 1997 where we have 10mb of ram to work with, 9/10 times you donât need to put yourself through hell to save a few megabyes of a bundle size of a web app. There are apps with billions of users that run fine on php. Also, any program you write should be extensively tested before release, so youâd catch those memory errors if you arenât being lazy and shipping broken software to the public. So literally, what is the point of Rust?
From the outside looking in, Rust is the most overwhelming proof possible to me that programmers are inheritly hobbists who like tinkering rather than actually making real world apps that solve problems. Because itâs a hard language, itâs complicated and itâs got one frivelous thing it can market âmemory safety!â, and if you master it youâre better than everyone else because you learned something hard, and thatâs enough for the entire programming space to rank it year after year the greatest language while rewriting minimal c programs in rust quadrupling the memory usage of them. And the thing is, thatâs fine, the issue I have is people lying and saying Rust is a drop in replacement for js and is the single greatest language ever created, like come on itâs not. Its syntax and poor 3rd party library support prove that better than I ever can
âOh but in rust you learn more about computers/low level concepts, youâre just not good at codingâ
Who cares? Coding is a tool to get shit done and I think devs forget this way too often, like if one works easier than the other why does learning lower level stuff matter? Itâs useless knowledge unless you specifically go into a field where you need lower level coding. Typescript is easy, rust is not. Typescript is therefore better at making things quick, the resourse usage doesnât matter to 99% of people and the apps look good and function good.
So at this point Iâm seeing very little reason to continue. I shouldnât have to fight a programming language, mostly for issues that are caused by lack of financial backing in 3rd party libraries or badly designed syntax and Iâm about to just give up and move on, but Iâm in the minority here. Apparently everyone loves dealing with hours and hours of debugging basic problems because it makes you a better programmer, or thereâs some information Iâm just missing. Imo tho think rust devs need to understand thereâs serious value in actually making things with code, the ergonomics/good clean design of the language, and having serious 3rd party support/widespread usage of libraries. When youâre running a company you donât have time to mess around with syntax quirks, you need thinks done, stable and out the door and I just donât see that happening with Rust.
If anyone makes a serious comment/counterargument to any of my claims here I will respond to it.
I would very much like to address some of these points, since I donât think you are making a good argument here.
I shall preface this by saying that comparing Rust to TypeScript is a bad idea. They are meant for fundamentally different things and you should not regard Rust as a TypeScript replacement. I will do my best to show why Rust took the paths it did whilst being as brief as possible, but if TypeScript is your measuring stick, you should stick to it.
First of all, cargo does a lot of stuff. This is true, but you are comparing Rust to TypeScript here, and therefore you should compare cargo to npm, npm is the same thing. It does everything all at once, and everyone loves it. Cargo doing everything it does is meant to be a convenient way to interact with Rust projects. That being said, if you donât like Cargo, you can use rustc directly. You can compile Rust code much the same way you would C/C++, with a Makefile.
Multiple string types: As compared to TypeScript, this would seem like an unnecessary complication, but letâs compare it to C++ for a second. In C++ you have two string types as well, namely
const char *
andstd::string
. These are âbasicallyâ the same as&str
andString
respectively. It comes down to whether or not you want your string to be heap allocated or not. Allocation is not something you get any control over in TypeScript and for that reason it is possible to have a single unified string type. Also, TypeScript hides the internal representation of strings from you, which is convenient, but can be a real pain in the butt if youâre trying to do low-level manipulations.I would agree that Rustâs syntax can be quite terse, but this is due in part to it being a strongly typed language, unlike TypeScript, which is very weakly typed and can therefore simplify a lot of things.
Async code looks ugly in rust. Yeah, it does. Mostly because itâs not doing the same thing that it would be in TypeScript. TypeScript async code and Rust async code are fundamentally different. If you have a look at async code in modern C++ you will see a lot of the same complexity as you do in Rust, since itâs more closely related to what Rust does.
You say that rust has many different integer types, yet in C you can âjust write
int
and be done with itâ. This is patently false. Here is a catalog of Rust integer types and their C/C++ equivalents:i8 -> char
u8 -> unsigned char
i16 -> short
u16 -> unsigned short
i32 -> int
(This is the only one you would get if you just write int.)u32 -> unsigned int
i64 -> long long
u64 -> unsigned long long
In TypeScript you have just
number
, thatâs true, but itâs a managed language. Again, this hides the complexity from you, but it comes at a steep cost. If you actually want to do low-level manipulations, you have to drop down to something like aUint32Array
type, which is exactly equivalent to[u32]
in Rust.Having to use
#[tokio::main]
to make an async main. This makes me think you donât understand how async code works. The reason you can just write async code in TypeScript is because there is a runtime. Your code doesnât just run. You need a browser or a Node.JS server or something similar. That is what tokio is (kind of). This also addresses the bloat argument for tokio. Rust does not have a runtime, and therefore when you want to write async code, you need to add one. In TypeScript land, you just get the runtime whether you want it or not.As for GET requests being 32MB, I donât understand what you mean here. The request itself will never be that large. If you are complaining about the binary size, though, you are likely compiling in debug mode. Switch to release mode and add
-C opt-level=3
to the compiler flags and youâll get a binary thatâs way smaller.About the libraries, Rust is a young language. Libraries can be hard to find for specific purposes, but that will change over time. Axum doesnât have a home page, btw, because the docs.rs page is more than good enough.
Memory safety is not a buzzword. In mission-critical software (which you would never write in TypeScript, because itâs buggy as all hell), memory safety is something you have to have. If you are using C/C++, your memory safety is âtrust me broâ. âJust use a garbage collectorâ is not an argument. When people want memory safety, itâs exactly because they donât want a garbage collector. I wonât go into the specific details, but you are pigeon-holing Rust in with languages like TypeScript and Java, which are designed for different use-cases. Again, Rust is not a âbetter TypeScriptâ and you should not use it if TypeScript is what you need.
Not true. Most memory errors that end up being exploited donât cause any bugs and are extremely hard to predict and test for. Rust provides a way for you to write robust software that has some strong guarantees about what the memory of your program looks like. If done correctly, it eliminates the risk that you may have forgotten a scenario in which your program would not be memory safe.
âJust use C/C++â: No. C++, for starters, tends to be much slower than Rust and C is way too low-level to get anything useful done without first having to re-invent the wheel. Rust is a modern language, C and C++ are relics of the past. They are rife with problems and technical debt and the fact that they are designed by committee is the reason for that.
If you donât see any reason to continue with Rust, then donât. People like Rust for reasons that would not make any sense to you as a TypeScript programmer. Rust is a good programming language, TypeScript is a patch on top of a broken language. TypeScript is meant to be easy to use and is therefore hard to use for anything other than what it was designed to do.
Everyone should want memory safety and garbage collection is a form of memory safety. A form that enforces the safety at runtime and comes with a steep cost there. People use unsafe languages not because of their lack of safety but because they donât want to pay the costs involved.
Even rust has a cost - but that is on the compiler and developer instead of at runtime. Rusts memory safety makes the compiler and language a bit more complex so is a bit more to learn to get a program to compile - which is a cost to the developer. Though IMO it does make it easier to write correct code.
Memory safety without a runtime cost is what rust is selling.