Skip to content

Instantly share code, notes, and snippets.

@ancms2600
Last active February 13, 2018 22:20
Show Gist options
  • Save ancms2600/c74bb44d4c2f6a91a60739c6753211e0 to your computer and use it in GitHub Desktop.
Save ancms2600/c74bb44d4c2f6a91a60739c6753211e0 to your computer and use it in GitHub Desktop.
Declarative vs. Imperative, Procedural vs. Object-oriented vs. Functional Programming
Declarative programming: Expresses the logic of a computation without describing its control flow. (e.g., no loops)
e.g., SQL, RegExp, Markdown
example: SELECT * FROM table;
Imperative programming: Uses statements that change a program's state. Consists of commands for the computer to perform.
e.g., OpenGL, Canvas, Turtle, GCode, ASM, FORTRAN, SVG
example: while (true): up(1); right(2); stroke(); done();
Procedural programming: Derived from structured programming, based upon the concept of the procedure call.
Procedures, also known as routines, subroutines, or functions (not to be confused with mathematical functions,
but similar to those used in functional programming), simply contain a series of computational steps to be carried out.
Object-oriented programming (OO or OOP):
Concept of "objects" which contain data structures, in the form of "fields", often known as "attributes";
and code, in the form of procedures, often known as "methods".
One selling point of objects is the idea of encapsulation, where access to object internals is controlled,
typically by "private", "protected", "public" keywords, or else by closure scope,
for the purpose of enforcing "interfaces" or contracts with other developers who may not immediately understand
how two objects are intended to interact by the original author.
A single object can prototype many "instances", each of which have a notion of "this" or "self" when referring to
the internals of that specific copy of the original object.
Typically when a `class` keyword is present in the language then all objects are instances of classes,
but it is still possible to implement without. (C structs, JS prototype)
Finally, in "strongly typed" languages, an additional distinction is made between user-defined object types (e.g., Animal)
and primitive types which are language-defined and platform dependent (e.g., int), which stricter languages
enforce at compile-time as an additional integrity check that prevents a broad range of runtime errors.
These programs are designed by making objects that interact with each other.
e.g., C++, Java, C#
example: class Animal { makeNoise() {} }; class Cow extends Animal { makeNoise() { return "moo"; } };
Functional programming: Originates from lambda calculus, which treats computation as the evaluation of mathematical functions,
which consider input/output as always immutable, and return values only influenced by inputs and internal state, never external or global state.
These are called "pure functions", or functions without "side-effects"; these functions can be "memoized" meaning for any given input x of function f(x),
it is safe to cache the return value, because subsequent calls to the same function with the same input will always produce the same return value,
regardless of changes to local or global program state, the passage of time, etc. This helps reduce computation time for complex functions.
This way of thinking necessitates a compiler which understands tail-call recursion optimization, and streams, making it extremely cheap to
operate within subsets of potentially infinite recursion. While these languages are typically not object-oriented, nothing precludes using
pure functions exclusively within objects.
e.g., Haskell, Scala, Lisp
example:
const fibonnaci = (n) => n < 2 ? n * 1 : fibonnaci(n - 2) + fibonnaci(n - 1);
const fibonnaciList = (ct) => ct < 1 ? [0] : [fibonnaci(ct)].concat(fibonnaciList(ct-1))
console.log(fibonnaciList(8).reverse()); // Array [ 0, 1, 1, 2, 3, 5, 8, 13, 21 ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment