|
Pretty surprising -- I had much the opposite experience. On our last product, we decided to start switching from Typescript to Rust on the backend because we got tired of crashes. I consider that to be one of the greatest technical mistakes I've made ever, as our productivity slowed massively. I'll just share two time-draining issues that only occur in Rust: (1) Writing higher-order functions (e.g.: a function to open a database connection, do something, and then close it -- yes, I know you can use RAII for this particular example), which is trivial in Haskell and TypeScript and JavaScript and C++ and PHP, turned out to be so impossible in Rust [even after asking Rust-expert friends for help], that I learned to just give up and never try, though it sometimes worked to write a macro instead. (2) It's happened many times that I would attempt a refactoring, spend all day fixing type errors, finally get to the top-level file, get a type error that's actually caused somewhere else by basic parts of the design, and conclude the entire refactoring I had attempted is impossible and need to revert everything. On top of that, Rust is the only modern language I can name where using a value by its interface instead of its concrete type lies somewhere between advanced and impossible, depending on what exactly you're doing. I came away concluding that application code (as opposed to systems or library code) should, to a first approximation, never be written in Rust. |
For example, I use the deadpool-postgres crate for database pooling. Getting a connection looks like this:
Because of RAII, you don't need a higher-order function helper, but if you really wanted to make one: Now you can do: If you know TypeScript, this shouldn't be too difficult to read or write. The gnarliest stuff here is knowing the type signature of the function argument; because of async, it must be AsyncFnOnce, for one, and you need to know that the type that the deadpool crate returns is called Object<Manager> (which doesn't sound like a connection, to be fair). Determining the exact concrete type to match type constraints on is sometimes a chore, but TypeScript is surely no different here!If you don't know Rust too well, the "move" part will be a little mysterious, to be sure.