>For-loops do exist, they just need to not have side effects,
No they don't. For loops and loops in general are procedural actions. You are jumping from directive to directive, command to command. Loops are NOT functional at all. loops are an artifact of the computational machine, jumping to different instructions.
Functional programs like functions in mathematics DO not contain for loops.
> which in practice means the likes of map/filter/reduce (ideally promoted to a first class language feature like sequence comprehensions).
>You could argue that those are still desugared to recursion, but I think at that point it's kinda moot - the construct is still readily recognizable as a loop,
All programs are desugared into assembly instructions. Assembly instructions are procedural by nature... they are not functional so your point is moot as everything is desugared into loop based jumps.
map/filter/reduce Are not loops. They are fundamentally different. It doesn't matter if it's "recognizeable" as a loop, it is NOT a loop. There is an isomorphism between imperative and functional programming, So the definition of Loop vs. no loops refers to the superficial differences between the two EVEN when the underlying things are the same.
>In general, so long as mutation can be encapsulated in modules that only expose pure functional interfaces, I think it should still count as FP for practical purposes.
It actually can't... for loops rely on mutation to work.
a for loop looks like this:
for i in range(10):
By nature the for loop needs to influence outer scope otherwise your for loop is utterly useless. So how would you influence outer scope from inner scope?
for i in range(10):
That's the only way man.
This is the fundamental nature of for loops. They are imperative constructs. Sure it can look very similar to map or reduce or even filter, but THEY are not the same.