## 1. Intro

In a previous post we introduced C++17 fold expressions and described a way to extend them for arbitrary callables. Implementation details don’t matter for what we’re elaborating on here but it should be clear that (given the tools we developed) the following is possible:

(Op<F>(args) + ...) (... + Op<F>(args))

i.e. performing a right or left fold respectively using the **“F”** type as the folding operator (the **“+”** operator is used just to generate the underlying expression templates). By **“F”** we mean a type that will serve as the reducing function (it generates callable instances) e.g. this:

Such tools enhance the notion of “reduce” being the ultimate **production line** where new algorithmic skeletons and processes can be forged sometimes to a surprising extend as we’ll see below.

## 2. On composition

In a nutshell composition is the pointwise application of one function to the result of another to produce a third one. Add another one to the pipeline and the mathematic notation goes something like this:

…and so on and so forth, we should be able to compose as many functions as we want provided that the result of the “inner” functions can be a valid input to the outer.

Now, look at the mathematical notation again. What does the right hand side look like? It’s just **folding over the function call operator!** Written in pseudo C++ (I say pseudo because C++ folds don’t support arbitrary operators out of the box) it would look like this:

args () ...

where `args`

is a pack of callables we want to compose. Now it all boils down to synthesizing the reducer, and composing two callables is easy enough, by creating a lambda that applies the left side to the result of calling the right side with whatever arguments you pass to it:

We’ve also added a helper `compose`

function to hide the fold generation even though it’s good to know that **it takes a right fold to do this**. Having this in place you can write things like

### One more thing

I might have oversimplified the definition of the `Comp`

structure. Taking move semantics into consideration is not only a matter of efficiency but correctness as well, since preserving value category is essential when using forwarded callables. To ammend this, the returned lambda will do a **perfect capture** using this helper type:

This type will be used by the (C++14 generalized) lambda capture to acquire either a reference (wrapper) or a moved callable (depending on its value category). So now `Comp`

is written as follows

## 3. On currying

Currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. In other words it could be described (nitpickers pardon me) by the production of partially applied functions something you see in C++ with certain applications of `std::bind`

. Following the same logic as above we’ll be using the **left fold pipeline** with the following reducer

Now this is possible

The last piece of the puzzle is **constexpr lambdas** that would really allow for this to extend to synthesizing `constexpr`

callables and this is on its way for C++17

## Demo

A runnable example can be found here. Note that this particular example only runs for g++ and I’ll be diving into clang in a later endeavor.

Interesting technique. But the thing that caught my eye is perfect capture. I wonder it it possible at all to write robust generic perfect capture. Taking into account C arrays, pairs and tuples of rvalue/lvalue references, etc.

LikeLike

Vittorio did a piece on this 2 weeks after your question. My thoughts on the topic are in this thread https://vittorioromeo.info/index/blog/capturing_perfectly_forwarded_objects_in_lambdas.html

LikeLike

Nice article! Inspired me to do my own experiments on currying… Take a look at them here:

https://godbolt.org/g/mp8OD1

LikeLiked by 1 person