3 ms·
> Regular functions always return (or crash the program). No, you can't say that; claiming they do is equivalent to claiming the halting problem is trivially s
by dragonwriter 2y ago
> Regular functions always return (or crash the program).
No, you can't say that; claiming they do is equivalent to claiming the halting problem is trivially solvable since any program it applies to will definitively halt.
Trivial counterexample:
def forever():
while True:
pass
> Regular functions run to completion before returning control to the caller.
This is true, but it need not be an inherent distinction of the function, but could be one made between the function, caller, and context: that is, the function can have points at which it can yield control, if it is called in the context of an event loop, it will yield at those points, and the caller can choose either to directly call the function and get sync behavior relative to itself or call it in the context of the same event loop as the caller is running, getting async behavior if the function yields early and the call returning an awaitable value (whether or not there is an early yield.)
For the way many “scripting” languages are implemented, where there is already a kind of yield to the runtime at IO, this would be a pretty natural implementation and lets a caller treat any function as async or not without caring if it was specifically implemented as async or not, though you’ll grt no real concurrency in a single-threaded runtime without the function having yield points. (This is, AIUI, basically what the async implementation in Ruby does, which is why while there are libraries specifically designed for async use, existing Ruby async-unaware code that does IO can be called as async and works concurrently out of the box.)
- shadowgovt 2y agoI was speaking loosely and lumped "run forever with no progress" and "crash the program" into the same space; my apologies for the lack of clarity. A more precise way to say it is "regular functions either return or we're in a bad place (or we're in a very special circumstance, like 'this program burns cycles on purpose because the scheduler requires something to be running')." For async functions, failure to progress to a returnable state is expected behavior, so the whole system needs to be built around allowing computational progress while waiting for the state to change to where the return can occur.