Programs first crawled from the murky oceans as simple lists of instructions that executed in sequence. From these humble beginnings they have since evolved an astonishing number of ways of delinearizing.
In fact, most programming paradigms simply amount to different ways to transform a linear source file into a program with nonlinear behavior.
Some examples:
- gotos that unconditionally jump to another point in the program
- an abort instruction that stops the program at some point other than the end
- a macro facility that substitutes one instruction for one or more other instructions
- a source file concatenation facility that concatenates multiple source files
- an include directive that is substituted for the contents of a source file
- structured repetition and selection, a la for, while, if, and switch
- subroutines and functions
- array oriented programming that replace explicit repetition with implicit repetition
- first class functions which delegation of behavior to the caller
- object oriented programming with dynamic dispatch, which allow the runtime type of an object to determine which instructions to execute
- aspect oriented programming, pattern matching against the structure of the call stack to execute instructions when functions are called or return
- event driven programming, executing instructions in response to external events
- declarative programming, which essentially delegates execution of one program to another