Mike Long asks:
> guaranteed to be a FAQ, what is pop?
> Please post, as this will be the initial FAQ, so someone might as well
> start with that one.
Judging by the early posts, there are a quite a few people who would
like an answer to this. Well, here's my $0.02 worth on the topic. Before
I launch into it, I'd like to point readers in the direction of the
following book. The first chapter of this book is written by Prof.
Popplestone, the "father" of the Pop-family, and contains the best
account of the early history of Pop that's available.
%E Anderson, James
%T Pop-11 Comes of Age
%I Ellis Horwood
%D 1989
%O A collection of papers on the history of dialects of Pop, the
%O features and benefits of the language, and some applications using
%O Pop-11.
Question: what is pop?
----------------------
Pop is the name used to describe a family of closely related programming
languages that are derived from POP-2. (POP-2 itself was preceded by a
series of early versions (COWSEL, POP-1) that are only of historical
interest nowadays.) This language was developed in the early 1960's
at Edinburgh University by Burstall and Popplestone as an AI programming
language.
The family of languages can be charicatured as follows: Pop has a syntax
that is reminiscent of Algol, a dynamic type and store management scheme
like Lisp's, and passes arguments and returns results to procedure calls
via an "open" stack in the same way as Forth. To the tiny subpopulation of
readers that know all three of these other languages, this is a nice
summary of the salient features that gives you no idea of what it is like
to use the language.
The most widely used dialect of Pop at the moment is POP-11. POP-11 is the
core language of the multi-language programming environment POPLOG. POPLOG
currently incorporates 4 programming languages: POP-11, Common Lisp, Prolog,
and Standard ML. POP-11 is also the most sophisticated of all the Pop
dialects.
From the computer scientist's viewpoint, the most important qualities of
Pop are :-
* Garbage collection (automatic store management).
* The language is dynamically typed (cf. Lisp).
* Arguments and results are passed and returned via a stack which
is open to the user to manipulate in any way.
* Procedures are first class datatypes, can be arbitarily nested,
and provide full-lexical scoping.
Taking these points in order. Garbage collection means that the programmer
doesn't have to be concerned with how store is managed and is assured that
store is deallocated efficiently, securely, and optimally on their behalf.
Because the language is dynamically typed, the programmer does not have to
explicitly contruct type unions and is secure in the knowledge that no
meaningful programs are disallowed by the type system. On the other hand,
the programmer has no systematic way of eliminating type errors from their
program.
The most interesting aspect of Pop is the use of the open stack.
For example, because procedures return their results onto the stack,
there is no special syntax or concepts required for returning multiple
results.
;;; A procedure that returns two results given one input argument.
define duplicate( x );
x; ;;; put the value of x onto the stack
x ;;; do it again
enddefine;
When constructing lists, strings, vectors, arrays, or any other composite
object, the results can come from the stack. For example, the brackets
"[%" and "%]" will build all the items put onto the stack between them
into a list. Here's how to filter out all the non-prime elements from a
list of numbers to be left with the prime numbers of that list.
;;; Readers familiar with the ZF-list notation in Miranda will see
;;; how to construct arbitrary (finite) list comprehensions from this
;;; simple example.
define only_primes( list );
vars i;
[%
;;; iterate over the elements of the list.
for i in list do
;;; if the element is prime leave it on the stack.
if isprime( i ) then
i
endif
endfor
%] ;;; gather all the items put on the stack between here and the
;;; opening brackets and build a new list out of them.
enddefine;
Like modern Lisps, Pop supports (and encourages) the use of procedures
to model all kinds of datatypes. Furthermore, procedures are "first-class
citizens", which can be constructed, passed as parameters, returned as
results, assigned to variables, concatenated together. Full lexical
binding is supported in POP-11, along with dynamic binding and a
generalised version of dynamic localisation (of which sys-unwind-protect is
a special instance).
As an example, the portable I/O model of Pop relies on the use of
higher-order procedures. The portable way to read from a file is
vars char_repeater = discin( 'my_file' );
The result of "discin( <file> )" is a character repeater/generator. This
is a procedure that when called returns the 'next' character from the
file. When the input is exhausted the special item "termin" is
returned. This gets interesting when you appreciate that there is a
"promotion" procedure called incharitem that takes a character repeater
and returns a token (item) repeater.
vars item_repeater = incharitem( char_repeater );
The item repeater acts in the same way as a character repeater pulling
in tokens or lexemes from the input stream. Furthermore, an X-repeater
can be promoted to a "dynamic" or lazy list by applying the procedure
pdtolist.
vars item_list = pdtolist( item_repeater );
Such a list causes the character repeater to be executed as it is
examined by the head (hd) and tail (tl) procedures.
This, I hope, gives a picture of Pop as a (family of) high-level language
that is suitable for complex programming tasks. Its implementation
technology is very similiar to modern-day Lisp systems. No current
implementations are suitable for "real-time" programming, by which
I mean applications that are critically sensitive to unpredictable
delays, since the demands of garbage collection and virtual memory are
difficult to reconcile with real-time work. However, Pop is suitable
for general-purpose programming tasks since the typical run-time system
is not excessive by the standards of today's technology. For example,
the richest and most complex implementation (POP-11) has a run-time
executable of approximately 500Kb.
Steve
|