Live data from Hacker News

Building a shared vision for Async Rust

blog.rust-lang.org

51–60 of 139 posts

Re: Building a shared vision for Async Rust

#51
post #39
post #34

Earlier quoted context omitted.

You want libraries to be able to offer implementations that are polymorphically async-or-not (perhaps using higher-kinded types). That's how I'm used to working in Scala.

This is also a problem over in Python-land. One of the interesting approaches is automatically generating non-async code from async code by editing out the async annotations (at the source level). The Trio folks call this "bleaching" the code, in reference to the "What color is your function?" blog post https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... complaining about how the common approach to async…

Wow. Reminds me of those go projects that use templated code with Canadian Aboriginal Syllabics to work around the lack of generics.

Re: Building a shared vision for Async Rust

#52
post #39

Earlier quoted context omitted.

This is also a problem over in Python-land. One of the interesting approaches is automatically generating non-async code from async code by editing out the async annotations (at the source level). The Trio folks call this "bleaching" the code, in reference to the "What color is your function?" blog post https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... complaining about how the common approach to async…

In Rust, you don't need to do this. If you want a blocking version of a non-blocking function, you spin on poll. Several async libraries ship a block_on function that does just that. If you can't do that, but don't want to bring in a proper big-boy executor; you can spin off another thread, have it block, and join it when it's done. (or use something like crossbeam's scoped threads) Colored functions are a problem in…

Well, 'Animats expresses a desire in another comment for functions not to go off and spawn a new thread.

I do somewhat agree with that desire - I don't think that this is a problem for performance, but since most of my use of Rust is dropping it into existing C code, I think that spawning a thread is likely to have annoying visible side effects on the calling code, which might not be expecting me to do that.

Using a proper, single-threaded executor and running it on the current thread seems like it would work, yes. (To be fair, I also feel like just having the sync version of a Python API call "trio.run(self.equivalent_async_api)" would probably also work, and I don't totally follow why that's insufficient....)

Re: Building a shared vision for Async Rust

#53
post #39

Earlier quoted context omitted.

This is also a problem over in Python-land. One of the interesting approaches is automatically generating non-async code from async code by editing out the async annotations (at the source level). The Trio folks call this "bleaching" the code, in reference to the "What color is your function?" blog post https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... complaining about how the common approach to async…

In Rust, you don't need to do this. If you want a blocking version of a non-blocking function, you spin on poll. Several async libraries ship a block_on function that does just that. If you can't do that, but don't want to bring in a proper big-boy executor; you can spin off another thread, have it block, and join it when it's done. (or use something like crossbeam's scoped threads) Colored functions are a problem in…

It's a problem if your function to query a database or whatever instantiates a bunch of futures and yields between them when you're just going to block. Given that Rust is designed for environments that are so limited that they can't afford garbage collection, that stuff is proportionately pretty costly.

Re: Building a shared vision for Async Rust

#54
post #28
post #26

The main thing I want for Async Rust is the ability to not use it. What I'm doing involves a virtual world viewer with maybe a dozen threads. Some are compute bound. Some are talking to the GPU. Some are waiting for I/O. The normal situation is about 2 or 3 CPUs of work. Sometimes more. I don't want an async model, which assumes you're I/O bound, interfering with keeping all those CPUs busy. Already I've had to switc…

Your comment touches on a few misconceptions I see a lot. Firstly, `reqwest` exposes both an async and a synchronous API, allowing the developer to choose which one to use. They are largely interchangeable code-wise. [1] Secondarily, and more broadly, async is possible to opt out of. You must understand that most web and network related libraries will be async by default for performance, because people who write in R…

Complexity kills code. Being able to reason about what your code is doing, is FAR more valuable to me than async. Having tokio act as my runtime and switch tasks as it sees fit will be debug hell.

The problem I see is the current async story is opt-out. It's use async or go find something else. Async should be opt in. As in, the code works regardless of an async runtime, async is added magic if you want it, but it will run like normal single threaded code if not.

Re: Building a shared vision for Async Rust

#55
post #27

Earlier quoted context omitted.

C# ties you to CLR and is also garbage collected by default. That’s very different from C++ and Rust both.

> C# ties you to CLR C++ and Rust have runtimes as well. For C++ that’s normally a DLL like libstdc++ or msvcrt. CLR is larger but still reasonable, for 64-bit Windows VC_redist.x64.exe is 14 MB, dotnet-runtime-3.1.13-win-x64.exe is 25 MB. > and is also garbage collected by default By default yes, but that’s avoidable. Modern .NET with their spans, value tuples, ref structs, ArrayPool, etc., make it relatively easy t…

I strongly disagree. The vast majority of extant .NET APIs encourage or require allocating memory dynamically, thereby requiring GC. Sure, if you rewrite everything that isn't already defined in terms of `Memory` or `Span`, you can do it, but that's a _tall_ order.

Even supposing you still mange to write a whole program that doesn't allocate dynamic memory, or that quickly stabilizes around a finite `ArrayPool`. You're still pulling in all the runtime GC machinery. Further, the minute someone _else_ contributes code, you run the risk of allocating again.

As much as I love C#, _this isn't its niche_.

Re: Building a shared vision for Async Rust

#56

Earlier quoted context omitted.

> Pouring effort into C++ does not guarantee safety. Indeed, but porting to C# does. For many practical applications, modern C# is already a language with C performance. The only large area where C# lags behind is SIMD. They made a good progress in .NET 3 and 5, but still somewhat worse than C/C++ with intrinsics. Here’s a library which implements media player component for ARM Linux: https://github.com/Const-me/Vrma…

Last I checked STM32 microcontrollers can't run .Net, and thus can't use C#. They can run Rust. Rust's embedded and OS-level capabilities are a big point in its favor, particularly over something like C#.

Indeed, you need a reasonably capable OS kernel to use .NET runtime. And enough RAM. And I wouldn’t want .NET for hard realtime use cases.

Even in embedded, for some products the tradeoff is good enough. A while ago I’ve shipped embedded software that uses .NET Core and runs on RK3288, worked quite well for us.

BTW, do you have good experience with Rust on bare metal STM32? I would expect STM-supported C toolset and libraries to be generally better?

Re: Building a shared vision for Async Rust

#57
> These stories are not fiction. They are an amalgamation of the real experiences of people

This claim bothers me. It might be a nitpick, but I think it's an important one. For a given amalgamation, it is fiction in a non-trivial way that there was a person who literally had all the experiences in the blog posts or tweets etc. that inspired that character. Truth values of facts are almost always dependent on the relationship to other facts.

It would be perfectly respectable to simply say that your user stories are rigorously based on real-world experience, which is a good idea BTW, without claiming that they are "nonfiction". That's a needless epistemological liability.

Re: Building a shared vision for Async Rust

#58

Earlier quoted context omitted.

> C# ties you to CLR C++ and Rust have runtimes as well. For C++ that’s normally a DLL like libstdc++ or msvcrt. CLR is larger but still reasonable, for 64-bit Windows VC_redist.x64.exe is 14 MB, dotnet-runtime-3.1.13-win-x64.exe is 25 MB. > and is also garbage collected by default By default yes, but that’s avoidable. Modern .NET with their spans, value tuples, ref structs, ArrayPool, etc., make it relatively easy t…

I strongly disagree. The vast majority of extant .NET APIs encourage or require allocating memory dynamically, thereby requiring GC. Sure, if you rewrite everything that isn't already defined in terms of `Memory` or `Span`, you can do it, but that's a _tall_ order. Even supposing you still mange to write a whole program that doesn't allocate dynamic memory, or that quickly stabilizes around a finite `ArrayPool`. You'…

> vast majority of extant .NET APIs encourage or require allocating memory dynamically

A lot of APIs in modern .NET already supports spans. They can be backed by anything, not just GC-managed memory.

For that project, some of these spans are backed by the memory mapped by V4L2 or ALSA API calls. Others are backed by unmanaged buffers allocated on startup with Marshal.AllocHGlobal. For small temporary stuff I use stackalloc, e.g. both mp4 and mkv use tons of variable-length encoded integers.

> the minute someone _else_ contributes code, you run the risk of allocating again.

Good point. On the other hand, someone else contributing code can introduce any bugs at all, not just GC-related performance issues.

> As much as I love C#, _this isn't its niche_.

A while ago some people were saying the same about C, and were instead coding assembly :-)

Re: Building a shared vision for Async Rust

#59
post #32

Earlier quoted context omitted.

I had understood your concern as wanting to avoid the complexity of asynchronous code execution in your codebase, I did not realize your concern is about writing very low level systems code. In that case, you are doing the right thing: libraries like ureq, minreq, Isahc, curl, and more all offer what you want. It is unclear to me what you mean by keeping the community "in check". There are a lot of people who rely on…

You're replying to John Nagle, as in https://en.m.wikipedia.org/wiki/Nagle%27s_algorithm -- perhaps it would be worth considering his words further, before dismissing his concerns? Surely we can all agree that spinning up unnecessary threads is undesirable?

[deleted]

Re: Building a shared vision for Async Rust

#60
post #21
post #8

I admire the passion, but I’m not sure why I would want Rust at all, not just async. When I want memory safety, async-await, I/O performance, easy multithreading, I write C#. When I want performance of CPU bound code, or lots of integration with native libraries/APIs, I write C++. Sometimes I want both in the same software, compile C++ code into a DLL (or shared library on Linux), and consume it from C#. I don’t have…

I think people want a language with C performance and are willing to sacrifice effort but not safety. Pouring effort into C++ does not guarantee safety. I think that's why something like Rust is desired.

I don't think safety is driving Rust's ascent. For example, WASM has more momentum with Rust than with C++. But WASM is already sandboxed, and does not support threads; so what is Rust bringing to the WASM table?

I think it's a monoculture phenomenon. Rust has a website and a pitch; C++ does not. Rust has a single compiler and one way to do things; C++ is overly diverse. Rust has learned from npm, etc. and has made package management first-class with a single package manager; C++ has not. Rust is just a much more familiar experience for developers coming from other monoculture languages.

Post reply on HN