Programming Paradigms

What is a paradigm?

A paradigm is simply a mental model. Human cognition is built around some model that is used to understand the world. The model is usually dictated by the culture or sub-culture and controls the way members of the culture view the world. If all you have is a hammer, then everything looks like a nail.

We can view programmers as a sub-culture divided into sub-sub-cultures, each using a different paradigm to view how computers solve problems.

Classifying architectures/paradigms

Treleaven's classification of computer architectures applies to programming paradigms if we view language processors as virtual computers.

According to Treleaven, an architecture is specified by a control mechanism that controls the flow of execution, and a data mechanism that controls the flow of data:

Architecture/Paradigm = Control Mechanism + Data Mechanism

Treleaven identifies four types of control mechanisms and two types of data mechanisms. Combining these gives us eight types of architectures/paradigms:

 

Control Mechanisms

Data Mechanisms

Control Driven

Data Driven

Demand Driven

Pattern Driven

Shared Memory

COSH

DASH

DESH

PASH

Message Passing

COME

DAME

DEME

PAME

Control Mechanisms

Control-Driven

Let's expand the definition of instruction to include functions, procedures, actions, events, phrases, etc.

In a control-driven architecture each instruction specifies the next instruction to be executed. A default mechanism is used in case a next instruction isn't specified. For example, if no next, then execute the physically next instruction.

The classical example of this is the goto instruction.

The call/return mechanism is an example of a control-driven mechanism.

Data-Driven

Normally an instruction decides which data too process, but this can be reversed. We see this in polymorphism. For example:

employee.print();

The type of employee might determine which print function should be called.

Demand-Driven

In lazy evaluation algorithms an operand is only evaluated if it is needed. For example:

false && 1 = 2/0

Demand-driven paradigm can also be seen in publisher-subscriber mechanisms, where subscriber instructions are executed each time a publisher object fires an event or changes state.

Pattern-Driven

Pattern matching algorithms are used to determine which instruction should be executed. We see this in XSLT, for example, when the pattern of an XML element determines the function used to convert it into HTML.

Data Mechanisms

Shared memory

Instructions process data. In shared memory architectures all data resides in a centralized repository (memory, storage, database, etc.) and is accessible by all instructions. This is very efficient but can lead to synchronization problems.

Message passing

In message passing architectures instructions send data to each other. Usually the computer must provide some sort of postal service. Message passing is common in networks. Message passing can be synchronous (TCP) or asynchronous (UDP).

Traditional Programming Paradigms

Imperative (COSH)

The imperative paradigm views a program as a collection of functions that use complex control structures and the call/return mechanism to update passive data structures.

Examples: C, Pascal, FORTRAN, Assembly

Declarative (PASH)

The declarative paradigm views a program as a database of facts and rules

The format of a rule is:

Conclusion if Assumption_1 && Assumption_2 && ... && Assumption_n

A goal is some assertion that the program is trying to verify or refute. Usually there is a stack of goals. The program must verify or refute each one.

The program works backwards from an initial goal or query.

[query]

It uses sophisticated pattern matching algorithms to match the goal to a fact or the conclusion of a rule. In the latter case the goal is replaced in the goal stack by the assumptions and the process repeats.

[Assumption_1 Assumption_2 ... Assumption_n]

The program halts when the stack is empty.

[]

Examples: Prolog, SQL, XSLT

Functional (COME, PAME)

Functional programming avoids shared memory. Instead, functions pass data through parameters. There are no variables or commands!

Some languages, like Haskell, also provide pattern-driven mechanisms.

Examples: Haskell/Hugs, LISP

Object-Oriented (DAME)

If we consider objects to be our principle or only form of data, then there are no functions in OO languages. There are methods, but these are things that objects (data) execute. We can regard a method invocations such as:

expression.evaluate()

As passing the print message to the employee object. Of course thanks to polymorhism, the actual code that gets executed might depend on the sub-type of the expression.

Examples: Smalltalk, Java