
There Are Three Programming Paradigms (2013) - setra
http://wiki.c2.com/?ThereAreExactlyThreeParadigms
======
brandonbloom
Logic programming really falls in to two main categories: search and
constraint satisfaction. In that light, there's really only two programming
paradigms: Temporal and Spatial.

Imperative programming is programming with time. Functional programming
projects time on to space. When you add concurrency, either effectively
becomes logic programming: Search runs multiple spatial processes in parallel.
Constraint satisfaction treats each constraint variable as its own timeline.

We only don't think of it this way because we've traditionally linearized
logic programs. You can linearize search with backtracking and you can
linearize constraint satisfaction with a constraint propagation queue.

~~~
Chris2048
Can you expand on this? I'm not sure I follow..

~~~
brandonbloom
I can try, but I'm not just going to guess what your misunderstanding is. What
specifically would you like me to expand upon?

~~~
Chris2048
I don't understand what you mean by:

> Imperative programming is programming with time. Functional programming
> projects time on to space.

and:

> Constraint satisfaction treats each constraint variable as its own timeline

~~~
brandonbloom
Think about a mutable variable. In an imperative program X can start with A,
then become B, then become C, etc. In a functional program, you can say that X
doesn't change, instead there's really a subscript: X0=A, X1=B, X2=3. That is,
you're projecting the time dimension, which is implicit, linear, etc, on to a
space dimension: The name of the variable expands from ["x"] to ["x", 1] etc.

Monads are the (an?) ultimate exploration of this idea. You project the
timeline of the entire world on to a space dimension. Each "bind" operation
builds up a new world and you can have many forks of the world, as it's just a
model, not the world itself. This model doesn't do anything until you "run"
the monad by handing it off to some higher level interpreter.

As for constraint satisfaction, check out Sussman's talk "We Really Don't Know
How To Compute"
<[https://www.youtube.com/watch?v=O3tVctB_VSU>](https://www.youtube.com/watch?v=O3tVctB_VSU>)
\- Even though they implement the propagator networks with a message queue and
a single thread, you could in theory run each propagator in parallel, sending
messages back and forth.

~~~
andreareina
Writing another comment, I had the thought that time is still present in the
functional paradigm, though not in the same way as it typically presents in
the imperative paradigm. This is a great way of thinking about it, thanks.

------
hardwaresofton
Last time I visited C2 it was just a site that served up HTML, what is this
new async loader business it's doing?

As a result, I can't see the actual content... I assume the three paradigms
were:

1\. Imperative

2\. Functional

3\. Logic-based?

~~~
sien
This is what they taught at University in Australia 20 years ago.

Wikipedia's programming paradigms page has ummm, more than is worth easily
counting.

[https://en.wikipedia.org/wiki/Programming_paradigm](https://en.wikipedia.org/wiki/Programming_paradigm)

It also features Homoiconic programming paradigm that so many interviews ask
questions about these days.

~~~
TeMPOraL
> _Homoiconic programming paradigm that so many interviews ask questions about
> these days._

What? You're telling me that companies discovered Lisp?

~~~
throwaway7645
Rebol...and upcoming Red/RedSystem are homoiconic too and might be more
accessible if you aren't a big lisp fan.

~~~
TeMPOraL
Sure, but besides maybe Clojure, I don't know of any homoiconic language
that'd be popular enough in the industry that you'd expect questions about
this showing up on interviews...

~~~
throwaway7645
You won't get an argument from me there. If it's a standard business logic
Java/C# shop you won't get those questions.

------
TuringTest
A must-read if you're interested in the topic: _Programming Paradigms for
Dummies: What Every Programmer Should Know_ [1]. (Visual summary thanks to
Wikipedia: [2])

In short, in this view, programming paradigms are traits of languages, or more
precisely a programming paradigm is the particular combination of traits that
you include in your language.

A single addition or removal of one language trait can make the language feel
quite different.

[1]
[http://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf](http://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf)

[2]
[https://en.wikipedia.org/wiki/File:Programming_paradigms.svg](https://en.wikipedia.org/wiki/File:Programming_paradigms.svg)

~~~
Chris2048
> A single addition or removal of one language trait can make the language
> feel quite different.

I agree with this, and in this is why I, to some degree, disagree with the
idea of a 'polyglot programmer', in the sense of an experienced programmer
having general "software engineering skills", appreciation of OOP principles
etcetc with the idea that they can quickly pick up _any_ language from having
a base set of sw skills.

In reality, understanding the _specific_ implementation of many languages (all
of which differ), and the nuances of the features of the languages are
important. A single trait can make a significant difference the way you should
use a language, not to mention differently-evolved community
standards/expectations.

~~~
jerf
I think most people mean "polyglot programmer" when they do in fact know
several languages in detail. I've got a number of languages for which I am not
"a world-class expert" but I am certainly an "expert", able to structure
significantly-sized systems with best-practices and a fairly detailed
understanding of all relevant costs and benefits I'll get from it. Precisely
because I've picked up so many languages, I also know that the hardest part of
that is what you point out, that every single difference ends up affecting the
best practices. With the exception of the very heavily bondage-and-discipline
languages (Haskell, Rust, Ada, Idris), the mere act of learning syntax and
most of the semantics of most languages is often a less-than-one day task.

~~~
Chris2048
True, but I've known people use it to mean something like language-agnostic
technologist, with the idea that they have enough experience in one or two
languages that they could pick up anything else at senior level.

> Precisely because I've picked up so many languages, I also know that the
> hardest part of that is what you point out

This is exactly it. The people I describe have a few similar languages under
their belt, and simply extrapolate from this.

I wouldn't, for example, assume a experienced senior java dev could pick up
Scala at the same level within a few months, despite the similarities; they
simply lack experience with the new traits.

------
the_cat_kittles
a pete peeve i've had about "goal based programming": it always sounds like
people are just arguing for a higher level of abstraction. is that essentially
what it is? people always say "i want to tell the computer _what to do_ not
_how to do it_ ", and i feel like that ignores the fact that right now you are
able to do that to some degree. in my chosen languages, i dont have to
allocate memory when i make an array. isn't that me saying "i want an array, i
dont care how you do it" and the computer obeying? help me understand how
"goal oriented programming" is a difference in kind and not degree. to me, it
just looks like an argument to walk higher up the ladder of abstraction.

~~~
Spivak
One of the canonical examples of goal oriented programming would be sorting a
list.

Rather than expressing how to take an arbitrary list and rearrange the
elements so that they're sorted you express what means for a list to _be
sorted_ and let the algorithm figure out how to get there.

* An empty list is sorted.

* A single element is sorted.

* If one splits the list into its first element and its remainder then it is sorted if the remainder is sorted and the first element is less than or equal to the head of the remainder.

This doesn't lead to an efficient sort but it is enough for an algorithm to
take any list and produce its sorted form. You can, with the right
constraints, get a goal oriented system to carry just about every sorting
algorithm and the benefit is that they're really concise and they read like
the high level pseudocode you might see in an algorithms class.

~~~
the_cat_kittles
i dont see how this is different from any other built in function, or external
library really. perhaps it seems different because there are alot of well
known sorting algorithms that have different strengths and weaknesses? there
are any number of ways of summing a list (most of them stupid), does sum()
qualify as goal oriented? i dont think what your saying is without merit, but
i do think the taxonomy needs to be discarded if thats what its referring to.

~~~
Spivak
The difference is that those three statements encapsulate the entire source
code required to perform a sort. It's not calling any kind of built-in sorting
function. From those constraints the system is able to logically derive the
sorted list.

~~~
cLeEOGPw
> those three statements encapsulate the entire source code required to
> perform a sort.

It is calling the resolver system though and all the accompanying functions
that actually do the sorting.

Not sure what is your definition of "source code", but I'm pretty sure nobody
counts external library function implementations as source code for the
program. Same as you don't count OS kernel as part of your program's source
code.

~~~
rapala
Yes, but the resolver is not specific to sorting. The runtime of Prolog
contains no list sorting code. (Or if it does, it does so as an optimization.)

------
AdieuToLogic
I think there is a fourth category not covered by the OP, which is Generative
Programming[0].

This paradigm does not have a fundamental reduction nature (the opposite,
actually), is not concerned with memory cell manipulation, and is not limited
to predicate calculus (though its products can certainly be used for such).

Well known examples include C++ templates, Scala macros, JavaScript/Perl/Ruby
evaluation of text blocks, Aspect Oriented Programming[1], amongst others
which I am sure I have unwittingly omitted.

0 - [https://www.amazon.com/Generative-Programming-Methods-
Tools-...](https://www.amazon.com/Generative-Programming-Methods-Tools-
Applications/dp/0201309777)

1 - [https://en.wikipedia.org/wiki/Aspect-
oriented_programming](https://en.wikipedia.org/wiki/Aspect-
oriented_programming)

~~~
chriswarbo
Maybe this could be seen as a form of term rewriting system? That's the
paradigm behind languages like Maude and Pure.

~~~
nickpsecurity
You beat me to it. That's exactly what I was thinking. It would be rooted in
equational logic or something like that. The K Framework they did the C
semantics and KCC compiler in comes to mind. There's also term rewriting
languages like Stratego that do everything that way. LISP's as used by Alan
Kay et al are like a hybrid of that, functional, and imperative programming
that made for great productivity with DSL's.

So, it may be a subset of something else or its own paradigm. Worth people
thinking on. Plus, I think the style doesn't get enough attention given the
results I've seen its practitioners pull off with little code.

------
a3n
After watching the loading (?) animation for awhile, I'm guessing the three
paradigms are:

* Plain text.

* HTML.

* Gratuitous javascript.

~~~
goatlover
Web assembly will be the fourth.

~~~
Qwertious
Web assembly is just a different interpretation of gratuitous javascript.

~~~
yellowapple
Specifically, it's the ability to compile other languages into gratuitous
JavaScript.

------
ivan_ah
working link:
[http://web.archive.org/web/20160709095702/http://c2.com/cgi/...](http://web.archive.org/web/20160709095702/http://c2.com/cgi/wiki?ThereAreExactlyThreeParadigms)

~~~
js8
Thanks, I wanted to save the page to my local computer, but I couldn't figure
out how to do it..

------
tehwalrus
I wonder if the author would consider genetic programming (generating random
code and executing it to compare it against a fitness function, sometimes used
in computer game bots) an example of their "missing paradigm" \- it fits the
description they give.

------
tlow
Thomas Kuhn and I have been secretly collaborating on a paradigm shift,
rendering this discussion irrelevant.

------
hyperpallium
Three shall be the number of the paradigms and the number of the paradigms
shall be three.

------
parasubvert
This is the original Wiki from 20 years ago , recently restored from backups
and thus probably not expecting to be Slashdotted^H^H^HHacker Newsed ...

~~~
yellowapple
It's a good thing we're not Slashdothacker Newsing it, then :)

------
forgotmypw
Would it be possible for someone to post a portion of the text? Even when I
whitelist the site in NoScript, it doesn't seem to load up

~~~
shagie
See also: archive.org's archive of the old wiki page:
[http://web.archive.org/web/20160709095702/http://c2.com/cgi/...](http://web.archive.org/web/20160709095702/http://c2.com/cgi/wiki?ThereAreExactlyThreeParadigms)

FunctionalProgramming

* where the value of an expression is computed, usually close to the lambda calculus.

* or to put it differently: where the fundamental operation is reduction (of applicative terms).

ImperativeProgramming

* where cells in some sort of memory are filled and overwritten with values. Inspired by the TuringMachine and curiously never mentioned in the above table (or to put it differently: where the fundamental operation is assignment.)

* Actually, this generalizes to the fundamental operation being communication. The common case is simply communication to a cell maintained by some memory service (you send either a 'set' or a 'get', or possibly an 'apply-function' as needed for atomic ops or fast XOR processing). The more general case can consist of sends and receives on a fully networked, distributed model.

* * (different author replying) Actually, this "generalization" sound much more like the ActorsModel, which is no where near ImperativeProgramming, actually the actor model is much more similar to FunctionalProgramming than it is to imperative programming.

LogicProgramming (and ConstraintProgramming)

* where a solution to a set of logic formulas is sought; very declarative and incorporating some sort of search strategy like backtracking.

* or to put it differently: where the fundamental operation is satisfaction of a predicate.

* ConstraintProgramming envelopes LogicProgramming, since any logic domain can be expressed in terms of a constraint system, but the inverse is not often easy to express (due to the more strictly typed variables in LogicProgramming). However, the fields are disparate enough to have been split into LogicProgramming, ConstraintProgramming, and ConstraintLogicProgramming. (ConstraintAndLogicProgramming). This sort of programming is also called 'DeclarativeProgramming', but the word 'declarative' is somewhat overloaded.

That's it! Everything else is built on one of these three paradigms
(Functional, Imperative and Logic), while sometimes incorporating elements of
the others.

~~~
forgotmypw
Thank you.

------
excitom
The site is down. I wonder which paradigm covers "build for scale"?

~~~
coolsunglasses
Changing C2 to a JS-backed website that runs a lot more slowly is probably one
of the worst things to happen to hacker heritage in the last few years.

If I'd known Ward wanted something more modern I would've volunteered to do a
rewrite for something that was faster myself.

------
agsamek
This article it good but misses the most common programming paradigm - Excel
programming. Not all programmers know this powerful paradigm and tend to write
code instead of solving problems.

------
wruza
c2.com is unusable js crap. Hoped I'll never see that in my lifetime.

~~~
endless1234
The largest thing it downloads with a XHR is names.txt, a 641 kB (265 kB
gzipped) list.. of names. 36852 names to be precise. Baffling.

Apparently it's to make links clientside in the text.
[https://github.com/WardCunningham/remodeling/blob/master/sta...](https://github.com/WardCunningham/remodeling/blob/master/static/index.html#L129)

------
konne88
My prediction was that the article would talk about: abstraction, application,
and variables.

[https://en.wikipedia.org/wiki/Lambda_calculus](https://en.wikipedia.org/wiki/Lambda_calculus)

------
kriro
I feel like some sort of Deep Learning oriented programming might be the "new
logic programming". Instead of the horn clause engine you get the DL engine.
Essentially you have a "universal mapping function" and "parameter fitting".
Instead of defining facts you provide data, instead of rules you provide
mappings and you also get the "inference for free" (which is sort of the
battle cry of Prolog). Instead of logical deductions you get probabilistic
deductions. Are there any dedicated machine learning/deep learning languages
or DSLs that work at this level of abstraction?

~~~
yellowapple
I reckon that's closer to "goal-based programming" (the proposed "missing"
fourth programming paradigm on that page). Basically (as I interpret it at
least) defining test cases / behavior specifications for what you want the
software to do, then letting an artificially-intelligent sort of
"autoprogrammer" automagically generate a program that conforms to that
specification.

Software like Cucumber [0] might be part of that particular paradigm once the
missing pieces around AI/ML take proper form.

[0]:
[https://en.wikipedia.org/wiki/Cucumber_(software)](https://en.wikipedia.org/wiki/Cucumber_\(software\))

------
isaiahg
Anyone else having trouble accessing this site.

~~~
robotkdick
Error:

Trouble Encountered
[http://c2.com/wiki/remodel/pages/ThereAreExactlyThreeParadig...](http://c2.com/wiki/remodel/pages/ThereAreExactlyThreeParadigms)
can't fetch document

See github link:
[https://github.com/WardCunningham/remodeling/issues/2](https://github.com/WardCunningham/remodeling/issues/2)

------
overgard
Wouldn't SQL count as goal based, by their logic?

~~~
AdieuToLogic
In the categorization presented in the OP, SQL would be categorized as
"constraint programming" as described here[0]. Essentially, SQL conforms to a
subset of predicate calculus[1] whose operations are quantified by relational
algebra[2].

HTH

0 - [http://lambda-the-ultimate.org/node/4370](http://lambda-the-
ultimate.org/node/4370)

1 - [https://en.wikipedia.org/wiki/First-
order_logic](https://en.wikipedia.org/wiki/First-order_logic)

2 -
[https://en.wikipedia.org/wiki/Relational_algebra](https://en.wikipedia.org/wiki/Relational_algebra)

------
Maro
tldr = Haskell+C+SQL

~~~
ebalit
+Prolog

------
phaedrus
This is a question I've thought about a lot this year. How many programming
paradigms are there? How will we know if/when we've discovered them all? Is
there a way to arrange them so that gaps in the table predict yet-to-be-
discovered paradigms in the same way the periodic table predicted elements or
the square of R/C/?/L predicted memristors?

After reading some of Greg Egan's hard science fiction that explores the
consequences of a universe where time is a spacelike dimension or another
where there are two timelike dimensions, I wondered if programming paradigms
could be categorized according to what kind of world lines data or variables
may have.

For instance, in some mathematical spacetimes, the future looping back on the
past is not a construct you can create. In others (such as Egan's Orthogonal
universe), it is quite possible for world lines to arbitrarily loop back on
the past. This could be analogous to in a programming paradigm whether
statements not yet reached can affect the statement you're looking at. For
instance, whether a logic program supports constraint satisfaction.

Mutability and immutability could be analogous to various ways of resolving
the Grandfather Paradox. If the result is the timeline is changed/overwritten,
that is analogous to a mutable programming paradigm. If the result is that you
either are prevented from doing it or doing it results in spawning a duplicate
timeline where history is changed, then that is analogous to an immutable or
functional paradigm.

Finally, it should be noted that the program and it's entire execution state-
space could be regarded as a "four dimensional object" the same way you could
consider the universe + its history as a four dimensional mathematical object.
(Not really "4" because the space of the program isn't necessarily 3
dimensional, but using the term as a metaphor.) In this sense, you could see
the _actual execution_ i.e. the _implementation of the execution_ of the
program as a vector or walk through this time-state-space that does not
necessarily have to follow the (human) conceptual vector of time through the
program! (Not to mention the lexical order of the program text.) For instance,
a SQL engine might build a query plan that approaches the execution of a SQL
"program's" time-state-space in a much different direction and order than what
a human would call the "time vector" through the program.

In Egan's Orthogonal universe he deals with the question of how can living
beings experience local time when a universe has all 4 dimensions as spacelike
by making a distinction between the arrow of time defined by entropy versus
"timelike" dimensions. In our universe the entropy arrow of time usually
aligns with the timelike dimension, but in the Orthogonal universe the entropy
arrow of time _could_ point along any dimension, but which dimension is the
"time" dimension is set by the combined entropy of the local surroundings.
Similarly, in a programming paradigm you can choose to define the "time
dimension" in many different ways, but there is also an entropy arrow of time.

As an example, imagine a simple imperative programming language that
conceptually executes from top to bottom. You could, in principle, make a
bizarre implementation that executes backwards, starting with the last
instruction and all possible result states, and searches for precondition
states that could have caused that result. Repeat for the second to last
statement for all of the candidate results, and so forth, until we reach the
most initial state.

It's clear that this is _possible_ to implement if the language is restricted
enough (for instance if it has few states, or if the only allowed operations
are of a certain type). It's also clear that the big-O time/space complexity
of this implementation strategy is astronomical for most complex programs. But
it is instructive to look at _why_ this is: it is because this time-reversed
execution implementation strategy is going backwards against the entropy arrow
of time! This is reflected in the enormous amount of energy it would require
to compute (drawing on the entropy of an outside system's energy source to
reverse local entropy), and/or the gargantuan amount storage it would require
(increasing the entropy in space of an outside system in order to reverse
local entropy).

Yet at the same time, no one would bat an eye at certain classes of "programs"
"running backwards", such as a linear equation solver, or a layout engine, or
a logic constraint solver, etc. (One wonders whether a nominally imperative
assembly language for a machine based on reversible computing would also fall
into this category.)

What I'm getting at is that there are myriad "potentially timelike" dimensions
in programs: lexical order, call stack, real execution time, the programmer's
conception of how time flows in the conceptual program, etc. And there's also
an entropy arrow of time related to how hard/easy it is to reorder the
operations. Finally, I view the execution implementation as sweeping a
hyperplane (or hypermanifold) through the four dimensional time-state-space of
the program & the result of its execution. Depending on the ways that the
time-state-space of the program are connected (or connectible) determines
along which direction(s) that sweep may or must proceed.

Programming paradigms may be understandable as rules governing how this time-
state-space may be connected up, which in turn affects what the entropy arrow
of time looks like in execution-implementation-space.

------
michaelmrose
It would be awesome if he/she used whichever one would best enable it to
actually withstand being posted on hacker news and still work. I'm not even
sure what its doing while its playing that loading animation because it ought
to be static content one would think. Unfortunately it never loads and is also
not available in the internet archive. Anyone have a copy of the text?

~~~
tikhonj
It's _the_ original wiki. The article was written by a variety of people,
probably in a conversational style.

I believe the wiki was recently rearchitected, which would explain why it
doesn't scale any more :P.

~~~
rch
Is c2 a fedwiki now? That's a work in progress I think.

------
marsrover
I really hate the new C2 wiki.

------
phkahler
Waste of time. Sounds like an architecture astronaut. First he mentions
Functional programming and then under imperative he babbles and then says
this: Actually, this "generalization" sound much more like the ActorsModel,
which is no where near ImperativeProgramming, actually the actor model is much
more similar to FunctionalProgramming than it is to imperative programming.

Just a bunch of incoherent CS speak IMHO.

~~~
echelon
C2 was the very first wiki. It has a great deal of historical significance.

"CS speak"? Having a formal education in CS should not be derided. Algorithms,
data structures, and other components of computer science are important, and
programmers lacking a knowledge of these areas can't really be trusted to work
in the more demanding corners of our industry. (Many interviewers select based
on these criteria.)

~~~
phkahler
I didn't mean to deride CS terminology, but in TFA it's incoherently thrown
around like someone who wants to sound like an expert but can't make solid
case for anything and keeps changing their mind about what concepts even
apply. I'm not sure where you were going with the trust and interviews thing,
but I wouldn't hire the author of this piece (turns out its not one author
though, it's a wiki).

