Global variables certainly create opportunities for side-effects. The author may be throwing everything into one big pot and labeling it I/O, but they're right that you can't sneak a global variable access into a function without changing the function's type. That's a valid point even if it's poorly worded.
> This is great for homework, but in the real life, IO needs to be performed throughout your entire application
My experience has been that I could get away with pushing I/O out to the fringes of the app and make 80-90% of the code pure. But everybody lives in a different "real life" and it's not unlikely that the kinds of things I do on the side for fun just don't require it.