Playing around with Closures, Currying, and Cool Abstractions
Tags: javascript, functional, webdev
Published: 2020-03-08 15:55:01

---
title: Playing around with Closures, Currying, and Cool Abstractions
published: true
description: We will talk about closures, curried functions, and play around with these concepts to build cool abstractions.
tags: javascript, functional_programming, webdev
canonical_url: https://leandrotk.github.io/tk/2020/03/closure-currying-and-cool-abstractions/index.html
---

![A Japanese curry rice](https://images.japancentre.com/recipes/pics/6/main/6-pork-katsu-curry.jpg?1469572800)

---

This article was first published at the [TK's blog](http://leandrotk.github.io/tk/2020/03/closure-currying-and-cool-abstractions/index.html).

In this article, we will talk about closures, curried functions, and play around with these concepts to build cool abstractions. I want to show the idea behind each concept, but also make it very practical with examples and refactor code to make it more fun.

## Closures

So closure is a common topic in JavaScript and we will start with it. As MDN web docs defines:

> "A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)."

Basically, every time a function is created, a closure is also created and it gives access to all state (variables, constants, functions, etc). The surrounding state is known as the `lexical environment`.

Let's show a simple example:

```javascript
function makeFunction() {
  const name = 'TK';
  function displayName() {
    console.log(name);
  }
  return displayName;
};
```

What do we have here?

- Our main function called `makeFunction`
- A constant named `name` assigned with a string `'TK'`
- The definition of the `displayName` function (that just log the `name` constant)
- And finally the `makeFunction` returns the `displayName` function

This is just a definition of a function. When we call the `makeFunction`, it will create everything within it: constant and function in this case.

As we know, when the `displayName` function is created, the closure is also created and it makes the function aware of the environment, in this case, the `name` constant. This is why we can `console.log` the `name` without breaking anything. The function knows about the lexical environment.

```javascript
const myFunction = makeFunction();
myFunction(); // TK
```

Great! It works as expected! The return of the `makeFunction` is a function that we store it in the `myFunction` constant, call it later, and displays `TK`.

We can also make it work as an arrow function:

```javascript
const makeFunction = () => {
  const name = 'TK';
  return () => console.log(name);
};
```

But what if we want to pass the name and display it? A parameter!

```javascript
const makeFunction = (name = 'TK') => {
  return () => console.log(name);
};

// Or a one-liner
const makeFunction = (name = 'TK') => () => console.log(name);
```

Now we can play with the name:

```javascript
const myFunction = makeFunction();
myFunction(); // TK

const myFunction = makeFunction('Dan');
myFunction(); // Dan
```

Our `myFunction` is aware of the arguments passed: default or dynamic value.
The closure does make the created function not only aware of constants/variables, but also other functions within the function.

So this also works:

```javascript
const makeFunction = (name = 'TK') => {
  const display = () => console.log(name);
  return () => display();
};

const myFunction = makeFunction();
myFunction(); // TK
```

The returned function knows about the `display` function and it is able to call it.

One powerful technique is to use closures to build "private" functions and variables.

Months ago I was learning data structures (again!) and wanted to implement each one. But I was always using the object oriented approach. As a functional programming enthusiast, I wanted to build all the data structures following FP principles (pure functions, immutability, referential transparency, etc).

The first data structure I was learning was the Stack. It is pretty simple. The main API is:

- `push`: add an item to the first place of the stack
- `pop`: remove the first item from the stack
- `peek`: get the first item from the stack
- `isEmpty`: verify if the stack is empty
- `size`: get the number of items the stack has

We could clearly create a simple function to each "method" and pass the stack data to it. It use/transform the data and return it.

But we can also create a private stack data and exposes only the API methods. Let's do this!

```javascript
const buildStack = () => {
  let items = [];

  const push = (item) => items = [item, ...items];
  const pop = () => items = items.slice(1);
  const peek = () => items[0];
  const isEmpty = () => !items.length;
  const size = () => items.length;

  return {
    push,
    pop,
    peek,
    isEmpty,
    size,
  };
};
```

As we created the `items` stack data inside our `buildStack` function, it is "private". It can be accessed only within the function. In this case, only the `push`, `pop`, etc could touch the data. And this is what we're looking for.

And how do we use it? Like this:

```javascript
const stack = buildStack();

stack.isEmpty(); // true

stack.push(1); // [1]
stack.push(2); // [2, 1]
stack.push(3); // [3, 2, 1]
stack.push(4); // [4, 3, 2, 1]
stack.push(5); // [5, 4, 3, 2, 1]

stack.peek(); // 5
stack.size(); // 5
stack.isEmpty(); // false

stack.pop(); // [4, 3, 2, 1]
stack.pop(); // [3, 2, 1]
stack.pop(); // [2, 1]
stack.pop(); // [1]

stack.isEmpty(); // false
stack.peek(); // 1
stack.pop(); // []
stack.isEmpty(); // true
stack.size(); // 0
```

So, when the stack is created, all the functions are aware of the `items` data. But outside the function, we can't access this data. It's private. We just modify the data by using the stack builtin API.

## **Curry**

> "Currying is the process of taking a function with multiple arguments and turning it into a sequence of functions each with only a single argument." - Wikipedia

So imagine you have a function with multiple arguments: `f(a, b, c)`. Using currying, we achieve a function `f(a)` that returns a function `g(b)` the returns a function `h(c)`.

Basically: `f(a, b, c)` —> `f(a) => g(b) => h(c)`

Let's build a simple example: add two numbers. But first, without currying!

```javascript
const add = (x, y) => x + y;
add(1, 2); // 3
```

Great! Super simple! Here we have a function with two arguments. To transform it into a curried function we need a function that receives `x` and returns a function that receives `y` and returns the sum of both values.

```javascript
const add = (x) => {
  function addY(y) {
    return x + y;
  }

  return addY;
};
```

We can refactor this `addY` into a anonymous arrow function:

```javascript
const add = (x) => {
  return (y) => {
    return x + y;
  }
};
```

Or simplify it by building one liner arrow functions:

```javascript
const add = (x) => (y) => x + y;
```

These three different curried functions have the same behavior: build a sequence of functions with only one argument.

How we use it?

```javascript
add(10)(20); // 30
```

At first, it can look a bit strange, but it has a logic behind it. `add(10)` returns a function. And we call this function with the `20` value.

This is the same as:

```javascript
const addTen = add(10);
addTen(20); // 30
```

And this is interesting. We can generate specialized functions by calling the first function. Imagine we want an `increment` function. We can generate it from our `add` function by passing the `1` as the value.

```javascript
const increment = add(1);
increment(9); // 10
```

---

When I was implementing the [Lazy Cypress](https://github.com/leandrotk/lazy-cypress), a npm library to record the user behavior in a form page and generate Cypress testing code, I want to build a function to generate this string `input[data-testid="123"]`. So here we have the element (`input`), the attribute (`data-testid`), and the value (`123`). Interpolating this string in JavaScript would look like this: `${element}[${attribute}="${value}"]`.

the first implementation in mind is to receive these three values as parameters and return the interpolated string above.

```javascript
const buildSelector = (element, attribute, value) =>
  `${element}[${attribute}="${value}"]`;

buildSelector('input', 'data-testid', 123); // input[data-testid="123"]
```

And it is great. I achieved what I was looking for. But at the same time, I wanted to build a more idiomatic function. Something I could write "*get an element X with attribute Y and value Z*". So what if we break this phrase into three steps:

- "*get an element X*": `get(x)`
- "*with attribute Y*": `withAttribute(y)`
- "*and value Z*": `andValue(z)`

We can transform the `buildSelector(x, y, z)` into `get(x)` ⇒ `withAttribute(y)` ⇒ `andValue(z)` by using the currying concept.

```javascript
const get = (element) => {
  return {
    withAttribute: (attribute) => {
      return {
        andValue: (value) => `${element}[${attribute}="${value}"]`,
      }
    }
  };
};
```

Here we use a different idea: returning an object with function as key-value. This way we can achieve this syntax: `get(x).withAttribute(y).andValue(z)`.

And for each returned object, we have the next function and argument.

Refactoring time! Remove the `return` statements:

```javascript
const get = (element) => ({
  withAttribute: (attribute) => ({
    andValue: (value) => `${element}[${attribute}="${value}"]`,
  }),
});
```

I think it looks prettier. And we use it like:

```javascript
const selector = get('input')
  .withAttribute('data-testid')
  .andValue(123);

selector; // input[data-testid="123"]
```

The `andValue` function knows about the `element` and `attribute` values because it is aware of the lexical environment as we talked about closures before.

---

We can also implement functions using "partial currying". Separate only the first argument from the rest for example.

Doing web development for a long time, I commonly used the [event listener Web API](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). It is used this way:

```javascript
const log = () => console.log('clicked');
button.addEventListener('click', log);
```

I wanted to create an abstraction to build specialized event listeners and use them by passing the element and callback handler.

```javascript
const buildEventListener = (event) => (element, handler) => element.addEventListener(event, handler);
```

This way I can create different specialized event listeners and use it as functions.

```javascript
const onClick = buildEventListener('click');
onClick(button, log);

const onHover = buildEventListener('hover');
onHover(link, log);
```

---

With all these concepts, I could create a SQL query using JavaScript syntax. I wanted to SQL query a JSON data like:

```javascript
const json = {
  "users": [
    {
      "id": 1,
      "name": "TK",
      "age": 25,
      "email": "tk@mail.com"
    },
    {
      "id": 2,
      "name": "Kaio",
      "age": 11,
      "email": "kaio@mail.com"
    },
    {
      "id": 3,
      "name": "Daniel",
      "age": 28,
      "email": "dani@mail.com"
    }
  ]
}
```

So I built a simple engine to handle this implementation:

```javascript
const startEngine = (json) => (attributes) => ({ from: from(json, attributes) });

const buildAttributes = (node) => (acc, attribute) => ({ ...acc, [attribute]: node[attribute] });

const executeQuery = (attributes, attribute, value) => (resultList, node) =>
  node[attribute] === value
    ? [...resultList, attributes.reduce(buildAttributes(node), {})]
    : resultList;

const where = (json, attributes) => (attribute, value) =>
  json
    .reduce(executeQuery(attributes, attribute, value), []);

const from = (json, attributes) => (node) => ({ where: where(json[node], attributes) });
```

With this implementation, we can start the engine with the JSON data:

```javascript
const select = startEngine(json);
```

And use it like a SQL query:

```javascript
select(['id', 'name'])
  .from('users')
  .where('id', 1);

result; // [{ id: 1, name: 'TK' }]
```

---

That's it for today. We could go on and on showing a lot of different examples of abstractions, but now I let you play with those concepts.

## Resources

- [JavaScript Course by OneMonth](https://mbsy.co/lFtbC)
- [Blog post source code](https://github.com/tk-notes/blog/tree/master/closures-currying-and-cool-abstractions)
- [Closures | MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
- [Currying | Fun Fun Function](https://www.youtube.com/watch?v=iZLP4qOwY8I)
- [React for Beginners Course](https://ReactForBeginners.com/friend/LEANDRO)
- [Advanced React Course](https://AdvancedReact.com/friend/LEANDRO)
- [Learn React by building an App](https://alterclass.io/?ref=5ec57f513c1321001703dcd2)