Saturday, August 18, 2007

Version out of the door

After some frustrations with what is provided by the Standard Library, I started to develop QuickFunctor with the declared purpose to create a library that allows its users to do pretty much anything that is reasonable to do with functors (aka "function objects"), and do it as easily and as efficiently as possible.

Many "idea leaders" in the C++ community (Bjarne Stroustrup, Scott Meyers, Herb Sutter, Daveed Vandevoorde, Nicolai Josuttis among them) advocate using functors, and I find their arguments persuasive. The standard library provides an implementation for functors, in the <functional> header, but from my point of view it has some drawbacks and limitations, which were significant enough to make me decide to write my own QuickFunctor, which I think has several advantages:

  1. Functors can be combined in expressions (arithmetic, boolean, string, ...), using most C++ operators. Expressions of numerical and string types are handled directly, and user types can easily be accommodated, if needed, including numeric user types (like Fraction) that can be combined in expressions with standard types (like int).

  2. Constructors for functors take a more diverse set of parameters. You can build a functor from pretty much anything.

  3. It can deal with functors with 3 or more parameters.

  4. A more consistent naming scheme.

  5. An extensive set of operations that can be applied to existing functors to create new functors. These operations include mathematical composition, various conversions, binding, parameter substitution, permutations and casting.

  6. The possibility of storing functors in variables with simple types. Functor<int, double, char> is a type that can store any functor that takes a double and a char as its parameters and returns an int.

These arguments also apply to some extent to Boost and TR1, which have some improvements over the current standard, but don't go far enough. The Loki library has its own functors but they can't do everything QuickFunctor does.

Depending on how advanced you are with C++, chances are that you'll find some new ideas for C++ metatemplate programming (popularized by Andrei Alexandrescu) and general C++ programming techniques, for those willing to look at the code. While some techniques that I use are well known, others have been developed by me. I'm sure that among them there are some that have been discovered independently by other people, but it's also possible that some of them are actually new.

One example would be a technique that allows to effectively have 2 template functions "template <class T> void f(T x)", which exist simultaneously in the same namespace, one of them called for some kind of arguments and the other for other kinds. Simply having in a source file the code "template <class T> void f(T) {}; template <class T> void f(T) {};" generates a compiler error, because of a duplicate definition of f. Yet, I introduce a technique that allows something that behaves like this to work. Probably somebody else thought of it before, but there are many other things, some of which might be new.

I wrote this library for myself, but by making it public I hope other people will benefit from my efforts and perhaps help me improve it.

Anyway, after lots of small tweaks and complete redesigns I finally managed to pack together a functional version of the library, together with documentation and examples, I decided to call it and I'm glad that it's out. While it's a beta and there are some "open issues", there are no bugs that I know of. The library can be downloaded from SourceForge. Since the SourceForge forums require users to log in, I decided to create this blog where I can post news about QuickFunctor and also get some feedback from people who don't want to log in.

FREE hit counter and Internet traffic statistics from