Jump to content

Function object

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Dmeranda (talk | contribs) at 17:39, 22 August 2005 (rv. undeleted removed text about Python generator, see Talk). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

A function object, often called a functor, is a computer programming construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. The exact meaning may vary among programming languages. A functor used in this manner in computing bears little relation to the term functor as used in the mathematical field of category theory.

Description

A typical use of a functor is in writing more intelligent callback functions. A callback in procedural languages, such as C, may be accomplished by using function pointers. However it can be difficult or awkward to pass state into or out of the callback function. This restriction also inhibits more dynamic behavior of the function. A functor solves those problems since the function is really a just a façade for a full object, thus it carries its own state.

Most modern object-oriented languages such as C++, Java, and Python support the definition of functors and may even make significant use of them.

Origins

Smalltalk was one of the first languages to support functors through the use of block constructs that are an integral part of the language syntax. For example, one can supply functors as arguments to collection objects to provide filtering & sorting. It is a perfect realization of the strategy pattern that promotes the use of pluggable behaviour.

Functors in C and C++

Consider the example of a sorting routine which uses a callback function to define an ordering relation between a pair of items. A C program using function pointers may appear as:

/* Declaration of C sorting function */
void sort( int* itemlist, int numitems, int (*cmpfunc)(item*, item*) );
...
/* Callback function */
int compare_function( item* A, item* B )
{
    if( *A < *B ) return -1;
    if( *A > *B ) return +1;
    return 0;
}
...
main()
{
    int items[] = {1, 2, 3, 4};
    sort( items, 4, compare_function );
}

In C++ a functor may be used instead of an ordinary function by defining a class which overloads the function call operator by defining an operator() member function. In C++ this is called a class type functor, and may appear as follows:

class cmp_item // C++ class type functor
{
    int operator()( item* A, item* B );
};
 
int cmp_item :: operator()( item* A, item* B )
{
    if( *A < *B ) return -1;
    if( *A > *B ) return +1;
    return 0;
}
...
// Declaration of C++ sorting function.
template < class cmp > void sort( int * itemlist, int numitems, cmp );
...
main()
{
    int items[] = {1, 2, 3, 4};
    cmp_item cmp;
    sort( items, 4, cmp );
}

Notice that the syntax for providing the callback to the sort() function is identical, but an object is passed instead of a function pointer. When invoked the callback function is executed just as any other member function, and therefore has full access to the other members (data or functions) of the object.

It is possible to use function objects in situations other than as callback functions (although the shortened term functor is normally not used). Continuing the example,

 functor_class Y;
 int result = Y( a, b );

In addition to class type functors, other kinds of function objects are also possible in C++. They can take advantage of C++'s member-pointer or template facilities. The expresiveness of templates allows some functional programming techniques to be used, such as defining functors in terms of other functors (like function composition). Much of the C++ Standard Template Library (STL) makes heavy use of template-based function objects.

Functors in Java

Functors in Java are typically expressed by defining a method signature in a base class (or an interface). Then different functors are created by deriving from the interface. This could be called an inheritance model of functors.

Take Apache's Jakarta Commons [1] project, which provides several common predicate and transformation functors. EqualPredicate, for instance, could be used as follows.

Predicate p = new EqualPredicate ("wikipedia");
if (p.evaluate (args[0]))
  System.err.println ("true; args[0] is 'wikipedia'.");
else
  System.err.println ("false; args[0] is not.");

Notice that p is an object having evaluate method, so it can be treated like every other object.

Functors in Python

A functor in Python is an object that emulates a callable object (either a plain function or code extensions usually written in C). They are created simply by defining or adding a __call__() attribute method in a class or even an individual object. Due to the dynamic nature of the language an ordinary object can be converted into a functor at run-time.

A special case of a functor is a generator, which is an object that creates a stream of other objects each time it is invoked.

Other meanings of functor

In some functional programming languages, such as ML, a functor represents a mapping from modules to modules, and is a technique for reusing code. Functors used in this manner are analogous to the original mathematical meaning of functor in category theory.

In a more theoretical context a function object may be considered to be any instance of the class of functions, especially in languages such as Common Lisp in which functions are first-class objects. In this case the shortened term functor is rarely used.

See also

References

  • David Vandevoorde: C++ Templates: The Complete Guide, ISBN 0-201-73484-2
    (Specifically, chapter 22 is entirely devoted to function objects.)