> Whoa, I think you're mixing things up there. Your original claim was that compilers get rid of the imperative nature of some programming languages.
Compilers most definitely try to work with as "functional" (ie. immutable values, not mutable variables) program representations as possible. Such as GCC's GIMPLE intermediate language and it's SSA subset or LLVM's IR "assembly". These languages operate mostly on values and try to avoid mutable variables as far as possible (like LLVM's mem2reg pass which does just this).
Getting to this intermediate representation from a C-like language is really painful (lots of iterative graph algorithms). Dealing with source level optimization in C-like languages is next to impossible and most compilers don't do this. Instead they transform the program to the intermediate representation with simpler semantics, which is most definitely less "imperative" than the source language.
A good compiler can use several source languages, which are translated to a common intermediate representation, where machine independent optimization takes place.
The final compilation phase from the intermediate representation to assembler re-introduces the "imperative" style to the program because the CPU operates that way.
> Also, as an aside, if you take some machine code that was compiled from C, even these days it is still ridiculously easy to take that code and turn it back into C.
If you crank up the optimizer to -O3 and give the compiler opportunities to optimize (inline functions or link time optimization), you cannot recognize the original program structure from the emitted assembly code except in the simplest of cases.