# What is the difference between variables and pointers?

Whist reading an article outlining differences in OO and Functional programming I came across function pointers. It has been a while since I completed my Computer Science degree (2003) and so I looked up pointers to refresh my memory.

Pointers are variables that contain a reference to a memory address. They can be considered to point to the data that is contained in that memory address if such data exists. Or, as in the case in the article, they might indicate the entry point to a section of code and can be used to call that code.

Why is this different from a variable? Variables are symbolic names for memory addresses and compilers will replace the name with the actual address. This means that variables contain references to memory locations and can be considered to point to the data at that address if such data exists.

If the difference is in behaviour (maybe a pointer cannot be reassigned at runtime, or can only be assigned a symbolic variable name, not any other value) doesn't that mean it is just a variable of a particular type, the pointer type? In just the same way a variable declared to be of type integer is restricted by the compile in what it can be used for.

What am I missing here?

• Nothing, a pointer is effectively a type whose semantic interpretation is that the contents of the variable is an address. Note of course that there's two address, there's the address of the pointer (i.e. where the variable is stored) and the address the pointer references (the actual data at the variable's address). A pointer is a type of reference. – Luke Mathieson Dec 29 '14 at 3:20

Your question is interesting in several ways, as it requires careful distinctions for several issues. But your vision seems to me to be essentially correct. I did not read your reference before writing most of this answer to avoid biasing my answer.

First, your statement Variables are symbolic names for memory addresses, it is almost correct, but confuses the concept and its usual implementation. A variable is actually just a container that can contain a value that can be changed. Usually, this container is implemented on a computer as a bock of memory space, characterized by and address and a size since variables may contain object that require representations with more or less information.

But I will consider mostly a more abstract point of view of the semantics of languages, independently of implementation techniques.

So variables are just containers from an abstract point of view. Such a container need not have a name. However, languages often have variables that are named by associating to it an identifier, so that uses of the variable can be expressed by the identifier. A variable can actually have several identifiers through various aliasing mechanism. A variable can also be a subpart of a larger variable: an example is a cell of an array variable, which can be named by specifying the array variable and the index of the cell, but could as well be also associated with identifiers through aliasing.

I am deliberately using the word container that is somewhat neutral, to avoid invoking other words that may be semantically loaded technically. It is actually close to the concept of reference described in wilipedia, which is often confused with a memory address. The word pointer itself is often understood as a memory address, but I do not think that is meaningful when considering most high-level languages, and probably inappropriate in the discussion paper you refer to (though addresses can be used), as it is inappropriately referring to a specific implementation. However, it is appropriate for a language like C, which is supposed to be much closer to implementation concepts and the machine architecture.

Actually, if you look at variables or values at the implementation level, there may be several complex systems of indirection, of "machine level pointers", but that are (and should be) invisible to the user, so that the abstract point of view I develop can be valid. For most programming languages, the user should not have to worry, or even know, about implementation, as implementation can vary a lot for a given language. This may not be true for some languages, such as C, that are intentionally close to the machine architecture, as an advanced substitute for assembly languages that are in almost direct relation to explicit binary coding, but far too low level for convenient use in most situations.

What the user of a language should know, and sometimes it should be even less than that, is what are values and associated operations, where they can be contained, how they can be associated to names, how the naming system works, how can new kinds of values be defined, etc.

So another important concept is identifiers and naming. Naming an entity (a value) can be done by associating an identifier with a value (usually in a declaration). But a value can also be obtained by applying operations to other named values. Names can be reused, and there are rules (scoping rules) to determine what is associated to a given identifier, according to context of use. There are also special names, called litterals, to name the values of some domains, such as integers (e.g. $612$) or boolean (e.g. true).

The association of an unchanging value with an identifier is usually called a constant. Litterals are constants in that sense.

"Value containers" can also be considered as values, and their association with an identifier is a variable in the usual "naive" sense that you have been using. So you might say that a variable is a "container constant".

Now you might wonder what is the difference between associating an identifier with a value (constant declaration) or assigning a value to a variable, i.e. storing the value in the container defined as a container constant. Essentially, declaration may be seen as an operation that defines a notation, that associate an identifier which is a syntactic entity to some value which is a semantic entity. Assignment is a purely semantics operation that modifies a state, i.e. modifies the value of a container. In some sense, declaration is a meta concept with no semantic effect, other than providing a naming (i.e. syntactic) mechanism for semantics entities.

Actually, assignments are semantic operations that occur dynamically as the program is executed, while declarations have a more syntactic nature and are usually to be interpreted in the text of the program, independently of execution. This is why static scoping (i.e. textual scoping) is usually the natural way to understand the meaning of identifiers.

After all this, I can say that a pointer value is just another name for a container,and a pointer variable is a container variable, i.e. a container (constant) that can contain another container (with possible limitations on the containing game imposed by some type system).

Regarding code, you state [pointers] might indicate the entry point to a section of code and can be used to call that code. Actually this is not quite true. A section of code is often meaningless alone (from high level or implementation point of view). From a high-level point of view, code usually contains identifiers, and you have to interpret these identifiers in the static context where they were declared. But there is actually a possible duplication of the same static context, due essentially to recursion which is a dynamic (run-time) phenomenon, and the code can only be executed in an appropriate dynamic instance of the static context. This is a bit complex, but the consequence is that the proper concept is that of a closure that associate a piece of code and an environment where the identifiers are to be interpreted. The closure is the proper semantic concept, i.e. is a properly definable semantic value. Then you can have closure constants, closure variables, and pointers to closures, which are containers that can contain another container containing a closure.

A function is a closure, usually with some parameters to define or initialise some of its entities (constants and variables).

I am skipping many variations on the uses of these mechanisms.

Closures can be used to define OO structures in imperative or functional languages. Actually, early work on OO style (probably before the name) was done that way.

The paper you reference, which I skimmed quickly, seems to be an interesting one, written by a competent person, but possibly not an easy reading if you do not have significant experience with a variety of languages and their underlying computational models.

But remember: many things are in the eyes of the beholder, as long as he preserves a consistent view. Points of view may differ.