Hacker News new | ask | show | jobs
by Chio 1477 days ago
To add my own few cents to this very common discussion Rust is hard is the same way that most programming languages that rely "non-standard" paradigms are hard because they challenge your current mental model of programming. However "different", instead of "hard", would be a better way to describe these sort of languages like Rust, Prolog, and Haskell (as well as a ton of other languages).

If you look at Rust from this perspective then it becomes much more valuable to consider learning because it teach you a different way to modelling your data, and how to break-up your code; and while a language like Java may not force you to consider the borrow checker you will probably be a better overall Engineer knowing how to make it happy even when working in other languages.

On the topic discussed in the actual article: I can't wait for scoped threads to finally go stable since being forced for throw an Arc around almost everything you want to share between threads does not really suit Rust which really emphasise zero-copy in their standard library.

3 comments

I think a lot of the complaints about rust's difficulty come from people trying to use async in rust. I don't think the problem there is that rust is "different". The problem is that async rust isn't ready yet.

Rust's ecosystem pushes users toward using async for IO, and async support in the language & compiler is wildly incomplete. And it has been for years - the last big async feature (the async keyword) landed 2.5 years ago [1]. But its barely usable as-is. Building software with async today feels like trying to build a house out of daggers. Traits? Nope. Closures? Nope. Regular types? Only if they're Pinned. Your types are pinned, right? Iterators over async objects? Nope that doesn't work. Library support? Without traits, libraries are limited in what they can provide. Async rust? Batteries are not included.

We need TAIT, GAT, async closures, async iterators / streams, and a bunch of other little quality of life improvements before I'd consider it "done". I don't know where async's momentum went, but its a bit disappointing how halfbaked async is given how nice the rest of the language is.

[1] https://areweasyncyet.rs/

I agree wholeheartedly on your points regarding async, which is a topic I've tried to avoid so far in all of my Rust projects because of all the reasons you've already raised above and you really don't need it for most use-cases.
I totally agree. I've been working with Rust since before 1.0, and I love the language, and I never want to work on async code in Rust. The mental model is too hard for the payoff. I've also found debugging async code to be more nightmarish.

Most Rust applications I've worked on which have used some kind of parallelism/concurrency would be fine with a thread pool of workers and good old sync channels.

How are people writing high throughput web/network services without async? Is there a async library to use. Like what do you reach for if you wanted to write redis or nginx with rust?
I'm not a rust expert by any means, but redis and nginx are both written in C, which doesn't have async as a language feature. Is there a reason the techniques used there wouldn't translate to rust, regardless of the state of rusts native async support?
You can, it's just not as nice. Writing code this way can also require unsafe. Async in Rust is primarily about achieving zero-cost async code in a safe way.
yeah, rusts async/await is just making it nicer to use the same ideas. like is there a libuv or libevent in the rust world thats being used?
https://crates.io/crates/mio is the de-facto standard package that's similar to libuv/libevent. The most popular async executor, Tokio, is built on top of this. They're maintained by the same organization.
I thought this library had alot less features then the popular c event loop libraries?
> Rust is hard is the same way that most programming languages that rely "non-standard" paradigms are hard

Agree.

And the problem is not (mainly) async, the borrow checker, etc.

Rust is truly different to other "imperative looking, functional looking" languages. I suspect the choice of make it look too close to C is part of the issue: You come to it and quickly start producing code as if it were another C/python/C# and that is a major mistake.

In specially, because Rust make SO MUCH SO EASIER... but not the things that other langs make easier (use of `String` anyone?), so is a major shock to see that supposedly "simple" things "not work".

Is only after getting that the core of Rust is `Struct Enum Pattern Matching Moves & Borrows`, and pls, stick all together with this `Traits` & composition, that are part of this important `Paradigms` is when Rust click.

This is the shock: Rust is not about the use of some `types` and then apply algorithms. Is the MODELING of behaviours (traits) and the INTERACTION of the types/traits.

That is the mind-bending. Is like see programming flipped!

> I can't wait for scoped threads to finally go stable since being forced for throw an Arc around almost everything you want to share between threads does not really suit Rust which really emphasise zero-copy in their standard library.

Note that this is only for lexical scopes so each set of scoped threads you create must be destroyed in the same lexical scope.

In practice, this means that thread pooling (and in particular async runtimes) cannot use them.

In fact, we used to have the closure passed to thread and join handle had a lifetime param 'a (not 'static), but this was unsound in combination with Arc etc that didn't require those. If you're interested, it's related to the drop guarantees and safety of `mem::leak`. There was a big debacle right before 1.0 and, imo, the team rushed this decision and we're paying for it with Arcs - any async code base is riddled with it.