A Quick Functional Refactoring Tip
Tags: functional, programming, javascript, tutorial
Published: 2019-05-23 18:13:32

---
title: 'A Quick Functional Refactoring Tip'
published: true
description: A quick refactoring tip to help make your codebase more functional.
tags: functional, programming, javascript, tutorial
---

_Originally posted on my personal site, [georgerodier.com](https://georgerodier.com/2019-5-23-quick-functional-refactor/)._

There's a ton of benefits to making your code more functional. However, there is a learning curve in getting started with functional programming. Luckily, with JavaScript, you can slowly adapt some functional practices and don't need to go full functional all at once.

One of the best things you can do is slowly start to refactor certain parts of your application until you can gain a better understanding. In a [previous post](https://dev.to/grodier/array-methods-the-gateway-to-functional-programming-f29), I talked about how refactoring for loops into array methods is a great first step that can teach you a ton about functional programming. However, that's not the only easy thing you can do to improve your codebase. The following video from [Eric Normand](https://twitter.com/ericnormand) provides a great tip for making your existing code more functional.

{% youtube 3mbTa2wgmTU %}

The tip is great and easier than you would think to implement.

```js
var myAge = 31;
var myName = 'George';

function nameAndDecadeString() {
  const decade = Math.floor(myAge / 10) * 10;
  const nameAndDecadeString =
    myAge === decade
      ? `${myName} is ${myAge} years old`
      : `${myName} is older than ${decade} and less than ${decade + 10}`;

  return nameAndDecadeString;
}

console.log(nameAndDecadeString());
// George is older than 30 and less than 40
```

In this example of a hypothetical existing codebase, myAge and myName are global mutable variables. They are both defined outside the scope of the _nameAndDecadeString_ function where they are referenced. The function doesn't mutate these variables and is only reading them. This is still problematic because the function will return a different result depending on when you read those values. They could be updated at some point by a user interaction thus changing what the function may return. To test this, we would need to set up mocks or globals that would make the tests brittle.

All that is needed to make _nameAndDecadeString_ more functional is to take the global variables (myAge and myName) and make them arguments to the function.

```js
var myAge = 31;
var myName = 'George';

function nameAndDecadeString(name, age) {
  const decade = Math.floor(age / 10) * 10;
  const nameAndDecadeString =
    age === decade
      ? `${name} is ${age} years old`
      : `${name} is older than ${decade} and less than ${decade + 10}`;

  return nameAndDecadeString;
}

console.log(nameAndDecadeString(myName, myAge));
// George is older than 30 and less than 40
```

Now that the parameters have been changed, the _nameAndDecadeString_ function can read in the global variables as arguments. The global variables could still be modified unexpectedly, but the code within the scope of _nameAndDecadeString_ is no longer relying on them. The overall functionality hasn't changed, but the code is now more testable and more functional.

One of the principles of functional programming is writing **pure functions**. Pure functions are any functions that will always produce the same outputs for the same inputs. Previously, _nameAndDecadeString_ didn't take any inputs, but might produce different outputs every time its called depending on the values of myAge and myName at any given time. Now that they are passed in as arguments, the function will produce the same output every time the same age and name are passed into the function. It no longer relies on global state.

The goal now is to slowly refactor your codebase following this approach. Your codebase won't be fully functional, but it is a good first step to having more reliable and testable code.