Declarative: The programmer defines the composition of functions, and lets the run-time optimize algorithms. Examples include Haskell, Erlang, and OCaml.
A classic way to describe the distinction between declarative and imperative programming is that declarative languages let the programmer describe what to do, whereas imperative languages let the programmer define how to do it.
If we extend this idea to a third type of language that lets the programmer define why choices are made, then we have discovered task-oriented programming languages.
Task-oriented: The programmer defines desired states, and lets the runtime resolve the compositio…