If we think of programming as a general concept for expressing problems in terms of an Input/Output system and by what is given, then three general paradigms can be differentiated. Interestingly these “paradigms” seem to directly match the three different concepts of philosophical reasoning.
1. Imperative Programming & Deduction
This first (and mostly applied) paradigm can be defined as:
Program( Input ) -> ???
thereby the Input data is known or given and the Program is defined in terms of transformation steps in order to generate the “unknown” Output data. In this sense it can be also said, that we are actually deducing the Output data from a given set of Input data and rules. Other paradigms such as structured, procedural, aspect-, feature-, and object-oriented programming can be associated primarily to this paradigm, since its main concern lays in the definition of the control flow.
2. Declarative Programming & Induction
It is mostly assumed to be the opposite to the previous paradigm, as it can be defined as follows:
??? ( Input ) -> Output
it exist some form of notation or description of the Input and Output, thereby the question marks do not represent the abstract concept of a Program in terms of a control flow. Instead it can be interpreted as an abstract machine, reasoner, a (search) algorithm, etc. that is used to generate the desired result on the basis of the formal description of the Input and Output. It would be wrong to consider Input & Output as some form of data only, instead it defines both values and transformations, depending on the applied “concept”. For example in functional programming the IO is expressed in terms of mathematical notion of functions and parameters, in logical programming as facts and rules, in “relational” programming as entities and relations, or in symbolic programing as symbols and formulas, etc. Thus, it is both that can be generated, such as in “Prolog” it is possible to resolve on the basis of facts and rules, if a certain fact is true/false or under which circumstances it becomes true/false, but it is also possible to query for a set of successive rules or to derive new ones. Thus, as in inductive reasoning we have the case and the result and try to infer the rule.
3. Probabilistic Programming & Abduction
For the sake of completeness, the last combination that has been left out so far is the following, which has recently
been denoted as the probabilistic programming paradigm:
Program( ??? ) -> Output
in this case the Program cannot be considered as a strict set of transformation steps either, which are simply applied backwards in reverse order to get from a known Output to its Input. Instead the Output here has to be
considered as some form of observation and the Program as some kind of probabilistic model. This model can be a vague description of a systems by using background knowledge, beliefs and assumptions, possible interactions between elements or transitions between states, etc. Whereby each of these aspects is described in terms of distributions and probabilities, which do not have to be defined in particular. Literally spoken, the Program itself is a huge sample generator for probability distributions that cannot be described mathematically. Hence, having a model and some observations allows to draw inferences about the Input. Thereby Input does not necessarily define input data, but also model parameters, probability functions, etc.
The most prominent example is the language “Picture”, which was developed in 2015 at the Massachusetts Institute of Technology. 50 lines of Picture code describing believes about human faces and projections were sufficient to solve the problem of inverse graphics, in which the most likely 3D models of human faces were inferred on the basis of given 2D photos (thus, the actual Output).
It seems for me that there are only three ways of solving a problem or philosophically speaking to reason, probably there are only these three general methods/paradigms. All other paradigms that are used in computer science relate to these in case of how we solve problems or try to express a solution. In this case OOP does not differ a lot from other paradigms such as Aspect-Oriented programming, both describe similar deductive solutions (solution steps) that we apply to solve a problem, but with a different syntax.
What would a programming language look like, that would allow us to describe problems/solution-steps in all three paradigms combined???