This is an example how to create continuation-like monadic behaviour in C++11 (encapsulate async execution) which is used for specific example: writing asynchronous scripts for system of distributed autotests.
I needed to add autotests into continuous integration of client-side multiplatform product. Basic way to build autotesting system is to grab one of well-known frameworks (especially if we are talking about web solutions) and test product locally. Local testing environment simulates clicks buttons inside UI and gets the results right away. This is simple and good way except the case when you have truly cross-platform solution (win, mac, web, iOS, android, etc), custom rich UI framework and you want to perform tests on various kinds of systems at same time.
So I came up with remote distributed scheme for autotests. And inside this post there are some ways to make this scheme shine.
This post contains 3 main points:
- what is distributed system of autotests and why the one would need it (advantages / disadvantages)
- how to implement asynchronous scenarios of distributed autotests using continuation monadic style in C++11/14 (how to encapsulate asynchronous execution and do this the most compact way)
- how to integrate ChaiScript scripting into such system to make it more flexible
This post is about one more functional programming idea – LENSES. As you could guess it could be implemented using modern C++.
Concept of lenses from functional programming is actually pretty simple – lens is just pair of getter and setter, which are separated from target object. The main power of lenses is that you could combine them into chain to save a lot of work when you access or modify parts of complex nested structures. The analogy is the following – you can’t get much profit from one lens, but if you combine the bunch of lenses you could make telescope or microscope, etc.
Also there is a big profit when you work with immutable data. In that case a setter is a function which creates a copy of object with modified part. To modify nested structure you could produce very large piece of boilerplate code. But as you will see the lenses could solve this problem brilliantly.
When I use std::pair or std::tuple I always feel sad about using std::get<> to get results. Because this is not so readable, not so maintainable and a bit ugly. Even when you use first/second it’s easy to forget what was first argument of std::pair and so on. When you use tuple to pass more than 3 arguments situation becomes even worse. New standard has nothing in box to solve this, but we can fix this writing our own solution using C++14.
At MeetingCPP 2015 conference I attended nice presentation by and found great solution there – named tuple. After some playtime I made my own implementation draft which you can find in this post.
Transducers – what are they? This is term from Clojure world. There is a classic video from inventor of this term Rich Hickey, and here is some manual page from closure’s docs. But I’ll try to explain all this the simplest possible way so you don’t have to watch all that stuff.
Also I will show my way to implement transducers using C++14 and a lot of examples how to use them.
As C++ is very flexible language there are a lot of ways to construct immutable-like data structures from functional programming style. For example, this nice presentation by Kelvin Henney contains one of the ways. Here I will present my way which is slightly different.
At the same time my approach also solves another problem of serialisation of such immutable structures. I use JSON format at the moment, but the approach is not limited to this format only.
Two recent posts in Bartosz’s programming cafe describe nice application of list monad to solve the following puzzle:
Each letter corresponds to single digit. There are a lot of methods to solve this. Bartosz is using list monad which is very simular to list comprehension methods which were described here. While this maybe not the fastest way to solve this specific puzzle, his approach shows the ways to solve large cluster of similar but smaller problems which we meet at basic “production” level. SEND+MORE problem may be is not so good example to show power of list monad because of one very important problem i want to discuss in this post.
C++11 treats functions as first-class citizens and this gives us ability to construct a lot of nice things as design patterns borrowed from functional languages. Meanwhile C++ has very powerful template metaprogramming. This post is aimed to make templated functions closer to first-class citizens, and to construct some simplicity and beauty which you can get from it.
Also here will be implementation for currying of such functions! If you don’t know what currying is – just remember std::bind.
And to make it shine we’ll add piping. (This article will improve some ideas from post about functional piping ). This step is optional and you can replace such piping with commas and function calls.
List comprehension in functional languages is the name of list constructor syntax, which is similar to set-builder notation from math.
What are the benefits of using list comprehension? One is readability, and the other one is the fact of decoupling iteration from actual construction. We could even hide parallel execution under the hood of list comprehension. Also by adding additional options to such declaration we could make the list construction a lot shorter.
If we look closer at list comprehension’s syntax, it will remind of one another very familiar thing – SQL select! Output expression, input set, predicates are equivalent to select, from, where sequence (of course not exactly, but they are very alike). Ok, let’s implement such syntax sugar using C++11 (without boost and LINQ-like libs).
This post is about making functional decomposition from perspective of Aspect Oriented Programming using C++11. If you are not familiar with ideas of AOP don’t be afraid – it’s rather simple concept, and by the end of this post you will understand the benefits of it.
You also can treat this post just as example how to use high-order functions in C++11.
In short – AOP tries to perform decomposition of every business function into orthogonal parts called aspects such as security, logging, error handling, etc. The separation of crosscutting concerns. It looks like: