Functional programming principles

JavaScript allows us to program in a variety of different ways. Many of the examples we've shared so far in this book have been more inclined towards OOP, which primarily uses objects to express problem domains. Functional programming is different in that it uses mostly pure functions and immutable data to express problem domains. 

All programming paradigms are broadly interested in the same thing: making it easier to express problem domains, to communicate our intent as programmers, and to accommodate the creation of useful and usable abstractions. The best principles we adopt from one paradigm may still apply to another, so adopt an open-minded approach!

It's easiest to observe and discuss the difference between OOP and functional programming by exploring an example. Let's imagine that we wish to build a mechanism so that we can fetch paginated data from a server. To achieve this in an object-oriented way, we might create a PaginatedDataFetcher class:

// An OOP approach

class PaginatedDataFetcher {

constructor(endpoint, startingPage) {
this.endpoint = endpoint;
this.nextPage = startingPage || 1;
}

getNextPage() {
const response = fetch(
`/api/${this.endpoint}/${this.nextPage}`
);
this.nextPage++;
return fetched;
}

}

The following is an example of how you would use the PaginatedDataFetcher class:

const pageFetcher = new PaginatedDataFetcher('account_data', 30);

await pageFetcher.getNextPage(); // => Fetches /api/account_data/30
await pageFetcher.getNextPage(); // => Fetches /api/account_data/31
await pageFetcher.getNextPage(); // => Fetches /api/account_data/32

As you can see, with each call to getNextPage, we retrieve the next page of data. The getNextPage method relies on the remembered state of its objects, endpoint and nextPage, in order to know which URL to request next.

A state can be thought of as the underlying remembered data of any program or piece of code that its results or effects are derived from. The state of a car may mean its current upkeep, its fuel and oil levels, and so on. Likewise, the state of a running program is the underlying data that it derives its functionality from.

Functional programming, as distinct from OOP, is purely interested in the usage of functions and immutable state to achieve its goals. The first mental blocker that people usually encounter when exploring functional programming is related to states, raising questions such as Where should I store my state? and How do I make things change without being able to mutate that state? We can explore this question by looking at the functionally programmed equivalent of the paginated data fetcher.

 We have created a function, getPage, to which we will pass an endpoint and a pageNumber, as follows:

// A more functional approach

const getPage = async (endpoint, pageNumber = 1) => ({
endpoint,
pageNumber,
response: await fetch(`/api/${endpoint}/${pageNumber}`)
next: () => getPage(endpoint, pageNumber + 1)
});

When called, the getPage function will return an object containing the response from the server, as well as the endpoint and pageNumber used. In addition to these properties, the object will also contain a function named next, which itself, if called, will fire off another request via a subsequent call to getPage. It can be used in the following way:

const page1 = await getPage('account_data');
const page2 = await page1.next();
const page3 = await page2.next();
const page4 = await page3.next();

// Etc.

You'll notice that, when using this pattern, we only need a reference to the last retrieved page in order to make the next request. Page 3 is retrieved via page 2's returned next() function. Page 4 is retrieved via page 3's returned next() function. 

Our getPage function does not mutate any data: it only uses the passed data to derive new data, and therefore, it can be said that it employs immutability. It can also be said that it is a pure function as well, in that, with a given set of input parameters (an endpoint and a pageNumber), it will always return the same thing. The next function returned by getPage is also pure, as it will always return the same thing: if I call page2.next() a million times, it'll always fetch page 3.

Functional purity and immutability are among the most vital functional concepts to understand, and, usefully, are principles that are applicable to all paradigms of programming. We're not looking to thoroughly explore functional programming here, but just to cover its most applicable principles in order to bolster our abstraction-crafting abilities.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.188.64