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[
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.
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.
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.
When people want memory safety, it’s exactly because they don’t want a garbage collector.
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.
Welcome to compiled systems programming languages? What’d you expect?
Rust syntax is badly designed compared to most other languages I used
It really isn’t badly designed. Yeah there are more symbols than you are used to from JS/Typescript world. But more symbols does not mean bad syntax. It makes things more explicit which IMO makes things easier to read and understand what is going on. Rather than all the implicit behavior in JS/TS.
Let’s take a look at hashmaps vs json
What is the point of this? Lets compare two different things to prove no point! Look I can do it to:
let person = Person { name: "joe".to_string(), age: 23 }
const scores = new Map(); scores.set('Name', Joe); scores.set('Age', 23);
Why would you construct a map like this? That is not what maps are for in either JS or rust. But either way all these examples are easy to read and can tell what they are doing even if you have not coded the language before. Now you do need more of an understanding of rust code to read some rust code but not these examples given.
Every single library in rust is half-baked.
That is just hyperbole. Many rust libraries are very mature now. Not having a website is not a sign of maturity and the docs for axum are very good in rust docs site. If you really want a webserver with a website then you have actix-web. Many rust projects do have sites like this or even books on how to use them. And if you look at the JS ecosystem, how many libraries do you use there that have nothing more then a readme on their github page? IMO I tend to find far worst documentation for JS libraries then I do for rust ones - if you look beyond the big things like react.
No GUI framework is as stable as something like Qt or GTK
This is true of basically all languages but C/C++ and maybe JS. Most languages just lean on these for good UIs, but there is a lot of effort ATM in getting nicer GUI support in native rust. It will come with time but a GUI library is a complex thing to make.
literally every rust project has like 1 dev maintaining it in his free time and has “expect breaking changes” in the readme
This is just more untrue hyperbole.
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.
One of the things I love about rust is I don’t need to spend hours and hours debugging basic problems because the language is explicit and makes me think better about things upfront. Rather then spending hours wondering why something is producing weird output at runtime because something somewhere else got a
"1"
instead of a1
. It takes a bit more effort to get something to compile, but I find vastly fewer surprises at runtime then I do in other languages. And it is those runtime bugs that take the most amount of time to solve.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
You also don’t want things to break in production and have to spend hours and hours debugging some weird edge case.
@cybergazer
> Syntax is very confusing for no reason.This comment alone (followed by your examples) tells me you don’t understand what problems Rust is trying to solve.
What is it trying to solve?
I’ve seen a lot about how it solves “memory safety” but it’s not an issue if you use a garbage collector which is perfectly suitable unless you write low level embedded systems or oses, and even if you use something like C or C++ where you manually allocate or deallocate, if the app is properly tested memory issues won’t happen.
if the app is properly tested memory issues won’t happen
yeah, no, not really
https://security.googleblog.com/2024/09/eliminating-memory-safety-vulnerabilities-Android.html
the percentage of memory safety vulnerabilities in Android dropped from 76% to 24% over 6 years as development shifted to memory safe languages
That sounds like they’re not testing their app properly then. If they don’t test every scenario then yeah there’s gonna be issues. Plus doesn’t Android use the JVM?
if you use a garbage collector which is perfectly suitable unless you write low level embedded systems or oses
Or games, or realtime systems, or high reliability/mission critical systems, or high performace systems. There’s a long list of programs that GC isn’t suitable for for one reason or another.
and even if you use something like C or C++ where you manually allocate or deallocate, if the app is properly tested memory issues won’t happen.
There’s about four decades of security vulnerabilities in extensively tested and widely used software that says this is absolutely false.
Stuff a solo dev usually isn’t gonna be coding. Plus nowadays if you’re serious about gaming it looks like Godot + Gdscript or C# is the best option, there’s no real point in coding an entire engine nowadays for most games.
Try Scala. It has all the functional goodness, all the OOP goodness, all the imperative goodness, clean syntax like python or like typescript, really well thought out libraries like ZIO, Akka, Tapir, Caliban and access to all Java libraries. Very mature and high performance runtime with best-in-class high performance concurrent GC and a green thread implementation that can handle 10s of millions of concurrent operations.
rust is a systems/low overhead programming language. really not much of a point comparing js/ts and rust, since js is much higher level. you should be comparing it with c, c++, zig, maybe nim, etc
you also imply it’s pointless to have a language geared towards performance because computers are better now, but 1) programs run on more than just personal computers and you wouldn’t run js in an embedded system and 2) just because your computer can put up with poor performance and resource waste doesn’t mean that it’s sensible to do so (hello electron)
also, rust does more than just cosmetic improvements. it adds a layer of statically guaranteed memory safety that no other commercially viable programming language that i know of has. even if its syntax looked like ancient eldritch runes, it would still be an attractive language. the fact that it manages to do more than other languages while still having a decent syntax is amazing
you can dislike rust if you want that’s fine but you don’t need to try to shit on it just bc it’s not your cup of tea
(…) rust, since js is much higher level. you should be comparing it with c, c++, zig, maybe nim, etc
Obvious troll.
what
That example is so insanely readable lol
Absolutely standard looking code for many languages.
It’s still less intuitive though, like someone looking at it doesn’t know what a hashmap or String::from is and it’s more code for the same thing. Once you start getting into Futures and Generics that’s where the real unreadability starts
Tbh as an experienced programmer I knew exactly what it was straight away. And I don’t know rust. I would imagine the others are similar.
The reason that example is simpler is because JSON is literally JavaScript Object Notation.
It’s also not the same thing. HashMap have type parameters. So you can only add strings to that HashMap whereas you can add anything in js. Does that code even compile?
You can also do “text”.to_string() which simplifies it more.
I feel you’re quite inexperienced and once you do more in different languages you’ll begin to realise why things are like this.
Rust is a compiled language with static typing so these things are required for the compiler to do its job.
It’s also a performance focused language and would blow ts/js out of the water completely on that metric.
Languages are just tools and they all have advantages and disadvantages. You use the right tool for the job.
… the issue I have is people lying and saying Rust is a drop in replacement for js
I am genuinely curious whether you’ve actually seen this claim before, or if you badly misunderstood or are simply exaggerating a claim about Rust being a good language for web servers, or if you simply made this up as a straw-man. I can’t imagine anyone who knows what they’re talking about using those words I that order.
Honestly, this is maybe the most telling about where OP is coming from… If not straight up flame baiting; that or they mistook /r/rustcirclejerk as a serious subreddit
In OP’s defense I have heard this said unironically by several engineers at my last job.
“Rust is going to replace JavaScript thanks to webassembly, so we should be moving all of our code to that.”
“Our client should be in the same language as our backend, just like in GWT”
But “drop-in replacement”? That’s a strong and specific claim.
I do actually think that WebAssembly will enable something - maybe Rust, but more likely something simpler - to eventually dethrone JS in the browser. I also do think it seems beneficial to have your client and backend in the same language.
If your primary exposure to programming is only typescript or JavaScript maybe you shouldn’t be jumping straight into something like rust. JS is a high level language and rust is aimed at the lower levels where things can’t be as automatic. There are many languages out there like C#, Kotlin and Swift that will help you get used to the idea of strong types and immutability.
If your primary exposure to programming is only typescript or JavaScript maybe you shouldn’t be jumping straight into something like rust.
That completely contradicts any claim that Rust is user-friendly and provides a decent user experience.
Ok, I’m going to just assume this isn’t a troll.
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.
I dont even understand your issue? It’s like npm or deno which can run your code, manage your dependencies, etc. How can a JS/TS dev possibly not understand this?
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.
I dislike ? because I think you should be handling errors as they come instead of sending them up the stack. I also like the explicit .clone() but if you dont want to use it, you can also add Copy to your derive’s and this will make it happen automatically.
module::function()
generally pollutes code much less thenstatic module.function()
orstatic function()
doesn’t it?Let’s take a look at hashmaps vs json
I hate all of this code, why arent you using struct’s here? In rust its:
struct Person {name String, age i32}
and in typescript itstype Person = {name: string age: number}
Similarly, Async code starts to look really ugly and overengineered in rust.
Sure
Multiple string types like &str, String, str, instead of just one “str” function
I know of &str and String, i’ve never heard of str though so you probably dont need it. &str is a string slice, aka a borrowed String. I generally say you shouldnt be using &str because generally if you get a lifetime error from using it, its because you’re doing it wrong, just use String while you’re learning the only real difference is that String is more verbose then
""
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.
“int” from C is i32, these are int’s and float’s of various bit sizes. i32 = int 32bit, i62 = int 64 bit, f32 = float 32, u32 = unsigned (only positive) int32. but you dont usually need to specify this, rust has type inference. Also speaking of C, what about double, long, short, long long, unsigned long long, unsigned short…
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?
I kind of agree? When async was initially designed it was done as a stackless minimal thing where we could build our own runners (like tokio) but no one really builds their own runners, they just use tokio.
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.
I don’t believe you, show me this project. As a personal project I have made a monolithic web server, that handles api calls, webpage calls etc, it uses axum, tokio and serde and when I run
cargo build --release
it compiles down to a 1.9mb binary. The only way I can see this happening is if you’re not using a release build, which is a concept you should understand as a JS dev.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.
This argument has happened a few times that I know of. This is done for security purposes. If someone ships a binary blob you have to trust it to run, as a community, it was decided that we shouldnt do this.
Another major issue I’ve encountered is libraries in Rust, or lack thereof. Every single library in rust is half-baked.
I kinda also agree with this one, a lot of rust libraries are still in 0.x, I wouldnt call them all “half baked” though. If you search youtube you can find plenty of people using these libraries in prod.
“expect breaking changes” in the readme.
This is not specifically a rust problem this happens with every popular language & framework.
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.
A garbage collector “freezes” you’re program when it runs usually. There are plenty of cases of people benchmarking rust against go, js, c#, java, etc rust performs vastly better.
Then use C or C++ if you really need performance. Both of them are way better designed than Rust.
Microsoft and Google came out and said that “~70% of their security flaws are a result of memory issues” or something like that. C and C++ are fundamentally flawed, which is why both of those companies have adopted rust.
There are apps with billions of users that run fine on php
True, but the number is going down, which implies a growing number of people choose to stop using PHP, we’re even doing it at work.
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
These are fighting words lol. I already mentioned Google and Microsoft have adopted rust for Windows, Chrome and Android. Other companies solving real world problems with rust include, Cloudflare, Dropbox, NPM, Yelp, Discord, Mozilla, Coursera, Figma, Facebook/Meta and Amazon.
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.
What are you building where the end user doesn’t care if the app performs well? Not caring about resource usage results in poor performance which results in dissatisfied users/customers which stop doing business with you. Have you heard about the unending war in JS land against bundle size?
So at this point I’m seeing very little reason to continue. I shouldn’t have to fight a programming language
No one is required to like every programming language, If you don’t like rust, stop using it.
I don’t believe you, show me this project. As a personal project I have made a monolithic web server, that handles api calls, webpage calls etc, it uses axum, tokio and serde and when I run cargo build --release it compiles down to a 1.9mb binary. The only way I can see this happening is if you’re not using a release build, which is a concept you should understand as a JS dev.
I mean if you run a basic get request with the reqwest library and compile it, 32mb. In C is a few KB. You can have chatgpt generate for you if you wanna try it yourself but not write the code. This is because rust doesn’t do proper tree shaking of code and bundles everything into it even if it’s not necessary.
What are you building where the end user doesn’t care if the app performs well? Not caring about resource usage results in poor performance which results in dissatisfied users/customers which stop doing business with you. Have you heard about the unending war in JS land against bundle size?
Yes but again with Rust it’s bikeshedding. Websites with hundreds of millions of users run on php just fine, a high level dynamic language. So why are the complexities of Rust worth it to save like 10ms loading a website? Not that as a language I like php that much due to no typing, but performance for a web app really isn’t that important.
Rust again isn’t that good for embedded either due to the large binary size. Maybe it would be good for writing a game engine or something very complex but why not just use Godot or something premade
This argument has happened a few times that I know of. This is done for security purposes. If someone ships a binary blob you have to trust it to run, as a community, it was decided that we shouldnt do this.
I get where you’re going with this but it’s not scalable. If you have to compile a large app with a lot of moving parts compiling everything from scratch wears out the CPU and takes forever. This is why oses just ship binaries for most things.
This can also be solved with a file hash. When you compile the app, ensure the compiled file hash matches the hash of the binary in cargo. So you can get the best of both worlds
No one is required to like every programming language, If you don’t like rust, stop using it.
Yes but the fact is rust is growing immensely in popularity so I made this post to understand what exactly I’m missing about it
This is because rust doesn’t do proper tree shaking of code and bundles everything into it even if it’s not necessary.
This isn’t true. a simple:
fn main() { println!("Hello World!); }
compiles into the same size binary as:fn main() { println!(hello_world()); }
fn hello_world() -> String { String::from("Hello World!") }
fn another_function() -> String { String::from("Completely unused function") }
So why are the complexities of Rust worth it to save like 10ms loading a website? Not that as a language I like php that much due to no typing, but performance for a web app really isn’t that important.
if the amount of rust, c and c++ in web infrastructure doesnt convince you that performance is important then I guess we’ll have to agree to disagree here.
Rust again isn’t that good for embedded either due to the large binary size
I’m not sure about this one, I’ve never worked on embedded but I’m not convinced. There’s an embedded rust book and their target hardware is a device with 256kb of flash memory, and 48kb of RAM.
This can also be solved with a file hash. When you compile the app, ensure the compiled file hash matches the hash of the binary in cargo. So you can get the best of both worlds
This doesn’t address security at all, the only thing a hash does is tell you that the file you download was the file that was uploaded. If I upload malware in my library to cargo, cargo generates a hash for my library, then you download my library. The only thing the hash tells you is that you did indeed download my malware. It’s also harder to audit my library because cargo has a binary blob instead of my code, you have to go to my repo in order to find the malware, and you better hope I haven’t done something clever like add the malware in locally instead of in the repo, so it’s only there when I build to upload to cargo.
FYI the JVM’s GC is concurrent and doesn’t freeze.
Huh, I knew Go’s GC ran on another thread but not the JVM, cool.
I thought they both had to stop the world at some point. And the advancements were about running more of the GC steps in the background to minimize the time needed in the stop the world phase.
Just looked it up, looks like you’re right. The Go GC has to pause when it sweeps and it looks like the JVM has multiple GC implementations but all of them have to pause for sweeps. I don’t really use either language so I didn’t know how the magic worked.
I mostly agree with you, just two nitpicks.
Int is either i16 or i32 in C/C++.
The async runtime in embedded is mostly embassy from what I can tell. It makes different tradeoffs and is a lot smaller but can only run on one core. It also takes care to put the core to sleep when there is nothing to execute.
This response needs more up votes
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?
You’re kidding, right? You do actually understand that languages that aren’t JavaScript don’t have built in async runtimes and they need to be provided by a library, right? You’re not actually writing a post about how much the programming language you have two days experience in made different design decisions and is therefore good at different things than the programming language you have five years experience in and therefore it sucks, right?
There are plenty of slimmer async runtimes for Rust. Pollster comes to mind, although it doesn’t provide any I/O functionality. (That’s where the “bloat” that’s in Tokio comes from – it’s providing functionality the Javascript runtime has built in. You see, Rust, unlike Typescript and Java that have compilers that emit source code for an interpreter, is actually a compiled language, and Rust programs compile to self-contained executables that don’t need any external dependencies to run. If you included the size of the node binary in your Javascript app, Rust would win the filesize war no contest.)
As for “performance doesn’t matter” – I’d like to tell you a personal story about a Rust program I’m working on. There’s an imageboard I’m a fan of, and it runs some booru-like software, meaning when you upload an image you give it a few dozen tags, and then people can search for images by their tags. The tag search functionality on the website I thought was missing a few features, so I downloaded a copy of the entire post database on that site (including URLs and tag lists of every post) and wrote my own search algorithm in Rust. I wrote a function that accepts a search query and a list of tags and returns a boolean, and searching the posts was as simple as
vec_of_posts.iter().filter(|post| matches(search_query, post)).collect()
. I then downloaded the rayon crate, and, with a sngle line change tovec_of_posts.par_iter().filter(|post matches(search_query, post).collect()
, I was running the search in parallel on all CPU cores. Running a full search of all four million posts takes about 50 milliseconds on my laptop, or 3 seconds running the search locally on an Android phone. Try that in an interpreted language.(So help me God, if you respond to that last point by saying “cloud computing”, I am going to shoot you in the head.)
You do actually understand that languages that aren’t JavaScript don’t have built in async runtimes and they need to be provided by a library, right?
How do you explain C#?
please tell me your argument is not “other language also does this thing, therefore it’s dumb for rust to not do it”
I think one thing to mention is that Rust is highly specific in what it does. In most of the examples you mentioned, string types, tokio::main, you can essentially just say that rust is more explicit. When initializing an integer variable in C using int, it’s not specified what use the integer is or whether it’s signed or not. i32, uint16_t you can see how it’s specified. Using tokio::main before your main function just specifies that you’re using the tokio asynchronous executor for your async code. In the case of string types, they all have different implementations which just help with being specific.
The reason I like Rust is because I know what’s happening when I read it. Did I have to read the whole async book to understand how the tokio::main stuff works? Yes. But now I understand exactly how it works. The problem I have with using Javascript is that it doesn’t have that high amount of explicitness(is that a word?). At the end of the day, if you’re using it for a personal project or you’re arguing for language supremacy, it really just comes down to personal preference.
When is an int not 32bits nowadays, and, seriously, not signed??
I mean on some obscure platform it might be 16 bits, but unsigned??!
Enter embedded programming, believe it or not there is a ton of low level C code being written; also, try adding a new protocol for networking, there are many cases where bitstructure matters, I recently wrote a small bit of code for a project that used bit packing so that we could fit inside of a single Ethernet frame so that we didn’t have to deal with fragmentation and the networking overhead it caused.
For context, what is your past programming background and what are you trying to do? While rust is a great language, it may not be the right tool for what you’re trying to do if these are things that you view as unnecessary
I have done low level dev, and put stuff in wan frames (576 bytes IIRC) and meddling with ethernet frames (1500 bytes), now you tell me where on earth you find a not totally obscure int thats unsigned by default.
That was my statement you know.
For rust, it feels like someone fell in love with c++ template meta programming (you know the … variadic template and all that) and wanted a better language for that. Good gor them if they like it.
Soooo, an int in most architectures is actually signed, usually a 2’s compliment signed 32 bit value; but the spec does not require it to be 32bits, some platforms might use an 8 bit or 16bit value instead (think older 8bit microcontrollers). That’s why they have ‘int32_t’, ‘uint32_t’, etc for C/C++, it just sounds like you haven’t used these number types (check stdint.h). Rust just requires you to use the more explicit number format by default (which I personally prefer because I have had to jump between embedded and Linux development).
The multiple string types are annoying at first, but its probably better to realize that they are more like two types (String and str) with the apperstand (&) ones being references (think pointer in C/C++). A String is like a C++ std::string and a str is more like a C-String (fixed sized array ish of chars).
@Valmond i32 is indeed Rust’s default integer type.
Thanks!
Is there an “int” to use the default int with?
@Valmond what do you mean by default int? (Either way, probably not; there’s usize though)
Downvote all you want, even tho gs you dont understand lol
In 99% of C/C++ compilers, if you write “int” then it is treated as a signed 32 bit data type. If you want something else you need to specify it. Like unsigned char for example is a non signed 16bit data tupe (again,on 99% of C/C++ compilers). Thus int defaults to a signed 32 bit data type which makes ‘int’ a default value. I don’t know how to better explain that better to a developer. If you don’t understand, please do tell.
@Valmond I’m aware of that, but that’s for different languages. C/C++ don’t get to define if programming in general has a “default int”
In C/C++ the default int definitely exists, and is a signed 32bit in the most overwhelming cases, what are you talking about?
On Arduino it’s 16 bits. (At least the original ATMEL ones; I dunno if they’ve finally moved to ARM yet.)
This lost me quite a lot of time when I tried to use their SD card library on a 32-bit Arduino and it hung due to some code assuming
int
was 16 bits.Unsigned ?
I mean the nintendo ds math library was 16 bits too, it happens, but unsigned? Never heard of it.
I use unsigned and fixed point sub-16 bit integers (you can make them almost any size you want) in gateware you can optimize things and one of those is not using a ton of huge numbers to do math when you don’t need to.
Default unsigned?
I think you misunderstood.
Maybe translation issue? I just meant for fpga work int is 32 signed by default, but it’s way more common to use logic variables which are unsigned and arbitrary length (>=1)
C/C++ compilers. Not FPGA.
Anyways, int is s32 very very very often, that’s all my point was. C, gpgpu, c#, java, …
When is an int not 32bits nowadays
C standard does not actually define the exact sizes of long/int and so on, it’s just what is now most popular (it does have some limitations and requirements on these types though)
It does define minimum sizes for different types. An int for example is at least two bytes, whatever size those might be!
Duh I know, it’s just that it’s now the standard that your ‘int’ is signed, you know as I said ‘show me otherwise’. It’s also wildly most common 32 bits.
I do systems programming work, sometimes with constrained memory scenarios. We always want to use the smallest types we can for any task, and unless negative numbers are a necessary, always prefer unsigned. That means a lot of u8 and u16 unless we know a value is likely to need more bits to be represented. Probably doesn’t matter as much in we programming but that’s not Rust’s niche (or well not its original niche).
Well where are those unsigned default ‘int’ I said doesn’t exist, and that everyone seems to not think I’m right about?
Don’t get me wrong, unsigned integers are useful, that’s why we hate java btw, but it was not really the question.
Also, if you’re using like 16 bits ints because you have memory constraints then you are doing it wrong. All modern compilers can handle any kind of bits as long as it’s less than the base size, so you can have a 3bit int, another 3bit int and 2 1 bit ints, nicely #packed into a byte. You use the :3 syntax.
Your default types for that are i32 or u32. It’s the exact same number of characters yet encodes more precise information.
I’m aware of packing, but for my specific niche the main bottleneck is CPU, and it’s important to minimize the amount of memory usage to improve data locality, increasing cache hit rates, ultimately increasing cpu throughout. Any gains we would make by packing such small values would likely be eliminated by the cost of unpacking them, unless it’s a flags-like value where we are primarily comparing individual bits.
So not default??
For the packing/unpacking, sure it all depends on where you want the cost.
I’ll try to post a longer answer later but Rust is really for systems programming and its choices follow from that. I liked this article:
Frankly, all of your points sound quite ignorant. Syntax is literally just a matter of getting used to it. Comparing HashMap ergonomics doesn’t make sense, you should rather compare to struct construction. There are many good reasons for different string types and number types. There are good reasons not to bake in async. Rust documentation is in the code for a very good reason and it’s actually really nice to read docs like that (obviously read it on docs.rs, not in the code itself).
I could go on but there are answers to all of your specific qualms if you just bothered to look for yourself.
Then use C or C++ if you really need performance.
And that’s where I stopped. I’m a real working programmer who’s done tons of work in C++, so I know firsthand that it absolutely sucks compared to Rust. Go back to Typescript if you hate Rust so much.
Same, I’ve done C and C++ for several decades and I’ve spent too much time of that hunting obscure memory issus triggered by rare race conditions. No matter how hard we try to use safe patterns we are all too human. The most experienced C++ devs I know are the first to admit this.
In Rust once it compiles much less time is spent debugging and a whole big category of bugs are gone from the production code.
And C++ aient pretty but maybe that’s subjective.