Indirection.
It might not be obvious why this is, or even what this means. But indirection is really at the basis of all of programming.
At a more superficial glance, it only seems to touch abstraction (as a concept), or perhaps also pointers (after all, they are the archetype of indirection). But pointers are just one instance (there! indirection!) of the concept, and there are many more, that are effectively equivalent upon closer examination.
First and foremost, variables are indirections because they allow the manipuation of a value indirectly via a symbol (name). As a direct consequence, functions are an indirection, because they replace one symbol (the formal parameter) with another (the actual parameter, or argument (sometimes, the definition is the other way round)).
Since classes are historically just functions in disguise, classes are obviously an indirection for the same reasons as functions.
Arrays (or lists, same thing) are another indirection, often exposed as a fundamental type. In fact, there is no difference between an array and a pointer. Both refer to other things, or none (in which case the array is empty, the pointer is null
or a special placeholder, “not in list”: NIL
).
I've recently read a paper where the pseudo code contained the following function, and use:
function UpdateItem(item, position) do
P <- { }
if item.x > position then
item.count <- 0
P <- { item }
item.count <- item.count + 1
item.x = position
Results <- { }
for something or other do
position <- GetPosition()
Result <- Result U UpdateItem(current, position)
The point here is that, like all good mathematical pseudo-codes, it operates on mathematical sets, and augments a Results
set by joining it to another one. Now, how would one implement this? Obviously, we could just use a Set
data structure, or an array, or a vector, or any of these. But usually, this is done via pointers, right?
item_t* update_item(item_t* item, int position) {
if (item->x > position) {
item->count = 0;
return NULL;
}
++item->count;
item->x = position;
return item;
}
item_t* result = (item_t*)malloc(sizeof item_t * N);
unsigned index = 0;
for (something; or; other) {
item_t* r = update_item(item, get_position());
if (r != NULL)
result[index++] = item;
}
For me, this shows really well that many, many different programming concepts just implement/perform some kind of indirection and that, despite all their differences, most of them can be expressed in terms of other means of indirection trivially.
So yes, I think indirection is really the first principle of programming, since all others are just indirection in disguise. Except recursion. Of course, recursion can be used to describe indirection. ;-)