There is no single answer there, because which style is better depends on what you're doing. For example, "lots of small functions" makes things easier to understand when you're working horizontally, trying to e.g. understand a module at a certain level of abstraction. However, in the same code, if you're trying to understand a single piece of functionality, e.g. to debug it, it's much easier when you have a vertical view - ideally a single fat function with all helper calls inlined. In first case, all the little functions form high-level languages that aid your understanding; in the latter, they're just noise that kills your working memory with all the jumping-to-definition around the codebase.
Our current programming paradigm forces you to make this style choice ahead of time. You can't have it both ways. This is the Pareto frontier - as you make your codebase easy for one type of work, it becomes hard to do other kinds of work in it. And this is a stupid state to be in, because you will be doing both horizontal and vertical tasks, and many others that benefit in yet different kinds of slicing through code, and you will be switching gears every few days or weeks.
Another concrete example: exceptions vs. algebraic return types (Expect/Result/Maybe/etc.). People love the latter for code locality, and mostly ignore the ridiculous amount of noise this method adds to all code, and/or invent ever more advanced math to paper over it. Exceptions were much better in this regard, if worse in others, but again, I posit that having to make that choice is dumb in the first place. Personally, I'm fine with Result return types. It's just that, 90% of the time, I don't give a damn about them, because I'm working on the success case/golden path, and they're just pure visual noise. It's something I'd like to just not see. But then, remaining 10% of the time, I'd like to make everything other than Result types and control flow disappear, because when working with error handling, success case becomes visual noise.
Inventing new species of monads or syntax keywords to cram this, and async, and other cross-cutting concerns, isn't the solution. The solution is to stop working on raw plaintext source code, and instead work on representations tailored to specific needs, while treating the underyling source code like we treat assembly today.