From HaskellWiki

Functional programming means that you write programs in terms of functions.
In contrast to that many today popular languages like Assembly language, Pascal, Modula, C/C++, Java, Python, Perl, Ruby are imperative languages.

The cleanest imperative programming language is certainly assembly language.
There you can write

move x,d0
move y,d1
add d0,d1
move z,d0
sub d1,d0
move d0,s

In Haskell you would write in a functional style

let s = z-(x+y)

You see that you are already a bit familiar with functional programming
because imperative languages use functions as structuring element since the advent of structured programming (Pascal et.al.).

So, is functional programming just structured imperative programming without using imperative style?
No, there is more in it.
The functional nature of a language is expressed by higher order functions
and in the case of Haskell also by lazy evaluation.

Haskell is a purely functional programming language.
Purely functional programming means that there are no side effects.
That is, if you call a function, no hidden state is altered and thus you can be sure,
that the next call with the same argument yields the same result.
This property is called referential transparency.
On the one hand this is a powerful property, since it gives you guarantees you cannot have in imperative languages.
On the other hand imperative languages provide functions like getRandomNumber or getUserInput
which can obviously return different values on each call.
Don't worry, these functions can also be nicely handled purely functional.
In Haskell this is done by Monads.

On the one hand the pure functional nature of Haskell allows lazy evaluation.
Because of the referential transparency it doesn't matter
whether a function computes its result completely at each call
or whether the computation is deferred until the result is really needed.

On the other hand lazy evaluation make functional programming more fun.
You can write large parts of the program in absence of any IO action,
since you can create data lazily by complex non-IO functions and
send it with a single IO action to the outside world (say write it to the disk).