Function Composition Operator
   HOME

TheInfoList



OR:

In
computer science Computer science is the study of computation, information, and automation. Computer science spans Theoretical computer science, theoretical disciplines (such as algorithms, theory of computation, and information theory) to Applied science, ...
, function composition is an act or mechanism to combine simple
function Function or functionality may refer to: Computing * Function key, a type of key on computer keyboards * Function model, a structured representation of processes in a system * Function object or functor or functionoid, a concept of object-orie ...
s to build more complicated ones. Like the usual
composition of functions In mathematics, the composition operator \circ takes two functions, f and g, and returns a new function h(x) := (g \circ f) (x) = g(f(x)). Thus, the function is applied after applying to . (g \circ f) is pronounced "the composition of an ...
in
mathematics Mathematics is a field of study that discovers and organizes methods, Mathematical theory, theories and theorems that are developed and Mathematical proof, proved for the needs of empirical sciences and mathematics itself. There are many ar ...
, the result of each function is passed as the argument of the next, and the result of the last one is the result of the whole. Programmers frequently apply functions to results of other functions, and almost all programming languages allow it. In some cases, the composition of functions is interesting as a function in its own right, to be used later. Such a function can always be defined but languages with
first-class function In computer science, a programming language is said to have first-class functions if it treats function (programming), functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning ...
s make it easier. The ability to easily compose functions encourages factoring (breaking apart)
function Function or functionality may refer to: Computing * Function key, a type of key on computer keyboards * Function model, a structured representation of processes in a system * Function object or functor or functionoid, a concept of object-orie ...
s for maintainability and
code reuse Code reuse is the practice of using existing source code to develop software instead of writing new code. ''Software reuse'' is a broader term that implies using any existing software asset to develop software instead of developing it again. An as ...
. More generally, big systems might be built by composing whole programs. Narrowly speaking, function composition applies to functions that operate on a finite amount of data, each step sequentially processing it before handing it to the next. Functions that operate on potentially infinite data (a
stream A stream is a continuous body of water, body of surface water Current (stream), flowing within the stream bed, bed and bank (geography), banks of a channel (geography), channel. Depending on its location or certain characteristics, a strea ...
or other
codata The Committee on Data of the International Science Council (CODATA) was established in 1966 as the Committee on Data for Science and Technology, originally part of the International Council of Scientific Unions, now part of the International ...
) are known as filters, and are instead connected in a
pipeline A pipeline is a system of Pipe (fluid conveyance), pipes for long-distance transportation of a liquid or gas, typically to a market area for consumption. The latest data from 2014 gives a total of slightly less than of pipeline in 120 countries ...
, which is analogous to function composition and can execute concurrently.


Composing function calls

For example, suppose we have two functions and , as in and . Composing them means we first compute , and then use to compute . Here is the example in the
C language C (''pronounced'' '' – like the letter c'') is a general-purpose programming language. It was created in the 1970s by Dennis Ritchie and remains very widely used and influential. By design, C's features cleanly reflect the capabilities o ...
: float x, y, z; // ... y = g(x); z = f(y); The steps can be combined if we don't give a name to the intermediate result: z = f(g(x)); Despite differences in length, these two implementations compute the same result. The second implementation requires only one line of code and is colloquially referred to as a "highly composed" form. Readability and hence maintainability is one advantage of highly composed forms, since they require fewer lines of code, minimizing a program's "surface area". DeMarco and Lister empirically verify an inverse relationship between surface area and maintainability. On the other hand, it may be possible to overuse highly composed forms. A nesting of too many functions may have the opposite effect, making the code less maintainable. In a
stack-based language Stack-oriented programming is a programming paradigm that relies on one or more stacks to manipulate data and/or pass parameters. Programming constructs in other programming languages need to be modified for use in a stack-oriented system. Most ...
, functional composition is even more natural: it is performed by
concatenation In formal language theory and computer programming, string concatenation is the operation of joining character strings end-to-end. For example, the concatenation of "snow" and "ball" is "snowball". In certain formalizations of concatenati ...
, and is usually the primary method of program design. The above example in
Forth Forth or FORTH may refer to: Arts and entertainment * ''forth'' magazine, an Internet magazine * ''Forth'' (album), by The Verve, 2008 * ''Forth'', a 2011 album by Proto-Kaw * Radio Forth, a group of independent local radio stations in Scotl ...
: g f Which will take whatever was on the stack before, apply g, then f, and leave the result on the stack. See postfix composition notation for the corresponding mathematical notation.


Naming the composition of functions

Now suppose that the combination of calling on the result of is frequently useful, and which we want to name to be used as a function in its own right. In most languages, we can define a new function implemented by composition. Example in C: float foo(float x) (the long form with intermediates would work as well.) Example in
Forth Forth or FORTH may refer to: Arts and entertainment * ''forth'' magazine, an Internet magazine * ''Forth'' (album), by The Verve, 2008 * ''Forth'', a 2011 album by Proto-Kaw * Radio Forth, a group of independent local radio stations in Scotl ...
: : foo g f ; In languages such as C, the only way to create a new function is to define it in the program source, which means that functions can't be composed at run time. An evaluation of an arbitrary composition of ''predefined'' functions, however, is possible: #include typedef int FXN(int); int f(int x) int g(int x) int h(int x) int eval(FXN *fs[], int size, int x) int main()


First-class composition

In functional programming languages, function composition can be naturally expressed as a higher-order function or operator. In other programming languages you can write your own mechanisms to perform function composition.


Haskell

In Haskell (programming language), Haskell, the example given above becomes: foo = f . g using the built-in composition operator (.) which can be read as ''f after g'' or ''g composed with f''. The composition operator itself can be defined in Haskell using a lambda expression: (.) :: (b -> c) -> (a -> b) -> a -> c f . g = \x -> f (g x) The first line describes the type of (.) - it takes a pair of functions, and returns a function (the lambda expression on the second line). Note that Haskell doesn't require specification of the exact input and output types of f and g; the a, b, c, and x are placeholders; only the relation between matters (f must accept what g returns). This makes (.) a polymorphic operator.


Lisp

Variants of
Lisp Lisp (historically LISP, an abbreviation of "list processing") is a family of programming languages with a long history and a distinctive, fully parenthesized Polish notation#Explanation, prefix notation. Originally specified in the late 1950s, ...
, especially Scheme, the interchangeability of code and data together with the treatment of functions lend themselves extremely well for a recursive definition of a
variadic In computer science, an operator or function is variadic if it can take a varying number of arguments; that is, if its arity is not fixed. For specific articles, see: * Variadic function * Variadic macro in the C preprocessor * Variadic template ...
compositional operator. (define (compose . fs) (if (null? fs) (lambda (x) x) ; if no argument is given, evaluates to the identity function (lambda (x) ((car fs) ((apply compose (cdr fs)) x))))) ; examples (define (add-a-bang str) (string-append str "!")) (define givebang (compose string->symbol add-a-bang symbol->string)) (givebang 'set) ;

> set! ; anonymous composition ((compose sqrt - sqr) 5) ;

> 0+5i


APL

Many dialects of APL feature built in function composition using the symbol . This higher-order function extends function composition to dyadic application of the left side function such that A f∘g B is A f g B. foo←f∘g Additionally, you can define function composition: o← In dialect that does not support inline definition using braces, the traditional definition is available: ∇ r←(f o g)x r←f g x ∇


Raku

Raku like Haskell (programming language), Haskell has a built in function composition operator, the main difference is it is spelled as or o. my &foo = &f ∘ &g; Also like Haskell (programming language), Haskell you could define the operator yourself. In fact the following is the Raku code used to define it in the
Rakudo Rakudo is a Raku compiler targeting MoarVM, and the Java Virtual Machine, that implements the Raku specification. It is currently the only major Raku compiler in active development. Originally developed within the Parrot Parrots (Psittacif ...
implementation. # the implementation has a slightly different line here because it cheats proto sub infix:<∘> (&?, &?) is equiv(& is assoc multi sub infix:<∘> () # allows ` ��@array` to work when `@array` is empty multi sub infix:<∘> (&f) # allows ` ��@array` to work when `@array` has one element multi sub infix:<∘> (&f, &g --> Block) # alias it to the "Texas" spelling ( everything is bigger, and ASCII in Texas ) my &infix: := &infix:<∘>;


Nim

Nim supports
uniform function call syntax Uniform function call syntax (UFCS) or uniform call syntax (UCS) or sometimes universal function call syntax is a programming language feature in D, Nim, Koka, and Effekt that allows any function to be called using the syntax for method calls (as ...
, which allows for arbitrary function composition through the method syntax . operator. func foo(a: int): string = $a func bar(a: string, count: int): seq
tring Tring is a market town and civil parish in the Borough of Dacorum, Hertfordshire, England. It is situated in a gap passing through the Chiltern Hills, classed as an Area of Outstanding Natural Beauty, from Central London. Tring is linked ...
= for i in 0 ..< count: result.add(a) func baz(a: seq
tring Tring is a market town and civil parish in the Borough of Dacorum, Hertfordshire, England. It is situated in a gap passing through the Chiltern Hills, classed as an Area of Outstanding Natural Beauty, from Central London. Tring is linked ...
= for i in a: echo i # equivalent! echo foo(5).bar(6).baz() echo baz(bar(6, foo(5)))


Python

In
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (prog ...
, a way to define the composition for any group of functions, is using function: from functools import reduce from typing import Callable def compose(*funcs) -> Callable int int]: """Compose a group of functions (f(g(h(...)))) into a single composite func.""" return reduce(lambda f, g: lambda x: f(g(x)), funcs) # Example f = lambda x: x + 1 g = lambda x: x * 2 h = lambda x: x - 3 # Call the function x=10 : ((x - 3) * 2) + 1 = 15 print(compose(f, g, h)(10))


JavaScript

In
JavaScript JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior. Web browsers have ...
we can define it as a function which takes two functions ''f'' and ''g'', and produces a function: function o(f, g) // Alternatively, using the rest operator and lambda expressions in ES2015 const compose = (...fs) => (x) => fs.reduceRight((acc, f) => f(acc), x)


C#

In C# we can define it as an Extension method which takes Funcs ''f'' and ''g'', and produces a new : // Call example: // var c = f.ComposeWith(g); // // Func g = _ => ... // Func f = _ => ... public static Func ComposeWith(this Func f, Func g) => x => f(g(x));


Ruby

Languages like
Ruby Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
let you construct a binary operator yourself: class Proc def compose(other_fn) ->(*as) end alias_method :+, :compose end f = ->(x) g = ->(x) (f + g).call(12) # => 13824 However, a native function composition operator was introduced in Ruby 2.6: f = proc g = proc (f << g).call(3) # -> 11; identical to f(g(3)) (f >> g).call(3) # -> 15; identical to g(f(3))


Research survey

Notions of composition, including the
principle of compositionality In semantics, mathematical logic and related disciplines, the principle of compositionality is the principle that the meaning of a complex expression is determined by the meanings of its constituent expressions and the rules used to combine them. ...
and
composability Composability is a system design principle that deals with the inter-relationships of components. A highly composable system provides components that can be selected and assembled in various combinations to satisfy specific user requirements. In ...
, are so ubiquitous that numerous strands of research have separately evolved. The following is a sampling of the kind of research in which the notion of composition is central. * directly applied function composition to the assemblage of building blocks known as ' monads' in the
Haskell programming language Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language f ...
. * addressed the
software reuse Code reuse is the practice of using existing source code to develop software instead of writing new code. ''Software reuse'' is a broader term that implies using any existing software asset to develop software instead of developing it again. An as ...
problem in terms of composability. * formally defined a proof rule for functional composition that assures a program's safety and liveness. * identified a strengthened form of compositionality by placing it into a
semiotic Semiotics ( ) is the systematic study of semiosis, sign processes and the communication of Meaning (semiotics), meaning. In semiotics, a Sign (semiotics), sign is defined as anything that communicates intentional and unintentional meaning or feel ...
system and applying it to the problem of structural
ambiguity Ambiguity is the type of meaning (linguistics), meaning in which a phrase, statement, or resolution is not explicitly defined, making for several interpretations; others describe it as a concept or statement that has no real reference. A com ...
frequently encountered in
computational linguistics Computational linguistics is an interdisciplinary field concerned with the computational modelling of natural language, as well as the study of appropriate computational approaches to linguistic questions. In general, computational linguistics ...
. * examined the role of compositionality in analog aspects of natural language processing. *According to a review by , formal treatment of composition underlies validation of component assembly in visual programming languages like IBM's Visual Age for the
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
language.


Large-scale composition

Whole programs or systems can be treated as functions, which can be readily composed if their inputs and outputs are well-defined.
Pipelines A pipeline is a system of pipes for long-distance transportation of a liquid or gas, typically to a market area for consumption. The latest data from 2014 gives a total of slightly less than of pipeline in 120 countries around the world. The Un ...
allowing easy composition of
filters Filtration is a physical process that separates solid matter and fluid from a mixture. Filter, filtering, filters or filtration may also refer to: Science and technology Computing * Filter (higher-order function), in functional programming * Fil ...
were so successful that they became a
design pattern A design pattern is the re-usable form of a solution to a design problem. The idea was introduced by the architect Christopher Alexander and has been adapted for various other disciplines, particularly software engineering. The " Gang of Four" ...
of operating systems. Imperative procedures with side effects violate
referential transparency In analytic philosophy and computer science, referential transparency and referential opacity are properties of linguistic constructions, and by extension of languages. A linguistic construction is called ''referentially transparent'' when for an ...
and therefore are not cleanly composable. However if one considers the "state of the world" before and after running the code as its input and output, one gets a clean function. Composition of such functions corresponds to running the procedures one after the other. The
monad Monad may refer to: Philosophy * Monad (philosophy), a term meaning "unit" **Monism, the concept of "one essence" in the metaphysical and theological theory ** Monad (Gnosticism), the most primal aspect of God in Gnosticism * ''Great Monad'', an ...
formalism uses this idea to incorporate side effects and input/output (I/O) into functional languages.


See also

*
Currying In mathematics and computer science, currying is the technique of translating a function that takes multiple arguments into a sequence of families of functions, each taking a single argument. In the prototypical example, one begins with a functi ...
*
Functional decomposition In engineering, functional decomposition is the process of resolving a functional relationship into its constituent parts in such a way that the original function can be reconstructed (i.e., recomposed) from those parts. This process of decompo ...
*
Implementation inheritance In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object ( prototype-based inheritance) or class ( class-based inheritance), retaining similar implementation. Also defined as deriving new class ...
*
Inheritance semantics In object-oriented programming, behavioral subtyping is the principle that subclasses should satisfy the expectations of clients accessing subclass objects through references of superclass type, not just as regards syntactic safety (such as the abs ...
*
Iteratee In functional programming, an iteratee is a composable abstraction for incrementally processing sequentially presented chunks of input data in a purely functional fashion. With iteratees, it is possible to lazily transform how a resource will emit ...
*
Pipeline (Unix) In Unix-like computer operating systems, a pipeline is a mechanism for inter-process communication using message passing. A pipeline is a set of process (computing), processes chained together by their standard streams, so that the output text of ...
*
Principle of compositionality In semantics, mathematical logic and related disciplines, the principle of compositionality is the principle that the meaning of a complex expression is determined by the meanings of its constituent expressions and the rules used to combine them. ...
*
Virtual inheritance Virtual inheritance is a C++ technique that ensures only one copy of a base classs member variables are inherited by grandchild derived classes. Without virtual inheritance, if two classes B and C inherit from a class A, and a class D inherits ...


Notes


References

*. *. *. *. *. *. *. *. *. *. *. *. *{{citation , last = Steele , first = Guy L. Jr. , author-link = Guy L. Steele, Jr. , contribution = Building interpreters by composing monads , doi = 10.1145/174675.178068 , pages = 472–492 , title = Proc. 21st ACM Symposium on Principles of Programming Languages , contribution-url = http://groups.csail.mit.edu/mac/~dae/related-papers/steele.ps.Z , year = 1994, doi-access = free , isbn = 0-89791-636-0 . Programming language topics Higher-order functions