5 ms·
> without touching async The pain comes from async. Over time, I came up to this conclusion: if someone tells me that Rust is nice and you only need to change
by hirrolot 4y ago
> without touching async
The pain comes from async. Over time, I came up to this conclusion: if someone tells me that Rust is nice and you only need to change your mind, this person doesn't write async code. Or he/she writes very-very straightforward, if not primitive async code and doesn't touch HOFs, traits, and similar stuff at all.
However, when you write networking code, you typically use async. The worst role is being an async library author (me).
- logicchains 4y agoPeople talk about C++ suffering from its commitment to zero-cost abstraction, but the same thing applies to Rust async. While async may theoretically be the fastest possible way to write asynchronous code, it feels like an order of magnitude more painful than the CSP/channel-based approached used in languages like Go and Clojure (and the upcoming Java Loom). Personally if I had to write async code that required anything other than the absolute minimum possible latency, I'd prefer to write Go, and I say that as someone who thinks Go's lack of generics was an absolutely terrible idea.
- crabbygrabby 4y agoGo now has generics. The performance of using them is hit or miss it seems. Your opinion is valid, but I would say, if you aren't juicing for the best performance, you can adopt easier patterns to async. There are comments on this post detailing how to go about doing that. Or yea use another language if you want.
- logicchains 4y ago>you can adopt easier patterns to async Can I do this without having to wrap half the libraries in the ecosystem if I want to use them without worrying about async? C# has that issue: the ecosystem buys heavily into async, so it can be hard to avoid it.
- crabbygrabby 4y agoProbably depends on what you are using and trying to do. So I'll say 'maybe'.
- gjvnq 4y agoBut Go still doesn't have enuns with data like in Rust.
- gwbas1c 4y agoI made the mistake of trying to learn Rust while doing async programming. IMO, when it comes to concurrent, it's a matter of picking your poison: Threaded Rust: No overhead of a GC, but overhead of context switches and multiple stacks. NodeJS: No overhead of context switches and multiple stacks, but the overhead of a highly optimized GC. (And I suspect that the GC can do tricks like run when the process is waiting on all tasks.) Some real data would be very interesting.
- klysm 4y agoThere’s plenty of real world data. I forget the name of the website but web server benchmarks are pretty good at showing the differences.
- WuxiFingerHold 4y agoUnless you really need the best performance possible there're pretty good alternatives. Mainly C# or Go and soon JVM with Loom. Some numbers: https://web-frameworks-benchmark.netlify.app/result?l=rust,go,csharp https://web-frameworks-benchmark.netlify.app/result?l=rust,g...
- Larrikin 4y agoWhy the need to wait for loom when there is Kotlin and coroutines?
- kaba0 4y ago> No overhead of a GC, but overhead of context switches and multiple stacks. Is it really an overhead if it happens in parallel? You have real parallelism, not only concurrency.
- int_19h 4y agoAsync in something like C# is much less painful precisely because it doesn't try to be a zero-cost (or at least as low cost as possible) abstraction. When the language can allocate stack frames on the heap implicitly as needed, and there's GC to clean them up, things "just work".
- HWR_14 4y ago> The pain comes from async. Over time, I came up to this conclusion: if someone tells me that Rust is nice and you only need to change your mind, this person doesn't write async code. Async code is a pain in almost any language. Certainly any language that differentiates between async code and non-async code has the async code be a pain.
- logicchains 4y agoWriting this kind of async code in Haskell (and to some extent OCaml) is much nicer, because you can abstract over the asyncness of code. This can't be done in Rust or C# because the type system isn't powerful enough (no higher-kinded types). To be fair, adding HKTs to Rust's existing type system is a challenging theoretical problem in itself.
- pjmlp 4y agoC++ surely has HKT, that is what templates that take other templates as type parameters are for.
- tialaramex 4y agoIn a sense, but the "ill-formed, no diagnostic required" hack allows for scenarios where what you wrote is nonsense, and a human can explain why, but your C++ compiler doesn't have that insight, so it compiles anyway and does... something. This avoids needing to teach the machine how to determine if what you did was sound. But this is of course not a very safe way to write software.
- pjmlp 4y agoIf the author is fool enough to not use the language features that exist since C++17 to validate template code, surely. I also don't find debugging Rust macros that fun, yet most likely the answer will be that the macro author didn't took enough care, and Rust is great to write gigantic DSL macros.
- accountofme 4y agoYou might be right on this. I have written a lot of rust and a fair bit of network code, but I never went near async. I'm not exactly sure what my problem with it is, but I started writing rust before async was a thing and always felt more comfortable with finite state machines and polling for network code (I guess I am atypical). Anyway, I am sorry that you have to use async.
- the__alchemist 4y agoOn embededded, you can write straightforward asynchronous code without using *Async*. You do it using DMA, and interrupts, perhaps with static analysis etc. There are efforts to use Async on embedded rust to abstract these, but it's not required. Of note re networking: My observation is that the Rust Async ecosystem only covers TCP and higher. There are loads of Async TCP, HTTP etc libs, but nothing that can do anything lower than that! At that point, you're looking at perhaps `socket2`, and `smoltcp`; the latter, of note, also works on embedded, and goes lower than TCP, despite its name. My best guess is that a lot of people are using Rust for TCP and HTTP level web programming, eg servers, where spawning 100s or more IO-bound processes at once makes sense; the area where Async shines. Why I'm confounded: #1: Rust excels at low-level programming; ie it's one of a select group capable of this (Along with C, C++, ADA, and zig) #2: Web application programming in Rust has a long way to go to get to the level of Django and Rails. It only has Flask analogues. Neither of those goals are served by the existing Async-based ecosystem; it occupies a spot in between.
- drogus 4y agoI disagree. I write Rust, I write mainly async Rust and while my code is maybe not the most sophisticated I use a lot of async traits and generics. I still find it one of the best languages I know, definitely my favourite for all around coding at the moment.
- jokethrowaway 4y agoThere are two things to mention: 1. Async for trivial things is straightforward and easy 2. Rust actively discourages some async patterns to protect you from some memory misuse edge cases It does limit your freedom in writing code that eg. relies a lot on async callbacks, but there's a reason. The first time I did a massive async project (think a rust binary maxing all cores executing the largest possible number of async fns doing various things in parallel - from fetching data online to running tensorflow) I came at it all wrong and wrote something that would have worked in node or haskell but that was a pain to compile in rust. After days of pain I understood what rust wanted and nowadays I use the same pattern and it's fairly easy for me. Just another tool in the shed.
- pdimitar 4y agoDid you do a write-up on this pattern? I'm finding myself in a similar situation lately and I'd appreciate the help a lot.
- iex_xei 4y agoThat's probably true. I've experimented a bit with tokio for local IO bound tasks, but decided it's unnecessarily complex. I think some patterns will emerge from current Rust async development eventually. Good parts will be easier and bad parts will be removed, but digestion of such concepts usually require time.