A FunctorObject is an object that acts as a function, and can be operated upon like an object.
See
FunctionalPatternSystemForObjectOrientedDesign.
In many languages which support these, there is a conventionally named method that executes or computes the function, for example "run()" in
EeLanguage, or "operator()" in
CeePlusPlus.
There are a variety of programming constructs that manipulate functions rather than objects. These include
HigherOrderFunctions,
CurriedFunctions,
InternalIteration and callback mechanisms among others. In order to use these constructs effectively it is necessary to be able to capture references to functions rather than just call them.
Therefore:
(In strongly typed languages) Create a family of interfaces that describe function call signatures. Use generic programming, generic types (like Java's Object) or naming conventions to insulate users and implementers of these interfaces from each other. Program
HigherOrderFunctions and other functional clients in terms of this interface. Implement adapter classes that can make the methods of ordinary objects available to these functional clients. Use block closures in Smalltalk, inner classes in Java and the ->* syntax in C++. Program objects whose behavior is to be parameterized using
HigherOrderFunctions that are coded against the
FunctorObjectInterface.
Resulting context:
Clients can parameterize objects that implement
HigherOrderFunctions by creating
FunctorObjects and passing them in. We expect to find
HigherOrderFunctions only in
FunctionalProgrammingLanguages, but they are actually found in more mundane settings as function pointers. The quicksort function in the standard C library is, in fact, a
HigherOrderFunction as are callback mechanisms of all sorts.
InternalIteration is another common use for
FunctorObjects and is a recurring theme in
ObjectFunctionalPatterns. The existence of
FunctorObjects makes it possible to implement a variety of other patterns including
CurriedFunctors,
GenericFunctions using
FunctorObjects to implement Specialized
Functions,
LazyEvaluation of
FunctorObjects, and other
ObjectFunctionalPatterns.
Since
FunctorObjects are an enabling mechanism for
LazyEvaluation some of the caveats for
LazyEvaluation should be noted here.
LazyEvaluation makes it impossible to know the exact order in which operations will be executed and in fact makes it possible for some operations not to be executed at all. It is therefore important to ensure that the
FunctorObjects that may be lazily evaluated do not rely on state that may change during the time when
LazyEvaluation may occur and that it does not change state that is relied on by other operations that may occur during the same time period.
FunctorObjects that can have side-effects are called Procedure Objects by
ThomasKuehne. These are very useful but some care must be taken with the timing of their side-effects.
Variations:
Argument binding: The basic
FunctorObject is supplied with its parameters at invocation time. It is possible, however, to separate argument application from invocation. The
PythonLanguage uses default argument values to make this separation. In other languages it is possible to create
FunctorObjects that can appear to store parameter values until invocation time. This is the enabling infrastructure for
CurriedFunctors.
Keyword parameters: Argument application can be further generalized by providing a mechanism for supplying parameters by name. This could be done through named methods or through keyword strings. Such an application can produce a new object - a form of
CurriedFunctor.
Default parameters: A
FunctorObject can also come with some parameters pre-applied. In this case the defaults can be overridden by some form of argument binding before the
FunctorObject is actually invoked.
Multiple results: A
FunctorObject can potentially calculate more than one result. In this case use
CommandQuerySeparation to separate invocation of the
FunctorObject from the queries that return its various results.
Composed FunctorObjects: A
FunctorObject may represent a
HigherOrderFunction that can be parameterized with another
FunctorObject. For instance a
FunctorObject may be parameterized with a predicate that will short-circuit the
FunctionObject unless some condition is true. This is especially valuable for use in
InternalIteration.
Known Uses:
C++ STL (Standard Template Library) --
StlFunctionObjects
In the C++
StandardTemplateLibrary, a "
FunctionObject" is an instance of a class that implements "operator()". As such, its usage is syntactically indistinguishable from a
FunctionPointer - a property that lets
FunctionObjects and
FunctionPointers be used interchangeably in template-based
GenericAlgorithms.
The benefit of using objects instead of
FunctionPointers is that the compiler can inline methods with
FunctionObjects.
[See
StlFunctionObjects for discussion.]
See also: FunctorObjectExample,
BlocksInJava,
FunctionalProgrammingInCpp
Discussion:
The name,
FunctorObject, is a very poor one. A
FunctorObject is an object that acts as a function, and can be operated upon like an object. As such, they are akin to mathematical functionals such as the
DiracDeltaFunction, or mathematical operators such as the derivative or the
FourierTransform.
In
CategoryTheory, the field of mathematics where the term
Functor originates, a
Functor is a mapping from one
Category to another that respects
Morphisms [functions]. For example, consider the
Category of
TopologicalSpaces and
ContinuousMaps. The
HomologyMorphism H_1 sends this
Category to that of
AbelianGroups and
HomoMorphisms. This means that if I have the following series of continuous topological maps:
f g
S ---------> T ----------> U,
I also get the series of homomorphisms:
H_1(f) H_1(g)
H_1(S) -----> H_1(T) ------> H_1(U),
and H_1(gf) = H_1(g)H_1(f).
You don't need to understand that; my point is that
Functors act on the entire problem domain, not just on functions or upon arguments. The only example I can think of right now is this.
Consider the
Category of
Objects and
Algorithms for functions whose results depend on no hidden variables. For example, real numbers and the sine function, but not decks of cards and a random shuffle function. Then, define the memoize functor to take objects to themselves, and algorithms to their memoized versions. The is a valid map from that category to itself - the memoized algorithm uses hidden variables, but the results do not.
--
EricJablow
A FunctorObject is an object that acts as a function, and can be operated upon like an object.
I think this would mean that it was very
well named? The word
functor comes from the latin from Latin
f�nctio, which means performance of a function. A synonym for
functor is
function. In
ComputerScience, it is very much like a lambda and sometimes no different than a
function. In fact, even in Category Theory the use
theory of functors and
function theory analogously. --
RobertDiFalco
In CategoryTheory, the field of mathematics where the term Functor
originates
This isn't true. Category Theory like many other branches of science and mathematics uses the term
functor but it did not
originate in abstract algebra -- at least that's not what my research says. Even if it did originate in Category Theory with set-valued functors or functory category, it wouldn't matter. In this case, we are talking about
functors as they exist in programming languages where for decades, a
functor has analogous to a
function. --
RobertDiFalco
The term
functor as used in Category Theory was originally borrowed from Carnap, and has been used unambiguously in mathematics at least since 1950. Anyway, there is a well established use of the term in computer science, specifically in the
SmlLanguage, where a
functor is a parametric structure. Because of that,
FunctorObject seems to be a poorly chosen name. For a similar concept the
CommonLispObjectSystem uses the more descriptive term
funcallable instance. What's wrong with
FunctionObject, besides the fact that its
WikiName is already taken? --
JimCoplien uses the word 'functor' in his book '
AdvancedCeePlusPlus'. If you've got a gripe with it ask him. --
PhilGoodwin
True, as Phil knows there are tons of synonyms for this such as: functor, functoid, function object, lexical closure, closure, code-block, and so on. There is a lot of history for functor and functiod, especially regarding enclosing functions in objects. --
RobertDiFalco
AndreiAlexandrescu uses the term
CallableEntity in his book
ModernCeePlusPlusDesign to refer to C-like functions, pointers or references to C-like functions, objects that define an operator(), or the result of applying operator.* or operator->* with a pointer to a member function in the right-hand side of the expression.
Let me see, when would I use this? Oh yes, when I need a function pointer. Nice to see an OO solution ;). --
RichardHenderson.
I appreciate your humor, and at the same hope everyone who reads it understands the irony. A FunctorObject (or LambdaExpression, LexicalClosure, CodeBlock, etc) includes a snapshot of its context (for example, a frame within which to bind its arguments and a safe place to answer its results). A naked function pointer, unless written very carefully, does not. It is certainly true that a FunctorObject can be constructed in, for example, CeePlusPlus using a function pointer -- some might argue that this was the impetus for CeePlusPlus -- but a function pointer by itself is NOT a FunctorObject.
No indeed, and I was only half-joking. I really do need safe function pointer-like behaviour. Specifically this provides a perfect analog of a connecting wire which explicitly connects two objects that don't need to know details about each other. Each adapts to the other by "requesting" a connection. Previously I used external adapter objects but this is much lighter weight and generally lovely
MicroArchitecture.
Is there a restriction on the degree of independence that a functor has from its parent? I'm jumping on its adapter properties, but the Factory pattern is not so far away in that there is an equivalent interaction.
One of the first things I built from these, in Java, was a PluggableAdaptor module, following the example in Smalltalk. I find this an elegant and powerful "ConnectingWire" - once you try it, you'll never turn back. -- TomStambaugh
Functors may also inform a factory about what they can do - either by proxy, or directly, allowing the factory to select the "optimum" functor from a collection of functors, using hints provided by the invoker of the factory...
When a language forces you to emulate simple functional values using a much more complicated object mechanism it is basically an instance of the
AbstractionInversion AntiPattern. I'm not saying that it would not make sense to emulate functional values using the object mechanism in an OO language that doesn't provide first class functional values, but I'm saying that the language effectively forces
AbstractionInversion. Consider the following example:
Scheme: ((lambda (x) x) 1)
Java: new Function() {
public Object with(Object x) {
return x;
}}.with(new Integer(1))
Even if the manifest typing would be removed from the Java version, there would still be an unnecessary indirection in the Java version. The dispatch to the with-method happens indirectly, which is not necessary as the necessary indirection is already provided by the use of the functional value. --
VesaKarvonen
Of course, Java's not exactly a good example of a proper OO language, Smalltalk does it with pure objects while remaining as simple as the Scheme equivalent.
[:x | x ] value: 1
Another issue worth mentioning is that
FunctorObject is strongly related to the
StrategyPattern.
FunctorObject essentially differs from the
StrategyPattern in that a
FunctorObject is less specific to a particular situation and that a
FunctorObject always contains just one entry point. Both
StrategyPattern and
FunctorObject are essentially "just parameterization". The most likely reason why they are given the high status as patterns in OO languages is that behavioral parameterization using functional values is not necessarily immediately obvious in OO languages that do not support first class functional values. --
VesaKarvonen
I would like to note that "functor" is a misnomer. It already has a meaning of "a morphism from category to category", which is approximately what a template is in C++ parlance. --
PanuKalliokoski
functor has a long history in discussions of Prolog predicates in terms of the 'functor' and the 'arity' of predicates. --
RobertShiplett
Someone created this page to discuss objects that combine dates/ranges with monetary amounts - moved to
DateAndValueObject.
Discussion of
ValueObjects (like
MoneyAmount) requiring garbage collection (
AlgorithmsThatDemandGarbageCollection) moved to
Do ValueObjectsRequireGarbageCollection?.
CategoryObjectFunctionalPatterns CategoryCodingConventions