A side effect is anything a procedure does that is observable from outside besides computing and returning its result: changing a variable or data structure, reading or writing a file, printing output, or raising an error. A procedure with no side effects always returns the same result for the same inputs and leaves the rest of the program untouched.
The Structure and Interpretation of Computer Programs analyses why side effects, and in particular assignment, complicate reasoning about programs. In its section on assignment and state, it shows that once a procedure modifies internal state, “two evaluations of the same procedure with the same arguments” need no longer produce the same result. It explains that introducing assignment breaks the substitution model of evaluation and violates referential transparency, the idea that equals may be substituted for equals, which the book says makes reasoning about programs “drastically more difficult.”
Functional programming responds by preferring pure functions, which have no side effects, and by treating data as immutable. Purely functional languages take this to its conclusion: the Haskell report describes Haskell as “a general purpose, purely functional programming language,” in which ordinary expressions cannot perform arbitrary effects.
Such languages do not abandon input and output; they isolate it. The same Haskell report notes that the language provides “a monadic I/O system,” a structured way to sequence effects so that the parts of a program that touch the outside world are kept distinct from the pure computations that do not. This separation makes the effectful parts of a program easier to identify and control.