# Paradigm

By [programming language](programming_language.md)'s paradigm (from Greek *paradeigma*, "pattern", "example") we mean the very essential concepts used as a basis for performing computation in that language. Among the most popular ones we'll find for example the [imperative](imperative.md), [object oriented](oop.md) and [functional](functional.md), but there's a sizable set of other paradigms in the world; a paradigm can be understood as a set of fundamental ideas, principles and [mathematical](math.md) models (e.g. [models of computation](model_of_computation.md), [data types](data_type.md), forms of [expressions](expression.md) etc.) upon which are built more complex constructs of the language -- paradigm forms foundations which are subsequently accompanied by a kind of "programming philosophy" (expressed for examples as "[everything is](everything_is.md) X" where *X* may be *[number](number.md)*, *[object](oop.md)*, *[array](array.md)*, *[list](list.md)* etc.), a naturally emerging "mindset", a set of recommendations the programmer should follow when using the language. But let it be set straight that paradigm will NOT include other than purely technical, engineering aspects of computation, i.e. artistic or political ideas (such as "eco-friendlieness", "anti-fascism", ...) are indeed not part of programming paradigm. Nevertheless, although of technical nature, aspects of paradigms are subjective, for example the question of drawing borders between them -- just like [music](music.md) genres or human [races](race.md), paradigms are [fuzzy](fuzzy.md) concepts, they have different definitions in different books, come in different flavors and are often combined; sometimes it's unclear how to classify paradigms (if one strictly falls under another etc.) or even if something is or isn't a paradigm at all. In a wider sense the term *paradigm* may also be used outside of programming languages, for example a paradigm of a [physics engine](physics_engine.md) might be "everything's a sphere" etc.

For example the [functional](functional.md) paradigm is built on top of [lambda calculus](lambda_calculus.md) (one of many possible mathematical systems that can be used to perform general calculations) which performs calculations by combining pure mathematical [functions](function.md) -- this then shapes the language so that a programmer will mostly be writing mathematical functions in it, AND this also usually comes with the natural "philosophy" of consequently viewing everything as a function, even such things as loops or [numbers](number.md) themselves. In contrast [object oriented](oop.md) (OOP) paradigm aims to solve problems by constructing a network of intercommunicating "objects" and so in OOP we tend to perceive everything as objects.

**Most common** practically used paradigm is the **[imperative](imperative.md)**, one based on the plain and simple concept of issuing "commands" to the [computer](computer.md) -- even though nowadays it almost always gets combined with some other [bullshit](bullshit.md) paradigm, most infamously [object orientation](oop.md). Prevalence of imperative paradigm is probably due to more than one factor, most important of which is most likely its [simplicity](kiss.md) (it's possibly the closest to human thinking, easiest to learn, predict etc.), efficiency thanks to being closest to how computers actually work (compilers have very small [overhead](overhead.md) in translation, less "[magic](magic.md)" is required), [historically](history.md) established status (which is related to simplicity; imperative was the first natural approach to programming), compatibility with [minimalism](minimalism.md) (AKA good design) etc. Even the more abstract paradigms are ultimately erected on top of an imperative system, so imperative computation is present in one way or another.

**List of notable paradigms** follows (keep in mind the subjectivity and fuzziness that affect classification):

- **[imperative](imperative.md)**: Programmer issues commands, the computer blindly executes them ("impero" = "to command"). The focus is on the process of computation. This is the most common paradigm.
  - **[procedural](procedural.md)**: Programmer writes procedures -- smaller subprograms that together solve the whole problem at hand. This is an extremely common paradigm; procedures are also often called *[functions](function.md)*, but they mustn't be confused with PURE mathematical functions used in functional paradigm. Examples: [Pascal](pascal.md), [C](c.md), [Fortran](fortran.md), ...
  - **[stack](stack.md)-based**: Computation happens on stack (or multiple stacks), a [data structure](data_structure.md) very convenient for this purpose. These languages often naturally use prefix or postfix notation, it is easy to implement parameter passing and returning values, many computations are elegant. This is a popular paradigm for [minimalist](minimalism.md) languages. Examples: [Forth](forth.md), [comun](comun.md), ...
  - **[event](event.md)-driven**: Programmer defines reactions to certain external events rather than a single run of a program. This is very often used in [GUI](gui.md) programming (with events such as "button clicked", "window resized" etd.). Example: [Javascript](javascript.md).
  - **[array](array.md)-based**: Operations mostly work on [arrays](array.md) as opposed to working on single values (scalars).
  - ...
- **[declarative](declarative.md)**: Programmer defines ("declares") what the result should look like, the program finds something that fits the definition. The focus is on the result, not the process to obtain it.
  - **[functional](functional.md)**: Programmer describes solution to a problem as composition of pure mathematical functions (which are not to be confused with more loosely defined "functions" present in many languages). Here everything, even branching and loops, are implemented as strictly mathematical functions that have no [side effects](side_effect.md). Formally this paradigm is based on [lambda calculus](lambda_calculus.md). Examples: [Haskell](haskell.md), [Lisp](lisp.md), ...
  - **[logic](logic.md)**: Programmer describes solution using formal [logic](logic.md). Example: [Prolog](prolog.md).
  - ...
- **[object oriented](oop.md)** (OOP): Programmer defines objects (greatly independent, small encapsulated abstract entities) that communicate with each other to solve given problem. Most generally the paradigm is only about "decomposing problems to objects" and so may be implemented as both imperative and declarative, though nowadays OOP is heavily combined with imperative programming and so is often seen as imperative. Examples: [Smalltalk](smalltalk.md), [Java](java.md), [C++](cpp.md), ...
  - class-based
  - classless
  - ...
- **[agent](agent.md) oriented** (AOP): Very similar to OOP, sometimes very vague, many times seen as OOP extension focusing on concurrency, agents are entities having their own goals (as opposed to mere objects as "service providers").
- ...

The list enumerates just the most important paradigms, other possible paradigms and "almost" paradigms may just include anything connected to any largely useful concept, e.g.: [recursive](recursion.md), [concurrent](concurrency.md), structured, [data](data.md) oriented, visual, [set](set.md)-based, table-based, [metaprogramming](metaprogramming.md), non[deterministic](determinism.md), value-level, message-based, [generic](generics.md), reflective, constraint programming, [genetic](genetic.md), term rewriting, [string](string.md)-based, symbolic etcetc.