← Back to context

Comment by VWWHFSfQ

3 months ago

Rust is very easy when you want to do easy things. You can actually just completely avoid the borrow-checker altogether if you want to. Just .clone(), or Arc/Mutex. It's what all the other languages (like Go or Java) are doing anyway.

But if you want to do a difficult and complicated thing, then Rust is going to raise the guard rails. Your program won't even compile if it's unsafe. It won't let you make a buggy app. So now you need to back up and decide if you want it to be easy, or you want it to be correct.

Yes, Rust is hard. But it doesn't have to be if you don't want.

This argument goes only so far. Would you consider querying a database hard? Most developers would say no. But it’s actually a pretty hard problem, if you want to do it safely. In rust, that difficultly leaks into the crates. I have a project that uses diesel and to make even a single composable query is a tangle of uppercase Type soup.

This just isn’t a problem in other languages I’ve used, which granted aren’t as safe.

I love Rust. But saying it’s only hard if you are doing hard things is an oversimplification.

  • Building a proper ORM is hard. Querying a database is not. See the postgres crate for an example.

    Querying a database while ensuring type safety is harder, but you still don't need an OEM for that. See sqlx.

    • Sqlx is completely lacking in the query composability department, and leads to a very large amount of boilerplate.

      You can derive FromRow for your structs to cut down the boilerplate, but if you need to join two tables that happen to have a column with the same name it stops working, unless you remember to _always_ alias one of the columns to the same name, every time you query that table from anywhere (even when the duplicate column names would not be present). If a table gets added later that happens to share a column name with another table? Hope you don't ever have to join those two together.

      Doing something CRUD-y like "change ordering based on a parameter" is not supported, and you have to fall back to sprintf("%s ORDER BY %s %s") style concatenation.

      Gets even worse if you have to parameterize WHERE clauses.

      2 replies →

  • My feeling is that rust makes easy things hard and hard things work.

    • I'm not going to deny your experience. But is Rust really that hard? It's a very smooth experience for me - sometimes enough for me to choose it instead of Python.

      I know that the compiler complains a lot. But I code with the help of realtime feedback from tools like the language server (rust-analyzer) and bacon. It feels like 'debug as you code'. And I really love the hand holding it does.

      1 reply →

  • > This just isn’t a problem in other languages I’ve used, which granted aren’t as safe.

    Most languages used with DBs are just as safe. This idea about Rust being more safe than languages with GC needs a rather big [Citation Needed] sign for the fans.

If you use Rust with `.clone()` and Arc/Mutex, why not just using one of the myriad of other modern and memory safe languages like Go, Scala/Kotlin/Java, C#, Swift?

The whole point of Rust is to bring memory safety with zero cost abstraction. It's essentially bringing memory safety to the use-cases that require C/C++. If you don't require that, then a whole world of modern languages becomes available :-).

  • For me personally, doing the clone-everything style of Rust for a first pass means I still have a graceful incremental path to go pursue the harder optimizations that are possible with more thoughtful memory management. The distinction is that I can do this optimization pass continuing to work in Rust rather than considering, and probably discarding, a potential rewrite to a net-new language if I had started in something like Ruby/Python/Elixir. FFI to optimize just the hot paths in a multi-language project has significant downsides and tradeoffs.

    Plus in the meantime, even if I'm doing the "easy mode" approach I get to use all of the features I enjoy about writing in Rust - generics, macros, sum types, pattern matching, Result/Option types. Many of these can't be found all together in a single managed/GC'd languages, and the list of those that I would consider viable for my personal or professional use is quite sparse.

    • > generics, macros, sum types, pattern matching, Result/Option types. Many of these can't be found all together in a single managed/GC'd languages

      What about e.g. Kotlin or Swift?

      1 reply →

    • Agree in this, i enjoy Rust and use the same approach.

      People are saying rust is harsh, i would day its not that much harder then other languages just more verbose and demanding.