Van Roy discusses the programming paradigms on his article, and tells the reasons behind languages, how do they behave in certain scenarios.
A programming paradigm is an approach to programming a computer based on a mathematical theory or a coherent set of principles. Each paradigm supports a set of concepts that makes it the best for a certain kind of problem.
For example, object-oriented programming is best for problems with a large number of related data abstractions organized in a hierarchy. Logic programming is best for transforming or navigating complex symbolic structures according to logical rules. Discrete synchronous programming is best for reactive problems, i.e., problems that consist of reactions to sequences of external events.
Each language realizes one or more paradigms, and each paradigm consists of a set of concepts.
He argues that there are two main properties of paradigms: having observable nondetermism and supporting state.
Having nondeterminism is when the execution of a program is not completely determined by its specification, i.e., at some point during the execution the specification allows the program to choose what to do next. During the execution, this choice is made by a part of the run-time system called the scheduler. The nondeterminism is observable if a user can see different results from executions that start at the same internal configuration.
This expressive power can be used to model real-world situations and to program independent activities, whereas it makes lif hard to use it for concurrent programming [especially in Java]. For concurrent programming, declarative concurrent paradigm is preferable, in which all programs are deterministic.
Three axeness of expressiveness are: state is named or unnamed, deterministic or undeterministic, sequential or concurrent.
The least expressive combination is functional programming (threaded state, e.g., DCGs in Prolog and monads in functional programming:
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