My pet theory is that because we typically understand our needs before we understand the code paths required to fulfill them, our V1 APIs are usually a declarative “this is what should be” interface. Then we spend days or months making it happen and by the time we understand the required code paths, we’ve totally baked our expectations about the “make it so” API into our architecture.
Getting to a good, explicit, imperative API requires a whole nother step, and often a major refactor. You have to step back and ask “what is really happening now and can I conduct it more directly?”
... but by that time your code works and it hardly seems worth the effort.
But it is worth the effort. The declarative API will just get uglier as you add to it, and provide no real guidance about where future additions should go. Just throw another key in the config. Add another conditional. An imperative one will constrain your future choices about how additions can work, and therefore helps you clarify your domain model as you add to it.