Functional Programming with JavaScript
Published: 2020-07-06 06:50:54

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pgn8pue2mgh8mkfwb761.PNG)

## Overview
Functional programming is a clean, robust alternative to the more typical procedural style of programming.

### First-class functions

#### Examples
```
// define function
var line = console.log
// call function
line("Hello and welcome to the course!")
```
### Higher-order functions

#### Examples
```
const DEBUG_MODE_ENABLED = true
var debug

// define function at debug variable
if (DEBUG_MODE_ENABLED) {
  debug = printDebugMessage
} else {
  debug = doNothing
}

// call function
debug("Some debug message")

// two functions
function printDebugMessage(message) {
  console.log("DEBUG: " + message)
}
function doNothing() { }

```

```
//define function
function ifElse(condition, func1, func2) {
  if (condition) {
    func1()
  } else {
    func2()
  }
}

var x = 1
// call function
ifElse(x === 1, function() {
  console.log("x is 1")
}, function() {
  console.log("x is not 1")
})
```

##### private variables
```
function createCounter() {
  var count = 0
  return {
    increment: function() {
      count += 1
    },
    currentValue: function() {
      return count
    }
  }
}

var myCounter = createCounter()

console.log(myCounter.currentValue())

myCounter.increment()
myCounter.increment()

console.log(myCounter.currentValue())
console.log(myCounter.currentValue())

```
### Array functions

#### Mapping
```
var _ = require("lodash")

var numbers = [ 1, 2, 3, 4, 5 ]
var numbersCubed = _.map(numbers, function(element) {
  return element * element * element
})

console.log(numbersCubed)
```
#### Filtering
```
var _ = require("lodash")

var numbers = [ 1, 2, 3, 4, 5 ]
var evensFromNumbers = _.filter(numbers, function(element) {
  return element % 2 === 0
})

console.log(evensFromNumbers)
```

```
var _ = require("lodash")

var employees = [
  { name: "John",  salary: 50000  },
  { name: "Susan", salary: 60000  },
  { name: "Greg",  salary: 100000 },
  { name: "Mary",  salary: 120000 }
]

var dueForARaise = _.filter(employees, function(employee) {
  return employee.salary < 70000
})

console.log(dueForARaise)
```

#### Every/some
```
var _ = require("lodash")

var numbers = [ 3, 5, 7, 9, 11, 13 ]

var arrayContainsEven = _.some(numbers, function(element) {
  return element % 2 === 0
})

var arrayIsAllEven = _.every(numbers, function(element) {
  return element % 2 === 0
})

console.log("Array contains even?: " + arrayContainsEven)
console.log("Array is all even?: " + arrayIsAllEven)
```

#### Reduce
```
var _ = require("lodash")

var shoppingList = [
  { name: "Eggs",    price: 4.99 },
  { name: "Milk",    price: 3.99 },
  { name: "Bananas", price: 2.79 },
  { name: "Beer",    price: 6.99 }
]

var totalCost = _.reduce(shoppingList, function(acc, item) {
  return acc + item.price
}, 0)

console.log(totalCost)
```

#### combine map, filter, reduce
```
var _ = require("lodash")

var employees = [
  { name: "John",   salary: 60000,  age: 27, gender: 'M' },
  { name: "Mary",   salary: 110000, age: 50, gender: 'F' },
  { name: "Susan",  salary: 50000,  age: 21, gender: 'F' },
  { name: "Greg",   salary: 100000, age: 45, gender: 'M' },
  { name: "Jerry",  salary: 90000,  age: 39, gender: 'M' },
  { name: "Barb",   salary: 95000,  age: 36, gender: 'F' }
]

var males = _.filter(employees, function(employee) {
  return employee.gender === 'M'
})
var maleAges = _.map(males, function(male) {
  return male.age
})
var maleAgeTotal = _.reduce(maleAges, function(acc, age) {
  return acc + age
})
var maleAgeAverage = maleAgeTotal / males.length

console.log("Average male age: " + maleAgeAverage)
```
### Callbacks with arguments

#### pass arguments example
```
function add(x, y, z) {
  return x + y + z
}

function partiallyApply(func, x, y) {
  return function(z) {
    return func(x, y, z)
  }
}

var add5and2 = partiallyApply(add, 5, 2)

console.log(add5and2(3))
console.log(add(5, 2, 3))
```
#### recursive function example
```
function loop(i) {
  console.log("i is " + i)
  if (i < 10) {
    loop(i + 1)
  }
}

loop(0)
```