If I have to traverse a tree, then recursion is more natural to me. With a loop you’ll have to manually use a stack (it’s fine, but more error prone). For lists, I rarely write loops or recursion. It’s mostly folds and maps.
I feel like this is a common enough pattern with well-known translations from one form to the others, that a compiler might optimize it one way or the other. Or is it still too high-level for even modern awesome compilers/interpreters?
For sure. Data structures and call graphs like to converge, so when designing a data model, you are actually designing the (most natural) program flow too.