Can someone guide me how do functional programming in C++? Is there some good online material that I can refer?
Please note that I know about the library FC++. I want to
UPD Dec 2018
I've created a comprehensive list of materials where you can find articles, talks, screencasts, papers, libraries and showcases:
Functional Programming in C++
Consider my 4 research projects:
This project is a working prototype of 'Amber' game. The code demonstrates many of major functional concepts: immutability
, lambdas
, monads
, combinators
, pure functions
, declarative code design
. It uses Qt C++ and C++11 features.
For a quick example, see how tasks can be chained into one big task that will modify the Amber's world when it's applied:
const AmberTask tickOneAmberHour = [](const amber::Amber& amber)
{
auto action1Res = magic::anyway(inflateShadowStorms, magic::wrap(amber));
auto action2Res = magic::anyway(affectShadowStorms, action1Res);
auto action3Res = magic::onFail(shadowStabilization, action2Res);
auto action4Res = magic::anyway(tickWorldTime, action3Res);
return action4Res.amber;
};
This is a showcase of generic functional lenses in C++. The implementatoin is built with using of Variadic Templates
, some intresting (and valid) C++ hacks to make lenses composable and neat-looking. The library is just a demo for the talk and thus it provides only a few of most important combinators, namely: set()
, view()
, traverse()
, bind()
, infix literal combinator to
, over()
and other.
(Note that there exist the 'C++ Lenses' project: but it's not about real 'lenses', it's about class properties with getters and setters in sense of C# or Java properties.)
Quick example
Car car1 = {"x555xx", "Ford Focus", 0, {}};
Car car2 = {"y555yy", "Toyota Corolla", 10000, {}};
std::vector cars = {car1, car2};
auto zoomer = traversed() to modelL();
std::function variator = [](std::string) { return std::string("BMW x6"); };
std::vector result = over(zoomer, cars, variator);
QVERIFY(result.size() == 2);
QVERIFY(result[0].model == "BMW x6");
QVERIFY(result[1].model == "BMW x6");
You have probably heard about monads. Monads are everywhere in talks about functional programming now. It's a buzzword. But what about comonads? I presented 1D and 2D celullar automata with the concept of comonads under the hood. The aim was to show how easy it is to move from the single-flow code to the parallel one using std::future as a Par monad. The project also benchmarks and compares two these approaches.
Quick example
template
UUB fmap(
const func& f,
const UUUUA& uuu)
{
const func f2 = [=](const UUUA& uuu2)
{
UB newUt;
newUt.position = uuu2.position;
newUt.field = fp::map(f, uuu2.field);
return newUt;
};
return { fp::map(f2, uuu.field), uuu.position };
}
Software Transactional Memory (STM)
library that is called cpp_stm_free
. (GitHub) (Slides (Eng)) (Talk (Rus)) (Tutorial (Eng)) (Dining Philosopher sample).This library is based on Free monad
and some other advanced ideas of Functional Programming. Its interface is similar to Haskell's native STM library. Transactions are monadically composable, pure functional, and there is a lot of useful monadic combinators to make designing of concurrent model more convenient and powerful. I've implemented the Dining Philosophers problem using the library, and it works well. Here is a sample of some transaction for taking of forks by a philosopher:
STML takeFork(const TFork& tFork) {
return withTVar(tFork, [=](const Fork& fork) {
if (fork.state == ForkState::Free) {
return writeTVar(tFork, Fork {fork.name, ForkState:Taken});
}
else {
return retry();
}
});
}
STML takeForks(const TForkPair& forks) {
STML lm = takeFork(forks.left);
STML rm = takeFork(forks.right);
return sequence(lm, rm);
}