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) => ** 106We can combine this procedure with itself to produce a procedure that calculates quadruples:
(double <> double)(4) => ** 16We 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]