Global variables are often used to pass rarely-used dependencies/parameters. e.g., stdin/stdout are usually global variables in languages because you never know when you want to print something.
This is exactly why global variables are useful and the source of all their problems: you don’t have to pass them explicitly to the function, but that also makes it harder to inject dependencies or test pieces.
- Dynamic scoping is a better model for global variables—dynamic scoping might work better than lexical scoping for some global variables
- Monads, Effect systems