4 ms·
I can see where you are coming from. But you can do most things purely in sync rust. There are sync rust multithreading libs like rayon that are a joy to use,
by rklaehn 3y ago
I can see where you are coming from. But you can do most things purely in sync rust.
There are sync rust multithreading libs like rayon that are a joy to use, and there are even blocking versions of popular http libraries like reqwest: https://docs.rs/reqwest/latest/reqwest/blocking/index.html https://docs.rs/reqwest/latest/reqwest/blocking/index.html
They are usually doing some ugly stuff internally to make this work, but as a pure library user you don't have to care.
If you want to write something small that e.g. pulls some data via http, performs some computation, then pushes the result, it is totally possible to do this fully in sync rust.
And if you are writing a highly concurrent web server, looking into async might not be the worst idea.
- eptcyka 3y agoHaving written a lot of async and sync rust, and having both components interact with one another, calling async stuff from a sync context isn't even that ugly these days. But maybe it's stockholm syndrome.
- rklaehn 3y agoIt's OK but not great. Ideally library authors should provide a sync facade so people don't have to deal with this, like reqwest does.
- vacuity 3y agoIdeal for library users but not for library authors...
- masklinn 3y agoThe implementation is really not complicated, though it’s hardly great if you expect it to be performant: reqwest just creates a tokio runtime, schedules the task on it, waits for completion, then tears it down. It’s repetitive but it’s simple.
- yencabulator 3y agoWhere it really breaks down is that there's no spawn without tying the library to e.g. tokio. Also, the other way around might be simpler. If the library wants to be async, make it async-only, and let callers block_on it. https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.html#method.block_on https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.ht...
- bheadmaster 3y agoOne thing I hate about "async" systems in general is the absurdity of suddenly having two types of functions behave differently with same syntax. And you have to add "await" keyword to async functions to make them synchoronous, i.e. behave normally. I find the Go's approach of "everything is synchronous, except when made asynchronous with the 'go' keyword" much more pleasant and much less error prone. Is there a Rust library that does this - that provides coroutine-style asychronous behavior, but with synchronous Go-like syntax?
- api 3y agoGo can do this because it’s closer to Java or C# than C. It has a runtime that gets compiled into every binary. Rust deliberately avoided that by design.
- rklaehn 3y agoIndeed. That means that the interop story for golang is horrible. Golang can somewha work with libraries with C bindings. But you can not publish a golang lib as a lib.so with C bindings because of the runtime.
- bheadmaster 3y agoYou can, actually, using '-buildmode c-shared' and '//export FuncName' comment directive. CGo supports exporting Go functions in shared libraries, and sets up the Go runtime to be used properly with native C types (e.g. int64 will be long long).
- pjmlp 3y agoNot necessarly, .NET and D have a much better interop story, despite having runtimes. You can certainly publish lib.so with Go, here is an example, https://www.ardanlabs.com/blog/2020/07/extending-python-with-go.html https://www.ardanlabs.com/blog/2020/07/extending-python-with...
- bheadmaster 3y agoWhy is runtime needed for a syntactic feature like that? All you need is an async wrapper for system calls, and every sync function could, in principle, be compiled down to a coroutine and ran on an executor of your choice. Just because Go has a runtime and has a go keyword, doesn't in itself mean that runtime is necessary for the go keyword to exist.
- vbezhenar 3y agoCan you expand what ugly stuff they're doing internally? I mean, synchronous code is the most simple way to do anything. POSIX API is synchronous by default. Why would you need ugly stuff? Asynchronous API might force you to do ugly stuff (e.g. for files or DNS).
- rklaehn 3y agoLet's say you are using a low level networking library that is async to the core, like hyper or quinn. Then you will have some ugliness at the boundary. You might get by with just spawning a current thread runtime to use your async lib, or do something like blocking channels if your low level library spawns long lived tasks. If your low level libraries are all sync, then there won't be much ugliness.