Your characterization of functional programming is pretty astonishing, to me as a person who was most recently employed writing and maintaining software in Clojure. The following are all surely idioms, features or possibilities of one or another FP language/approach, but none of them are essential to FP:
1. "creating a list of items and combining operators, then magically evaluating those combinators all at once and getting a cake" — I think the reality is that this can be overdone (and sometimes it is), but for people who live and breathe the abstractions that come with a FP language, it tends to reflect the expressive qualities of core concepts and operators-as-functions. (reduce + 0 args) is just a whole lot more expressive, when familiar, than total = 0; for (val in args): total += val; return total.
2. "lazy evaluation" — I'm not really sure this needs to be specific to FP, but it does really shine with abstractions often associated with FP (e.g. map, reduce, filter, and so on).
3. "macros" — I cherry-picked this away from the C preprocessor reference to contrast with lispy/homoiconic macros, which are hardly the nightmare of metaprogramming in languages with every-which-way syntax, but even when macros are sane they tend to be strongly discouraged.
4. "monads" — I see monads far more in imperative code than functional, so I don't even. (I'm talking about the lovely Promise pattern, which is excellent.) Then again, I don't write Haskell.
I'd characterize FP differently: a function of a given set of arguments should always return the same value, without side-effects; in non-pure languages, add the caveat unless you have a good reason, which should be identified clearly in code; with that caveat, you can kinda do FP in any language (though it may be horribly inefficient).
In other words, stateful code is hard to reason with, and the greatest care should be taken to making it clear when it cannot or must not be avoided. This should be true in any programming environment.
You're right that people tend to mentally model in terms of objects—that is, the combination of data and action. But it doesn't have to be stateful by default, and there's a lot to gain from reversing that.
- - -
A little anecdote: for kinda silly reasons, I've been doing some one-off work in Node.js after spending a good long while in Clojure. It came time for me to reverse an array, and I wrote code like the following: var foo = bar.reverse();. With almost no real JS work for over a year, I could not recall the following:
1. Will bar be reversed?
2. Does Array#reverse actually return a reversed array value, or something else?
I couldn't know what that very simple code does, simply by reading it. I had to go evaluate it! It turns out that Array#reverse is a bit unusual in JS as it is both stateful (it reversed bar) and it sort of looks like it returns a value (it returned a reference to bar). That code which should do an obvious thing actually caused a bug, because I had to make guesses about state, and I guessed wrong.
- - -
There are reasons to choose a stateful implementation—performance, expressiveness, interop with stateful environments or libraries—but it's not a given, and not even always consistent with a normal mental model, for statefulness to be assumed.