Introduction to Currying and Partial Application

Lesson Introduction

Welcome to our lesson on "Introduction to Currying and Partial Application" in C++. Today, we’ll explore these functional programming techniques and understand their benefits. The goals for this lesson include grasping the concepts of currying and partial application and implementing them in C++.

Currying and partial application transform functions to be more modular and reusable. Understanding these techniques helps you write cleaner and more maintainable C++ code.

Currying: Basic Concepts

Currying is a technique where a function is transformed into a sequence of functions, each with a single argument. Instead of a function taking multiple arguments, you have a series of functions, each taking one argument.

For example, consider a function add that takes two arguments, a and b, and returns their sum:

C++
auto add = [](int a, int b) {
    return a + b;
};

When we curry this function, it becomes:

C++
auto curriedAdd = [](int a) {
    return [a](int b) {
        return a + b;
    };
};

Currying: Practical Example

Let's see currying in action with an example:

C++
#include <iostream>

int main() {
    auto curriedAdd = [](int a) {
        return [a](int b) {
            return a + b;
        };
    };

    // Create a function add5 which adds 5 to its argument
    auto add5 = curriedAdd(5);
    std::cout << "Currying: 5 + 3 = " << add5(3) << '\n';  // Outputs: Currying: 5 + 3 = 8

    return 0;
}

In the code above, curriedAdd takes an integer a and returns a lambda that takes another integer b. The function add5 is created by calling curriedAdd with 5, resulting in a function that adds 5 to its argument. Calling add5(3) adds 5 and 3, giving us 8. This method makes functions more modular and reusable.

Partial Application: Basic Concepts

Partial application is similar to currying but less strict. Instead of transforming a function to take a single argument at a time, you can fix a few arguments, creating a new function with fewer arguments. We have already explored the basics of partial application in the first lesson of this course. Let's recall it.

For example, the same add function can be partially applied using std::bind:

C++
#include <functional>
#include <iostream>

auto add = [](int a, int b) {
    return a + b;
};

int main() {
    // Partially apply 'add' with the first argument as 5
    auto add5_partial = std::bind(add, 5, std::placeholders::_1);
    std::cout << "Partial Application: 5 + 3 = " << add5_partial(3) << '\n';  // Outputs: Partial Application: 5 + 3 = 8

    return 0;
}

In this code:

  1. std::bind creates a new function add5_partial where the first argument of add is fixed to 5.
  2. std::placeholders::_1 is a placeholder indicating that the new function still requires one argument.
  3. Calling add5_partial(3) adds 5 and 3, resulting in 8.

Partial application lets you pre-set arguments, making functions more adaptable and your code cleaner.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal