More formally, imperative programming requires identifiable computation states, and transitions between these states with imperative instructions. Declarative programming requires a well-defined class of problems for which a close to optimal solution is implementable with the existing software and hardware.
Low level computational models and hardware are traditionally imperative. One exception is represented by analog computers, which were declarative in the way they were programmed. Therefore, the first generations of programming languages were imperative, as well as the precursor concept of an algorithm.
During the evolution of programming languages the computational states became more abstracted and less directly mapped to the hardware states. In the fourth generation of programming languages, languages were used to replace imperative programs with declarative ones. This led to domain-specific programming languages, because declarative programming is necessarily limited to only the problems for which the solution is known. Then the process of drifting towards declarative programming reached its equilibrium, as the maintenance of declarative solutions written in multiple languages became a problem due to language impedance. Furthermore, understanding of complex declarative solutions is—in general—more difficult, effects of errors are less predictable, performance optimization is hard, etc.
Presently, in the higher level languages, the margin between imperative and declarative is very blurred. General purpose languages contain both imperative and declarative constructs.
This category has the following 43 subcategories, out of 43 total.