&gt; Essentially, compilation is rewriting of a source AST into the target machine code.<p>While that is true of most modern compilers, do consider that there&#x27;s the whole Wirth school of compilers that don&#x27;t use an AST at all but generate machine code directly during parsing.<p>&gt; For a human it is much easier to structure such a rewrite as a sequence of very trivial changes.<p>I&#x27;m not convinced, as I&#x27;ve written elsewhere, because while the changes may be trivial, you need to keep track of what a program is expected to look like in between each stage, and that becomes harder the more stages you introduce. E.g. my forever-in-progress Ruby compiler has a stage where it makes closures explicit: It allocates an environment to store variables in and rewrites variable accesses accordingly. For following stages the language I&#x27;m working on is different: I can no longer use closures.<p>The more stages you have, the more language dialects you need to manage to mentally separate when working on the stages. And if you decide you need to reorder stages, you often have painful work to adapt the rewrites to their new dialects.<p>The end result looks very simple. But try to make changes and it&#x27;s not necessarily nearly as simple.