What is higher order function ?
Functions that operate on other functions, either by taking them as
arguments or by returning them, are called higher-order functions.
Let me start with a small example and then we get back to the problem in the question.
function evenNumberFilter(number) {
return number%2==0
}
function oddNumberFilter(number) {
return !evenNumberFilter(number)
}
evenNumberFilter(2) // true
oddNumberFilter(3) // true
Now we know if we call function
evenNumberFilter with parameter X it will return true if it is even number
oddNumberFilter with parameter X it will return true if it is odd number
Let's extend the problem and say
"I would like to have all even numbers till number 10"
"I would like to have all odd numbers till number 10"
function evenNumberFilter(number) {
return number %2 == 0
}
function oddNumberFilter(number) {
return !evenNumberFilter(number)
}
function evenNumberBeforeTen() {
const result = []
for(number=0; number<10; number++) {
if (evenNumberFilter(number)) {
result.push(number)
}
}
return result
}
function oddNumberBeforeTen() {
const result = []
for(number=0; number<10; number++) {
if (oddNumberFilter(number)) {
result.push(number)
}
}
return result
}
evenNumberBeforeTen(); //[0,2,4,6,8]
oddNumberBeforeTen(); //[1,3,5,7,9]
If we look at the code both evenNumberBeforeTen and oddNumberBeforeTen share good amount of common code
- The way for loop is itereated
- The way result is appended to an array
- The result that is returned at the end of the function.
Only difference between these two functions is, what filter it operates on either evenNumberFilter or oddNumberFilter.
So can we refactor the code and write one generic filter function which can take the predicate as a parameter ?
Predicate: a boolean-valued function P: X? {true, false}.
In our case both evenNumberFilter and oddNumberFilter are
predicates
function evenNumberFilter(number) {
return number %2 == 0
}
function oddNumberFilter(number) {
return !evenNumberFilter(number)
}
function filter(predicate) {
const result = []
for(number=0; number<10; number++) {
if (predicate(number)) {
result.push(number)
}
}
return result
}
filter(evenNumberFilter); //[0,2,4,6,8]
filter(oddNumberFilter); //[1,3,5,7,9]
Now, in the above example function filter is higher order function because it takes function predicate as parameter.
Let's get into the problem you mentioned in the question.
repeat is a higher order function which takes number and function action as a parameter.
unless is a higher order function which takes boolean and function then as a parameter
When you execute
repeat(3, n => {
unless(n%2 == 1, () => {
console.log(`${n} is even`);
});
});
repeat is called first and then it will execute function below 3 times.
function (n) => {
unless(n%2 == 1, () => {
console.log(`${n} is even`);
});
- When above function is called with parameters 0,1,2. It calls
unless function with boolean of n%2==1 which will be either true or false and function below as parameter.
function() => {
console.log(`${n} is even`);
});
When unless is called with true and then it will not execute the then function so no log is printed
When unless is called with false and then it will execute the then function which prints the log