HELP UPDATER Updated. A. Sloman, April 1985 updater() -> ; -> updater(); A procedure for accessing a data structure has two independent tasks to perform. One is to extract the contents of the appropriate component; the other is to change the contents of the components. Thus: hd(x) -> v; ;;; get HD of x and assign it to v v -> hd(x); ;;; set the value of v to be the HD of x Two separate procedures are therefore needed; one called the SELECTOR procedure (in this case HD) and the other its updater (i.e. updater(hd)). The updating procedure is stored as one component of the selector procedure, as is the *PDPROPS. When a procedure call follows an assignment arrow (i.e. ->) the updater part of the procedure is called, so that instead of executing: v -> f(x); we could execute: updater(f)(v,x); Updaters take their arguments off the stack (see *HELP STACK) in the same way as other procedures. Moreover, items occuring before the assignment arrow are merely additional arguments for the updater. So x,y -> f(p,q,r) is equivalent to -> f(x,y,p,q,r) and to: x,y,p,q,r -> f(); If we call the updater of f, g, updater(f) -> g; then the above are also equivalent to: g(x,y,p,q,r) Most procedures, of course, have no updater. If we define a new data structure accessing procedure it is sensible to give it an updater, for example: define second(list); hd(tl(list)) enddefine; define setsecond(value,list); value -> hd(tl(list)) enddefine; setsecond -> updater(second); vars l; [a b c d] -> l; second(l) => ** b "e" -> second(l); l => ** [a e c d] A more convenient syntax for declaring updaters uses 'define updaterof': define updaterof second(value, list); value -> hd(tl(list)) enddefine; Just as DEFINE sets the PDPROPS of a procedure to be its name, so DEFINE UPDATEROF sets the PDPROPS of the UPDATER to be the name of the procedure. Every POP-11 procedure has a 'slot' available for an updater - not only procedures associated with fields of data-structures. However, for most procedures the default updater is merely a procedure which produces an error. define test(x); x * x enddefine; test(3) => ** 9 9 -> test(3); ;;; MISHAP - EXECUTING NON-EXISTENT UPDATER ;;; INVOLVING: ;;; DOING : compile nextitem popval compile Thus if a procedure has not been given an updater, and your program attempts to run its updater, an error message will result. Since every procedure can have an updater, the use of updaters is not restricted to procedures which access fields of data-structures. Updaters can be used to associate two procedures which do related computations. For instance if procedure F does some elaborate computation to solve a problem, the updater of F could then be used to store a solution to be found by F by direct lookup. See also HELP *DEFINE - for form and content of procedure definitions *PDPROPS - stores information about a procedure (its name etc.) *EFFICIENCY - has a comment on using updater loops *CLOSURES - are procedures and therefore can have updaters. *PARTAPPLY - for further information on creating closures.