## DEV Community is a community of 848,284 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Animesh Pandey

Posted on • Updated on

# Fundamentals of Functional JavaScript

## Introduction

Is Functional Programming any style of code that utilizes functions? If only it was that simple!
Functions are indeed at the core of Functional Programming, but it's how we use those functions that make our implementation functional.

This article aims to lay down some fundamentals of Functional Programming, while mainly pertaining to their application in `JavaScript`, that will help you understand :

1. What are Functions?
2. Functions versus Procedures
3. Declarative versus Imperative Programming
4. Understanding Function Inputs and Outputs

These foundations will immensely aid you in grasping further concepts of Functional JavaScript, to be covered in future articles, if this one helps.

The next article will cover :

1. Function Purity (Pure versus Impure Functions)
2. Side Effects
3. Extracting and Containing Impurity
4. How all of this collectively defines what Functional Programming is, and why it is used
5. Is `JavaScript` a Functional Programming Language?
6. Why consider Functional Programming style for your code?

Stay tuned!

## 1. What are Functions?

Well, like any introductory programming class will tell you, a function is a reusable piece of code that performs some task upon execution. While this definition is reasonable, it misses out an important perspective that is the core of a function as it applies to Functional Programming.

Let's try to understand Functions more completely, with the example of very basic Mathematics.

You may remember reading about `f(x)` in school, or the equation `y = f(x)`.
Let's assume the equation `f(x) = x2 - 1`. What does that mean? What does it mean to graph that equation? Here's the graph:

It's equivalent to :

``````function f(x) {
return Math.pow(x,2) - 1;
}
``````

What you can notice is that for any value of `x`, say `1`, if you plug it into the equation, you get `0`. What is `0`, though? It's the return value of the `f(x)` function, which we earlier said represents a `y` value.

In math, a function always takes input(s), and always gives an output. A term you'll often hear around FP is "morphism"; this is a fancy way of describing a set of values that maps to another set of values, like the inputs of a function related to the outputs of that function.

In our code, however, we can define functions with all sorts of input(s) and output(s), even though they'll rarely be interpreted as a visually plotted curve on a graph.

As such, a more complete definition of function would be :

A function is the semantic relationship between input and computed output.

Also note the usage of `function` and function throughout this article. While function is the concept we're discussing, `function` is just the `JavaScript keyword`.

Essentially, Functional Programming is about embracing using `functions` as functions in this mathematical sense.

## 2. Functions vs Procedures?

The terms Functions and Procedures are often used interchangeably, but they actually mean different things.

A Procedure is an arbitrary collection of functionality. It may have inputs, it may not. It may have an output (as a `return` value), it may not.

Whereas, a Function takes input(s) and definitely always has a `return` value.

For Functional Programming, we use functions as much as possible, and trying to avoid procedures wherever possible. All your functions should take input(s) and return output(s).

Based upon this knowledge, let's consider the following example :

``````// Example 1: Function or Procedure?

function addPokémon(team1 = 0, team2 = 0, team3 = 0) {
var total = team1 + team2 + team3;
console.log(total);
}

function countPokémon(currentTeam = 6, ...args) {
}

countPokémon();
// Output : 6

countPokémon(6, 5, 6);
// Output : 17
``````

Try to assess whether `function` `addPokémon` and `countPokémon` are functions or procedures?

Here are some basic observations :

1. `addPokémon` has a defined input, but no output specified by `return`. It should be a procedure.
2. `countPokémon` has a defined input and a defined `return`, so it should be a function?

We're correct about `addPokémon` being a procedure, but `countPokémon` is also a procedure, and not a function, since it makes a call to a procedure within itself.

In summary :

Note that a `function` that calls a procedure within itself, is also a procedure. The "impurity" of a procedure, which is a concept to be explained further down, trickles down and "pollutes" all those who directly or indirectly call it.

Now, we would probably like to understand how to convert the last example's procedures into functions?

Based on the more complete definition of a function mentioned in the last section, try to make changes to the last example, before looking ahead for one of many possible solutions. For this example, it should be pretty straight-forward.

``````// Example 2: Converting Procedures to Functions?

function addPokémon(team1 = 0, team2 = 0, team3 = 0) {
var total = team1 + team2 + team3;
// Instead of logging a value, we returned it,
// so there's a proper output/return now.
}

function countPokémon(currentTeam = 6, ...args) {
// Now, a call to a function, not a procedure, is returned
}

console.log(countPokémon());
// Output : 6

console.log(countPokémon(6, 5, 6));
// Output : 17
``````

Let's look at one more example for differentiating procedures and functions.

``````// Example 3. Identifying functions and procedures

function neighbouringPokémonID(x) {
x = Number(x);
return [x - 1, x + 1];
}

function generateNeighboursForTeam(team) {
var teamIDs = Object.keys(team);
teamIDs.forEach(element =>
console.log(neighbouringPokémonID(element)));
}

var myTeam = {
25: "Pikachu",
155: "Cyndaquil"
};

generateNeighboursForTeam(myTeam);
// Output :
// [24, 26]
// [154, 156]
``````

This snippet effectively returns the Pokédex IDs of the immediate neighbours of a Pokémon, given its own ID.

Clearly, `neighbouringPokémonID` is a function, as it has an input and `return`s an output based upon it.

Also, `generateNeighboursForTeam` is a procedure, as it doesn't `return` anything.

Once again, we can modify this example such that both are functions.

``````// Example 4. Converting the procedure to a function

function neighbouringPokémonID(x) {
x = Number(x);
return [x - 1, x + 1];
}

function generateNeighboursForTeam(team) {
var teamIDs = Object.keys(team);
var neighbourIDs = [];
// Use a temporary array to store computation
teamIDs.forEach(element =>
neighbourIDs.push(neighbouringPokémonID(element)));
return neighbourIDs;
}

var myTeam = {
25: "Pikachu",
155: "Cyndaquil"
};

generateNeighboursForTeam(myTeam);
// Output :
// [[24, 26],[154, 156]]
``````

## 3. Declarative vs Imperative Programming?

Another basic concept to be familiar with is, the distinction between Declarative and Imperative styles of coding, which is honestly a bit relative in its meaning.

There's no style that's absolutely Declarative or absolutely Imperative. It's a spectrum in itself.

That said, let's introduce ourselves to a common, simple definition.

Imperative programming is like how you do something, and Declarative programming is more like what you do.”

It's a bit ambiguous and open-ended, so let's take a small example.

Declarative: Throw a pokéball when the pokémon is weak. (What to do)

Imperative: When the health bar of the pokémon is below 30%, press X to throw a pokéball. (Exactly how to do it)

In general, explicitly listing out all the steps one by one, is Imperative. It's rather robotic to understand, and requires going through it line by line.

And utilizing some level of abstraction and trusted helper functions, to list the steps in a manner in which it only presents the basic idea, is Declarative. It's easier to understand, as we don't need to bother about how something is happening, rather what is happening.

As what and how can be rather subjective, we can't draw a hard boundary around what is declarative or imperative.

For example, for a person programming in machine language, which is super imperative, Java can seem rather declarative. Or for a person who works on a purely functional language, like Haskell or Clojure, even functional implementations in JavaScript can feel rather imperative.

Our concern at the moment, which is to set the foundations of Functional Programming and Functional JavaScript, we need to understand that we should make our code as declarative as possible, by utilizing functions.

Moving on, let's understand a bit more about Function Inputs and Outputs.

## 4. Function Inputs

This section covers some more aspects of Function Inputs, chiefly :

• Arguments and Parameters
• Defaulting Parameters
• Counting Inputs
• Arrays of Arguments
• Parameter Destructuring
• Benefits of Declarative Style
• Named Arguments
• Unordered Parameters

Let's get started.

### a. Arguments and Parameters

There's often a slight confusion about the difference between arguments and parameters.

Put simply, arguments are the values you pass into a `function`, and parameters are the named variables inside the `function` that receive those values.

Note: In JavaScript, the number of arguments do not need to match the number of parameters. If you pass more arguments than you have declared parameters to receive them, the values pass in just fine.

These extra arguments can be accessed in a few ways, including the `args` object. If you pass fewer arguments, each unmatched parameter is assigned `undefined`.

### b. Defaulting Parameters

Parameters can declare default values. In the case where the argument for that parameter is not passed, or it's passed the value `undefined`, the default assignment expression is substituted.

``````function f(x = 10) {
console.log(x);
}

f();                // Output : 10
f(undefined);       // Output : 10
f(null);            // Output : null
f(0);               // Output : 0
``````

It's always a good practice to think about any default cases that can aid the usability of your functions.

### c. Arity, or Count of Inputs

The number of arguments a `function` "expects" is determined by the number of parameters that are declared.

``````function f(x,y,z,w) {
// something
}

f.length;
// Output :
// 4
``````

`f(..)` expects `4` arguments, as it has `4` declared parameters. This count has a special term: Arity, which is the number of parameters in a `function` declaration. The arity of `f(..)` is `4`.

Furthermore, a `function` with arity 1 is additionally called unary, a `function` with arity 2 is also called binary, and a `function` with arity 3 or higher is named n-ary.

The `length` property of that `function` reference returns its arity.

While this may sound simple, the implications are far-reaching.

One reason for determining the arity during execution would be if a piece of code received a function reference from multiple sources, and has to send different values depending on the arity of each.

For example, let's say a `fn` function reference could expect one, two, or three arguments, but you always want to just pass a variable `x` in the last position:

``````// `fn` is set to some function reference
// `x` exists with some value

if (fn.length == 1) {
fn(x);
}
else if (fn.length == 2) {
fn(undefined, x);
}
else if (fn.length == 3) {
fn(undefined, undefined, x);
}
``````

Tip: The `length` property of a function is read-only and it's determined at the time you declare the function. It should be thought of as essentially a piece of metadata that describes something about the intended usage of the function.

One gotcha to be aware of is that certain kinds of parameter list variations can make the `length` property of the function report something different than you might expect:

``````function foo(x,y = 2) {
// something
}

function bar(x,...args) {
// something
}

function baz( {a,b} ) {
// something
}

foo.length;             // Output : 1
bar.length;             // Output : 1
baz.length;             // Output : 1
``````

What about counting the number of arguments the current function call received? This was once trivial, but now the situation is slightly more complicated. Each function has an `arguments` object (array-like) available that holds a reference to each of the arguments passed in. You can then inspect the `length` property of `arguments` to figure out how many were actually passed:

``````function f(x,y,z) {
console.log(arguments.length);
}

f(3, 4);
// Output :
// 2
``````

As of ES5 (and strict mode, specifically), `arguments` is considered by some to be sort of deprecated; many avoid using it if possible. However, `arguments.length`, and only that, is okay to keep using for those cases where you need to care about the passed number of arguments.

A function signature that accepts an indeterminate amount of arguments is referred to as a variadic function.

Say you do need to access the arguments in a positional array-like way, possibly because you're accessing an argument that doesn't have a formal parameter at that position. How do we do it?

ES6 to the rescue! Let's declare our function with the `...` operator, referred to as "spread", "rest", or "gather":

``````function f(x,y,z,...args) {
// something
}
``````

The `...args` in the parameter list is an ES6 declarative form that tells the engine to collect all remaining arguments (if any) not assigned to named parameters, and put them in a real array named `args`. `args` will always be an array, even if it's empty. But it will not include values that are assigned to the `x`, `y`, and `z` parameters, only anything else that's passed in beyond those first three values.

``````function f(x,y,z,...args) {
console.log(x, y, z, args);
}

f();                // undefined undefined undefined []
f(1, 2, 3);         // 1 2 3 []
f(1, 2, 3, 4);      // 1 2 3 [ 4 ]
f(1, 2, 3, 4, 5);   // 1 2 3 [ 4, 5 ]
``````

So, if you want to design a function that can account for an arbitrary number of arguments, use `...args`.

You can use the `...` operator in the parameter list even if there are no other formal parameters declared.

``````function (...args) {
// something
}
``````

`args` will now be the complete array of arguments, whatever they are, and you can use `args.length` to know exactly how many arguments have been passed in.

### d. Arrays of Arguments

What if you wanted to pass along an array of values as the arguments to a function call?

``````function f(...args) {
console.log(args[3]);
}

var arr = [1, 2, 3, 4, 5];
f(...arr);
// Output :
// 4
``````

Our new friend, the `...` operator is used here, but now not just in the parameter list; it's also used in the argument list at the call-site.

It has the opposite behavior in this context.
In a parameter list, we said it gathered arguments together. In an argument list, it spreads them out. So the contents of `arr` are actually spread out as individual arguments to the `f(..)` call.

Also, multiple values and `...` spreadings can be interweaved, as needed:

``````var arr = [2];

f(1, ...arr, 3, ...[4,5]);
// Output :
// 4
``````

Think of `...` in this symmetric sense: in a value-list position, it spreads. In an assignment position -- like a parameter list, because arguments get assigned to parameters -- it gathers.

`...` makes working with arrays of arguments much easier.

### e. Parameter Destructuring

Consider the variadic `f(..)` from the previous section:

``````function f(...args) {
// something
}

f( ...[1,2,3]);
``````

What if we wanted to change that interaction so the caller of our function passes in an array of values instead of individual argument values? Just drop the two `...` usages:

``````function f(args) {
// something
}

f([1,2,3]);
``````

Simple enough. But what if now we wanted to give a parameter name to each of the first two values in the passed-in array? We aren't declaring individual parameters anymore, so it seems we lost that ability.

Thankfully, ES6 destructuring is the answer. Destructuring is a way to declare a pattern for the kind of structure (object, array, etc.) that you expect to see, and how decomposition (assignment) of its individual parts should be processed.

Consider:

``````function f([x,y,...args] = []) {
// something
}

f([1,2,3]);
``````

Do you spot the `[ .. ]` brackets around the parameter list now? This is called array parameter destructuring.

In this example, destructuring tells the engine that an array is expected in this assignment position (aka parameter). The pattern says to take the first value of that array and assign it to a local parameter variable called `x`, the second to `y`, and whatever is left is gathered into `args`.

### f. Benefits of Declarative Style

Considering the destructured `f(..)` we just looked at, we could instead have processed the parameters manually:

``````function f(params) {
var x = params[0];
var y = params[1];
var args = params.slice(2);
// something
}
``````

But here we highlight a principle that declarative code communicates more effectively than imperative code.

Declarative code (for example, the destructuring in the former `f(..)` snippet, or the `...` operator usages) focuses on what the outcome of a piece of code should be.

Imperative code (such as the manual assignments in the latter snippet) focuses more on how to get the outcome. The outcome is coded there, but it's not as clear because it's crowded by the details of how we got there.

The earlier `f(..)` is regarded as more readable, because the destructuring hides the unnecessary details of how to manage the parameter inputs.

Wherever possible, we should strive for declarative, self-explanatory code.

### g. Named Arguments

Just as we can destructure array parameters, we can destructure object parameters:

``````function f({x,y} = {}) {
console.log(x, y);
}

f({
y: 3
});
// Output :
// undefined 3
``````

We pass in an object as the single argument, and it's destructured into two separate parameter variables `x` and `y`, which are assigned the values of those corresponding property names from the object passed in. It didn't matter that the `x` property wasn't on the object; it just ended up as a variable with `undefined` like you'd expect.

With a normal call-site like `f(undefined,3)`, position is used to map from argument to parameter; we put the `3` in the second position to get it assigned to a `y` parameter.

But at this call-site where parameter destructuring is involved, a simple object-property indicates which parameter (`y`) the argument value `3` should be assigned to.

Some languages have an explicit feature for this: named arguments. In other words, at the call-site, labeling an input value to indicate which parameter it maps to. JavaScript doesn't have named arguments, but parameter object destructuring is the next best thing.

### h. Unordered Parameters

Another key benefit is that named arguments, by virtue of being specified as object properties, are not fundamentally ordered. That means we can specify inputs in whatever order we want:

``````function f({x,y} = {}) {
console.log(x, y);
}

f({
y: 3
});
// Output :
// undefined 3
``````

The call-site is no longer cluttered by ordered-placeholders like `undefined` to skip a parameter.

## Function Outputs

This section covers some more aspects of Function Outputs.

In JavaScript, `functions` always `return` a value. These three functions all have identical `return` behavior:

``````function foo() {}

function bar() {
return;
}

function baz() {
return undefined;
}
``````

The `undefined` value is implicitly `returned` if you have no `return` or if you just have an empty `return;`.

But keeping as much with the spirit of Functional Programming function definition as possible -- using functions and not procedures -- our functions should always have outputs, which means they should explicitly `return` a value, and usually not `undefined`.

A `return` statement can only return a single value. So if your function needs to return multiple values, your only viable option is to collect them into a compound value like an array or an object:

``````function f() {
var retValue1 = 1;
var retValue2 = 3;
return [retValue1, retValue2];
}
``````

Then, we'll assign `x` and `y` from two respective items in the array that comes back from `f()`:

``````var [x, y] = f();
console.log(x + y);
// Output : 4
``````

Collecting multiple values into an array (or object) to return, and subsequently destructuring those values back into distinct assignments, is a way to transparently express multiple outputs for a function.

Let's cover some concepts related to Function Outputs, chiefly :

• Early Returns
• Un`return`ed Outputs
• Higher-Order Functions (HOFs or Functions of Functions)

### a. Early Returns

The `return` statement doesn't just return a value from a `function`. It's also a flow control structure; it ends the execution of the `function` at that point.

A `function` with multiple `return` statements thus has multiple possible exit points, meaning that it may be harder to read a function to understand its output behavior if there are many paths that could produce that output.

Consider:

``````function f(x) {
if (x > 10) return x + 1;

var y = x / 2;

if (y > 3) {
if (x % 2 == 0) return x;
}

if (y > 1) return y;

return x;
}

f(2);    // Output : 2
f(4);    // Output : 2
f(8);    // Output : 8
f(12);   // Output : 13
``````

First off, `f(x)` is highly unreadable and difficult to follow. Dry-running this in your mind is quite tedious. That's because we're using `return` not just to return different values, but also as a flow control construct to quit a function's execution early in certain cases.

Consider this version of the code:

``````function f(x) {
var retValue;

if (retValue == undefined && x > 10) {
retValue = x + 1;
}

var y = x / 2;

if (y > 3) {
if (retValue == undefined && x % 2 == 0) {
retValue = x;
}
}

if (retValue == undefined && y > 1) {
retValue = y;
}

if (retValue == undefined) {
retValue = x;
}

return retValue;
}
``````

This version is unquestionably more verbose. But it is slightly simpler logic to follow, because every branch where `retValue` can get set is guarded by the condition that checks if it's already been set.

Rather than `return`ing from the function early, we used normal flow control (`if` logic) to determine the `retValue`'s assignment. At the end, we simply `return retValue`.

In summary, it's more readable to have just a single `return` at the end. Try to figure out the most explicit way to express the logic.

### b. Un`return`ed Outputs

One technique that you've probably used in most code you've written, and maybe didn't even think about it much, is to have a function output some or all of its values by simply changing variables outside itself.

Remember our `f(x) = x2 - 1` function from earlier? We could have defined it like this in JS:

``````var y;
function f(x) {
y = (2 * Math.pow( x, 2 )) + 3;
}
``````

We could just as easily have `return`d the value instead of setting it into `y` from within the function:

``````function f(x) {
return (2 * Math.pow( x, 2 )) + 3;
}
``````

Both functions accomplish the same task, so is there any reason we should pick one version over the other?

One way to explain the difference is that the `return` in the latter version signals an explicit output, whereas the `y` assignment in the former is an implicit output.

But changing a variable in an outer scope, as we did with the `y` assignment inside of `f(..)`, is just one way of achieving an implicit output. A more subtle example is making changes to non-local values via reference.

Consider:

``````function sum(list) {
var total = 0;
for (let i = 0; i < list.length; i++) {
if (!list[i]) list[i] = 0;
total = total + list[i];
}
}

var nums = [ 1, 3, 9, 27, , 84 ];
sum(nums);
// Output :
// 124
``````

The most obvious output from this function is the sum `124`, which we explicitly `return`ed. But instead of an `undefined` empty slot value in position `4`, now there's a `0`.

The harmless looking `list[i] = 0` operation ended up affecting the array value on the outside, even though we operated on a local `list` parameter variable.

Why? Because `list` holds a reference-copy of the `nums` reference, not a value-copy of the `[1,3,9,..]` array value. JavaScript uses references and reference-copies for arrays, objects, and functions, so we may create an accidental output from our function all too easily.

This implicit function output has a special name in the FP world: Side Effects. And a function that has no side effects also has a special name: Pure Function. Both these concepts will be covered in the next article.

### c. Higher-Order Functions (HOFs or Functions of Functions)

Functions can receive and return values of any type. A function that receives or returns one or more other function values has the special name: higher-order function.

Consider:

``````function forEach(list,fn) {
for (let v of list) {
fn( v );
}
}

forEach( [1,2,3,4,5], function each(val){
console.log( val );
} );

// Output :
// 1 2 3 4 5
``````

`forEach(..)` is a higher-order function because it receives a function as an argument.

A higher-order function can also output another function, like:

``````function f() {
return function upper(x){
return x.toUpperCase();
};
}

var g = f();
g("Hello!");

// Output :
// HELLO!
``````

`return` is not the only way to "output" an inner function:

``````function f() {
return g(function upper(x){
return x.toUpperCase();
} );
}

function g(func) {
return func("Hello!");
}

f();

// Output :
// HELLO!
``````

Functions that treat other functions as values are higher-order functions by definition. These are very crucial to Functional Programming!

## Summary

1. What are Functions?
2. Functions versus Procedures
3. Declarative versus Imperative Programming
4. Function Inputs
• Arguments and Parameters
• Defaulting Parameters
• Counting Inputs
• Arrays of Arguments
• Parameter Destructuring
• Benefits of Declarative Style
• Named Arguments
• Unordered Parameters
5. Function Outputs
• Early Returns
• Un`return`ed Outputs
• Higher-Order Functions (HOFs or Functions of Functions)

The next article will cover :

1. Function Purity (Pure versus Impure Functions)
2. Side Effects
3. Extracting and Containing Impurity
4. How all of this collectively defines what Functional Programming is, and why it is used
5. Is `JavaScript` a Functional Programming Language?
6. Why consider Functional Programming style for your code?

### Credits

• Functional-Light JS book by Kyle Simpson, for inspiring this article, as well as,
• FrontEnd Masters : Functional-Light JavaScript

## Discussion (34)

I find FP to be intriguing, but I have been making apps with Svelte lately. I find it difficult to use FP patterns with a framework that is based on a MVVM pattern. How can I make use of FP with MVVM?

I am looking forward to the rest of the articles in this series. Thank you for doing this!

Animesh Pandey

Agreed. FP patterns, in general, can sometimes be difficult to implement with many frameworks. In that case, we can only try our best to accommodate them. Perhaps, I'll try to cover this by taking examples of some common frameworks. I personally haven't worked with Svelte yet, I'll check it out sometime.

In my own view, a framework that doesn't allow enough freedom to try various design patterns, is too restrictive to work with; since it basically feeds you its own guidelines at that point, and forces you to only think along those lines.

This might be a good idea to cover later. Thanks for the suggestion!

And, thank you for enjoying this! It takes a lot of time to put these together, but it is very rewarding if it helps even one person out.

myleftshoe

Have you seen cyclejs? Didn't/hasn't really taken off - possibly because it's too far from the norm. It's a "framework" that suffers the opposite restrictiveness problem to most others - forces you to think functionally

Animesh Pandey

Ah, no hadn't heard of it yet. It looks really interesting from an overview of its docs. Time to try it out someday? Thanks for sharing!

myleftshoe

Check out the authors videos about it too - really good

Animesh Pandey

myleftshoe

Sorry, haven't got the link anymore but there's one where he describes the philosophy behind it

myleftshoe
Animesh Pandey

Oh my. It is ultra insightful! Will have to go through it a couple of times to properly appreciate.

John Kazer

Might also like Hyperapp

Animesh Pandey

Thanks!

Marwan El Boussarghini • Edited on

Very cool article thanks for writing it. I'm also super enthusiastic about FP and it's good that people write content about it 😄

About the section "a. Early Returns" I tend to disagree with you: let's take this code

``````function getPokemonWeaknesses({ types = [] }) {
let weaknesses = []

if (types.includes('WATER')) {
if (!types.includes('EARTH')) {
weaknesses = ['ELECTRICITY']
} else {
weaknesses = ['PLANT']
}
}
if (types.includes('FIRE')) {
if (!types.includes('WATER')) {
weaknesses = ['WATER']
} else {
weaknesses = ['PSY']
}
}
return weaknesses
}
``````

I generally feel that I would have far more troubles debugging it and understanding it at first glance than a code like this one:

``````function getPokemonWeaknesses({ types = [] }) {
if (types.includes('WATER')) {
if (!types.includes('EARTH')) return ['ELECTRICITY']
return ['PLANT']
}

if (types.includes('FIRE')) {
if (types.includes('WATER')) return ['PSY']
if (types.includes('PLANT')) return ['COMBAT']
return ['PLANT']
}

return []
}
``````

PS: sorry for my knowledge on Pokemon types, it has been a long time since I've played any Pokemon game 😅

Animesh Pandey • Edited on

Haha, thanks. 😊

In the end, I guess the point is to make the code more readable. In your example, for sure, the early returns can look more obvious to read. In many cases, they make people lose the flow and intention of the code.

My own preference would certainly depend upon the specific case under consideration, but this was a piece of general advice I have received from many throughout my journey.

Anyway, the main idea of mentioning early returns in the article was to explain that they exist and can be used as an exit from a function (as a function output), but if they complicate the readability too much, it's better to have a single return.

Even my Pokémon knowledge is rusty now. Looking forward to the Diamond and Pearl remakes, and Pokémon Legends. :D

Hope you'll stick around for more! Take care!

Marwan El Boussarghini

I always like to challenge my knowledge and the things I do without even thinking about them, it's cool to read some interesting articles that help me do so 👍🏽

Lars Feldeisen

Pure functions have no side effects yes. That does not mean that "implicit output" is a side effect. Pure functions have as first rule: the same input gives the same output. (That's the important part)

Implicit outputs is also not a kind of style. it's just lazy. And a bad programming. You working with globals and that could be a real problem in real world. You should more clarify that, because for beginners it looks some kind of cool. And wow its easy. But its the opposit, the code get fast messy and working with other developers would be hard.

But realy nice you are writing about functional programming. And im looking forward to read more. You should go on: "Curry and Function Composition" in some of your next chapters. They are the real deal and helpful af.

Animesh Pandey

Yep, thanks for mentioning that. I think I accidentally glossed over this, because the article was already getting too long.

I thought of covering Pure Functions and Side Effects very properly in the next one, after introducing relevant terms here in this one to aid in understanding the upcoming concepts.

Will be definitely going over Composition and Currying in a later one!

Thanks a lot for liking it!

max

Waow, what a great article. I'm a teacher and this will greatly help some of my students which want to improve in JS.

Some returns to improve it :

1. Prefer using let instead of var, new JS stuff :p
2. You should differenciate logs & returns, and not using the same "output" term, in your examples ;)

Thanks a lot for this great work, have a nice day :)

Animesh Pandey • Edited on

And also thank you for your feedback. There was really no reason for me to prefer var over let, it was just my own habit. The outputs/returns could use some improvement though. I am looking into better ways to inject executable code into an article, so it could be of more help. Right now the best option seems to be CodePen. I will revisit and update all previous articles once I am satisfied.

Well, stay tuned for more! Thanks again!

John Kazer

Thanks, that was a good intro. JavaScript I've found is really a good way to learn functional programming. it allows you to slowly integrate the style into your day-to-day.

The funny thing is that the more I converted to using functional JavaScript the more I was able to understand a more completely functional language like Clojure. As ClojureScript is a variant that compiles to JavaScript and can use JavaScript libraries I am now wondering what really is the point anymore of writing JavaScript at all?

Animesh Pandey

Haha, I once had to contribute to a project written in ClojureScript long ago, for a bounty. Back then, I didn't have much understanding of FP, so I was absolutely blown away! Eventually, I got the hang of it, and I'm looking forward to making something of my own out of it! But it was probably the steepest learning curve of my life, so far.

I was going to bring it up eventually, in one of the articles to come, about how exceedingly amazing FP implementation can be in ClojureScript, for someone coming from a JavaScript or similar background.

JavaScript on its own, in my opinion, has a sweet balance between imperative and declarative styles, hence quite amazing for learning any new concepts.

Thanks for liking the article! There's so much to cover under the umbrella of "fundamentals", it's no wonder many learners are flabbergasted when they are directly skipped over to some advanced FP concept.

Hope you'll like the next one too!

Lorenzo Costa

Man, this article is pure gold! It should be in a curated list for anyone who uses JS! I have not finished it, though. Is there any particular reason for the use of "var" over "let" or "const" in your samples provided?

Animesh Pandey

Thanks! I appreciate it.

Choosing "var" / "let" / "const" wasn't really relevant to the concepts being explained, so I just went with the simple "var". No particular reason for it.

pris stratton

Great article, looking forward to the next chapter!

I love FP - there's a great podcast by a guy called Eric Normand which is on Spotify which got me into it.

Animesh Pandey

Thanks a lot! :)

Oh, I'll check the podcast out too. Maybe there'll be a reference from it next article?

pris stratton

It’s called “Thoughts on Functional Programming” if you do search for it.

Animesh Pandey

Yep, found it! Pretty good, thanks!

Of all development and programming-related platforms, I didn't think there'd be something like this on Spotify, haha! 😆

David Yao

Very detailed explanation, even though FP has some of kind of steep learning curve, but it is definitely worth mastering if developers want to dive more. Thanks for the effort.

Animesh Pandey

Glad you liked it! Thank you!

Ashley Oliver

a. Early Returns

There is a mistake in your test case. f(12) should clearly return 13.

Animesh Pandey

Yep, you are right! Thanks a lot!

Animesh Pandey

Thanks! Hope it helped just a little bit, atleast!

DenVarenie

Thanks!

Animesh Pandey