This depends on what your definition of "functional" is. Most people hold it to be first class functions and some include higher order functions. Immutable data structures are not strictly necessary - every recognized functional language allows destructive update in some form.
C has first class functions (via function pointers) and C++ inherited that from C. That makes functional programming possible if not necessarily easy.
You are correct that it is not recognized ... it is there nonetheless.
You have a different definition of "support". By my definition, "support" for something in a language means that something can be accomplished within the scope of the language's syntax and semantics. To that end, assembler supports all possible paradigms - BASIC, for example, does not.
I believe C++ was designed to add OO concepts to a procedural base language. Clearly it was not designed to *be* OO because objects are not central to coding nor even necessary. Writing purely OO code is impossible in C++ because object support does not extend to the basic data types. However, writing purely procedural code is easy.
C++'s support for generics is no more than a kludge - a compiler trick. True generics allow functions to be written without regard to data types. That is impossible in C++. Templates allow code to be more easily "specialized" for a particular concrete type but they are a far cry from generics.
I mean design.
All the paradigms we are discussing are thought exercises. OO centers on abstracting the "world" in terms of actors and actions they perform. Functional and procedural models center on actions and the objects to be acted on. These models are not orthagonal, they are two sides of the same coin.
I believe good designers bounce back and forth between these modes of thinking constantly. Our thought processes naturally deconstruct problems in a certain way ... some problems are more actor oriented and some are more action oriented. Procedural thinking makes solving an actor oriented problem clumsy - OO thinking does the same for an action oriented problem.
Implementation issues are secondary to the thought process. Any Turing complete language can simulate any other (with varying degrees of effort). The extent to which any particular language helps in implementing the program model is relevent only to expediency. As all program solutions involve some aspects from each of the models, the choice of implementation language is less critical than the solution itself.
I firmly believe the language wars arise, in part, because programmers forget that their chosen language facilitates a model of thinking that they find comfortable, and it is not the language they are defending but their model of thinking.
My response is: you absolutely CAN do this in C. Full C++ inheritence is possible in C as evidenced by the first C++ compilers which compiled C++ code into C. The result is very messy and, IMO, unmaintainable, but it clearly demonstrates that C, in and of itself, does support OO (at least to the same degree that C++ does).
How is it a "mistake" to be ignorant of the cost of using a feature? Particularly when the cost is either not known or not advertised. As I said before, most of these issues were found by frustrated developers looking at the compiler's output. The documentation for your compiler rarely tells the gory details of the implementation of language forms.
People who write code for GHz processors with virtual memory and RAM to burn largely don't care about the overall efficiency of their compiler or the relative efficiency of language forms (they may pay it lip service, but in the end it doesn't affect their ability to write the program). I'm reading this thread in comp.arch.embedded where most programmers do care.
George