"Writing code in terms of small, composable, reusable functions with a clear single intent (through good naming), that you can then mix, match, and reuse to compose into larger functions is what makes good functional code so much easier to write, test, and reason about than imperative code."
Absolute, that holds for non functional code as well.
It just does not matter whether the smallest function inside that system of functions has a loop or a map inside it. Loops are as easy to tuck into reusable functions as maps or anything else. Notably examples in the presentation you link have functional version shorter, but harder to read - they have more features however. Even the first one pipe(..., reduce(add, 0)) just does not read fluently.
But again, this low level has very little influence on maintainability of the larger program. In anything that is not computational library, how you compose them matters more. It is as if you assumed code with loops can not be split into smaller composable units.
I worked with codebase written in largely functional style. It was hard to read at first, but then I got used to it. However, it never became all that much easier to read them loops nor easier to work with. It gets bad when people get clever with composing functions.