Skip to main content


Showing posts from 2017

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…