But the problem is, programming isn't about just putting down a first order encoding of your needs. It's about bridging the gap between that encoding and the libraries actually available to you.
That's where declarative programming becomes unintuitive to people. How do you bridge the gap between your declaration and the declarations provided by Rails/Vue/Webpack/etc? You need to somehow imagine the transformation that will get you there.
Imperative programs, on the other hand, always have a ready axis for decomposition: time. You break your program up into tiny time slices, and then work backwards to find procedures that that get you to the first one, then the second one, etc, until you hit the end of your program.
With declarative programs, you need to slice the program in an abstract space. In my experience it takes 6-12 months to get up to speed with a new declarative programming landscape like Rails or Ember.
I used this video to get a better understanding - I hope it helps others too:
Insightful comment. When using libraries, we always use the API in an imperative way. Even if the library uses a declarative model, we pass around declarative data via imperative API calls. Is this because imperative is somehow more natural and easy? Or is it is because the fundamental cross library binding model in a C/Unix world is imperative only?
In a different world, what would a declarative binding model even look like? If the system provided a declarative binding model (e.g. by exposing a library as set of bindable data flow cells, instead of a set of callable functions) perhaps integrating with declarative libraries might be easier?