> Usually, ordering of operations in code is indicated by the line number (first line happens before the second line, and so on), but I understand that this might fly out the window in async code
This isn’t always true at the language level, and almost certainly not at the CPU pipeline and microcode level.
Logic languages like Prolog will execute statements out of order, by design. Other languages like Mercury use the IO monad to signify serial operations
I'm not sure what you mean by "statements" in Prolog as it's not a term the language defines. If you're referring to clauses, it's not true that execution is unordered: the Prolog interpreter attempts to unify a goal with clauses from the knowledge base in the order they appear. This ordering is semantically significant for control flow.
If instead you're referring to goals within the body of a clause, this is also incorrect. Goals are evaluated strictly left-to-right, and each must succeed before the next is attempted. This evaluation order is likewise required and observable, especially in the presence of side effects.
> the Prolog interpreter attempts to unify a goal with clauses from the knowledge base in the order they appear.
I was under the impression that when plugging holes during unification, that these statements/clauses could happen in any order just as you would like solving a crossword puzzle
This isn’t always true at the language level, and almost certainly not at the CPU pipeline and microcode level.
Logic languages like Prolog will execute statements out of order, by design. Other languages like Mercury use the IO monad to signify serial operations