POP-2 (also called POP2) is a programming language developed around 1970 from the earlier language POP-1 (developed by Robin Popplestone in 1968, originally named COWSEL) by Robin Popplestone and Rod Burstall at the University of Edinburgh. It drew roots from many sources: the languages Lisp and ALGOL 60, and theoretical ideas from Peter J. Landin. It used an incremental compiler, which gave it some of the flexibility of an interpreted language, including allowing new function definitions at run time and modification of function definitions while a program runs (both of which are features of dynamic compilation), without the overhead of an interpreted language.
Description
Stack POP-2's syntax is ALGOL-like, except that assignments are in reverse order: instead of writing
a := 3;
one writes
3 -> a;
The reason for this is that the language has explicit notion of an operand stack. Thus, the prior assignment can be written as two separate statements:
3;
which evaluates the value 3 and leaves it on the stack, and
-> a;
which pops the top value off the stack and assigns it to the variable 'a'. Similarly, the function call
f(x, y, z);
can be written as
x, y, z; f();
(commas and semicolons being largely interchangeable) or even
x, y, z.f;
or
(x, y, z).f;
Because of the stack-based paradigm, there is no need to distinguish between statements and expressions; thus, the two constructs
if a > b then c -> e else d -> e close;
and
if a > b then c else d close -> e;
are equivalent (use of close, as endif hadn't become a common end-of-if-clause notation yet).
Arrays and doublet functions There are no special language constructs to create arrays or record structures as they are commonly understood: instead, these are created with the aid of special builtin functions, e.g., newarray (for arrays that can contain any type of item) and newanyarray to create restricted types of items. Thus, array element and record field accessors are simply special cases of a doublet function: this is a function that had another function attached as its updater, which is called on the receiving side of an assignment. Thus, if the variable a contains an array, then
3 -> a(4);
is equivalent to
updater(a)(3, 4);
the builtin function updater returning the updater of the doublet. Of course, updater is a doublet and can be used to change the updater component of a doublet.
Functions Variables can hold values of any type, including functions, which are first-class objects. Thus, the following constructs
function max x y; if x > y then x else y close end;
and
vars max; lambda x y; if x > y then x else y close end -> max;
are equivalent. An interesting operation on functions is partial application, (sometimes termed currying). In partial application, some number of the rightmost arguments of the function (which are the last ones placed on the stack before the function is involved) are frozen to given values, to produce a new function of fewer arguments, which is a closure of the original function. For instance, consider a function for computing general second-degree polynomials:
function poly2 x a b c; a * x * x + b * x + c end;
This can be bound, for instance as
vars less1squared; poly2(% 1, -2, 1%) -> less1squared;
such that the expression
less1squared(3)
applies the closure of poly2 with three arguments frozen, to the argument 3, returning the square of (3 - 1), which is 4. The application of the partially applied function causes the frozen values (in this case 1, -2, 1) to be added to whatever is already on the stack (in this case 3), after which the original function poly2 is invoked. It then uses the top four items on the stack, producing the same result as
poly2(3, 1, -2, 1)
i.e.
1*3*3 + (-2)*3 + 1
Operator definition In POP-2, it was possible to define new operations (operators in modern terms).
vars operation 3 +*; lambda x y; x * x + y * y end -> nonop +*
The first line declares a new operation +* with precedence (priority) 3. The second line creates a function f(x,y)=x*x+y*y, and assigns it to the newly declared operation +*.
… excerpt ends here. Continue reading the full article.
