[HN Gopher] Blocking code is a leaky abstraction
___________________________________________________________________
Blocking code is a leaky abstraction
Author : zdw
Score : 12 points
Date : 2024-10-19 20:24 UTC (2 hours ago)
(HTM) web link (notgull.net)
(TXT) w3m dump (notgull.net)
| paulyy_y wrote:
| Or just use fibers and avoid icky futures.
| aphantastic wrote:
| Doesn't change the core issue, which is that if you want to do
| multiple operations simultaneously that take time to execute,
| you're going to need to write _stuff_ to handle that which you
| wouldn't otherwise. Whether it's channel piping or async
| awaiting is semantics.
| nemetroid wrote:
| The author seems to reinforce the original point, that the async
| paradigm ends up working best in an all-or-nothing deal. Whether
| the difficulties in interfacing the paradigms should be
| attributed to the blocking part or the async part does not really
| matter for the practical result: if calling blocking code from
| async code is awkward and your project's main design is async,
| you're going to end up wanting to rewrite blocking code as async
| code.
| PaulDavisThe1st wrote:
| Sometimes, things need to leak.
|
| For example, the fact that code actually takes time to execute
| ... this is an abstraction that should almost certainly leak.
|
| The fact that some data you want is not currently available ...
| whether you want to obscure that a wait is required or not is up
| for debate and may be context dependent.
|
| "I want to always behave as though I never have to block" is a
| perfectly fine to thing to say.
|
| "Nobody should ever have to care about needing to block" is not.
| klodolph wrote:
| What is the difference between code that blocks waiting for I/O
| and code that performs a lengthy computation? To the runtime or
| scheduler, these are very different. But to the caller, maybe it
| does not matter _why_ the code takes a long time to return, only
| that it does.
|
| Async only solves one of these two cases.
|
| I'd like to draw an analogy here to [?] "bottom" in Haskell. It's
| used to represent a computation that does not return a value. Why
| doesn't it return a value? Maybe because it throws an exception
| (and bubbles up the stack), or maybe because it's in an infinite
| loop, or maybe it's just in a _very long_ computation that
| doesn't terminate by the time the user gets frustrated and
| interrupts the program. From a certain perspective, sometimes you
| don't care _why_ [?] doesn't return, you just care that it
| doesn't return.
|
| Same is often true for blocking calls. You often don't care
| whether a call is slow because of I/O or whether it is slow
| because of a long-running computation. Often, you just care
| _whether_ it is slow or _how slow_ it is.
|
| (And obviously, sometimes you do care about the difference. I
| just think that the "blocking code is a leaky abstraction" is
| irreparably faulty, as an argument.)
| worik wrote:
| Asynchronous code is the bees knees
|
| Async/await is a horrible fit for Rust.
|
| > Some of this criticism is valid. async code is a little hard to
| wrap your head around, but that's true with many other concepts
| in Rust, like the borrow checker and the weekly blood sacrifices.
| Many popular async libraries are explicitly tied to heavyweight
| crates like tokio and futures, which aren't good picks for many
| types of programs. There are also a lot of language features that
| need to be released for async to be used without an annoying
| amount of Boxing dynamic objects.
|
| Yes. So don't do it
|
| It is entirely possible to write asynchronous code without using
| asyc/await.
|
| async/await is a fun paradigm for garbage collected systems. It
| is a horrible mess in Rust
___________________________________________________________________
(page generated 2024-10-19 23:00 UTC)