With or without side effects, a function call says "go to this other place and do this other thing and bring back the result". That's a kind of goto – a structured kind that's always paired with a return. This is higher level than the old-fashioned GOTO but that doesn't make it complexity-free. It's still possible to create spaghetti with it.
Maybe that sounds pedantic, but I don't think it is, because interaction complexity needs to be minimized just like other kinds of complexity do. When you call a function you are implicitly drawing a line between the caller and the callee. Imagine a picture of your program with all those lines drawn at once. That picture ought to have some order to it.
Side effects are a different kind of complexity. If pure function calls are like going camping and leaving nothing behind, then function calls with side effects are like going camping and burning a fire or littering or what have you.
Maybe that sounds pedantic, but I don't think it is, because interaction complexity needs to be minimized just like other kinds of complexity do. When you call a function you are implicitly drawing a line between the caller and the callee. Imagine a picture of your program with all those lines drawn at once. That picture ought to have some order to it.
Side effects are a different kind of complexity. If pure function calls are like going camping and leaving nothing behind, then function calls with side effects are like going camping and burning a fire or littering or what have you.