What is induction method when it comes to C++ template metaprogramming? - c++

People keep saying solve the problem using induction when it comes to template metaprograms. For example see this answer : https://stackoverflow.com/a/11811486/4882052
I know induction proofs etc, but how this theory is used to solve metaprogram?. I'd love examples with examples :)

"Induction" is just recursion looked at from a different point of view. In each you need one or more base cases in which a problem can be solved without recursion and you need a recursive case in which a problem can be solved by using the solutions of related problem(s) that are closer to base cases.
In run-time recursive programming, base cases can be detected by run-time conditionals. In recursive meta-programming, even compile-time conditionals are not quite enough to handle base cases. You need separate definitions utilizing overloading or specializing to cover base cases.
The first time I used it myself is a rather messy situation, which I can't quote in full, but the general idea might be instructive. The compiler did various optimizations before unwinding short loops and various other optimizations after unwinding short loops. But I really needed one of those "before" optimizations done after. So I needed to force the compiler to unwind some short loops earlier in compilation, roughly:
template<unsigned N>
struct unwind {
void operator()(X*p) { unwind<N-1>()(p); work(p[N]); } };
template<>
struct unwind<0> {
void operator()(X*p) { work(p[0]); } };
When you use that compile-time recursion instead of a run-time loop, the compiler will unwind the whole loop before doing any of the optimization, so optimizations of a type done before loop unwinding that in my work code aren't visible until after loop unwinding will be done.

As observed by in one of the comments under the OP, the TMP technique is essentially recursive, which I guess could be seen a form of `reverse induction' (an idea originally due to Fermat). The idea is that, for some N, you define the corresponding thing you want in terms of some lesser N, eventually terminating at some base case.
Consider the following TMP code for factorial:
template <int N>
struct Factorial {
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0> {
enum { value = 1 };
};
void foo() {
std::cout << Factorial<0>::value << "," << Factorial<3>::value;
// outputs 1, 6
}
So the the general case (N) is given by a template with a value defined in terms of lesser values of (potentially more specialised) templates, terminating at some lower bound.

An inductive proof typically has the structure:
show that X is (usually trivially) true for some value Y
Show that if X is true for Y, then it remains true for some other value Y + delta
Therefore conclude that X is true for all Y + delta * N
(...and in a lot of cases, it's really handy if delta is 1, so we can say "X is true for all non-negative integers", or something on that order). In a fair number of cases, it's also handy to extend the proof in both directions, so we can say that X is true for all integers (for one obvious example).
Most purely recursive solutions (whether template meta programming or otherwise) tend to follow roughly the same structure. In particular, we start with processing for some trivial case, then define the more complex cases in terms of an application of the base case plus some extending step.
Ignoring template metaprogramming for the moment, this is probably most easily seen in recursive algorithms for preorder, inorder and postorder traversal of trees. For these we define a base case for processing the data in a single node of the tree. This is usually sort of irrelevant to the tree traversal itself, so we often just treat it as a function named process or something similar. With this given, we can define tree traversals something like:
void in_order(Tree *t) {
if (nullptr == t)
return;
in_order(t->left);
process(t);
in_order(t->right);
}
// preorder and postorder are same except for the order of `process` vs. recursion.
The reason many people think of this as being unique (or at least unusually applicable to) template meta-programming is that it's an area where C++ really only allows purely recursive solutions--unlike normal C++, you have no loops or variables. There have been other languages like that for quite some time, but most of them haven't really reached the mainstream. There are quite a few more languages that tend to follow that style even though they don't truly require it--but while some of them have gotten closer to the mainstream, most of them are still sort of on the fringes.

Related

What is compile time function in C++?

I've searched this question here(on SO), and as far as I know all questions assume what is compile time functions, but it is almost impossible for a beginner to know what that means, because resources to know that is quite rare.
I have found short wikipedia article which shows how to write incomprehensible code by writing never-seen-before use of enums in C++, and a video which is about future of it, but explains very little about that.
It seems to me that there are two ways to write compile time function in C++
constexpr
template<>
I've been through a short introduction of both of them, but I have no idea how they pop up here.
Can anyone explain compile time function with a sufficiently good example such that it encompasses most relevent features of it?
In cpp, as mentioned by you, there are two ways of evaluating a code on compile time - constexpr functions and template metaprogramming.
There are a few differences between those solutions. The template option is older and therefore supported by wider range of compilers. Additionaly templates are guaranteed to be evaluated in compile time while constexpr is somewhat like inline - it only suggests compiler that it is possible to do work while compiling. And for templates the arguments are usually passed via template parameters list while constexpr functions take arguments as regular functions (which they actually are). The constexpr functions are better in a manner that they can be called as regular functions in runtime.
Now the similarities - it must be possible for their parameters to be evaluated at compile time. So they must be either a literal or result of other compile-time function.
Having said all that let's look at compile time max function:
template<int a, int b>
struct max_template {
static constexpr int value = a > b ? a : b;
};
constexpr int max_fun(int a, int b) {
return a > b ? a : b;
}
int main() {
int x = 2;
int y = 3;
int foo = max_fun(3, 2); // can be evaluated at compile time
int bar = max_template<3, 2>::value; // is surely evaluated at compile time
// won't compile without compile-time arguments
// int bar2 = max_template<x, y>::value; // is surely evaluated at compile time
int foo = max_fun(x, y); // will be evaluated at runtime
return 0;
}
A "compile time function" as you have seen the term used is not a C++ construct, it's just the idea of computing stuff (hence, function) at compile-time (as opposed to computing at runtime or via a separate build tool outside the compiler). C++ makes this possible in several ways, of which you have found two:
Templates can indeed be used to compute arbitrary stuff, a set of techniques called "template metaprogramming". That's mostly by accident as they weren't designed for this purpose at all, hence the crazy syntax and struggles with old compilers. But in C++03 and before, that's all we had.
constexpr has been added in C++11 after seeing the need for compile-time calculations, and brings them back into somewhat saner territory. Its toolbelt has been expanding ever since, allowing more and more normal-looking code to be run at compile-time by just tacking a constexpr in the right place.
One could also mention macro metaprogramming, of which Boost.Preprocessor is a good example. But it's even more wonky and abhorrently arcane than old-school template metaprogramming, so you probably don't want to use it if you have a choice.

c++ support for last call optimization in template metaprogramming

I am reading about C++ templates and would like to contrast two different implementations of a function which computes sum from 0 to N.
Unfortunately, I have problems and would like to address a few questions through examples:
Code for naive sum:
#include <stdio.h>
template<int N>
struct Sum {
// Copied the implementation idea from Scott Meyers book
// "Effective C++". Is there a better way?
enum { value = N + Sum<N - 1>::value };
};
template<>
struct Sum<0> {
enum { value = 0 };
};
int main() {
// Works well in this case, but gives compilation error, if
// it's called with a larger value, such as 10000
// (error: template instantiation depth exceeds maximum of 900").
// How to improve the program properly, that it would
// not give compile time error?
printf("%d\n", Sum<100>::value);
}
Now my idea for an improvement is to use an accumulator:
template<int Acc, int N>
struct Sum {
enum { value = Sum<Acc + N, N - 1>::value };
};
// Is that an appropriate way of writing the base case?
template<int Acc>
struct Sum<Acc, 0> {
enum { value = Acc };
};
However, when compiled with simple g++ on Ubuntu OS:
int main() {
// Still gives the "depth exceeded" error.
printf("%d\n", Sum<0, 1000>::value);
}
Hence, my main concern is:
Does any modern c++ compiler support last call optimisation for
template metaprogramming? If yes, what is an appropriate way to write code for such optimisation?
Does any modern c++ compiler support last call optimisation for template metaprogramming? If yes, what is an appropriate way to write code for such optimisation?
No, and it wouldn't make sense. Template instantiations are not function calls... last/tail call optimisation has no relevance here. Unlike function calls, template instantiations are not transient with automatic variables to reclaim; rather, each template instantiation becomes a new type in the compiler's state.
The whole point of template metaprogramming is that all of these "calls" will be optimised out of your program; they are "executed" during the build.
That doesn't change the fact that there is an implementation-defined limit to the amount of recursion you can use during this process. This is the limit you've hit.
So, no, there's no "optimisation" to work around it.
Short answer: incorporating LCO is not worth the trouble.
Longer explanation:
C++ template meta programming is Turing Complete. In theory it would be possible to compute any computable function at compile time using only templates (if enough resources were given). LCO would make such computation more efficient.
That does not mean templates should be used for sophisticated computations. Run time is for that. C++ templates merely aid to avoid writing identical code.
In fact, doing complicated computation through templates is discouraged, because one has little compiler support. The preprocessor will only expand templated code into more code and that's it. No type checking, etc. is happening when processing templates.
So I think the designers of c++ have more interesting things to add in the language rather than optimise template meta programming. Maybe after 20 years we will have LCO support. Currently there is no.

What can C++ offer as far as functional programming?

Are the following things, considered intrinsic to FP, possible in C++?
higher order functions
lambdas (closures/anonymous functions)
function signatures as types
type polymorphism (generics)
immutable data structures
algebraic data types (variants)
adhock data structures (tuples)
partial function applications
type inference
tail recursion
pattern matching
garbage collection
Let me start by noting that most of these are not "intrinsic", or shall we say, "required"; many of these are absent from notable functional languages, and in theory, many of these features can be used to implement the others (such as higher order functions in untyped lambda calculus).
However, let's go through these:
Closures
Closures are not necessary, and are syntactical sugar: by the process of Lambda Lifting, you can convert any closure into a function object (or even just a free function).
Named Functors (C++03)
Just to show that this isn't a problem to begin with, here's a simple way to do this without lambdas in C++03:
Isn't A Problem:
struct named_functor
{
void operator()( int val ) { std::cout << val; }
};
vector<int> v;
for_each( v.begin(), v.end(), named_functor());
Anonymous functions (C++11)
However, anonymous functions in C++11 (also called lambda functions, as they derive from the LISP history), which are implemented as non-aliasingly named function objects, can provide the same usability (and are in fact referred to as closures, so yes, C++11 does have closures):
No problem:
vector<int> v;
for_each( v.begin(), v.end(), [] (int val)
{
std::cout << val;
} );
Polymorphic anonymous functions (C++14)
Even less of a problem, we don't need to care about the parameter types anymore in C++14:
Even Less Problem:
auto lammy = [] (auto val) { std::cout << val; };
vector<int> v;
for_each( v.begin(), v.end(), lammy);
forward_list<double> w;
for_each( w.begin(), w.end(), lammy);
I should note this fully support closure semantics, such as grabbing variables from scope, both by reference and by value, as well as being able to grab ALL variables, not merely specified ones. Lambda's are implicitly defined as function objects, providing the necessary context for these to work; usually this is done via lambda lifting.
Higher Order Functions
No problem:
std::function foo_returns_fun( void );
Is that not sufficient for you? Here's a lambda factory:
std::function foo_lambda( int foo ) { [=] () { std::cout << foo; } };
You can't create functions, but you can function objects, which can be passed around as std::function same as normal functions. So all the functionality is there, it's just up to you to put it together. I might add that much of the STL is designed around giving you reusable components with which to form ad-hoc function objects, approximating creating functions out of whole cloth.
Partial Function Applications
No problem
std::bind fully supports this feature, and is quite adept at transformations of functions into arbitrarily different ones as well:
void f(int n1, int n2, int n3, const int& n4, int n5)
{
std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
int n = 7;
// (_1 and _2 are from std::placeholders, and represent future
// arguments that will be passed to f1)
auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n);
For memoization and other partial function specialization techniques, you have to code it yourself using a wrapper:
template <typename ReturnType, typename... Args>
std::function<ReturnType (Args...)>
memoize(ReturnType (*func) (Args...))
{
auto cache = std::make_shared<std::map<std::tuple<Args...>, ReturnType>>();
return ([=](Args... args) mutable
{
std::tuple<Args...> t(args...);
if (cache->find(t) == cache->end())
(*cache)[t] = func(args...);
return (*cache)[t];
});
}
It can be done, and in fact it can be done relatively automatically, but no one has yet done it for you.
}
Combinators
No problem:
Let's start with the classics: map, filter, fold.
vector<int> startvec(100,5);
vector<int> endvec(100,1);
// map startvec through negate
std::transform(startvec.begin(), startvec.end(), endvec.begin(), std::negate<int>())
// fold startvec through add
int sum = std::accumulate(startvec.begin(), startvec.end(), 0, std::plus<int>());
// fold startvec through a filter to remove 0's
std::copy_if (startvec.begin(), startvec.end(), endvec.begin(), [](int i){return !(i==0);} );
These are quite simple, but the headers <functional>, <algorithm>, and <numerical> provide dozens of functors (objects callable as functions) which can be placed into these generic algorithms, as well as other generic algorithms. Together, these form a powerful ability to compose features and behavior.
Let's try something more functional though: SKI can easily be implemented, and is very functional, deriving from untyped lambda calculus:
template < typename T >
T I(T arg)
{
return arg;
}
template < typename T >
std::function<T(void*)> K(T arg)
{
return [=](void*) -> T { return arg; };
}
template < typename T >
T S(T arg1, T arg2, T arg3)
{
return arg1(arg3)(arg2(arg1));
}
These are very fragile; in effect, these must be of a type which returns it's own type and takes a single argument of their own type; such constraints would then allow for all the functional reasoning of the SKI system to be applied safely to the composition of these. With a little work, and some template metaprogramming, much of this could even be done at compile time through the magic of expression templates to form highly optimized code.
Expression templates, as an aside, are a technique in which an expression, usually in the form of a series of operations or sequential order of code, is based as an argument to a template. Expression templates therefore are compile time combinators; they are highly efficient, type safe, and effectively allow for domain specific languages to be embedded directly into C++. While these are high level topics, they are put to good use in the standard library and in boost::spirit, as shown below.
Spirit Parser Combinators
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last)
{
using qi::double_;
using qi::phrase_parse;
using ascii::space;
bool r = phrase_parse(
first,
last,
double_ >> (char_(',') >> double_),
space
);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
This identifies a comma deliminated list of numbers. double_ and char_ are individual parsers that identify a single double or a single char, respectively. Using the >> operator, each one passes themselves to the next, forming a single large combined parser. They pass themselves via templates, the "expression" of their combined action building up. This is exactly analogous to traditional combinators, and is fully compile time checked.
Valarray
valarray, a part of the C++11 standard, is allowed to use expression templates (but not required, for some odd reason) in order to facilitate efficiency of transforms. In theory, any number of operations could be strung together, which would form quite a large messy expression which can then be aggressively inlined for speed. This is another form of combinator.
I suggest this resource if you wish to know more about expression templates; they are absolutely fantastic at getting all the compile time checks you wish done, as well as improving the re-usability of code. They are hard to program, however, which is why I would advise you find a library that contains the idioms you want instead of rolling your own.
Function Signatures As Types
No problem
void my_int_func(int x)
{
printf( "%d\n", x );
}
void (*foo)(int) = &my_int_func;
or, in C++, we'd use std::function:
std::function<void(int)> func_ptr = &my_int_func;
Type Inference
No problem
Simple variables typed by inference:
// var is int, inferred via constant
auto var = 10;
// y is int, inferred via var
decltype(var) y = var;
Generic type inference in templates:
template < typename T, typename S >
auto multiply (const T, const S) -> decltype( T * S )
{
return T * S;
}
Furthermore, this can be used in lambdas, function objects, basically any compile time expression can make use of decltype for compile time type inference.
But that's not what you are really after here, are you? You want type deduction as well as type restriction, you want type reconstruction and type derivations. All of this can be done with concepts, but they are not part of the language yet.
So, why don't we just implement them? boost::concepts, boost::typeerasure, and type traits (descendant from boost::tti and boost::typetraits) can do all of this.
Want to restrict a function based on some type? std::enable_if to the rescue!
Ah, but that's ad hoc right? That would mean for any new type you'd want to construct, you'd need to do boilerplate, etc etc. Well, no, but here's a better way!
template<typename RanIter>
BOOST_CONCEPT_REQUIRES(
((Mutable_RandomAccessIterator<RanIter>))
((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)),
(void)) // return type
stable_sort(RanIter,RanIter);
Now your stable_sort can only work on types that match your stringent requirements. boost::concept has tons of prebuilt ones, you just need to put them in the right place.
If you want to call different functions or do different things off types, or disallow types, use type traits, it's now standard. Need to select based on parts of the type, rather than the full type? Or allow many different types, which have a common interface, to be only a single type with that same interface? Well then you need type erasure, illustrated below:
Type Polymorphism
No problem
Templates, for compile time type polymorphism:
std::vector<int> intvector;
std::vector<float> floatvector;
...
Type erasure, for run time and adaptor based type polymorphism:
boost::any can_contain_any_type;
std::function can_call_any_function;
any_iterator can_iterator_any_container;
...
Type erasure is possible in any OO language, and involves setting up small function objects which derive from a common interface, and translate internal objects to it. With a little boost MPL boilerplate, this is fast, easy, and effective. Expect to see this become real popular soon.
Immutable Datastructures
Not syntax for explicit constructions, but possible:
Can be done via not using mutators or template metaprogramming. As this is a lot of code (a full ADT can be quite large), I will link you here, to show how to make an immutable singly linked list.
To do this at compile time would require a good amount of template magic, but can be done more easily with constexpr. This is an exercise for the reader; I don't know of any compile time libraries for this off the top of my head.
However, making an immutable datastructure from the STL is quite easy:
const vector<int> myvector;
There you are; a data structure that cannot be changed! In all seriousness, finger tree implementations do exist and are probably your best bet for associative array functionality. It's just not done for you by default.
Algebraic data types
No problem:
The amazing boost::mpl allows you to constrain uses of types, which along with boost::fusion and boost::functional to do anything at compile time that you would want in regards to ADT. In fact, most of it is done for you:
#include <boost/mpl/void.hpp>
//A := 1
typedef boost::mpl::void_ A;
As stated earlier, a lot of the work isn't done for you in a single place; for example, you'd need to use boost::optional to get optional types, and mpl to get unit type, as seen above. But using relatively simple compile time template mechanics, you can do recursive ADT types, which means you can implement generalized ADT's. As the template system is turing complete, you have a turing complete type checker and ADT generator at your disposal.
It's just waiting for you to bring the pieces together.
Variant based ADT's
boost::variant provides type checked unions, in addition to the original unions in the language. These can be used with no fuss, drop in:
boost::variant< int, std::string > v;
This variant, which can be int or string, can be assigned either way with checking, and you can even do run time variant based visitation:
class times_two_visitor
: public boost::static_visitor<>
{
public:
void operator()(int & i) const
{
i *= 2;
}
void operator()(std::string & str) const
{
str += str;
}
};
Anonymous/Ad-hoc data structures
No problem:
Of course we have tuples! You could use structs if you like, or:
std::tuple<int,char> foo (10,'x');
You can also perform a good deal of operations on tuples:
// Make them
auto mytuple = std::make_tuple(3.14,"pi");
std::pair<int,char> mypair (10,'a');
// Concatenate them
auto mycat = std::tuple_cat ( mytuple, std::tuple<int,char>(mypair) );
// Unpack them
int a, b;
std::tie (a, std::ignore, b, std::ignore) = mycat;
Tail Recursion
No explicit support, iteration is sufficient
This is not supported or mandated in Common LISP, though it is in Scheme, and therefore I don't know if you can say it's required. However, you can easily do tail recursion in C++:
std::size_t get_a_zero(vector<int>& myints, std::size_t a ) {
if ( myints.at(a) == 0 ) {
return a;
}
if(a == 0) return myints.size() + 1;
return f(myints, a - 1 ); // tail recursion
}
Oh, and GCC will compile this into an iterative loop, no harm no foul. While this behavior is not mandated, it is allowable and is done in at least one case I know of (possibly Clang as well).
But we don't need tail recursion: C++ totally is fine with mutations:
std::size_t get_a_zero(vector<int>& myints, std::size_t a ) {
for(std::size_t i = 0; i <= myints.size(); ++i){
if(myints.at(i) == 0) return i;
}
return myints.size() + 1;
}
Tail recursion is optimized into iteration, so you have exactly as much power.
Furthermore, through the usage of boost::coroutine, one can easily provide usage for user defined stacks and allow for unbounded recursion, making tail recursion unnecessary. The language is not actively hostile to recursion nor to tail recursion; it merely demands you provide the safety yourself.
Pattern Matching
No problem:
This can easily be done via boost::variant, as detailed elsewhere in this, via the visitor pattern:
class Match : public boost::static_visitor<> {
public:
Match();//I'm leaving this part out for brevity!
void operator()(const int& _value) const {
std::map<int,boost::function<void(void)>::const_iterator operand
= m_IntMatch.find(_value);
if(operand != m_IntMatch.end()){
(*operand)();
}
else{
defaultCase();
}
}
private:
void defaultCause() const { std::cout << "Hey, what the..." << std::endl; }
boost::unordered_map<int,boost::function<void(void)> > m_IntMatch;
};
This example, from this very charming website shows how to gain all the power of Scala pattern matching, merely using boost::variant. There is more boilerplate, but with a nice template and macro library, much of that would go away.
In fact, here is a library that has done all that for you:
#include <utility>
#include "match.hpp" // Support for Match statement
typedef std::pair<double,double> loc;
// An Algebraic Data Type implemented through inheritance
struct Shape
{
virtual ~Shape() {}
};
struct Circle : Shape
{
Circle(const loc& c, const double& r) : center(c), radius(r) {}
loc center;
double radius;
};
struct Square : Shape
{
Square(const loc& c, const double& s) : upper_left(c), side(s) {}
loc upper_left;
double side;
};
struct Triangle : Shape
{
Triangle(const loc& a, const loc& b, const loc& c) : first(a), second(b), third(c) {}
loc first;
loc second;
loc third;
};
loc point_within(const Shape* shape)
{
Match(shape)
{
Case(Circle) return matched->center;
Case(Square) return matched->upper_left;
Case(Triangle) return matched->first;
Otherwise() return loc(0,0);
}
EndMatch
}
int main()
{
point_within(new Triangle(loc(0,0),loc(1,0),loc(0,1)));
point_within(new Square(loc(1,0),1));
point_within(new Circle(loc(0,0),1));
}
As provided by this lovely stackoverflow answer
As you can see, it is not merely possible but also pretty.
Garbage Collection
Future standard, allocators, RAII, and shared_ptr are sufficient
While C++ does not have a GC, there is a proposal for one that was voted down in C++11, but may be included in C++1y. There are a wide variety of user defined ones you can use, but the C++ does not need garbage collection.
C++ has an idiom know as RAII to deal with resources and memory; for this reason, C++ has no need for a GC as it does not produce garbage; everything is cleaned up promptly and in the correct order by default. This does introduce the problem of who owns what, but this is largely solved in C++11 via shared pointers, weak pointers, and unique pointers:
// One shared pointer to some shared resource
std::shared_ptr<int> my_int (new int);
// Now we both own it!
std::shared_ptr<int> shared_int(my_int);
// I can use this int, but I cannot prevent it's destruction
std::weak_ptr<int> weak_int (shared_int);
// Only I can ever own this int
std::unique_ptr<int> unique_int (new int);
These allow you to provide a much more deterministic and user controlled form of garbage collection, that does not invoke any stop the world behavior.
That not easy enough for you? Use a custom allocator, such as boost::pool or roll your own; it's relatively easy to use a pool or arena based allocator to get the best of both worlds: you can easily allocate as freely as you like, then simply delete the pool or arena when you are done. No fuss, no muss, and no stopping the world.
However, in modern C++11 design, you would almost never use new anyway except when allocating into a *_ptr, so the wish for a GC is not necessary anyway.
In Summary
C++ has plenty of functional language features, and all of the ones you listed can be done, with the same power and expression ability of Haskell or Lisp. However, most of these features are not built in by default; this is changing, with the introduction of lambda's (which fill in the functional parts of the STL), and with the absorption of boost into the standard language.
Not all of these idioms are the most palatable, but none of them are particularly onerous to me, or unamendable to a few macros to make them easier to swallow. But anyone who says they are not possible has not done their research, and would seem to me to have limited experience with actual C++ programming.
From your list, C++ can do:
function signatures as types
type polymorphism (but not first-class like in many functional languages)
immutable data structures (but they require more work)
It can do only very limited forms of:
higher order functions / closures (basically, without GC most of the more interesting higher-order functional idioms are unusable)
adhoc data structures (if you mean in the form of light-weight structural types)
You can essentially forget about:
algebraic data types & pattern matching
partial function applications (requires implicit closures in general)
type inference (despite what people call "type inference" in C++ land it's a far shot from what you get with Hindley/Milner a la ML or Haskell)
tail calls (some compilers can optimise some limited cases of tail self-recursion, but there is no guarantee, and the language is actively hostile to the general case (pointers to the stack, destructors, and all that))
garbage collection (you can use Boehm's conservative collector, but it's no real substitute and rather unlikely to coexist peacefully with third-party code)
Overall, trying to do anything functional that goes beyond trivialities will be either a major pain in C++ or outright unusable. And even the things that are easy enough often require so much boilerplate and heavy notation that they are not very attractive. (Some C++ aficionados like to claim the opposite, but frankly, most of them seem to have rather limited experience with actual functional programming.)
(Just to add a little to Alice's answer, which is excellent.)
I'm far from a functional programming expert, but the compile-time template metaprogramming language in C++ is often seen as being "functional", albeit with a very arcane syntax. In this language, "functions" become (often recursive) class template instantiations. Partial specialisation serves the purpose of pattern matching, to terminate recursion and so on. So a compile-time factorial might look something like so:
template <int I>
struct fact
{
static const int value = I * fact<I-1>::value;
};
template <>
struct fact<1>
{
static const int value = 1;
};
Of course, this is pretty hideous, but many people (particularly the Boost developers) have done incredibly clever and complex things with just these tools.
It's possibly also worth mentioning the C++11 keyword constexpr, which denotes functions which may be evaluated at compile time. In C++11, constexpr functions are restricted to (basically) just a bare return statement; but the ternary operator and recursion are allowed, so the above compile-time factorial can be restated much more succinctly (and understandably) as:
constexpr int fact(int i)
{
return i == 1 ? 1 : i * fact(i-1);
}
with the added benefit that fact() can now be called at run-time too. Whether this constitutes programming in a functional style is left for the reader to decide :-)
(C++14 looks likely to remove many of the restrictions from constexpr functions, allowing a very large subset of C++ to be called at compile-time)
On a funny note, if there's a <functional> standard header, that means that there's at least some substantial support for functional programming.
Indeed, a great and important part of the C++ language is, in fact, template meta-programming, which is a powerful tool when one needs to write generic code. But TMP is compile-time and, most importantly, is about type computation. And types can't be changed, so once you "declare a variable holding a type", it will not hold any other type (more on the matter here); it's immutable, so you have to think in terms of functional programming principles to work with and to understand TMP. To cite Louis Dionne (from the intro to his Boost.Hana's documentation),
Programming with heterogeneous objects is inherently functional – since it is impossible to modify the type of an object, a new object must be introduced instead, which rules out mutation. Unlike previous metaprogramming libraries whose design was modeled on the STL, Hana uses a functional style of programming which is the source for a good portion of its expressiveness. However, as a result, many concepts presented in the reference will be unfamiliar to C++ programmers without a knowledge of functional programming. The reference attempts to make these concepts approachable by using intuition whenever possible, but bear in mind that the highest rewards are usually the fruit of some effort.
With reference to the list in the question, I would suggest reading Why Functional Programming Matters, which highlights that the truly fundamental features of such a programming paradigm are mainly 2:
higher order functions,
lazy evaluation.
And C++ gives you both. At least today:
That C++ has higher-order functions is not been a secret for a long time. Most if not all <algorithm>s accept a function or function object to customize their behavior, so algorithms are higher-order function. Some "standard" function objects you might want to pass to higher-order functions are defined in <functional> and with the help of lambdas you can write as many and as varied as you want.
As stated in a comment, you can do all you want with a Turing-complete language, and C++ offers tools to make lazy evaluation possible with human-level efforts (no, I'm not saying I'd been able to do it). A library which leverages a lot of C++ power to enable lazy evaluation is Range-v3 (which C++20's <ranges> is just a small part of). To give a silly example, if you were to execute
somelist = join $ map (take 1) $ chunk 2 $ drop 10 $ [0..] in Haskell
you'd have in somelist a proxy for an infinite list that would materialize to [10,12,14,16,…] if you were to try traversing it. Similarly with Range-v3 you could do the same think by writing something very similar, such as auto somelist = iota(0) | drop(10) | chunk(2) | transform(take(1)) | join; (working code for a similar example is here), where the differences are minimal, if you think about it.
Furthermore, I would suggest to refer to Ivan Čukić' Functional Programming in C++ for some practical examples of how you can write functional programming in C++.
And since I mentioned it, I would strongly suggest to read QuickStart of Louis Dionne's Boost.Hana (I'll make some reference to specific bits of the doc in the rest of the answer).
Now, some comments on some of the points in the list.
higher order functions
I'd say C++ has this since… the '90s? Having higher-order functions in a language simply means that functions are first class or, in other words, that they can be passed to and returned by other functions calls. Now, strictly speaking, properly said C++ functions are not like that: you can't a pass a function to anther one, but just a pointer to it, which in many scenarii works the same, but it's still a different thing. On the other hand C++ has operator overloading, which allows you to write a struct+operator(), and an object of that class *can be passed around and behaves just like a function. So yes, C++ has had higher-order functions for a long time; at least since operator overloading was introduced (1985, apparently).
lambdas (closures/anonymous functions)
Lambdas were introduced in C++11, but they have become more powerful with each standard. To give some examples, C++14 introduced generic lambdas, C++17 made stateless lambdas constexprable, and C++20 allowed an explicit list of template parameters. They obviously are more restricted than hand-written struct+operator()s, but as far as functional programming is concerned, they are just good. Personally, I only see them come short pre-C++20 because you can't make them accept all types satisfying a concept: you either have [](the type){} or [](auto){}. With C++20 you can have []<SomeConcept T>(T){}, so I don't know why I'd ever want to write a struct+operator().
immutable data structures
Well, I would say that mutating data structures is a choice, more than a tool. I'm happy I can mutate things if I want to, but I can still write code by adhering to functional programming principles.
partial function applications
As soon as you can pass functions around, you can write higher-order functions to curry or partially apply functions. I think there's an example in the book I mentioned above, but more practically, you can just make use of Boost.Hana's abstractions. It offers boost::hana::partial to partially apply a function, satisfying partial(f, x...)(y...) == f(x..., y...); but also reverse_partial, which satisfies reverse_partial(f, x...)(y...) == f(y..., x...). But in reality, it offers quite a bit combinators which are common to the functional programming language par excellence, Haskell, and which I list below¹.
tail recursion
I suspect this is more about how good compilers can be at understanding your code and producing the most appropriate binary.
pattern matching
Not there yet, but this talk by Herb Sutter is a "must watch"!
garbage collection
C++11 introduced std::unique_ptr, std::shared_ptr, std::weak_ptr, which have (all?) improved over time. They all together provide what you need to have a deterministic garbage collector in C++.
(¹) Here are some of the combinators offered by Boost.Hana.
filp, satisfying flip(f)(x, y, z...) == f(y, x, z...) and, if you are familiar with Haskell, corresponding to Haskell's namesake,
id, which corresponds to C++20 std::identity and to Haskell's namesake
on, which satisfies on(f, g)(x...) == f(g(x)...) and corresponds to Haskell's Data.Function.on, but is actually more general!
compose, which corresponds to Haskell's namesake
always, which corresponds to Haskell's const
demux, which I don't dare explaining in words, but which obeys demux(f)(g...)(x...) == f(g(x...)...)

C++ templates for performance? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I have seen online a few times it has been mentioned that C++ can be ever faster using templates.
Could someone explain, including at a low level why this is exactly? I always presumed such a "nice" feature would have overhead like most useful concepts.
I am really intrigued by this from a ultra low latency perspective!
A common example is sorting.
In C, qsort takes a pointer to a comparison function. Generally speaking, there will be one copy of the qsort code, which is not inlined. It will make a call through the pointer to the comparison routine -- this of course is also not inlined.
In C++, std::sort is a template, and it can take a functor object as comparator. There is a different copy of std::sort for each different type used as a comparator. Assuming you use a functor class with overloaded operator(), then the call to the comparator can easily be inlined into this copy of std::sort.
So, templates give you more inlining because there are more copies of the sort code, each of which can inline a different comparator. Inlining is quite a good optimization, and sort routines do a lot of comparisons, so you can often measure std::sort running faster than an equivalent qsort. The cost of this is the chance of much larger code -- if your program uses a lot of different comparators then you get a lot of different copies of the sort routine, each with a different comparator baked into it.
In principle there's no reason why a C implementation can't inline qsort into the place it is called. Then if it was called with the name of the function, the optimizer could in theory observe that at the point it is used, the function pointer must still point to that same function. Then it can inline the call to the function, and the result would be similar to the result with std::sort. But in practice, compilers tend not to take the first step, inlining qsort. That's because (a) it's large, and (b) it's in a different translation unit, usually compiled into some library that your program is linked against, and (c) to do it this way, you'd have an inlined copy of qsort for every call to it, not just a copy for every different comparator. So it would be even more bloated than the C++, unless the implementation could also find a way to common up the code in cases where qsort is called in different places with the same comparator.
So, general-purpose functions like qsort in C tend to have some overheads on account of calls through function pointers, or other indirection[*]. Templates in C++ are a common way of keeping the source code generic, but ensuring that it compiles to a special-purpose function (or several such functions). The special-purpose code hopefully is faster.
It's worth noting that templates are not by any means just about performance. std::sort is itself more general-purpose than qsort in some ways. For example qsort only sorts arrays, whereas std::sort can sort anything that provides a random-access iterator. It can for example sort a deque, which under the covers is several disjoint arrays allocated separately. So the use of templates doesn't necessarily provide any performance benefit, it might be done for other reasons. It just happens that templates do affect performance.
[*] another example with sorting - qsort takes an integer parameter saying how big each element of the array is, and when it moves elements it therefore must call memcpy or similar with the value of this variable. std::sort knows at compile-time the exact type of the elements, and hence the exact size. It can inline a copy constructor call that in turn might translate to instructions to copy that number of bytes. As with the inlined comparator, it's often possible to copy exactly 4 (or 8, or 16, or whatever) bytes faster than you'd get by calling a routine that copies a variable number of bytes, passing it the value 4 (or 8, or 16, or whatever). As before, if you called qsort with a literal value for the size, and that call to qsort was inlined, then the compiler could perform the exact same optimization in C. But in practice you don't see that.
"faster" depends on what you compare it to.
Templates are fully evaluated by the compiler, and so they have zero overhead at runtime. Calling Foo<int>() is exactly as efficient as calling FooInt().
So compared to approaches which rely on more work being done at runtime, for example by calling virtual functions, templates can indeed be faster. Compared to hand-written code written precisely for that scenario, there is zero difference.
So the nice thing about templates isn't that they are "faster" than what you could do otherwise, but that they are "as fast" as hand-written code, while also being generic and reusable.
Another remarkable example of using templates to improve runtime performance is the Blitz++ numerics library. It pioneered the use of so-called expression templates, using compile-time logic to transform arithmetic expressions involving large vectors and matrices into equivalent ones that are much easier to compile to efficient machine code. For instance, given the following pseudocode:
vector<1000> a = foo(), b = bar(), c = baz(), result;
result = a + b + c;
A naive approach would add each elemnt of a and b together, store the result in a temporary vector, then do the same with c, and finally copy the result into result. Using expression template magic, the resulting code will instead be equivalent to this:
for(int i = 0; i < 1000; ++i) {
result[i] = a[i] + b[i] + c[i];
}
This is much faster, making better use of cache locality and avoiding unnecessary temporaries along the way. It also avoids aliasing problems, where the compiler cannot prove that two pointers point to distinct memory areas, forcing it to produce unoptimal code. Expression templates are now commonly used in high-performance numerics, as well as having other uses not involving performance, such as the Boost.Spirit parsing library.
I am not sure if you are talking about C++ template metaprogramming : doing some calculation during compilation time so you get result during run time almost instantly.
If so,here is a example.
By using template metaprogramming and template specialization to provide the ending condition for the recursion, the factorials used in the program, ignoring any factorial not used, can be calculated at compile-time by this code
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
int x = Factorial<4>::value; // == 24
int y = Factorial<0>::value; // == 1
}
Here is a bit more to read
http://en.wikipedia.org/wiki/Template_metaprogramming
Most likely they're talking about template metaprogramming, which is a trade between compilation speed for runtime speed. The basic idea is that you can write a program which will execute in the C++ compiler. For example (stolen from wikipedia):
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
int x = Factorial<4>::value; // == 24
int y = Factorial<0>::value; // == 1
}
Thus, to calculate Factorial<4>::value, the compiler needs to "unroll" the template and calculate Factorial<3>::value and so on. This is all done at compile time, which obviously increases the amount of time to compile, but will effectively replace it with a constant value at runtime.
The reason templates are considered faster is that they are visible to the compiler.
So while a plain C sorting algorithm would look like this:
void qsort ( void * base, size_t num, size_t size,
int ( * comparator ) ( const void *, const void * ) );
Accepting a function pointer to do comparisons and thus inuring a function call on each comparison the C++ version would look like this:
template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp);
Thus comp is a template argument and if it's a class with operator() defined the compiler can inline the implementation of the function into the loop and avoid many function calls.
I don't think the point that was being made is that template meta programming is faster since this is a rarely used feature in most code bases.

Are efficient "repeatedly used intermediates" possible in C++ expression template programming?

Here's one thing I haven't seen explicitly addressed in C++ expression template programming in order to avoid building unnecessary temporaries (through creating trees of "inlinable templated objects" that only get collapsed at the assignment operator). Suppose for the illustration we're modeling 1-D sequences of values, with elementwise application of arithmetic operators like +, *, etc. Call the basic class for fully-created sequences Seq (which holds a fixed-length list of doubles for the sake of concreteness) and consider the following illustrative pseudo-C++-code.
void f(Seq &a,Seq &b,Seq &c,Seq &d,Seq &e){
AType t=(a+2*b)/(a+b+c); // question is about what AType can be
Seq f=d*t;
Seq g=e*e*t;
//do something with f and g
}
where there are expression templated overloads for +, etc, elsewhere. For the line defining t:
I can implement this code if I make AType be Seq, but then I've created this full intermediate variable when I don't need it (except in how it enables computation of f and g). But at least it's only calculated once.
I can also implement this making AType be the appropriate templated expression type, so that a full Seq isn't created at the commented line, but consumed chunk-by-chunk in f and g. But then the same computation involved in creating every particular chunk will be repeated in both f and g. (I suppose in theory an incredibly smart compiler might realise the same computation is being done twice and CSE-it, but I don't think any do and I wouldn't want to rely on an optimiser always being able to spot the opportunities.)
My understanding is that there's no clever code rewriting and/or usage of templates that allow each chunk of t to be calculated only once and for t to be calculated chunkwise rather than all at once?
(I can vaguely imagine AType could be some kind of object that contains both an expression template type and a cached value that gets written after it's evaluated the first time, but that doesn't seem to help with the need to synchronise the two implicit loops in the assignments to f and g.)
In googling, I have come across one Masters thesis on another subject that mentions in passing that manual "common subexpression elimination" should be avoided with expression templates, but I'd like to find a more authoritative "it's not possible" or a "here's how to do it".
The closest stackoverflow question is Intermediate results using expression templates
which seems to be about the type-naming issue rather than the efficiency issue in creating a full intermediate.
Since you obviously don't want to do the entire calculation twice, you have to cache it somehow. The easiest way to cache it seems to be for AType to be a Seq. You say This has the downside of a full intermediate variable, but that's exactly what you want in this case. That full intermediate is your cache, and cannot be trivially avoided.
If you profile the code and this is a chokepoint, then the only faster way I can think of is to write a special function to calculate f and g in parallell, but that'd be super-confusing, and very much not recommended.
void g(Seq &d, Seq &e, Expr &t, Seq &f, Seq &g)
{
for(int i=0; i<d.size(); ++i) {
auto ti = t[i];
f[i] = d[i]*ti;
g[i] = e[i]*e[i]*ti;
}
}
void f(Seq &a,Seq &b,Seq &c,Seq &d,Seq &e)
{
Expr t = (a+2*b)/(a+b+c);
Seq f, g;
g(d, e, t, f, g);
//do something with f and g
}