Hacker News new | ask | show | jobs
by HWR_14 1482 days 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.

3 comments

> Certainly any language that differentiates between async code and non-async code has the async code be a pain.

Function colouring is not the only problem with async code. The difference is that concurrency in other high-level languages usually don't break down polymorphism and other language features. Also, they don't push you to deal with lifetimes, which is a serious issue in Rusty async.

Writing async code in C# is a lot easier to me than in Rust. Unfortunately, I didn't have a chance to write async in functional languages, such as Haskell or F#, because they are well-known for elegant concurrency.

I'm not sure if C# async was derived from F#, but it definitely looks very similar. The main difference is that in F# async is vastly more customizable (but also slower, because the compiler can't make certain assumptions due to said customizability.

https://docs.microsoft.com/en-us/dotnet/fsharp/language-refe...

Writing 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.
C++ surely has HKT, that is what templates that take other templates as type parameters are for.
In 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.

If 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.

> If the author is fool enough to not use the language features that exist since C++17 to validate template code, surely.

To be sure the fact the diagnostics aren't required does not forbid them from being provided, but it does mean you'd need to know whether you've been provided with such diagnostics and how effective they actually are. Unless the answer is "I have diagnostics and they are 100% effective" you're in the same situation.

> I also don't find debugging Rust macros that fun

Which kind? I don't find debugging the declarative macros too hard, they are after all just expanding what you wrote according to some simple rules, and you can ask the compiler to show that expansion to you.

Procedural macros present unlimited potential for exciting debugging because now you're essentially modifying the compiler at runtime. A C++ pre-processor macro can cause some nasty problems but it's not going to run a different compiler... [Technically Mara's nightly-crimes only runs the same compiler with different flags, but it could run a different one if she'd needed to do that]

Sure, but the exchange is that you get worse performance.
No, C# or Typescript is way easier, as a GC does the memory management for us. Lifetimes in async Rust are one the hardest things.