To offer a perspective inspired by practice here. Personally I've invested some time in Haskell in the past (including recursion schemes which I found awesome). And while I liked many of the ideas there, I never got to a level where I was _not_ painting myself in a corner by applying all these structured approaches.
Now I'm writing a compiler in C, and I can tell you for sure that processing an AST by doing 4 or more passes over the tree to achieve various computations and transformations is not beautiful. (I'm doing at least symbol binding, macro expansion, typechecking, constant folding, and compilation).
I've thought about changing the tree to some flat representation in post-order (think Postscript, Forth) but I would need more than one (I'm pretty sure I need to pass down information from the root sometimes as well).
For now I'm staying with explicit recursion and of course there will be a little pain when I want to change the AST because there are so many dependencies there. But I figure that recursion schemes or flat representations couldn't help all that much there since there is not only recursive structure, but quite simply a lot of diverse data stored in all the nodes there :). There are simply going to be a lot of dependencies on varies information stored in the tree, from a variety of places in the client code.
For me, the basic insight from doing Haskell and Garbage-collected languages is that we should avoid trees and recursive structures whenever possible, and try index into flat arrays. Where that's possible, there is no recursion at all. Also, parallel arrays are great for modularity.