[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

updaters in POP-11/POP-2

Thanks for sending me a copy of your reply to the enquiry about
updaters. I had not seen the original. Which news group was it in?

Just a few comments, some of which Robert may already have made direct
to you.

(a) There is at present no complete published specification of POP-11
(the most recent descendent of POP-2) apart from the online "REF" files
distributed with Poplog. We plan to publish a proper reference manual,
but other work keeps getting in the way. The two books you referred to
both describe subsets of POP-11. The one by Laventhol (deliberately)
describes a smaller subset corresponding to the version for the Mac
known as Alphapop, reviewed in Byte May 1988. e.g. the book does
not include lexical variables.

Alphapop is distributed with a complete specification of Alphapop. In
the USA it is distributed by Prof Robin Popplestone, Dept of computer
science univ. of Amherst, and he can answer just about any question
about Pop-2 or Pop-11, being one of the main inventors of the original
language. (pop@cs.umass.edu)

(b) adding key fields
You say.
>Note that the key contains entries only for certain built-in
>operations.  You cannot, as far as I know, define new operations
>of this sort.
Right. Keys as such are not extendable. However, Pop-11 also includes
"properties", i.e. hash tables, and if you wished to define the notion
of the class_something associated with each key, you'd make
class_something a property, set up the associations, then the syntax for
accessing or changing the class_something of a key would be the same as
for the built in class_ procedures, e.g.

    'funny string' -> class_something(datakey(1))

would do it for the integer key. (Note that properties are treated
as a special type of function, and they therefore have updaters.)

The main limitation of Pop-11 keys is not the lack of extendability but:
    1. There is no notion of a sub-class inheriting features from
        a super-class (though there are OOP libraries)
    2. It is hard to associate a key with a derived data type.
        E.g. there is a key for pairs, but no notion of a key for
        lists, built from pairs. Thus we can't give lists a different
        class_print from pairs (e.g.pairs whose backs are neither pairs
        nor nil).

(c) A minor correction. You say
>If you do
>     set_whatever -> updater(whatever);

> then
>     x -> whatever(y).
> will put x in the whatever part of y.

This is misleading. There need not be any notion of "the whatever
part of y". Strictly the only way to understand

     x -> whatever(y)

is as follows:

    put x on the stack,
    put y on the stack,
    call the updater of whatever

The updater of whatever can be any arbitrary procedure. It need not put
x (or anything else) anywhere, although putting x somewhere associated
with y is the NORMAL use of the updater mechanism.

(d) Another minor correction

You give the following incorrect Pop-11 syntax for defining updaters:

     define updater whatever(newval, object) ... enddefine;

The actual keyword is not "updater" but "updaterof"

This syntax was not available in Pop2 - updaters had to be assigned
explicitly, using the updater of updater.

(e) A point of clarification
>You can do the 'define updater' even if the accessing procedure
>has not yet been defined, which may put some interesting constraints
>on the implementation, but I do not know what the actual
>implementation is.
It's simple. If "whatever" has not been defined, and you do

    define updaterof whatever; ... enddefine;

Then a default un-executable procedure is created for whatever, and the
defined updater is associated with it. So you can do

    x -> whatever(y)

even though the procedure whatever has not been defined, only its
updater. If you try running the procedure


you'll get an error message

    ;;; INVOLVING:  <procedure whatever>

This could be (and probably is) achieved by making the default procedure
the Pop-11 closure:

    mishap(%0,'ONLY UPDATER DEFINED'%);

i.e. the error procedure mishap "partially applied" to the number
0 (no error objects) and the string defining the error. A new closure
would be created for each undefined procedure.

Since in Pop-11 a closure is just a type of procedure (as is an array
or a property), it can be given an updater.

If you later define whatever, itself, then its previously defined
updater is transferred to the new version. This is because any time
you redefine a procedure its old updater (if any) is transferred to the
new procedure so that you don't have to do it explicitly.

Not all users appreciate that the convenience of updaters has a slight
speed penalty compared with having a separate "set" function: an extra
indirection is needed to get the updater. (This is optimised away if the
updater is one defined in the system or declared as a constant procedure
by the user.)