-
Notifications
You must be signed in to change notification settings - Fork 0
Functional Programming
Table of content
Modern programming falls into two categories, Imperative (procedural) and declarative (functional). Examples of imperative programming are Object-Oriented Programming (OOP), procedural programming. Examples of declarative programming are functional programming, logic programming, and data processing, but we want to focus on functional programming.
Functional programming means writing code that does something (declares what is done) but isn't specific about doing it (imperative programming).
One specific sentence I saw about functional programming is as follows:
"It doesn't allow any mutation nor shared state, as functions should remain pure and true to their expression under this paradigm." -Sonny Recio
This tells me two things already; One, functional programming shouldn't mutate, and Two; functions should be pure.
One of the essential concepts for functional programming is higher-order functions; functions are values. Meaning you would use a function as a parameter in another function. This is done by assigning a function to a variable. The most well-known HOF is .filter()
Here is an example I created last year.
/* MAP: return an array which only contains the species of the animal
Create a HOF to return species of object array animals*/
const getSpecies = (animal) => {
return animal.species;
}
/* .map creates object of animalSpecies. ex: dog,dog,fish,fish,dog,pig,pig,dog*/
const mappedAnimalSpecies = animals.map(getSpecies)
console.log(`animals contain the following species: ${mappedAnimalSpecies}`)
/* FILTER: return an array which only contains dogs */
const isDog = (animal) => {
return animal.species === 'dog';
}
/* Tables the filtered object of animals by species tag 'dog' and puts it in object */
const filteredDoggyArray = animals.filter(isDog)
Another essential concept of functional programming is pure functions; this means that your function's output should only depend on its inputs.
For example: You have a function called toString, which takes a value as an argument and formats it to a string. This could be made impure by mutating the argument, in this case, a number directly. This could be seen as a side-effect, and functional programming should not create side-effects. Besides this, pure functions should not rely on outside value to produce a returned value.
Pure functions are easier to test and read because nothing happens outside of the function itself.
let value = 1337;
// Pure Function
function toString(value) {
return value.toString();
}
toString(1337);
// Impure Function
function toString() {
value = num; //By mutating the number variable directly
return value.toString();
}
toString();
D. de Vries, cmda-tt, course-20-21
Functional programming is stateless, which means that when data is created, it is never mutated. Most array methods do mutate the array, which we don't want within the paradigm. Instead, you want to return a new array.
D. de Vries, cmda-tt, course-20-21
Composition in functional programming has to create functions in the smallest possible way, so it can be composed to do something more complex. Composition allows for reusability and clear insight of where and what happens.
See example from Danny de Vries in the course page.
const sum = arr => arr.reduce((i, runningSum) => i + runningSum);
const average = (sum, count) => sum / count;
const averageArr = arr => average(sum(arr), arr.length);
The composition can go to another level by dividing the functions into modules, utilities, and more. But don't take it too far as that removes the benefit of composition.
Currying is when a function doesn't take all of its arguments upfront instead it wants to give it the first argument and the function returns another another function which you are supposed to call with the second argument which in turn will return a new function which you are supposed to call with the third argument and so on until all arguments have been provided and the function at the end of the function returns the output. -MPJ, Fun Fun Function
Did you get this? Yeah, I didn't either at first. As MPJ said, the confusion is good. Besides Fun Fun Function, I have also found an article about understanding currying in javascript there. Chidume explains it as a sequence of nesting functions, where it goes through the arity (number of arguments a function takes).
function multiply(a) {
return (b) => {
return (c) => {
return a * b * c
}
}
}
log(multiply(1)(2)(3)) // 6
See the log? That is what currying is, by taking arguments in a chain looking manner and do what the last function returns.
https://medium.com/javascript-in-plain-english/what-are-javascript-programming-paradigms-3ef0f576dfdb https://medium.com/dailyjs/functional-js-6-function-composition-b7042c2ccffa https://blog.bitsrc.io/functional-programming-in-javascript-how-and-why-94e7a97343b https://blog.bitsrc.io/understanding-currying-in-javascript-ceb2188c339
https://github.com/cmda-tt/course-20-21/blob/master/examples/functional-patterns/immutability.md https://github.com/cmda-tt/course-20-21/blob/master/examples/functional-patterns/impure.md https://github.com/cmda-tt/course-20-21/blob/master/examples/functional-patterns/composition.md
Higher-order functions - Part 1 of Functional Programming in JavaScript Currying - Part 6 of Functional Programming in JavaScript