The big oh is the same man. It just feels like it’s less efficient but it’s not. Think about it.
And it’s more modular with more loops. If you’re trying to shove 4 different operations into one loop you’re not programming modularly and you’re trying to take shortcuts.
Reduce FPS of your game from 60 to 15, tell players it's the same cause complexity haven't changed.
But it's not even mainly about performance. The structure of the code changes with every requirement change. In a non-artificial code you're doing stuff other than calculating the result, and all the associated state and dependencies now have to be passed to 4 different loops.
While in the ugly non-modular imperative code you add 3 local variables and you're done, everything outside that innermost loop stays exactly the same.
> you’re trying to take shortcuts
Yes, that's the point. I started by admiting FP code is more elegant. But shortcuts are not inherently worse than elegance. They are just the opposite sides of a trade-off.
tbh FP is so heavily modularized that even the concept of "looping" is modularized away from the logical operation itself. In haskell it looks like this:
f = a . b . c . d
a1 = map a
b1 = map b
c1 = map c
d1 = map d
f2 = a1 . b1 . c1 . d1
Where f is the composition of operations on a single value and f2 operates on a list of values and returns the mapped list.
Gaming and applications that require extreme performance is the only application where Fp doesn’t work well.
> But it's not even mainly about performance. The structure of the code changes with every requirement change. In a non-artificial code you're doing stuff other than calculating the result, and all the associated state and dependencies now have to be passed to 4 different loops.
No. I’m saying the initial design needs to be one loop for every module. You then compose the modules to form higher level compositions.
If you want new operations then all you do is use the operations on intermediary state.
That’s how the design should be. Your primitive modules remain untouched through out the life cycle of your code and any additional requirements are simply new modules or new compositions of unchanged and solid design modules.