12.6.1 Complementing A Function
12.6.1 Complementing A Function
We write a function complement that takes a reference to a function and returns a reference to a function that behaves as a mathematical complement of the input function. The definition of this function is given below.
Program 12.28
sub complement{
my $fn = $_[0];
my $complementFRef = sub {
my $res = funcallS $fn, $_[0];
return !$res;
};
return $complementFRef;
}
This function creates a local my variable called $complementFRef that is assigned the value of an anonymous function created inside the function. This anonymous function remembers the value of the variable $fn that contains the reference to a function passed to the complement function. This remembering is done because of the property of closures. The anonymous function calls the remembered function referenced by $fn on a scalar parameter passed to the anonymous function. The anonymous function returns the negation of this call. Therefore, whenever the function referenced by $fn returns true, the anonymous function returns false, and vice versa. For purposes of our code here, we assume that 1 represents true and 0 represents false.
A call to the complement function is the following.
funcallS (complement $between10and45P, 90)
This call returns a result of 1. The predicate function referenced by $between10and45P was defined earlier in the chapter. It returns true if the scalar parameter given to it is a number between 10 and 45. The complement of this function is obtained by the following call.
complement $between10and45P
This call returns a reference to a function that behaves like the mathematical complement of the function referenced by $between10and45P. This complement function is called with the parameter 90 using the funcallS function we have defined earlier. funcallS returns 1 because the function referenced by $between10and45P returns false or 0.
Another call to the complement function is seen below.
find (complement (\&biggerThan10P), 10, 2, 30, 45, 7)
Here we use the find function defined earlier. The function biggerThan10P has also been defined earlier. \&biggerThan10P returns a reference to the function biggerThan10P and this reference is given as parameter to complement. complement returns a reference to a new function that acts like the mathematical complement of its input. find culls all those elements of the list of numbers given to it that satisfy the function whose reference is given to it as the first parameter. In this case, that means that the call to find
returns all those elements that do not satisfy the function biggerThan10P. Consequently, the call to find returns the list containing the numbers 10, 2, and 7.
A final illustrative use of complement is seen below.
find (complement ($between10and45P), 10, 2, 30, 45, 7)
This call to find returns all those numbers from the list given that satisfy the complement of the function referenced by $between10and45P. As a result, the call returns the list
10 2 45 7
