FP
Definition:
Functional programming is a way of writing software applications using only pure functions and immutable values
Main concepts:
Pure functions
Immutability
Functions as first-class entities
Functions composition
High order functions
Recursion
Currying/Memoization
Pure Functions
A pure function is a function that depends only on its declared input parameters and its algorithm to produce its output. It does not read any other values from “the outside world” — the world outside of the function’s scope — and it does not modify any values in the outside world.
Main rules:
Output depends only on input
The function always evaluates to the same result value given the same argument value (Idempotent)
Produce no side effects
Example: Reducer in the Redux
Immutability
The basic definition of immutability is to be unable to change.
Whenever your object would be mutated, don’t do it. Instead, create a changed copy of it
Props of immutability:
Time Travel Debugging (almost free undo/redo)
Performance Boost (on huge datasets with libs or in React world)
Predictability (has no side effects)
Easier to cache (memoize)
Easier to test
Concurrency (can share data between threads without concern over concurrent access. Not a concern in JavaScript)
Cons of immutability:
It needs dependencies to make it right
It is less performant than mutable approach with small datasets
It needs a discipline thorough the team
Example in JS (string, Object.freeze)
Examples in FE (Redux, ImmutableJS, Immer)
ImmutableJS (huge API, good docs, lazy evaluation, performance optimization)
Immer (lightweight, use JS Proxy under the hood, use JS data structures, use sync style, used in Redux toolkit under the hood)
Functions as first-class entities
First-class functions when functions in that language are treated like any other variable. For example, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.
The function that we pass as an argument to another function, is called a Callback Function.
Example: any callback in Array methods
Functions composition
Function composition is the process of combining two or more functions to produce a new function.
Сompose implementation in JS: const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
Pipe implementation in JS: const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
This implementation above is written in a points-free style, which means that it does not identify the arguments on which it operates at all.
Examples: Lodash (compose, flow), used in Redux (compose function), decorators in Storybook,
High order functions
A function that returns a function or composes other functions is called a Higher-Order Function.
Examples in JS: Array methods, Promises, Event handlers, HOC, Closure.
Recursion
Recursion is a programming term that means calling a function from itself. Recursive functions can be used to solve tasks in elegant ways.
Recursion is when a function calls itself until someone stops it.
It can be used instead of a loop.
If no one stops it, it'll recurse forever and crash your program.
A base case is a condition that stops the recursion. Don't forget to add them!
Loops use extra state variables for tracking and counting, while recursion only uses the provided parameters.
When a function calls itself, that’s called a recursion step. The base case of recursion is function arguments that make the task so simple that the function does not make further calls.
A recursively-defined data structure is a data structure that can be defined using itself. (linked list)
Trees like HTML elements tree are naturally recursive: they branch and every branch can have other branches.
Example of using: Walk through HTML tree.
Currying/Memoization
Currying: A function returning another function that might return another function, but every returned function must take only one parameter at a time.
Example: const add = x => y => z => x + y + z;
Example in FE: connect function in Redux, event handling in React.
Partial application: A function returning another function that might return another function, but each returned function can take several parameters.
Example: const add = x => (y, z) => x + y + z;
Example in JS: Function.prototype.bind function.
What is in common: Both currying and partial application functions are not the same functions as the original. They are newly returned functions and take fewer parameters.
What is not in common: Currying takes only one parameter, unlike partial application which can take more than one.
Advantages:
Both of them allow developers to take advantage of lazy evaluation.
gives flexibility on using a different specialized function.
Make use of dependency injection for testing
Disadvantages:
can hit performance for a big amount of complex function
Memoization:
Memoization is a programming technique which attempts to increase a function’s performance (speed up calculations) by caching its previously computed results. Because JavaScript objects behave like associative arrays, they are ideal candidates to act as caches. Each time a memoized function is called, its parameters are used to index the cache. If the data is present, then it can be returned, without executing the entire function. However, if the data is not cached, then the function is executed, and the result is added to the cache.
Props:
computation speed increases
Cons:
memoized solution requires more memory (meaningful for big datasets)
Example: Reselect lib
Last updated
Was this helpful?