Functions Currying

    Feb 19, 2023

    Definitions and examples for Functions Currying

    Unary, Binary and Variadic

    Definition : The function that only applies and receives one argument value.

    For example, this is a typical unary

    const func = (para) => para;
    

    Corresponding the defination of Binary : The function that applies and receives two argument values. We could expand this defination into the Variadic : The function that applies and recieves multiple argument values.

    const add = (x, y) => x + y; // Binary Function
    const sum = (...args) => args.reduce((acr, cur) => acr + cur); // Variadic Function
    

    Currying

    Definition : The currying is the process that transform a variadic into a nested unary.

    It may be difficult to understand only by reading at this definition. Here is a detailed explanation by example.

    We have an add function:

    const add = (a, b) => a + b;
    

    It applies two argument values to get its sum. But if we need to apply this function for multiple arguments, it should be rewrite as:

    const add = (...args) => {
      let sum = 0;
      for (val of args) {
        sum += val;
      }
      return sum;
    };
    

    However, it pulls in a temporary variable sum to store the amount while traversing the array, it also called as State.

    The one of the principles in functional programming is avoid pulling state into program for it may make effects, which causes bugs to make harder debugging.

    So we should remove the state variable sum by currying.

    For example, the Binary function of sum :

    const add = (a, b) => a + b;
    

    We rewrite it such as:

    const add = (a) => (b) => a + b;
    

    When I want to get the sum of 2 and 3:

    add(2)(3); // 5
    

    The function calling process:

    add(2); // return a function (b) => (b + 2)
    add(2)(3); // call to a function returned by the previous layer (3) => (3 + 2) , the b is assigned as 3.
    

    Similarly, if we have three arguments, the currying should like:

    const add = (a) => (b) => (c) => a + b + c;
    

    The javascript supports variadic functions, we could derive a generator functions for currying:

    const curry = (func) => {
      if (typeof func !== "function") {
        return;
      }
      return function curriedFn(...args) {
        if (args.length < func.length) {
          return curriedFn.apply(null, args.concat([].slice.call(arguments)));
        }
        func.apply(null, args);
      };
    };
    

    So we can curry a variadic functions by function curry;

    const add = (a, b, c) => a + b + c;
    const curriedAdd = curry(add);
    curriedAdd;
    curriedAdd(1)(2)(3); // 6