“Monty’s codebase must remain sync. Introducing async into it will only affect the project negatively.”
This seems like a very strong assertion to me, so I’d like to see a clarification of what is being claimed here, as well as some supporting (and/or opposing) arguments. Anyone?
To kick things off, I’ll start with a statement from the Goog:
Q: Are actor systems always async?
Yes, by definition, the actor model is inherently asynchronous. All communication between actors is done exclusively through asynchronous message passing.
Here is why:
Communication Mechanism: Actors interact by sending immutable messages to each other’s mailboxes without waiting for a direct return value. This “fire and forget” mechanism prevents the sender from blocking its own execution to wait for a response.
Concurrency and Isolation: Actors run concurrently and operate within their own isolated domains, managing their own private state. The asynchronous nature of communication allows for many actors to operate independently and simultaneously without race conditions that arise from shared mutable state and synchronous access.
Scalability: This asynchronous design is key to the actor model’s ability to support highly concurrent and distributed systems, as actors can be spread across different threads or even different machines without the caller needing to know their physical location (location transparency).
While a specific implementation might allow for something resembling synchronous calls using request/response patterns with Futures or async/await, the underlying principle and fundamental advantage of the model is its asynchronous nature. True synchronous communication where the sender blocks until the receiver is ready (like in Communicating Sequential Processes or CSP) is a different concurrency model altogether.
If “synchronous” means remote procedure calls and such (as opposed to actor-style messages), I suspect that any scaled-up version of Monty would quickly get tangled up in deadlocks and such. Details upon request…
OTOH, if “synchronous” means guaranteed delivery order and timing (etc.), I’d want to finesse this issue using time-tagged data sets, queue management, etc.
As an example, consider the problem of processing audio input. It’s possible to simulate the ears’ output (e.g., amplitudes of given frequencies, phase differences between the ears), using a microphone and some pre-processing software (e.g., ring buffer, FFT).
However, this immediately puts Monty into a world of time-tagged data buffers, rather than continuous, “synchronous” input streams. So, it seems like some heavy lifting may be involved…
This isn’t about asynchronicity per se: it’s about refactoring the current code base in order to introduce async/await. I’m saying this because I’ve done that. It is only viable and makes sense when this code base is stable, most if not all assumptions about requirements have already been verified, and changes are only expected to extend it. Otherwise, it creates an additional layer of complexity (actually not even one) that falls on developers’ shoulders, yet achieves comparatively very little. I should have, probably, clarified that Monty’s code must remain sync until it’s mature enough, and other, more fundamental issues have been resolved, because that’s what I really meant; as I already mentioned here, Monty will need asynchronicity in some form. But not until it is safe to do so, from the roadmap’s point of view.
I’m not a big fan of async/await as a programming model, but my reasons mostly have to do with the fact that humans aren’t very good at thinking about concurrent execution paths. Although there are certainly folks who can think clearly about this sort of thing (e.g., Dining Philosophers Problem), I’m not one of them!
I also agree that Monty’s code has a long way to go before concurrency and/or distribution will become Real Issues ™. OTOH, there’s nothing to keep us (for some value of “us” :-) from:
thinking about “systems-level” issues in Monty’s design
imagining concurrent and/or distributed versions of Monty
hacking up and testing experimental framework infrastructure
gently nudging Monty’s code base away from OOPish idioms
encouraging internal APIs (etc) that would scale gracefully
Can only agree. Again, questions like OOP vs FP vs whatever are probably in the cage fight territory as well, but overall - I’ll confess, I do have a vision of what an architecture allowing most if not all of that could look like. It will take some time to make it work, but it’s doable