Categories
JavaScript Best Practices

JavaScript Best Practices— Currying and Partial Applications

Spread the love

JavaScript lets us do a lot of things. It’s sometimes too forgiving in its syntax.

In this article, we’ll look at how to curry and partially call functions.

Immediate Object Initialization

We can use IIFEs to initialize objects.

For instance, we can write the following code:

({
  hello() {
    return 'hello';
  },
  init() {
    console.log(this.hello());
  }
}).init();

Then we get 'hello' logged since we called the init method in the object.

We see that this.hello can be called as init is part of the same object.

We can either write:

({...}).init();

or:

({...}.init());

A curly brace that has methods inside is recognized as an object literal rather than a code block.

We can also use this to protect our variables from the global namespace just like we do with IIFEs.

Function Properties

Function can have properties just like any other objects.

We can use that to do caching by adding items to a property of it and using it later if needed.

For instance, we can write:

const foo = (param) => {
  if (!foo.cache[param]) {
    const result = {};
    // ...
    foo.cache[param] = result;
  }
  return foo.cache[param];
};

In the code above, we have the param parameter used as the key of the cache.

Then we can check if there’s anything cached with the key param in the cache property.

If there’s nothing cached, then we run the code inside the if block.

Otherwise, we return the cached value.

This is handy for storing computed values.

Configuration Objects

We can also create a configuration object for storing configuration for our software.

The configuration object can be used as a single parameter for an object rather than passing in multiple parameters.

Since the fewer parameters, the better. We can use that with the destructuring syntax to make our lives easier.

For instance, we can write:

const person = ({
  first,
  last
}) => {
  //,..
}

Then we can create an object as follows:

const conf = {
  first: "joe",
  last: "smith"
};

and use that to call the function:

person(conf);

Using configuration objects as parameters great because we don’t need to remember the order of the parameter.

Also, we can skip the optional parameters of safety.

This means easier maintenance and makes our code easier to read.

We don’t have to change the signature to add and remove parameters.

However, we do have to remember the names. Destructuring helps with that a lot though.

And property names can’t be minified.

Currying

Curring is when we return a function that has the arguments partially applied.

We don’t pass in all the arguments to the function we return.

For instance, we can write the following:

const curry = (firstName) => {
  return (lastName) => {
    return `${firstName} ${lastName}`;
  }
}

The code above takes a parameter, firstName in the outer function, then returns a function that takes lastName and a string that comes both together.

This lets us call 2 functions to complete the string.

The benefit of curry is that we minimize the number of changes to the program’s state.

Now we get 2 functions that have no side effects in the example above.

Partial Application

Partial application is the process of passing in fewer than the expected arguments to a function at one time.

For instance, if we have the following function:

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

Then we can apply one argument first:

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

Then we can partially call a function by using the Lodash partial method.

We can run:

const partialAdd = _.partial(add, 5);

To return a function with 5 applied as the first argument.

Then we can write:

const result = partialAdd(3);

to call the returned function with another argument.

Then we get that x is 5 and y is 3 so the sum is 8.

When to Use Currying

Currying is useful for situations when we call the same function and passing mostly the same parameters.

We can create a new function with the parameters passed in and we can call the function with the remaining parameters that they don’t share.

Conclusion

We can call methods in objects right after we define them.

This way, we only use them once and forget about them.

Currying and partial application of functions are great for calling the function with some arguments and return ones with those arguments applied.

Then we don’t have to call them again with those same arguments repeatedly.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *