> His argument is that to understand what this function depends on will require reading all the code in the function and all the code in every function which it calls, to work out which global variables it accesses. Without doing that, you have to assume that this simple function depends on all 313 of them, even though you would never write a function which explicitly took that many arguments.

That is not what he said. He said that a function in an imperative language depends on all global state in the program, not could depend:

> The behaviour of every function in a mutable, imperative environment is dependent upon the state of all of the other (variables|attributes|bindings|whatever) in your program at the time the function is invoked.

This is obviously false. And if you did have a function that was dependent on all 316 global variables, then your equivalent functional program will have functions all over the place threading 316 state parameters through the program! That is what I was trying to say in the post above.

Now lets consider the more reasonable situation that the function does not depend on all global variables:

> The middle ground is to say, hey, but the function really did depend on some of those global variables, so in the real world the function will have more than three arguments. More than three, but less than 316, lets call it five.

So what's the advantage of explicitly writing out the parameters? You could do the same in an imperative program: just write a comment above the function definition that says which globals it uses and which ones it modifies. The advantage of mutable state is that you don't have to do this: you can abstract over stateful entities. Consider logging for example. You could have a global variable called "log" that is a list of strings. Then define a log function:

logmessages = []

def log(msg):
logmessages <- cons(msg,logmessages)

If you want to log something in the middle of your program you can just insert a log("message") call. If you wanted to do the same in a functional program you'd have to thread the logmessages variable through your entire program. You need to change all functions that want to log and all functions that call functions that want to log to take an extra argument and to return an extra value (changing the functions so that they return tuples, and all call sites have to unpack the tuple, etc). Which solution is better? The whole point of imperative programming is that you don't have to write these kludges.

It gets even worse very quickly if you don't just consider mutable global variables, but also mutable objects. It is not at all obvious how you'd translate an imperative program that mutates objects into a functional program without essentially writing an interpreter for an imperative language. There are papers on doing this when there is a single reference to the object that gets mutated (Zippers), but the real power of state comes from having multiple references to a single stateful entity.

Imperative programming has native support for stateful entities (or you could say has native support for time), in functional programming you have to manage time yourself. It's like manual memory management vs garbage collection.