This is the curriculum for the 2018 Foxtrot Web Developer Bootcamp.

Higher Order Functions

Higher order functions are simply functions that take other functions as arguments. In javascript, which supports higher order functions, you can assign functions to variables, and pass them around like any other variables. Higher order functions are what allow us to practice the principles we've been talking about so far. We can write declarative, functional programs that pass functions around to do our work using higher order functions.

What is a higher order function? Let's look at filter() as an example.

Consider this array of objects:

let muppets = [
  {name: 'Doc', type: 'bear'},
  {name: 'Fozzie', type: 'bear'},
  {name: 'Kermit', type: 'frog'},
  {name: 'Scooter', type: 'human'}
]

How would we get a list of all the bears in the list above using a for loop?

var bears = []
for(var i=0; i < muppets.length; i++){
  if(muppets[i].type === 'bear'){
    bears.push(muppets[i])
  }
}

This code isn't very functional because its continually manipulating the state of the bears array, and its not declarative either. We're coding the 'how' instead of the 'what'.

Using filter(), which is a higher order function, we can be both declarative and functional.

let bears = muppets.filter((muppet)=>{
  return muppet.type === 'bear'
})

This function takes a callback function that does the comparison. We could write it this way to make that even clearer:

let isABear = (muppet) => {
  return muppet.type === 'bear'
}
let bears = muppets.filter(isABear)

Here we create a new variable isABear, and assign a function to it. Then we pass the variable into the filter function as a callback.

Less code === Less bugs

One of the main advantages of writing code in a declarative style is that we most often write a lot less code overall, and this is a very good thing. Writing less code means we have fewer opportunities to write bugs.

Challenge

1) Using filter(), refactor the following code from an imperative style to a declarative one:
2) Refactor your code to use the same matching function for both signed and unsigned operations

let contracts = [
  {name: "rental agreement", signed: true},
  {name: "car loan", signed: false},
  {name: "health insurance", signed: false},
  {name: "employment", signed: true}
]

function getSigned(contracts){
  let signed = []
  for(var i=0; i<contracts.length; i++){
    if(contracts[i].signed){
      signed.push(contracts[i])
    }
  }
  return signed
}


function getUnSigned(contracts){
  let signed = []
  for(var i=0; i<contracts.length; i++){
    if(!contracts[i].signed){
      signed.push(contracts[i])
    }
  }
  return signed
}

Iterables Tasklist Challenge

Fork the JS Fundamentals github repo: JS Fundamentals

Try the following exercises:

map-vs-for-loop.js
map-vs-for-loop_practice.js
array-methods-practice.js
array-methods-with-callbacks-practice.js

Or, get some review:
loops.js
loops_practice.js
objects.js
var-const-let.js
objects-practice-1.js
functions-practice.js