std::function instead of templates for predicates - c++

Many standard library algorithms take predicate functions. However, the type of these predicates is an arbitrary, user-provided template parameter. Why doesn't C++11 specify that these take a specific type, like std::function instead? For example:
template< class InputIt >
InputIt find_if( InputIt first, InputIt last,
std::function<bool()> p );
Isn't using this instead of a template as argument type not much more clean?

std::function is for runtime polymorphism. Any particular std::function instance could be storing a functor of any type (a type that's appropriate for the std::function's signature, of course).
Standard library algorithms and such are templated on the type of their function parameters. As such, they don't need runtime polymorphism to do their job; they rely on compile-time polymorphism.
Most important of all, such algorithms don't need to force the cost of runtime polymorphism on you. If you want runtime polymorphism, you can send it a std::function or whatever. If you want compile-time polymorphism, you provide it a type that doesn't use polymorphic dispatch (aka: most functors or functions).
The cost of runtime polymorphism also includes the inability to inline the function call. Using a proper functor (or even function pointers, depending on how good your compiler is), the compiler can generally inline the function call if it so desires. With runtime polymorphism, not only are you paying the cost of the runtime dispatch (which may include additional parameter forwarding costs), you're also loosing important optimization opportunities.

Performance!
Template base function is very very better than std::function mode. I did this test for you:
template <typename F>
void test1(const F &f)
{
for (unsigned long long i = 0; i < 19000000; i++)
f();
}
void test2(function<void()> &f)
{
for (unsigned long long i = 0; i < 19000000; i++)
f();
}
int main()
{
{
LARGE_INTEGER frequency, start, end;
double interval;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
unsigned long long x = 0;
test1([&x]()
{
x++;
});
QueryPerformanceCounter(&end);
interval = (double) (end.QuadPart - start.QuadPart) / frequency.QuadPart;
cout << "Template mode: " << interval << " " << x << endl;
}
{
LARGE_INTEGER frequency, start, end;
double interval;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
unsigned long long x = 0;
function<void() > f = [&x]()
{
x++;
};
test2(f);
QueryPerformanceCounter(&end);
interval = (double) (end.QuadPart - start.QuadPart) / frequency.QuadPart;
cout << "std::function mode:" << interval << " " << x << endl;
}
}
Template mode: 2.13861e-006
std::function mode:0.220006
gcc 4.7.2 on Windows7 -O2 Core2 Duo CPU 2.40GHz

Because std::function is imperfect.
How is it imperfect? Let me enumerate the ways.
{
First, std::function doesn't support perfect fowarding of arbitrary objects passed in to it. And, in practice, it cannot. std::function exposes one fixed signature to callers, and can accept many kinds of callees, and perfect forwarding requires a custom-crafted signature for each caller and callee. It does support perfect forwarding of exactly the arguments it exposes in its signature, but that isn't sufficient.
Imagine a std::function that takes two arguments, and int and a double. For it to do perfect forwarding, it would have to accept int&, int&& and int const&, times the same set for double (let alone volatile varients thereof). The number of signatures that each std::function has to accept to pull off perfect forwarding grows exponentially with the number of arguments it has. std::function's set of signatures it exposes (currently 1) is fixed at instantiation, while a templates set of signatures it exposes is unlimited and only generated when used. This is important because some function-like objects do optimize for these cases differently! So every std::function you have removed opportunities to perfectly forward calls to the wrapped type.
A second reason why std::function is imperfect is because compilers suck. If you wrap a lambda in a std::function then call an algorithm with it, the compiler in theory could realize that this std::function is wrapping some fixed lambda -- but in practice, it loses track of this fact, and treats the std::function as a wrapper around some generic class. So even in cases where the signature of the std::function exactly matches the use-cases of the algorithm, preventing the type-bottleneck of std::function from making the forwarding imperfect, in practice there will be overhead due to the type-erasure performed by std::function, and the compiler will find it hard to optimize over the std::function call "barrier".
A third reason why std::function is imperfect is that it would encourage algorithm writers to overly restrict what parameters can be passed in algorithms. If you examine find_if, the naive assumption is that the thing you are looking for should be the same type as the types stored in the container, or at least convertible: but the std::find_if algorithm only requires that they be comparible under the passed in functor.
This allows you to write multi-type aware functors and pass in a target object that is of an unrelated type to the type on the container, and things work just fine. Most people don't need this, and their code works find without it -- which is good as well.
The naive std::find_if would extract the underlying type of the container, and the comparison function would be between pairs of that type -- or, it would be a 4 way comparison between container types and the type of the thing being searched for. In one case, we lose flexibility -- in the other case, everyone pays for a strange corner case. And in C++, you should only pay for the features you need when you need them!
A forth reason why std::function is imperfect is that it is fundamentally a tool of type erasure. These are implementation details, but I'm not aware of a compiler which strays far from them. A std::function's purpose is expose a single signature and return value, and say "I can store anything that matches this signature and this return value, and you can call it". It exposes a static run-time interface and implementation to do this task. When you initialize a std::function, it does compile-time work to generate a helper object that wraps that particular object in the uniform std::function interface, then stores that in the pImpl pattern. All of this is work that is unnecessary if you don't need type erasure.
The standard algorithms are about writing high level code that is nearly as efficient as hand-crafted solutions. Even the cost of a pointer function call isn't required to solve most of these problems, let along a virtual call through a type erased std::function.
}; // enum
std::function is an awesome tool for callbacks, to replace boilerplate single-purpose virtual interfaces, and when you need to hide the implementation details from the caller (say, you need to cross compilation unit boundaries for design decisions).
The good news is that better solutions to this problem are coming down the pipe. In particular, one of the goals for C++14 or C++17 is that it is going to have some kind of "concept" support, where you can say "this template argument has the following properties". What the exact syntax will be is far from certain -- the C++11 Concept proposal is probably going way to far -- but there is lots of enthusiasm about it, and there is a working group on the problem right now.
When or if it is done, you'll be able to mark up the functor with meaningful concept information that says "this argument isn't just any type, but a type that is a functor that takes two values (including the contained data types), and returns a bool compatible value" that the compiler, your IDE, and you can understand without having to go to the documentation for the function.

Related

Minimum syntax to guarantee no dynamic memory with std::function

Quite often I want to write higher order functional code like
void f(int value, const std::function<void(int)>& callback);
int x, y=5;
f(y, [&](int result) { x = result; });
In cases like these, I would like to be able to guarantee that the std::function constructor does not allocate any memory. The guarantees in the spec are... hard to read. There seems to be some guarantees surrounding reference_wrapper, but I have not been able to get them to work cleanly, due to what I think are lvalue vs rvalue issues. I end up with
auto callback = [&](int result) { x = result; };
f(y, std::ref(callback));
In many of these cases, I want to leverage virtual functions, so I can't just template these issues away (although I have played with using a wrapper that accepts the lambda type as an argument, and wraps it with std::ref, sidestepping any issues regarding temporaries)
What is the minimum amount of syntactic boilerplate needed to ensure this pattern does not allocate any memory?
There are no guarantees of allocations (or lack of thereof) specified in the standard for std::function constructors. Most you can hope for is a recommendation, from 20.14.17.3.2:
Recommended practice: Implementations should avoid the use of
dynamically allocated memory for small callable objects, for example,
where f refers to an object holding only a pointer or reference to an
object and a member function pointer.
So your best bet would be to look at your implementation and check when allocation does not happen.

Modern C++ approach for providing optional arguments

Let's take the following function declaration:
void print(SomeType const* i);
Here, the const* nature of the argument i suggest the intent, that the parameter is optional, since it may be nullptr. If this was not intended, the argument would instead just be a const&. Communicating optional-semantics were certainly not the original intent for designing pointers, but using them to do so happens to work just fine for a long time.
Now, since using raw pointers is generally discouraged in modern C++ (and should be avoided in favor of std::unique_ptr and std::shared_ptr to precisely indicate particular ownership-semantics), I wonder how to properly indicate function parameters' optional-semantics without passing by value, i. e. copying, as
void print(std::optional<SomeType> i);
would do.
After thinking about it for a while I came up with the idea of using:
void print(std::optional<SomeType const&> i);
This would in fact be most precise. But it turns out that std::optional cannot have reference types.¹
Also, using
void print(std::optional<SomeType> const& i);
would in no way be optimal, since then we would require our SomeType to exists in an std::optional on the caller-side, again possibly (or rather likely) requiring a copy there.
Question: So what would be a nice modern approach for allowing optional arguments without copying? Is using a raw pointer here still a reasonable approach in modern C++?
¹: Ironically the depicted reason for why std::optional cannot have reference types (controversy about rebinding or forwarding on assignment) does not apply in the case of std::optionals of const references, since they cannot be assigned to.
Accepting a raw pointer is perfectly fine and is still done in plenty of "modern" codebases (which I'll note is a fast-moving target). Just put a comment on the function saying that it's allowed to be null and whether the function holds a copy of the pointer after the call (i.e. what are the lifetime requirements for the pointed-to value).
Does function overloading provide a clean solution here? E.g. To declare both the const ref and empty param list versions of the function?
This may depend on what the function body does in the no argument/null case - and how you can manage the two implementations to minimize code overlap.
Raw pointers are usually fine for this type of optional argument passing, actually one of the only times it is fine to use raw pointers overall. This is also the canonical recommended way.
That being said, boost::optional does allow you to use reference optional and const reference optionals. It was decided against to have this feature in the std library (for reasons I leave out here).
This is actually what std::reference_wrapper was made for. Also see Does it make sense to combine optional with reference_wrapper? for more reasoning as to when to use it, and when not to use it.
Here, the const* nature of the argument i suggest the intent, that the parameter is optional since it may be nullptr.
[...]
So what would be a nice modern approach for allowing optional arguments without copying?
Allowing an optional argument (not in the std::optional sense, but in the semantic sense) with differing implementation variations based on whether the optional argument is present or not sound like an ideal candidate for overloading:
struct SomeType { int value; };
namespace detail {
void my_print_impl(const SomeType& i) {
std::cout << i.value;
}
} // namespace detail
void my_print() {
const SomeType default_i{42};
detail::my_print_impl(default_i);
}
void my_print(const SomeType& i) {
detail::my_print_impl(i);
}
or
namespace detail {
void my_print_impl() {
std::cout << "always print me\n";
}
} // namespace detail
void my_print() {
detail::my_print_impl();
}
void my_print(const SomeType& i) {
detail::my_print_impl();
std::cout << "have some type: " << i.value;
}
or some similar variation, depending on what your implementation should do depending on the existence/non-existence of the optional argument.
Optional references, otherwise, are basically raw pointers, and the latter may just as well be used (if overloading is not applicable).

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++11 std::set lambda comparison function

I want to create a std::set with a custom comparison function. I could define it as a class with operator(), but I wanted to enjoy the ability to define a lambda where it is used, so I decided to define the lambda function in the initialization list of the constructor of the class which has the std::set as a member. But I can't get the type of the lambda. Before I proceed, here's an example:
class Foo
{
private:
std::set<int, /*???*/> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
I found two solutions after searching: one, using std::function. Just have the set comparison function type be std::function<bool (int, int)> and pass the lambda exactly like I did. The second solution is to write a make_set function, like std::make_pair.
SOLUTION 1:
class Foo
{
private:
std::set<int, std::function<bool (int, int)> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
SOLUTION 2:
template <class Key, class Compare>
std::set<Key, Compare> make_set (Compare compare)
{
return std::set<Key, Compare> (compare);
}
The question is, do I have a good reason to prefer one solution over the other? I prefer the first one because it makes use of standard features (make_set is not a standard function), but I wonder: does using std::function make the code (potentially) slower? I mean, does it lower the chance the compiler inlines the comparison function, or it should be smart enough to behave exactly the same like it would it was a lambda function type and not std::function (I know, in this case it can't be a lambda type, but you know, I'm asking in general) ?
(I use GCC, but I'd like to know what popular compilers do in general)
SUMMARY, AFTER I GOT LOTS OF GREAT ANSWERS:
If speed is critical, the best solution is to use an class with operator() aka functor. It's easiest for the compiler to optimize and avoid any indirections.
For easy maintenance and a better general-purpose solution, using C++11 features, use std::function. It's still fast (just a little bit slower than the functor, but it may be negligible) and you can use any function - std::function, lambda, any callable object.
There's also an option to use a function pointer, but if there's no speed issue I think std::function is better (if you use C++11).
There's an option to define the lambda function somewhere else, but then you gain nothing from the comparison function being a lambda expression, since you could as well make it a class with operator() and the location of definition wouldn't be the set construction anyway.
There are more ideas, such as using delegation. If you want a more thorough explanation of all solutions, read the answers :)
It's unlikely that the compiler will be able to inline a std::function call, whereas any compiler that supports lambdas would almost certainly inline the functor version, including if that functor is a lambda not hidden by a std::function.
You could use decltype to get the lambda's comparator type:
#include <set>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
auto comp = [](int x, int y){ return x < y; };
auto set = std::set<int,decltype(comp)>( comp );
set.insert(1);
set.insert(10);
set.insert(1); // Dupe!
set.insert(2);
std::copy( set.begin(), set.end(), std::ostream_iterator<int>(std::cout, "\n") );
}
Which prints:
1
2
10
See it run live on Coliru.
Yes, a std::function introduces nearly unavoidable indirection to your set. While the compiler can always, in theory, figure out that all use of your set's std::function involves calling it on a lambda that is always the exact same lambda, that is both hard and extremely fragile.
Fragile, because before the compiler can prove to itself that all calls to that std::function are actually calls to your lambda, it must prove that no access to your std::set ever sets the std::function to anything but your lambda. Which means it has to track down all possible routes to reach your std::set in all compilation units and prove none of them do it.
This might be possible in some cases, but relatively innocuous changes could break it even if your compiler managed to prove it.
On the other hand, a functor with a stateless operator() has easy to prove behavior, and optimizations involving that are everyday things.
So yes, in practice I'd suspect std::function could be slower. On the other hand, std::function solution is easier to maintain than the make_set one, and exchanging programmer time for program performance is pretty fungible.
make_set has the serious disadvantage that any such set's type must be inferred from the call to make_set. Often a set stores persistent state, and not something you create on the stack then let fall out of scope.
If you created a static or global stateless lambda auto MyComp = [](A const&, A const&)->bool { ... }, you can use the std::set<A, decltype(MyComp)> syntax to create a set that can persist, yet is easy for the compiler to optimize (because all instances of decltype(MyComp) are stateless functors) and inline. I point this out, because you are sticking the set in a struct. (Or does your compiler support
struct Foo {
auto mySet = make_set<int>([](int l, int r){ return l<r; });
};
which I would find surprising!)
Finally, if you are worried about performance, consider that std::unordered_set is much faster (at the cost of being unable to iterate over the contents in order, and having to write/find a good hash), and that a sorted std::vector is better if you have a 2-phase "insert everything" then "query contents repeatedly". Simply stuff it into the vector first, then sort unique erase, then use the free equal_range algorithm.
A stateless lambda (i.e. one with no captures) can decay to a function pointer, so your type could be:
std::set<int, bool (*)(int, int)> numbers;
Otherwise I'd go for the make_set solution. If you won't use a one-line creation function because it's non-standard you're not going to get much code written!
From my experience playing around with the profiler, the best compromise between performance and beauty is to use a custom delegate implementation, such as:
https://codereview.stackexchange.com/questions/14730/impossibly-fast-delegate-in-c11
As the std::function is usually a bit too heavy. I can't comment on your specific circumstances, as I don't know them, though.
If you're determined to have the set as a class member, initializing its comparator at constructor time, then at least one level of indirection is unavoidable. Consider that as far as the compiler knows, you could add another constructor:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
Foo (char) : numbers ([](int x, int y)
{
return x > y;
})
{
}
Once the you have an object of type Foo, the type of the set doesn't carry information on which constructor initialized its comparator, so to call the correct lambda requires an indirection to the run-time selected lambda operator().
Since you're using captureless lambdas, you could use the function pointer type bool (*)(int, int) as your comparator type, as captureless lambdas have the appropriate conversion function. This would of course involve an indirection through the function pointer.
The difference highly depends on your compiler's optimizations. If it optimizes lambda in a std::function those are equivalent, if not you introduce an indirection in the former that you won't have in the latter.

Could multiple proxy classes make up a STL-proof bitvector?

It's well known that std::vector<bool> does not satisfy the Standard's container requirements, mainly because the packed representation prevents T* x = &v[i] from returning a pointer to a bool.
My question is: can this be remedied/mitigated when the reference_proxy overloads the address-of operator& to return a pointer_proxy?
The pointer-proxy could contain the same data as the reference_proxy in most implementations, namely a pointer into the packed data and a mask to isolate the particular bit inside the block pointed to. Indirection of the pointer_proxy would then yield the reference_proxy. Essentially both proxies are "fat" pointers, which are, however, still rather light-weight compared to disk-based proxy containers.
Instead of T* x = &v[0] one could then do auto x = &v[0], and use x like if(*x) without problems. I would also like to be able to write for(auto b: v) { /* ... */ }
Questions: would such a multi-proxy approach work with the STL's algorithms? Or do some algorithms really rely on the requirement that x needs to be a real bool*? Or are there too many consecutive user-defined conversions required that prevent this to work? I'd like to know any of such obstructions before trying to fully complete the above implementation sketch.
UPDATE (based on #HowardHinnant 's answer and this ancient discussion on comp.std.c++)
You can come a long way to almost mimic the builtin types: for any given type T, a pair of proxies (e.g. reference_proxy and iterator_proxy) can be made mutually consistent in the sense that reference_proxy::operator&() and iterator_proxy::operator*() are each other's inverse.
However, at some point one needs to map the proxy objects back to behave like T* or T&. For iterator proxies, one can overload operator->() and access the template T's interface without reimplementing all the functionality. However, for reference proxies, you would need to overload operator.(), and that is not allowed in current C++ (although Sebastian Redl presented such a proposal on BoostCon 2013). You can make a verbose work-around like a .get() member inside the reference proxy, or implement all of T's interface inside the reference (this is what is done for vector::bit_reference), but this will either lose the builtin syntax or introduce user-defined conversions that do not have builtin semantics for type conversions (you can have at most one user-defined conversion per argument).
My question is: can this be remedied/mitigated when the
reference_proxy overloads the address-of operator& to return a
pointer_proxy?
libc++ actually does this.
#include <vector>
#include <cassert>
int main()
{
std::vector<bool> v(1);
std::vector<bool>::pointer pb = &v[0];
assert(*pb == false);
*pb = true;
assert(v[0] == true);
std::vector<bool>::const_pointer cbp = pb;
assert(*cbp == true);
v[0] = false;
assert(*cbp == false);
}
It even extends to const_pointer and const_reference in ways that mimic the same types for vector<int>. This is a non-conforming extension for libc++. But it makes writing generic code which might be instantiated on vector<bool> far more likely to compile and behave correctly.
Questions: would such a multi-proxy approach work with the STL's
algorithms? Or do some algorithms really rely on the requirement that
x needs to be a real bool*? Or are there too many consecutive
user-defined conversions required that prevent this to work?
All of libc++'s algorithms work with vector<bool>. Some of them with quite spectacular performance. One algorithm in particular must have special treatment which the standard unfortunately does not mandate:
#include <vector>
#include <cassert>
int main()
{
std::vector<bool> v(1);
bool b = true;
assert(v[0] == false);
assert(b == true);
std::swap(b, v[0]);
assert(v[0] == true);
assert(b == false);
}
This is very easy for the implementation to accomplish. One simply needs to make sure swap works for any combination of bool and vector<bool>::reference. But I don't know if any implementation besides libc++ does this, and it is not mandated by C++11.
An array of bits is a wonderful data structure. But unfortunately it is poorly specified in the C++ standard. libc++ has gone somewhat outlaw to demonstrate that this can be a very useful and high performance data structure. The hope is that a future C++ standard may migrate in this direction to the benefit of the C++ programmer.
Offhand I would say first, that it will actually depend more on the particulars of each individual STL implementation since it doesn't officially conform to the standard requirement that a *reference_type to be lvalue of T*. So regarding potential implementation issues:
The main reason any piece of code would be explicitly dependent on the container's pointer being a real bool* is if the algo was using pointer arithmetic, in which case the size of the pointer type becomes relevant. Pointer arithmetic though would bypass the iterator interface and thus defeat the main purpose of the whole STL container-by-iterator design. std::vector<> itself is guaranteed to be contiguous in C++11, which allows optimized specializations of both STL algos and compiler for(:), both of which may use pointer arithmetic internally. If your type isn't derived from std::vector then that shouldn't be an issue; everything should just assume the iterator method instead.
However! STL code may still take pointers not for the purpose of pointer arithmetic but rather for some other purpose. In this case the problem is C++ syntax. Eg, quoting your own question:
Instead of T* x = &v[0] one could then do auto x = &v[0]
Any templated code in the STL will also have to do the same thing... and that seems entirely unlikely at this point that STL implementations will be making wide use of auto. There may be other situations were the STL attempts to do clever r-value casting tricks that end up failing because it isn't expecting mismatched reference types.
Regarding for(auto b: v) { /* ... */ }: I see no reason that shouldn't work. I think it will generate code that will be far less efficient than the same version you could just roll yourself in 15 mins (or less). I only bring it up since you mention intrinsics in the OP, which imples some consideration for performance. You won't be able to help it out using intrinsics either. There's nothing an intrinsic can do that somehow surpasses a simple bitwise shift for sequentially traversing an array of bits. Most of the added overhead will be from the compiler generating code to update the iterator pointer and mask values, and then reload the mask value on the next iteration. It won't be able to magically deduce what you're trying to do and turn it into a sequential shift op for you. It may at least be able to optimize out the pointer update+writeback stage by caching it into a register outside the loop, though honestly I'd be very skeptical based on my experiences.
Here's one way for going through bits from start to end, just for sake of comparison (a version capable of starting at any arbitrary point in the bitstream would require a little extra setup logic):
uint64_t* pBitSet = &v[-1]; // gets incremented on first iteration through loop.
uint64_t curBitSet = v[0];
for (int i=0; i<v.length(); ++i) {
if ((i % 64) == 0) {
curBitSet = *(++pBitSet);
}
int bit = curBitSet & 1;
curBitSet >>= 1;
// do stuff based on 'bit' here.
}