Live data from Hacker News

Why asynchronous Rust doesn't work

eta.st

41–50 of 305 posts

Re: Why asynchronous Rust doesn't work

#41
post #38

Earlier quoted context omitted.

> It's just making things needlessly hard for programmers in an attempt to save effort from computers. Well actually it is supposed to make concurrency easier for programmers. What would you say is an "easy" way to deal with concurrency? Handle threading, memory visibility issues, locking, etc yourself? Doing it "reactive"? I guess personally I too would say something messaging based such as the actor pattern but not…

When async is visible in the type system it means you need to write things like iterating containers twice: once for dealing with non-async values, and a second time for handling async operations. Well maybe this isn't the best example because you already have iterators for the plain iteration part; however let's say you wanted to make an iterator for a container that needs async to iterate the data, then you find yo…

> When async is visible in the type system it means you need to write things like iterating containers twice

It should be noted that this is only if the type-system in your language is unable to properly abstract over containers and their capabilities.

If it is powerful enough however, then you can write the code once, under the (important!) assumption of short-circuiting in the case of errors.

Re: Why asynchronous Rust doesn't work

#42

Earlier quoted context omitted.

> What would you say is an "easy" way to deal with concurrency? The Beam/Erlang/Elixir model. It's a bit more constraining but it's just so clean and reliable, and processes having individual mailboxes makes it much simpler than having to wonder what synchronisation primitives to use, then decide how to share them (globals? parameters? others?). Just get a reference to a process and you can send it messages, simple.…

> The Beam/Erlang/Elixir model. It's a bit more constraining but it's just so clean and reliable [..] I agree. But I think that only works if you embed it in the language like Erlang did. If you make it optional you get libraries which use different models, people still making concurrency mistakes, etc. But for more generic languages then Erlang such as Rust (or Java, C#, etc.) this simply isn't an option. Because th…

We know how to do interiperable DSLs for IO, see eg IO monads in Haskell, or ebpf in Linux. And Erlang could adapted for embedding, it's already designed to isolate its processes in a vm out of the box, so wouldn't leak back to the host language...

Re: Why asynchronous Rust doesn't work

#43
post #32

Earlier quoted context omitted.

Async is bread and butter of JS and you rarely have any larger bits of sync code, so you learn to deal with this. And then being able to just freely pass bits of data accessing code (closures) around is such wonderful feeling that you'll miss it everywhere else you go. I recently had a little excursion into Python and had to invent a very nasty hack to concisely keep short bits of code accessible through some constan…

Frontend or backend js? Because in the frontend everything is just scheduled to a single thread, so you only deal with concurrency, not parallelism.

"Modern" frontend JS is increasingly async. Yes, it's not true async, but it still has all the problems, but the benefit of not locking up the UI is worth the pain.

Even old frontend JS was async in that events could be triggered by the user at any time, and in any order, and xhr and image loads requests were async as well.

Re: Why asynchronous Rust doesn't work

#44
> As someone who used to really love Rust, this makes me quite sad.

The current async story is still an MVP and I too dislike it. In the months before async, the ecosystem seemed on halt, waiting for async to land on stable Rust. Since then nothing has changed. The ecosystem "degraded" noticeable and has not recovered since. Maybe in future async will be great, but right now I try to avoid it.

... I still love Rust

Re: Why asynchronous Rust doesn't work

#45
post #32

Earlier quoted context omitted.

Frontend or backend js? Because in the frontend everything is just scheduled to a single thread, so you only deal with concurrency, not parallelism.

"Modern" frontend JS is increasingly async. Yes, it's not true async, but it still has all the problems, but the benefit of not locking up the UI is worth the pain. Even old frontend JS was async in that events could be triggered by the user at any time, and in any order, and xhr and image loads requests were async as well.

Yeah I know, but I think the gp is thinking of nasty debugging sessions that come from parallelism, not concurrency. Concurrency issues one can step through with a debugger on a single thread.

Re: Why asynchronous Rust doesn't work

#46

Earlier quoted context omitted.

From my very limited expeirience with Rust I noticed that it becomes way more easy and laid back language when you just skip using references and lifetimes nearly completely and just wrap everything in Rc . Then you are getting expeirience of fairly high level language with a lot of very cool constructs and features like exhaustive pattern matching and value types with a lot of auto-derived functionality. Does Rc hel…

If you are going to wrap everything in Rc, just use kotlin or c-sharp or python?

Because Rust feels even nicer than Python and C# (I don't have any experience with kotlin but from what I've seen it's as decent as Python at least) and even with Rc Rust is quite light-weight and fast.

One of its selling points is zero-cost abstractions and pretty powerful abstractions at that.

Re: Why asynchronous Rust doesn't work

#47

Earlier quoted context omitted.

From my very limited expeirience with Rust I noticed that it becomes way more easy and laid back language when you just skip using references and lifetimes nearly completely and just wrap everything in Rc . Then you are getting expeirience of fairly high level language with a lot of very cool constructs and features like exhaustive pattern matching and value types with a lot of auto-derived functionality. Does Rc hel…

If you are going to wrap everything in Rc, just use kotlin or c-sharp or python?

Rust has advantages over C#, even for high level programming:

* Rust traits are more flexible than C# interfaces, especially when combined with generics (implementing traits for foreign types, associated types, each method can have its own constraints, conditional trait implementation, #derive)

* Rust has much stronger thread safety guarantees (absence of data races, preventing access to a mutex's data without locking)

* Options are cleaner than null (though at least C# supports non-nullable reference types nowadays)

* Cleaner error handling through `Result`s. In C# you either have to use exceptions (discouraged for errors that are expected to happen), or use ad-hoc approaches which don't benefit from syntax sugar like the `?` operator.

* Support for discriminated unions ("enums")

* I like cargo better than msbuild+nuget ("it just works", feature-flags + conditional dependencies, distribution as source instead of binaries)

On the other hand C# has better IDEs and you don't have to deal with the rigors of ownership and the borrow checker. In particular I struggle with LINQ style functional programming in Rust, since the lifetimes of closures and the fields they close over are difficult to reason about.

I haven't used Kotlin, but expect it to be similar to C# in its strengths and weaknesses. Python is not an option for me, since I like static typing.

Re: Why asynchronous Rust doesn't work

#48
post #26

Maybe it’s only my take, but from what I understand, the author wants to easily create closures with mutable references and call them from anywhere, asynchronously? And the complaint is that Rust semantics makes this hard. Well yes, Rust makes it uncomfortable to shoot your own foot, that’s kind of the point.

Why would the first example with the database be "shooting your own foot"? I'm not a Rust dev, but in other languages that code makes perfect sense to me.

What if you do:

    my_fn(|| {
        db.store(42);
    });
    db.drop();
(Assuming you can just drop the database object, the semantics don’t really matter but the idea is the same.) The OP wants an easy way to do this but this is just not an easy thing to do. How can the closure guarantee that the database object will exist if my_fn decides to sleep for a couple seconds? Most languages do not have this problem because either: they use a garbage collector (Java and it’s cousins, Python, Go) or they are not safe (C, C++). Rust is in a particularly difficult (and ambitious and exciting!) intersection where this problem is tricky.

Re: Why asynchronous Rust doesn't work

#49
post #32

Earlier quoted context omitted.

Async is bread and butter of JS and you rarely have any larger bits of sync code, so you learn to deal with this. And then being able to just freely pass bits of data accessing code (closures) around is such wonderful feeling that you'll miss it everywhere else you go. I recently had a little excursion into Python and had to invent a very nasty hack to concisely keep short bits of code accessible through some constan…

Frontend or backend js? Because in the frontend everything is just scheduled to a single thread, so you only deal with concurrency, not parallelism.

I think this whole thread is about woes of asynchronous programming (concurrency) not parallelism which is another can of worms.

Re: Why asynchronous Rust doesn't work

#50

Earlier quoted context omitted.

From my very limited expeirience with Rust I noticed that it becomes way more easy and laid back language when you just skip using references and lifetimes nearly completely and just wrap everything in Rc . Then you are getting expeirience of fairly high level language with a lot of very cool constructs and features like exhaustive pattern matching and value types with a lot of auto-derived functionality. Does Rc hel…

If you are going to wrap everything in Rc, just use kotlin or c-sharp or python?

Correct me if I'm wrong, but:

- GC pauses, Rc does not, it's simply a deallocation by the last reference holder

- Rc still has predictable memory allocation/deallocation, GC is not guaranteed to run until needed

- More efficient memory use, no need to keep track of allocated objects

- The rest of the Rust language is a pleasure to use (imo)

- Python is slow for certain applications, and not concurrent

- Kotlin is kind of more niche than Rust, it's very popular in the Android community, like C# is popular on Windows

Just my 2 cents, I love progamming in all languages. There are some use-cases where a high level language is absolutely the way to go. For others, Rust provides much more control with a handy escape hatch. Absolutely don't go wrapping everything in Rc like a madman, only when the reduced complexity is more beneficial than dealing with references/lifetimes.

Post reply on HN