- Goto Considered Harmful
- Between the BEGIN and the END
- ALGOL and the B5000
- The ALGOL Family
Between the BEGIN and the END
An ALGOL program uses the keywords BEGIN and END to indicate a lexical scope. The concept of lexical scope in which variables have a visibility and a lifetime defined by a region of the source code—originates with ALGOL 60.
Variable scoping is related to the idea of binding from lambda calculus. Variables, in their most abstract form, are simply names for regions of memory, optionally with some defined structure. An assembly language typically has no concept of scope at all. Regions of memory can be given names, but these names are visible to the entire program—the equivalent of global variables in modern programming languages. Any other address must be computed explicitly from known locations, such as global values or the stack.
High-level languages typically allow you to name regions of memory without needing to be aware of their physical location. In a language like C, you might write this:
int a;
Occurring in a function body, this means several things:
- Allocate enough space for an int on the stack.
- Deallocate this space when program flow exits this scope.
- Make any references to the name a refer to this address on the stack, for the duration of this scope.
In C, scopes are indicated by braces ({ }). ALGOL instead used the keywords BEGIN and END, a convention picked up by a lot of ALGOL-family languages, most notably Pascal. Irrespective of how the scope is defined, the important thing is that it's a block within the source code. This mapping from the name a to the region of memory defined by the declaration persists only within that block in the code.
Lisp had a notion of scoping that was much closer to lambda calculus. In early versions of Lisp, a reference to a variable was looked up at the point where the code was executed, rather than where it was created. It's much harder to implement and reason about this dynamic scoping.
Lexical scoping is such an ingrained concept in modern programming languages that you don't tend to think of it as ever having been invented—it's just naturally how programming languages work. It's a very simple concept, but one that has been very important in software engineering.
Lexical scoping dramatically reduces the amount of a program that you need to read to understand a small part. For example, consider this statement:
n = a + b;
To understand what this statement is doing, you need to know what n, a, and b are. In a lexically scoped language, determining this information is relatively simple: Just look up the page until you find the nearest declaration of each one. In a dynamically scoped language, you need to look for their declarations or assignments not just where this line is used, but anyplace where the function containing it is used.