Now suppose we wanted to do the same using not double, but a procedure that produces the double of the double, i.e. one that quadruples its input. We can create such a procedure by composing double with itself, thus:
(double <> double)(2) => ** 8and we can give that procedure as the second argument input to list_results:
list_results([1 2 3 4 5], double <> double) => ** [4 8 12 16 20]Now if we want to make a procedure that takes a list of numbers, and creates a new list containing the quadruples of all those numbers we can partially apply list_results to a procedure made by composing double with itself, e.g.
vars quadruple_elements = list_results(% double <> double %);or, equivalently
define quadruple_elements = list_results(% double <> double %) enddefine;so
quadruple_elements([1 2 3 4 5]) => ** [4 8 12 16 20]Incidentally, this is equivalent to
list_results( list_results( [1 2 3 4 5], double ), double ) =>or
[1 2 3 4 5], double, list_results(), double, list_results() =>(as explained in Chapter 3.)
Here we have invoked list_results twice. This creates a list of doubles, then a new list of doubles of the doubles. This is wasteful because creating the intermediate temporary list uses up space that is not needed again and will have to be reclaimed by the Pop-11 garbage collector. This is one of many examples of ways in which two mathematically equivalent methods of doing something may be very different in terms of efficiency. (See also HELP EFFICIENCY)