int x = 0; x = 3; x = x + 1;you are stating that "int x = 0" should be performed before "x = 3" which should come before "x = x + 1". Programs like this proceed by evaluating each statement in turn, and each evaluation may have side effects, meaning that the state of the program (roughly the values of its variables) changes. Functional programming tries to remove this dependency on side effects, and to remove these explicit references to time (i.e. ordering of statements). After we get a bit more comfortable with functional programming in a specific language - Scheme is the language we'll use - we'll try to talk about what benefits there are in the functional approach.
Here are the basic properties that define a language as being functional:
Why is it desireable? The fact that f(x) - f(x) is not always zero in imperative programs is a source of error for humans, and it limits what can be done automatically with programs. Ex: Optimizing compilers, automatic parallelization
Lack of referential tranparency does interesting things.
For example, suppose S is a stack of numbers with 3 on the
top and 5 second from the top, and suppose you
evaluate the expression "S.pop() - S.pop()".
What do you think you get? Hard to say! Depends which
pop gets executed first. In C++, for example, this is not
specified, so different compilers could give you different
things. It's not just a question of the ambiguity - after
all C++ could change the rules to fix that the
leftmost operand, for example, gets evaluated first and
there wouldn't be any ambiguity. The point is that
determining the value of a very simple expression becomes
a very subtle exercise.
Additionally, there are several properties that functional languages traditionally have, mostly because realizing the above properties would be difficult without them.
We often call functional programs "declarative" instead of "imperative". In declarative programming we describe the object to be computed. In imperative we give a sequence of commands - the actions that accomplish the computation. In other words, declarative programming describes the result of the computation, while imperative describes the computation itself.