Regarding "betterness", it's a philosophical shift -- some problems are better suited to one domain or another. My favorite metaphor for functional programming is Unix pipes:
cat file | grep XYZ | sort -r -n | ...
There's no explicit state but you can track the flow... output a file, search for something, sort that result, pipe it somewhere else, etc.
Imperative/state-based programming forces you to give names to all those intermediate results, just so you can pass them along. Sometimes variables are just a place to hold data until you can pass them to the next function; functional programming makes that so easy you don't need the variable. And think about how much easier it is to debug; once you get a part of the pipeline working, you can move to the next part (without worrying about global variables and other hidden interactions that can happen with imperative programming).
Also, your comment of:
The world is imperative! Things have state! We do not live in an imaginary fluffy world of mathematical elegance & correctness.
I would check out article by Rick Hickey on state on the Clojure website:
It will get you thinking about how often your objects really need to have "state".
Imperative / functional languages are equally powerful, but are they equally expressive? There's a reason I wrote the above in a shell script vs. an OO-language (or C): shell scripting captures my intent with minimal overhead, with the right primitives built-in.
OO-languages force you to define classes, methods, type input parameters, etc. up front. So if you know you just want that exact workflow then you can model it.
What if I want to customize the sort routine? Well, I guess I can define a sorting interface and take that as an argument.
And what if I want a more flexible data structure? (With unix it's all text, but why not a hashmap being passed around?). Well, I can define a generic "list" class with an infinite number of members, and all the operations change this list.
But now we've gotten away from OO programming (saying data is of type "List" is not saying much at all).
We're basically trying to recreate functional programming ideas:
* Simple, flexible, built-in data structures (list of lists)
* Pass around functions at runtime, as you please (no interface to define, instantiate an object of that interface, and pass in)
* Composable functions (at runtime, decide that function Z is really F(G(x)))
It's not that the operations aren't possible, but OO languages seem to lead you down a specification-first path, usually customized to a problem domain.
You can "get around" this by using design patterns like Strategy, but again, you're recreating functional ideas in another language. Not that it's impossible, but it's not quite suited for the problem domain (like doing text processing in C vs. using perl... yes, you can find a regex lib, and a better string class, but why not use a language with it built in?).
Hope this helps -- different languages help you think differently. I've used C# a lot and really love the mix of functional and imperative styles in the latest versions (3.5). Joel had a good post (http://www.joelonsoftware.com/items/2006/08/01.html) on this regarding map/reduce: it's not that it's "impossible" in OO languages, but you don't instinctively think about ideas like "passing around a function and apply it to data".
using namespace UnixUtilities;
yourUtility = sort . grep "XYZ" . cat