I think ultimately you're just demonstrating the larger point. There is no value trying to label it as imperative or declarative except in the niche situation where one is debating whether it is imperative or declarative, which at some point is just a philosophical question.
I think it was Plato who asked this question - if I take two pieces of clay and smash them together, which piece grew? You can argue all day about it, and it has some fun implications about identity, but that's philosophy.
If you care about the type of thing you need to write, there's tons of reason to make the distinction.
The thing about writing "code that outputs a data structure" is that you can voluntarily choose to use no control flow.
The tool takes declarative input, and optionally you can use imperative code to make the job of writing that input easier.
That's very different from a tool that gives you helper functions for writing an imperative core. In that case you're always writing something that's full of control flow, and it's up to you to make sure you get all the state transitions to be consistent with each other.
I think it was Plato who asked this question - if I take two pieces of clay and smash them together, which piece grew? You can argue all day about it, and it has some fun implications about identity, but that's philosophy.