Earlier quoted context omitted.
It's been a stable (and documented) behavior of the Python standard library for almost a decade now. It's possible it may change--nothing is ever set in stone--but that would be a large change in Python that would come with plenty of warning and time for adjustment.
And then one day, Astral creates a new Python implementation in Rust or something that is way faster and all the rage, but does this particular thing different than CPython. Whoops, you can’t use that runtime, because you now have cursed parts in your codebase that produce nondeterministic behaviour you can’t really find a reason for.
Async Python Is Secretly Deterministic
31–38 of 38 posts
Re: Async Python Is Secretly Deterministic
#32Earlier quoted context omitted.
How do you differentiate between something that "happens to work due to an implementation detail" and a "proper feature that's specified to work" in a language without a specification?
In a language without a spec? You don't. But python has a very strong spec.
Re: Async Python Is Secretly Deterministic
#33> This makes it possible to write simple code that’s both concurrent and safe. Yeah, great, my hello world program is deterministic. What happens when you introduce I/O? Is every network call deterministic? Can you depend on reading a file taking the same amount of time and being woken up by the scheduler in the same order every time?
No, but determinism reduces the number of stones you need to turn over when debugging hairy problems such as your program occasionally returning different results for the same inputs. You may not have control over the timing of I/O operations or order of external events (including OS scheduler), but at least you know that your side of the innovation/response is, in isoaltion, behaving predictably.
Re: Async Python Is Secretly Deterministic
#34Earlier quoted context omitted.
No, but determinism reduces the number of stones you need to turn over when debugging hairy problems such as your program occasionally returning different results for the same inputs. You may not have control over the timing of I/O operations or order of external events (including OS scheduler), but at least you know that your side of the innovation/response is, in isoaltion, behaving predictably.
I go the opposite approach for this sort of thing, since I would much rather flip and remove the stones: I explicitly randomize order of containers during development and testing, and always in my unit tests, so depending on order can't be a problem. No luck required!
Randomization is great at avoiding erroneous dependencies on spurious cause-and-effect chains. Determinism is needed to ensure the cause-and-effect chains that are core to the problem actually work.
Re: Async Python Is Secretly Deterministic
#35Is this guaranteed by the async specification? Or is this just current behavior which could be changed in a future update. Feels like a brittle dependency if its not part of the spec.
It's documented behavior for the low-level API (e.g. asyncio.call_soon https://docs.python.org/3/library/asyncio-eventloop.html#asy... ). More broadly, this has been a stable behavior of the Python standard library for almost a decade now. If it does change, that would be a huge behavioral change that would come with plenty of warning and time for adjustment.
For example what happens if I use a different async backend like Tokio?
Re: Async Python Is Secretly Deterministic
#36No, determinstic scheduling is not a property of async python. Yes, the stdlib asyncio event loop does have deterministic scheduling, but that's an implementation detail and I would not rely on it for anything critical. Other event loops - for instance trio [1] - explicitly randomize startup order so that you won't accidentally write code that relies on it. [1] https://github.com/python-trio/trio/issues/32
Re: Async Python Is Secretly Deterministic
#37Re: Async Python Is Secretly Deterministic
#38Earlier quoted context omitted.
I go the opposite approach for this sort of thing, since I would much rather flip and remove the stones: I explicitly randomize order of containers during development and testing, and always in my unit tests, so depending on order can't be a problem. No luck required!
You want both. More specifically, you want to be in control of which one you're actually doing. Randomization is great at avoiding erroneous dependencies on spurious cause-and-effect chains. Determinism is needed to ensure the cause-and-effect chains that are core to the problem actually work.
Determinism isn't required unless it's required.
If it's not required, then you must plan for it NOT being deterministic, with any accidental determinism being ignored (to be safe, forcefully so with an intentional randomization/delays within the library). If it is required, then my random input should always (from the tests perspective) come out the same as I put it in.
If possible, force the corner case if the corner case is a concern. That's the purpose of testing. If there's a concern with timing, force bad timing with random delays. The alternative is relying on luck. I try to make my code as unlucky as possible, during development/testing.