Disclaimer: I am one of the developers of Puppet.
It will execute it in a consistent but unpredictable order, with the exception of any explicit or implicit dependencies in the code. Explicit dependencies are things that you specify with the subscribe
or require
metaparameters. Implicit dependencies come from the autorequire feature, which does things like automatically apply file resources in a sensible order.
The reason for this isn't so much that the language is declarative, but rather the language is declarative because order doesn't matter for most things in the underlying problem space.
For example, there really isn't much connection between managing ssh and managing postfix for most people - you could do the work in either order, or even at the same time, and everything would work out the same.
That frees us up to improve things in a whole lot of ways that "everything is in linear order" doesn't. We are working, for example, to batch up package installs while still respecting the explicit dependencies outside packages.
So, the order of execution and dependencies follows the underlying problem, and we have preserved that property to be able to do more awesome things.
The goal is exactly what you say at the end: that you declare what you want, and we take care of all the details of getting it there. In time we hope to be much smarter about logical dependencies, so you have to say even less to get that, too.