[ninja author] I like how their example is a build system, given Ninja constructs an object literally called "Plan"[1].
However, when I later revisited the design of Ninja I found that removing the separate planning phase better reflected the dynamic nature of how builds end up working out, where you discover information during the build that impacts what work you have planned. See the "Single pass" discussion in my design notes[2], which includes some negatives of the change.
If the author reads this, in [2] I made a Rust-based Ninja rewrite that has some similar data structures to those in the blog post, you might find it interesting!
Cast that thought in terms of state. If all the state can be represented up front then plans are great. But if the understanding of the problem changes half way through a project and previously un-identified state is found during the runtime then a plan-execute pattern will get ugly quickly.
It is good to name things, but the challenge to manage isn't in the implementing of a plan-execute architecture. It is in identifying the threshold where there is enough runtime state in the problem domain that a plan-execute architecture can't be sustained.
However, when I later revisited the design of Ninja I found that removing the separate planning phase better reflected the dynamic nature of how builds end up working out, where you discover information during the build that impacts what work you have planned. See the "Single pass" discussion in my design notes[2], which includes some negatives of the change.
If the author reads this, in [2] I made a Rust-based Ninja rewrite that has some similar data structures to those in the blog post, you might find it interesting!
[1] https://github.com/ninja-build/ninja/blob/dcefb838534a56b262... [2] https://neugierig.org/software/blog/2022/03/n2.html