Skip to main content


The video of New Tools for a More Functional C++

My previous talk on New Tools for a More Functional C++ ran into some audio issue during the meetup. I did not upload the video back then because it had no audio what-so-ever. I finally got around to record the audio track for the talk and I mixed it with the video. So here is the final video. Have fun with FP in C++!

If you don't have 35 minutes, checkout the partial video transcripts below.

Functional Programming Tools in C++ from Sumant Tambe on Vimeo.

Video Transcripts00:16
We’re going to talk about functional [programming] tools in C++ and what new capabilities exist in modern C++. 
2:00 I'm reviewing Functional Programming in C++ book by Manning---a good book for C++ programmers to acquire beginner to intermediate level knowledge of FP in C++.
2:30 Sum types and (pseudo) pattern matching in C++
5:00 Modeling a game of Tennis using std::variant
7:30 std::visit spews blood when you miss a case in the visitor. See an example. Therefore, language-supported pattern matching is muc…
Recent posts

New Tools for a More Functional C++

I presented the following slide deck at the ACCU meetup yesterday.

New Tools for a More Functional C++ from Sumant Tambe
Abstract: Variants have been around in C++ for a long time and C++17 now has std::variant. We will compare inheritance and std::variant for their ability to model sum-types (a fancy name for tagged unions). We will visit std::visit and discuss how it helps us model the pattern matching idiom. Immutability is one of the core pillars of Functional Programming (FP). C++ now allows you to model deep immutability; we'll see a way to do that using the standard library. We'll explore if `return std::move(*this)` makes any sense in C++. Immutability may be a reason for that.

Binding std::function to member functions

I realized that std::function can be bound to member functions without requiring the *this object. Consider the following examples. // std::string::empty is a const function. All variables from e1 to e5 are fine. std::function<bool(std::string)> e1 = &std::string::empty; std::function<bool(std::string &)> e2 = &std::string::empty; std::function<bool(const std::string &)> e3 = &std::string::empty; std::function<bool(std::string *)> e4 = &std::string::empty; std::function<bool(const std::string *)> e5 = &std::string::empty; // std::string::push_back is not a const function. p4 and p5 don't compile. std::function<void(std::string, char)> p1 = &std::string::push_back; std::function<void(std::string &, char)> p2 = &std::string::push_back; std::function<void(std::string *, char)> p3 = &std::string::push_back; // These two don't compile because push_back is a non-const function std::func…

Avoiding intermediate copies in std::accumulate

std::accumulate makes a ton of copies internally. In fact it's 2x the size of the number of elements in the iterator range. To fix, use std::ref and std::reference_wrapper for the initial state. std::shared_ptr is also a possibility if the accumulated state must be dynamically allocated for some reason. Live code on wandbox.

Update: Please see alternative solutions in the comments section.

#include <iostream> #include <cstdlib> #include <algorithm> #include <vector> #include <string> #include <numeric> #include <functional> struct Vector : public std::vector<int> { Vector(std::initializer_list<int> il) : std::vector<int>(il){ std::cout << "Vector(std::initializer_list)\n"; } Vector() { std::cout << "Vector()\n"; } Vector(const Vector &v) : std::vector<int>(v) { std::cout << "Vector(const Vector &)\n"; } Vector & operator = (co…

Playing with C++ Coroutines

While looking for some old photos, I stumbled upon my own presentation on C++ coroutines, which I never posted online to a broader audience. I presented this material in SF Bay ACCU meetup and at the DC Polyglot meetup in early 2016! Yeah, it's been a while. It's based on much longer blogpost about Asynchronous RPC using modern C++. So without further ado.

C++ Coroutines from Sumant Tambe

Folding Monadic Functions

In the previous two blog posts (Understanding Fold Expressions and Folding Functions) we looked at the basic usage of C++17 fold expressions and how simple functions can be folded to create a composite one. We’ll continue our stride and see how "embellished" functions may be composed in fold expressions.

First, let me define what I mean by embellished functions. Instead of just returning a simple value, these functions are going to return a generic container of the desired value. The choice of container is very broad but not arbitrary. There are some constraints on the container and once you select a generic container, all functions must return values of the same container. Let's begin with std::vector.
// Hide the allocator template argument of std::vector. // It causes problems and is irrelevant here. template <class T> struct Vector : std::vector<T> {}; struct Continent { }; struct Country { }; struct State { }; struct City { }; auto get_countries…

Folding Functions

In the last post we looked at basic usage of C++17 Fold Expressions. I found that many posts on this topic discuss simple types and ignore how folds may be applicable to more complex types as well. [Edit: Please see the comments section for some examples elsewhere in the blogosphere.] In this post I'm going to describe folding over functions.

Composing Functions

Function composition is a powerful way of creating complex functions from simple ones. Functions that accept a single argument and return a value are easily composable. Consider the following example to compose two std::functions. template <class A, class B, class C> std::function<C(A)> compose(std::function<B(A)> f, std::function<C(B)> g) { return [=](A a) -> C { return g(f(a)); }; } int main(void) { std::function<int(std::string)> to_num = [](std::string s) { return atoi(s.c_str()); }; std::function<bool(int)> is_even = [](int i) { return i%2==0; }; auto is_str_even…