Someone asked me recently how I categorize different programming paradigms. I thought it was a very interesting question, so here's what I responded. Please bear in mind that this is very much the way I see things, and is neither an exhaustive nor a formally-ratified taxonomy.
One way to look at languages is whether they're declarative or imperative:
Declarative programming languages map the way things are by building up “truths”: this category includes functional programming languages (such as Miranda, Haskell and Erlang) which tend to be mathematical in nature (you define equations) and start with lambda calculus as a foundation. The other main set of declarative languages are logic programming languages (such as Prolog), which start with propositional calculus as a foundation (you declare axioms that build up to a system against which you can run queries). Declarative languages tend to focus on describing the problem to solve, rather than how to solve it.
Imperative programming languages, on the other hand, are lists of instructions of what to do: I tend to consider procedural programming languages (such as C, COBOL, Fortran and Pascal) as a sub-category which focus on the definition and execution of sub-routines, while some people treat the terms imperative and procedural as synonyms.
Considering these definitions, object-oriented programming languages (such as Smalltalk and Eiffel) should probably be considered declarative, as conceptually they map real-world objects, but the truth is that the most popular OO languages (such as C++) are impure, and so most OO systems combine big chunks of procedural (i.e. imperative) code. Many people who think they’re doing OOP are actually packaging up procedures.
Note that I've tried not to list multi-paradigm languages such as Ada, C++ and F# in the above categorisation. It's possible that some of the languages I've listed are also multi-paradigm, but anyway.
One other way to think about languages is whether they’re top-down or bottom-up:
Bottom-up languages are ultimately layered on how a processor works (from machine code to assembly language to C & C++), while top-down languages start from the world of mathematics and logic and add language features that allow them to be used for programming (i.e. declarative languages are therefore top-down). This latter set of languages are starting to see increased adoption, as they assume much less (even nothing) about the underlying machinery, in which big changes are occurring with multiple processing cores being introduced (which essentially invalidate the assumptions of previous generations of programmers, who have been conditioned to think in terms of the processor's ability to store and access state).
Many popular - or soon to be popular - programming environments are pragmatic in nature: C++ allows OOP but can also be used for procedural programming, VB.NET now allows you to define and access objects while coming from a long line of procedural languages, F# is multi-paradigm, combining OO with functional and imperative programming.
There are bound to be people with differing views on this subject (and many of them are no doubt more intelligent and experienced in these matters than I), but this is how I would answer the question of how to categorise programming languages.
For those of you with an interest in the future of programming languages, I can strongly recommend the following Channel 9 episodes. If you're not aware of Channel 9, then prepare to be impressed: Microsoft has given a fantastic gift to the development community with this resource.
Burton Smith: On General Purpose Super Computing and the History and Future of Parallelism
Erik Meijer: Functional Programming
Anders Hejlsberg, Herb Sutter, Erik Meijer, Brian Beckman: Software Composability and the Future of Languages
Brian Beckman: Don't fear the Monads
Joe Armstrong - On Erlang, OO, Concurrency, Shared State and the Future, Part 1
Joe Armstrong - On Erlang, OO, Concurrency, Shared State and the Future, Part 2
Enjoy! :-)