This section illustrates some of the ways in which procedures can be manipulated to create new procedures. We'll create a procedure called double, then show how to combine it with itself to get a new procedure that quadruples. We'll also show how to combine it with a general list-manipulating procedure to produce a new specialised procedure for operating on lists of numbers.
The example will use procedure composition and partial application. Suppose you have a procedure that takes a number and doubles it:
define double(num) -> num;
;;; Double num then return it as a result
num + num -> num;
enddefine;
double(53) =>
** 106
We can combine this procedure with itself to produce a procedure that
calculates quadruples:
(double <> double)(4) =>
** 16
We can also illustrate how the procedure (or function) double can be
given as input to a procedure that takes a list and a procedure, applies
the procedure to every element of the list, and returns a list of the
results. We can define such a "list mapping" procedure thus:
define list_results(list, proc) -> newlist;
lvars item;
[% ;;; start making a list
for item in list do
proc(item) ;;; apply proc to the item
;;; leaving the result on the stack
endfor
;;; now finish making the list of results
%] -> newlist
enddefine;
(There is actually a built in procedure in Pop-11 called maplist, that
does something very similar, except that it includes instructions to
produce an error message if the second argument is not a procedure.)
We can give double as second argument to list_results, thus:
list_results( [1 2 3 4 5], double ) =>
** [2 4 6 8 10]