Classification of the Principal Programming Paradigms (2009)
Classification of the principal programming paradigms
 












 

 Classification of the principal programming paradigms
  Print this figure as a poster!





Peter Van Roy

Department of Computing Science and Engineering

Université catholique de Louvain (UCL) à Louvain-la-Neuve


 Programming
Paradigms for Dummies: What Every Programmer Should Know (article) 

This article appears as a chapter in New Computational Paradigms for Computer Music,
G. Assayag and A. Gerzso (eds.), IRCAM/Delatour France, 2009.
The article presents and explains the most recent version of the poster.

Paradigms poster in French

Explanation of the chart

This chart is inspired by
Concepts, Techniques, and Models 
of Computer Programming (MIT Press, 2004).
This textbook presents many programming paradigms
using the Oz multiparadigm programming language
for its examples.
A programming paradigm is an approach for programming 
a computer that is defined by a specific set of programming
concepts and techniques, as embodied by its kernel language,
the small core language in which all the paradigm's abstractions can be defined.
A multiparadigm language allows programming in 
each of many paradigms without interference from the others.
Multiparadigm programming is a natural approach to programming: it allows
to use the concepts necessary for a program
without being encumbered by unnecessary concepts.

The chart classifies programming paradigms according to 
their kernel languages.  Kernel languages 
are ordered according to the creative extension principle: a new 
concept is added when it cannot be encoded with only local 
transformations.  Two languages that implement the same 
paradigm can nevertheless have very different "flavors" for the 
programmer, because they make different choices on what 
programming techniques and styles to facilitate. 
All paradigms that support functional programming can also
support object-oriented programming.

When a language is mentioned under a paradigm, it means that 
part of the language is intended (by its designers) to support 
the paradigm without interference from other paradigms.  It
does not mean that there is a perfect fit between the language 
and the paradigm.  It is not enough that libraries have been 
written in the language to support the paradigm.  The language's
kernel language should support the paradigm.  When there is a 
family of related languages, usually only one member of the 
family is mentioned to avoid clutter.  The absence of a language 
does not imply any kind of value judgment. 

State is the ability to remember information, or more precisely,
to store a sequence of values in time.  Its expressive power is
strongly influenced by the paradigm that contains it.  We distinguish
four levels of expressiveness, which differ in whether the state
is unnamed or named, deterministic or nondeterministic, and
sequential or concurrent.  The least expressive is functional
programming (threaded state, e.g., DCGs and monads: unnamed,
deterministic, and sequential).  Adding concurrency gives declarative
concurrent programming (e.g., synchrocells: unnamed, deterministic,
and concurrent).  Adding nondeterministic choice gives concurrent
logic programming (which uses stream mergers: unnamed, nondeterministic,
and concurrent).  Adding ports or cells, respectively, gives message
passing or shared state (both are named, nondeterministic, and concurrent).
Nondeterminism is important for real-world interaction (e.g., client/server).
Named state is important for modularity.

Axes that are orthogonal to this chart are typing, aspects, and 
domain-specificity.  Typing is not completely orthogonal: it 
has some effect on expressiveness.  Aspects should be 
completely orthogonal, since they are part of a program's 
specification.  A domain-specific language should be definable 
in any paradigm (except when the domain needs a particular 
concept). 

Metaprogramming is another way to increase the 
expressiveness of a language.  The term covers many different 
approaches, from higher-order programming, syntactic 
extensibility (e.g., macros), to higher-order programming 
combined with syntactic support (e.g., meta-object protocols 
and generics), to full-fledged tinkering with the kernel 
language (introspection and reflection).  Syntactic extensibility 
and kernel language tinkering in particular are orthogonal to 
this chart.  Some languages, such as Scheme, are flexible 
enough to implement many paradigms in almost native 
fashion.  This flexibility is not shown in the chart. 


