Functional Programming 101: Currying Pattern
Tags: typescript, functional, javascript
Published: 2020-09-29 00:37:33

### Core Concepts of Functional Programmming.

## My story with OOP and Functional Programming
The first programming language I learn was Java, so obviously I needed to learn the Object Oriented Programming (called OOP from now on) too, although today Java allows some Functional Programming concepts too.

When I was learning the core concepts of OOP I sat down on my desktop and I was reading things like *encapsulation*, yeah, *inheritance*, oh yeah, and suddenly "*Dude, what the heck is polymorphism?*". The concept was painful at first time, but applying it was easier than I thought. After time, I learn Python using POO (it was a weird result), a bit of C#, C++, Ruby... I mean, I explored just using OOP.  And finally, I learned JavaScript, and yeah, I use OOP again. For any reason, on JavaScript the OOP don't convinced me at all (I was bored to use it too). I think that the JavaScript versatility get lost when I use OOP. Then ES6 appears on my life and it changes everything. I noticed that ES6 allowed Functional Programming, so I decided to learn about using JavaScript (with TypeScript) with functional programming paradigm. When I was learning the core concepts of functional programming I sat down on my desktop and I was reading things like *pure functions*, yeah, *high order functions*, and suddenly "*Dude, what the heck is a currying function?*". Again, the concept was painful at first time, but applying it was easier than I thought.

Today, I will explain you what is a currying function with my own words using TypeScript in this section called "Functional Programming 101".

## Core concept of Currying Function

The currying function is a function that returns another function which takes only one parameter at a time.
> Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c). [1]

```js
function currying(a) {
    return function(b) {
        // do somethig with the assigned 'a' var
        // by using another function that pass 'b' var.
        return a + b; // for example
    }
}
```

This is a very simple example that you could found searching on the web.
So if we do something like:

```js
console.log(currying(1)); // function currying(b)
```

we obtain as a result a function. Everything is ok here. So, has sense if we do:

```js
console.log(currying(1)(1)) // 2
```

The currying concept works thanks to the JS closures.
> A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time. [2]

### Advantages

This simple concept is so powerful when you need to use it, and the code is cleaner. Maybe for some librabries, using exported currying functions would be a great idea (if it is possible) or in some scenarios it allows more flexibility.

### Disavantages

Currying is not common when we're solving problems. Well, In my case I used it a few times, specifically on *Factories*.

## Our first Currying Function using JavaScript
```js
// No curried function
const sumThreeNumbers = (a, b, c) => (a + b + c);
 
// You designed a function that always will suon only three numbers.
// But what if I need a sum four numbers? or 'n' numbers?
console.log(sumThreeNumbers(1, 2, 3)); // 6


// Curried
const add = (a) => (function(b) { return a + b} );

// I can sum as I want without depend of the number of arguments.
console.log(add(add(1)(2))(3)); // 6
console.log(add(add(add(1)(2))(3))(4)); // 10
```

But this code looks a little bit confusing. So, I will improve it, but this time using TypeScript.

## Improving our first Currying Function using TypeScript
There are two proposals to improve our first currying function. The first one is cool, but the second one is my favorite.

### By saving state

This example looks much like a very similar to the core concept and I don't needed to design a currying function that returns a limited curried functions to sum a exactly 'n' times.

```typescript
const add = (...a: number[]): Function => {

  function curried(...b: number[]) {
    return add(...a, ...b)
  }

  // Just saving the 'state' to the returned value.
  // Remeber that Functions are objects too in JS.
  curried.done = a.reduce((result: number, value: number) => result + value;

  return curried;
}

// I designed a nice currying sum by saving the state.
console.log(add(1)(2)(3)(4)(5)(6).done); // 21
```

It works fine, but I have one problem: I'm using a object and I want use only functions. So, here is the second proposal to improve our currying function.

### By use recursion

This case designed to use the passed function until it detect there's no more arguments given.

```typescript
const curryUntilHasNoArguments = (functionToCurry: Function): Function => {
  const next = (...args: any[]) => {
  // I tried to avoid use any[] without spread the var with no success.
    return (_args: any[]) => {
      if (!(_args !== undefined && _args !== null)) {
        return args.reduce((acc, a) => {
          return functionToCurry.call(functionToCurry, acc, a)
        }, 0);
      }
      return next(...args, _args);
    };
  };
  return next();
};


const add = curryUntilHasNoArguments((a: number, b: number) => a + b);
// Don't forget end with '()' to tell that there's no more arguments.
console.log(add(1)(3)(4)(2)());
```

## Real-world example

Finally, I want to finish this article solving a 'real-world' problem (kind of). The sum currying example is trivial and I used it just with demonstrative purposes.

### Logger

```typescript
enum Method {
    WARN = "warn",
    ERROR = "error",
    LOG = "log",
    DEBUG = "debug",
    INFO = "info"
}

function createLogger(name: string, ): Function {
  return function(action: Method){
    return function print(message: string): void {
        console[action](`[${new Date()}] [${name}] ${message}`);
    }
  }
}

const logger = createLogger("Curry");
logger(Method.DEBUG)("This is a debug"); // [Dummy Date][Curry] This is a debug
```

You could avoid a lot of 'if' by using this kind of logger implementation.

```typescript
// Dummy scenario
const response = await api.call();
const {metadata, message} = response;

createLogger(api.name)(getMethod(metadata))(message);

function getMethod(metadata: ApiMetadata): Method {
 // do something with the metadata to return a valid Method.
 switch (metadata){
     case metadata.fail: return Method.error; 
 }
}

```

## Resources.
1. https://javascript.info/currying-partials
2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures.