|
1 | 1 | # Higher Order Functions |
2 | 2 |
|
3 | | -Higher order functions, are functions that accept other functions as arguments or return a function it generates. |
| 3 | +Higher order functions are functions that manipulate other functions. |
| 4 | +For example, a function can take other functions as arguments and/or produce a function as its return value. |
| 5 | +Such *fancy* functional techniques are powerful constructs available to you in JavaScript and other high-level languages like python, lisp, etc. |
4 | 6 |
|
5 | | -This is a *fancy* and extremely powerful construct available in JavaScript and other high-level languages (python, lisp, ...) |
6 | | - |
7 | | -Now lets pass our `double` function as an argument to another function called `transform` : |
| 7 | +We will now create two simple functions `add_2` and `double` and higher order |
| 8 | +function called `map(f,list)` which applies the function `f` (the first argument) |
| 9 | +to each of the elements in the array `list` (the second argument). |
8 | 10 |
|
9 | 11 | ```javascript |
10 | | -// Our double function |
| 12 | +// Define two simple functions |
| 13 | +var add_2 = function(x) { |
| 14 | + return x + 2; |
| 15 | +}; |
11 | 16 | var double = function(x) { |
12 | 17 | return 2 * x; |
13 | 18 | }; |
14 | 19 |
|
15 | | -// A function that accepts two arguments |
16 | | -// first the function to call |
17 | | -// second the value to call it on |
18 | | -var transform = function(func, value) { |
19 | | - return func(value); |
| 20 | +// map is cool function that accepts 2 arguments: |
| 21 | +// func the function to call |
| 22 | +// list a array of values to call func on |
| 23 | +var map = function(func, list) { |
| 24 | + var output=[]; // output list |
| 25 | + for(idx in list) { |
| 26 | + output.push( func(list[idx]) ); |
| 27 | + } |
| 28 | + return output; |
| 29 | +} |
| 30 | + |
| 31 | + |
| 32 | +// We use map to apply a function to an entire list |
| 33 | +// of inputs to "map" them to a list of corresponding outputs |
| 34 | +map(add_2, [5,6,7]) // => [7, 8, 9] |
| 35 | +map(double, [5,6,7]) // => [10, 12, 14] |
| 36 | +``` |
| 37 | + |
| 38 | +The functions in the above example were intentionally simple, |
| 39 | +and serves to illustrate that passing functions as arguments |
| 40 | +to other functions allows for flexibility when building things. |
| 41 | + |
| 42 | +For example, if we notice that we use the invocations `map(add_2, ...)` and `map(double, ...)` very often in our code, we could decide we want to create two special-purpse list processors that have the desired operation baked into them. Using function composition, we could do this as follows: |
| 43 | + |
| 44 | +```javascript |
| 45 | +process_add_2 = function(list) { |
| 46 | + return map(add_2, list); |
| 47 | +} |
| 48 | +process_double = function(list) { |
| 49 | + return map(double, list); |
| 50 | +} |
| 51 | +process_add_2([5,6,7]) // => [7, 8, 9] |
| 52 | +process_double([5,6,7]) // => [10, 12, 14] |
| 53 | +``` |
| 54 | + |
| 55 | +Now let's create a function called `buildProcessor` that takes a function `func` as input |
| 56 | +and returns a `func`-processor, that is, a function that applies `func` to each input in list. |
| 57 | + |
| 58 | +```javascript |
| 59 | +// a function that generates a list processor that performs |
| 60 | +var buildProcessor = function(func) { |
| 61 | + var process_func = function(list) { |
| 62 | + return map(func, list); |
| 63 | + } |
| 64 | + return process_func; |
20 | 65 | } |
| 66 | +// calling buildProcessor returns a functoin which is called with a list input |
| 67 | + |
| 68 | + |
| 69 | +// using buildProcessor we could generate the add_2 and double list processors as follows: |
| 70 | +process_add_2 = buildProcessor(add_2); |
| 71 | +process_double = buildProcessor(double); |
21 | 72 |
|
22 | | -// This does the same as double(3) |
23 | | -transform(double, 3); |
| 73 | +process_add_2([5,6,7]) // => [7, 8, 9] |
| 74 | +process_double([5,6,7]) // => [10, 12, 14] |
24 | 75 | ``` |
25 | 76 |
|
26 | | -The above example was intentionally simple, having functions as values grants enormous flexibility and allows for many powerful constructs. |
27 | 77 |
|
28 | | -Now lets create a function called `buildMultiplier` that takes a number `x` and returns a function that multiplies it's argument by `x` : |
| 78 | +Let's look at another example. |
| 79 | +We'll create a function called `buildMultiplier` that takes a number `x` as input and returns a function that multiplies it's argument by x : |
29 | 80 |
|
30 | 81 | ```javascript |
31 | 82 | var buildMultiplier = function(x) { |
|
0 commit comments