(From comp.lang.functional's FAQ)
Functional programming is a style of programming that emphasizes the evaluation of expressions, rather than execution of commands. The expressions in these language are formed by using functions to combine basic values. A functional language is a language that supports and encourages programming in a functional style.
Therefore instead of every segment returning a value you compound statements and they may or may not return a value. We can see a function not returning a value as not having a "side effect". For instance, this function is side effect free:
(lambda (x y) (+ x (* x x) (/ x (* x y))))
However this function is not:
(lambda (x y) (set! x (+ *some-global* x)) (+ x (* x x) (/ x (* x y))))
The reason that this function has a side effect is the set! modifies the variable x before performing its computation.
This side-effect-free-ness is called referential transparency.
The simplest way to spot side effects inside of functions is to examine which functions they call. If you see a set! or a set-cdr! or any function with a ! in it, then according to the variable-naming-conventions of scheme, you know that the function being called has a side effect, and there-fore so does yours. Probably.
Anything having to do with a global variable may, or may not cause a side effect. If you see a global variable, then you might in fact be dealing with a function containing a side effect. (but you might not!)
Anything having to do with I/O, such as display I/O or file I/O, probably causes side-effects.
Note that these are not hard-and-fast rules, but generalizations.
Haskell has an excellent method of dealing with and removing side effects, called monadic-programming.