Function composition (computer science)
Programming mechanism
- 18 min read
- 5 chapters
Related on Lably
Through Computer science, Function (computer programming) and Function composition
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 functions make it easier.
The ability to easily compose functions encourages factoring (breaking apart) functions for maintainability and code reuse. 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 or other codata) are known as filters, and are instead connected in a pipeline, which is analogous to function composition and can execute concurrently.
Composing function calls
For example, suppose we have two functions f and g, as in z = f(y) and y = g(x). Composing them means we first compute y = g(x), and then use y to compute z = f(y). Here is the example in the C language:
<span id="mwJQ"></span><span class="kt" id="mwJg">float</span><span class="w" id="mwJw"> </span><span class="n" id="mwKA">x</span><span class="p" id="mwKQ">,</span><span class="w" id="mwKg"> </span><span class="n" id="mwKw">y</span><span class="p" id="mwLA">,</span><span class="w" id="mwLQ"> </span><span class="n" id="mwLg">z</span><span class="p" id="mwLw">;</span> <span class="c1" id="mwMA">// ...</span> <span class="n" id="mwMQ">y</span><span class="w" id="mwMg"> </span><span class="o" id="mwMw">=</span><span class="w" id="mwNA"> </span><span class="n" id="mwNQ">g</span><span class="p" id="mwNg">(</span><span class="n" id="mwNw">x</span><span class="p" id="mwOA">);</span> <span class="n" id="mwOQ">z</span><span class="w" id="mwOg"> </span><span class="o" id="mwOw">=</span><span class="w" id="mwPA"> </span><span class="n" id="mwPQ">f</span><span class="p" id="mwPg">(</span><span class="n" id="mwPw">y</span><span class="p" id="mwQA">);</span>
The steps can be combined if we don't give a name to the intermediate result:
<span id="mwRA"></span><span class="n" id="mwRQ">z</span><span class="w" id="mwRg"> </span><span class="o" id="mwRw">=</span><span class="w" id="mwSA"> </span><span class="n" id="mwSQ">f</span><span class="p" id="mwSg">(</span><span class="n" id="mwSw">g</span><span class="p" id="mwTA">(</span><span class="n" id="mwTQ">x</span><span class="p" id="mwTg">));</span>
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, functional composition is even more natural: it is performed by concatenation, and is usually the primary method of program design. The above example in Forth:
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.
Sign in to keep reading
4 more chapters are free with a Lably account.
Naming the composition of functions
Now suppose that the combination of calling f() on the result of g() is frequently useful, and which we want to name foo() 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:
<span id="mwaw"></span><span class="kt" id="mwbA">float</span><span class="w" id="mwbQ"> </span><span class="nf" id="mwbg">foo</span><span class="p" id="mwbw">(</span><span class="kt" id="mwcA">float</span><span class="w" id="mwcQ"> </span><span class="n" id="mwcg">x</span><span class="p" id="mwcw">)</span><span class="w" id="mwdA"> </span><span class="p" id="mwdQ">{</span> <span class="w" id="mwdg"> </span><span class="k" id="mwdw">return</span><span class="w" id="mweA"> </span><span class="n" id="mweQ">f</span><span class="p" id="mweg">(</span><span class="n" id="mwew">g</span><span class="p" id="mwfA">(</span><span class="n" id="mwfQ">x</span><span class="p" id="mwfg">));</span> <span class="p" id="mwfw">}</span>(the long form with intermediates would work as well.) Example in Forth:
: 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:
<span id="mwiQ"></span><span class="cp" id="mwig">#include</span><span class="w" id="mwiw"> </span><span class="cpf" id="mwjA"><stdio.h></span> <span class="k" id="mwjQ">typedef</span><span class="w" id="mwjg"> </span><span class="kt" id="mwjw">int</span><span class="w" id="mwkA"> </span><span class="nf" id="mwkQ">FXN</span><span class="p" id="mwkg">(</span><span class="kt" id="mwkw">int</span><span class="p" id="mwlA">);</span> <span class="kt" id="mwlQ">int</span><span class="w" id="mwlg"> </span><span class="nf" id="mwlw">f</span><span class="p" id="mwmA">(</span><span class="kt" id="mwmQ">int</span><span class="w" id="mwmg"> </span><span class="n" id="mwmw">x</span><span class="p" id="mwnA">)</span><span class="w" id="mwnQ"> </span><span class="p" id="mwng">{</span><span class="w" id="mwnw"> </span><span class="k" id="mwoA">return</span><span class="w" id="mwoQ"> </span><span class="n" id="mwog">x</span><span class="w" id="mwow"> </span><span class="o" id="mwpA">+</span><span class="w" id="mwpQ"> </span><span class="mi" id="mwpg">1</span><span class="p" id="mwpw">;</span><span class="w" id="mwqA"> </span><span class="p" id="mwqQ">}</span> <span class="kt" id="mwqg">int</span><span class="w" id="mwqw"> </span><span class="nf" id="mwrA">g</span><span class="p" id="mwrQ">(</span><span class="kt" id="mwrg">int</span><span class="w" id="mwrw"> </span><span class="n" id="mwsA">x</span><span class="p" id="mwsQ">)</span><span class="w" id="mwsg"> </span><span class="p" id="mwsw">{</span><span class="w" id="mwtA"> </span><span class="k" id="mwtQ">return</span><span class="w" id="mwtg"> </span><span class="n" id="mwtw">x</span><span class="w" id="mwuA"> </span><span class="o" id="mwuQ">*</span><span class="w" id="mwug"> </span><span class="mi" id="mwuw">2</span><span class="p" id="mwvA">;</span><span class="w" id="mwvQ"> </span><span class="p" id="mwvg">}</span> <span class="kt" id="mwvw">int</span><span class="w" id="mwwA"> </span><span class="nf" id="mwwQ">h</span><span class="p" id="mwwg">(</span><span class="kt" id="mwww">int</span><span class="w" id="mwxA"> </span><span class="n" id="mwxQ">x</span><span class="p" id="mwxg">)</span><span class="w" id="mwxw"> </span><span class="p" id="mwyA">{</span><span class="w" id="mwyQ"> </span><span class="k" id="mwyg">return</span><span class="w" id="mwyw"> </span><span class="n" id="mwzA">x</span><span class="w" id="mwzQ"> </span><span class="o" id="mwzg">-</span><span class="w" id="mwzw"> </span><span class="mi" id="mw0A">3</span><span class="p" id="mw0Q">;</span><span class="w" id="mw0g"> </span><span class="p" id="mw0w">}</span> <span class="kt" id="mw1A">int</span><span class="w" id="mw1Q"> </span><span class="nf" id="mw1g">eval</span><span class="p" id="mw1w">(</span><span class="n" id="mw2A">FXN</span><span class="w" id="mw2Q"> </span><span class="o" id="mw2g">*</span><span class="n" id="mw2w">fs</span><span class="p" id="mw3A">[],</span><span class="w" id="mw3Q"> </span><span class="kt" id="mw3g">int</span><span class="w" id="mw3w"> </span><span class="n" id="mw4A">size</span><span class="p" id="mw4Q">,</span><span class="w" id="mw4g"> </span><span class="kt" id="mw4w">int</span><span class="w" id="mw5A"> </span><span class="n" id="mw5Q">x</span><span class="p" id="mw5g">)</span> <span class="p" id="mw5w">{</span> <span class="w" id="mw6A"> </span><span class="k" id="mw6Q">for</span><span class="w" id="mw6g"> </span><span class="p" id="mw6w">(</span><span class="kt" id="mw7A">int</span><span class="w" id="mw7Q"> </span><span class="n" id="mw7g">i</span><span class="w" id="mw7w"> </span><span class="o" id="mw8A">=</span><span class="w" id="mw8Q"> </span><span class="mi" id="mw8g">0</span><span class="p" id="mw8w">;</span><span class="w" id="mw9A"> </span><span class="n" id="mw9Q">i</span><span class="w" id="mw9g"> </span><span class="o" id="mw9w"><</span><span class="w" id="mw-A"> </span><span class="n" id="mw-Q">size</span><span class="p" id="mw-g">;</span><span class="w" id="mw-w"> </span><span class="n" id="mw_A">i</span><span class="o" id="mw_Q">++</span><span class="p" id="mw_g">)</span><span class="w" id="mw_w"> </span><span class="n" id="mwAQA">x</span><span class="w" id="mwAQE"> </span><span class="o" id="mwAQI">=</span><span class="w" id="mwAQM"> </span><span class="p" id="mwAQQ">(</span><span class="o" id="mwAQU">*</span><span class="n" id="mwAQY">fs</span><span class="p" id="mwAQc">[</span><span class="n" id="mwAQg">i</span><span class="p" id="mwAQk">])(</span><span class="n" id="mwAQo">x</span><span class="p" id="mwAQs">);</span> <span class="w" id="mwAQw"> </span><span class="k" id="mwAQ0">return</span><span class="w" id="mwAQ4"> </span><span class="n" id="mwAQ8">x</span><span class="p" id="mwARA">;</span> <span class="p" id="mwARE">}</span> <span class="kt" id="mwARI">int</span><span class="w" id="mwARM"> </span><span class="nf" id="mwARQ">main</span><span class="p" id="mwARU">()</span> <span class="p" id="mwARY">{</span> <span class="w" id="mwARc"> </span><span class="c1" id="mwARg">// ((6 + 1) * 2) - 3 = 11</span> <span class="w" id="mwARk"> </span><span class="n" id="mwARo">FXN</span><span class="w" id="mwARs"> </span><span class="o" id="mwARw">*</span><span class="n" id="mwAR0">arr</span><span class="p" id="mwAR4">[]</span><span class="w" id="mwAR8"> </span><span class="o" id="mwASA">=</span><span class="w" id="mwASE"> </span><span class="p" id="mwASI">{</span><span class="n" id="mwASM">f</span><span class="p" id="mwASQ">,</span><span class="w" id="mwASU"> </span><span class="n" id="mwASY">g</span><span class="p" id="mwASc">,</span><span class="w" id="mwASg"> </span><span class="n" id="mwASk">h</span><span class="p" id="mwASo">};</span> <span class="w" id="mwASs"> </span><span class="n" id="mwASw">printf</span><span class="p" id="mwAS0">(</span><span class="s" id="mwAS4">"%d</span><span class="se" id="mwAS8">\n</span><span class="s" id="mwATA">"</span><span class="p" id="mwATE">,</span><span class="w" id="mwATI"> </span><span class="n" id="mwATM">eval</span><span class="p" id="mwATQ">(</span><span class="n" id="mwATU">arr</span><span class="p" id="mwATY">,</span><span class="w" id="mwATc"> </span><span class="mi" id="mwATg">3</span><span class="p" id="mwATk">,</span><span class="w" id="mwATo"> </span><span class="mi" id="mwATs">6</span><span class="p" id="mwATw">));</span> <span class="w" id="mwAT0"> </span><span class="c1" id="mwAT4">// ((6 - 3) * 2) + 1 = 7</span> <span class="w" id="mwAT8"> </span><span class="n" id="mwAUA">arr</span><span class="p" id="mwAUE">[</span><span class="mi" id="mwAUI">2</span><span class="p" id="mwAUM">]</span><span class="w" id="mwAUQ"> </span><span class="o" id="mwAUU">=</span><span class="w" id="mwAUY"> </span><span class="n" id="mwAUc">f</span><span class="p" id="mwAUg">;</span><span class="w" id="mwAUk"> </span><span class="n" id="mwAUo">arr</span><span class="p" id="mwAUs">[</span><span class="mi" id="mwAUw">0</span><span class="p" id="mwAU0">]</span><span class="w" id="mwAU4"> </span><span class="o" id="mwAU8">=</span><span class="w" id="mwAVA"> </span><span class="n" id="mwAVE">h</span><span class="p" id="mwAVI">;</span> <span class="w" id="mwAVM"> </span><span class="n" id="mwAVQ">printf</span><span class="p" id="mwAVU">(</span><span class="s" id="mwAVY">"%d</span><span class="se" id="mwAVc">\n</span><span class="s" id="mwAVg">"</span><span class="p" id="mwAVk">,</span><span class="w" id="mwAVo"> </span><span class="n" id="mwAVs">eval</span><span class="p" id="mwAVw">(</span><span class="n" id="mwAV0">arr</span><span class="p" id="mwAV4">,</span><span class="w" id="mwAV8"> </span><span class="mi" id="mwAWA">3</span><span class="p" id="mwAWE">,</span><span class="w" id="mwAWI"> </span><span class="mi" id="mwAWM">6</span><span class="p" id="mwAWQ">));</span> <span class="p" id="mwAWU">}</span>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, the example foo = f ∘ g 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:
<span id="mwAXc"></span><span class="p" id="mwAXg">(</span><span class="o" id="mwAXk">.</span><span class="p" id="mwAXo">)</span><span class="w" id="mwAXs"> </span><span class="ow" id="mwAXw">::</span><span class="w" id="mwAX0"> </span><span class="p" id="mwAX4">(</span><span class="n" id="mwAX8">b</span><span class="w" id="mwAYA"> </span><span class="ow" id="mwAYE">-></span><span class="w" id="mwAYI"> </span><span class="n" id="mwAYM">c</span><span class="p" id="mwAYQ">)</span><span class="w" id="mwAYU"> </span><span class="ow" id="mwAYY">-></span><span class="w" id="mwAYc"> </span><span class="p" id="mwAYg">(</span><span class="n" id="mwAYk">a</span><span class="w" id="mwAYo"> </span><span class="ow" id="mwAYs">-></span><span class="w" id="mwAYw"> </span><span class="n" id="mwAY0">b</span><span class="p" id="mwAY4">)</span><span class="w" id="mwAY8"> </span><span class="ow" id="mwAZA">-></span><span class="w" id="mwAZE"> </span><span class="n" id="mwAZI">a</span><span class="w" id="mwAZM"> </span><span class="ow" id="mwAZQ">-></span><span class="w" id="mwAZU"> </span><span class="n" id="mwAZY">c</span> <span class="nf" id="mwAZc">f</span><span class="w" id="mwAZg"> </span><span class="o" id="mwAZk">.</span><span class="w" id="mwAZo"> </span><span class="n" id="mwAZs">g</span><span class="w" id="mwAZw"> </span><span class="ow" id="mwAZ0">=</span><span class="w" id="mwAZ4"> </span><span class="nf" id="mwAZ8">\</span><span class="n" id="mwAaA">x</span><span class="w" id="mwAaE"> </span><span class="ow" id="mwAaI">-></span><span class="w" id="mwAaM"> </span><span class="n" id="mwAaQ">f</span><span class="w" id="mwAaU"> </span><span class="p" id="mwAaY">(</span><span class="n" id="mwAac">g</span><span class="w" id="mwAag"> </span><span class="n" id="mwAak">x</span><span class="p" id="mwAao">)</span>
The first line describes the type of (.) - it takes a pair of functions, f, g 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 f, g matters (f must accept what g returns). This makes (.) a polymorphic operator.
A polymorphic operator with multiple arguments, in Haskell's point-free notation
<span id="mwAbM"></span><span class="nf" id="mwAbQ">f</span><span class="w" id="mwAbU"> </span><span class="n" id="mwAbY">g</span><span class="w" id="mwAbc"> </span><span class="n" id="mwAbg">x</span><span class="w" id="mwAbk"> </span><span class="n" id="mwAbo">y</span>
is
<span id="mwAcI"></span><span class="p" id="mwAcM">(</span><span class="o" id="mwAcQ">.</span><span class="p" id="mwAcU">)</span><span class="o" id="mwAcY">.</span><span class="p" id="mwAcc">(</span><span class="o" id="mwAcg">.</span><span class="p" id="mwAck">)</span>
where the parameter names are immaterial, as stated above. Michal Ševčík credits CScalfani with a systematic exposition for function composition using additional parameters.
Lisp
Variants of Lisp, 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 compositional operator.
<span id="mwAd4"></span><span class="p" id="mwAd8">(</span><span class="k" id="mwAeA">define</span><span class="w" id="mwAeE"> </span><span class="p" id="mwAeI">(</span><span class="nb" id="mwAeM">compose</span><span class="w" id="mwAeQ"> </span><span class="o" id="mwAeU">.</span><span class="w" id="mwAeY"> </span><span class="nv" id="mwAec">fs</span><span class="p" id="mwAeg">)</span> <span class="w" id="mwAek"> </span><span class="p" id="mwAeo">(</span><span class="k" id="mwAes">if</span><span class="w" id="mwAew"> </span><span class="p" id="mwAe0">(</span><span class="nb" id="mwAe4">null?</span><span class="w" id="mwAe8"> </span><span class="nv" id="mwAfA">fs</span><span class="p" id="mwAfE">)</span><span class="w" id="mwAfI"> </span><span class="p" id="mwAfM">(</span><span class="k" id="mwAfQ">lambda</span><span class="w" id="mwAfU"> </span><span class="p" id="mwAfY">(</span><span class="nf" id="mwAfc">x</span><span class="p" id="mwAfg">)</span><span class="w" id="mwAfk"> </span><span class="nv" id="mwAfo">x</span><span class="p" id="mwAfs">)</span><span class="w" id="mwAfw"> </span><span class="c1" id="mwAf0">; if no argument is given, evaluates to the identity function</span> <span class="w" id="mwAf4"> </span><span class="p" id="mwAf8">(</span><span class="k" id="mwAgA">lambda</span><span class="w" id="mwAgE"> </span><span class="p" id="mwAgI">(</span><span class="nf" id="mwAgM">x</span><span class="p" id="mwAgQ">)</span><span class="w" id="mwAgU"> </span><span class="p" id="mwAgY">((</span><span class="nb" id="mwAgc">car</span><span class="w" id="mwAgg"> </span><span class="nv" id="mwAgk">fs</span><span class="p" id="mwAgo">)</span><span class="w" id="mwAgs"> </span><span class="p" id="mwAgw">((</span><span class="nb" id="mwAg0">apply</span><span class="w" id="mwAg4"> </span><span class="nb" id="mwAg8">compose</span><span class="w" id="mwAhA"> </span><span class="p" id="mwAhE">(</span><span class="nb" id="mwAhI">cdr</span><span class="w" id="mwAhM"> </span><span class="nv" id="mwAhQ">fs</span><span class="p" id="mwAhU">))</span><span class="w" id="mwAhY"> </span><span class="nv" id="mwAhc">x</span><span class="p" id="mwAhg">)))))</span> <span class="c1" id="mwAhk">; examples</span> <span class="p" id="mwAho">(</span><span class="k" id="mwAhs">define</span><span class="w" id="mwAhw"> </span><span class="p" id="mwAh0">(</span><span class="nf" id="mwAh4">add-a-bang</span><span class="w" id="mwAh8"> </span><span class="nv" id="mwAiA">str</span><span class="p" id="mwAiE">)</span> <span class="w" id="mwAiI"> </span><span class="p" id="mwAiM">(</span><span class="nb" id="mwAiQ">string-append</span><span class="w" id="mwAiU"> </span><span class="nv" id="mwAiY">str</span><span class="w" id="mwAic"> </span><span class="s" id="mwAig">"!"</span><span class="p" id="mwAik">))</span> <span class="p" id="mwAio">(</span><span class="k" id="mwAis">define</span><span class="w" id="mwAiw"> </span><span class="nv" id="mwAi0">givebang</span> <span class="w" id="mwAi4"> </span><span class="p" id="mwAi8">(</span><span class="nb" id="mwAjA">compose</span><span class="w" id="mwAjE"> </span><span class="nb" id="mwAjI">string->symbol</span><span class="w" id="mwAjM"> </span><span class="nv" id="mwAjQ">add-a-bang</span><span class="w" id="mwAjU"> </span><span class="nb" id="mwAjY">symbol->string</span><span class="p" id="mwAjc">))</span> <span class="p" id="mwAjg">(</span><span class="nf" id="mwAjk">givebang</span><span class="w" id="mwAjo"> </span><span class="ss" id="mwAjs">'set</span><span class="p" id="mwAjw">)</span><span class="w" id="mwAj0"> </span><span class="c1" id="mwAj4">; ===> set!</span> <span class="c1" id="mwAj8">; anonymous composition</span> <span class="p" id="mwAkA">((</span><span class="nb" id="mwAkE">compose</span><span class="w" id="mwAkI"> </span><span class="nb" id="mwAkM">sqrt</span><span class="w" id="mwAkQ"> </span><span class="nb" id="mwAkU">-</span><span class="w" id="mwAkY"> </span><span class="nv" id="mwAkc">sqr</span><span class="p" id="mwAkg">)</span><span class="w" id="mwAkk"> </span><span class="mi" id="mwAko">5</span><span class="p" id="mwAks">)</span><span class="w" id="mwAkw"> </span><span class="c1" id="mwAk0">; ===> 0+5i</span>
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.
<span id="mwAlc"></span><span class="nv" id="mwAlg">foo</span><span class="kd" id="mwAlk">←</span><span class="nv" id="mwAlo">f</span><span class="na" id="mwAls">∘</span><span class="nv" id="mwAlw">g</span>
Additionally, you can define function composition:
<span id="mwAmA"></span><span class="nv" id="mwAmE">o</span><span class="kd" id="mwAmI">←</span><span class="kt" id="mwAmM">{</span><span class="bp" id="mwAmQ">⍺⍺</span><span class="w" id="mwAmU"> </span><span class="bp" id="mwAmY">⍵⍵</span><span class="w" id="mwAmc"> </span><span class="bp" id="mwAmg">⍵</span><span class="kt" id="mwAmk">}</span>In dialect that does not support inline definition using braces, the traditional definition is available:
<span id="mwAm0"></span><span class="bp" id="mwAm4">∇</span><span class="w" id="mwAm8"> </span><span class="nv" id="mwAnA">r</span><span class="kd" id="mwAnE">←</span><span class="p" id="mwAnI">(</span><span class="nv" id="mwAnM">f</span><span class="w" id="mwAnQ"> </span><span class="nv" id="mwAnU">o</span><span class="w" id="mwAnY"> </span><span class="nv" id="mwAnc">g</span><span class="p" id="mwAng">)</span><span class="nv" id="mwAnk">x</span> <span class="w" id="mwAno"> </span><span class="nv" id="mwAns">r</span><span class="kd" id="mwAnw">←</span><span class="nv" id="mwAn0">f</span><span class="w" id="mwAn4"> </span><span class="nv" id="mwAn8">g</span><span class="w" id="mwAoA"> </span><span class="nv" id="mwAoE">x</span> <span class="bp" id="mwAoI">∇</span>
Raku
Raku like Haskell has a built in function composition operator, the main difference is it is spelled as ∘ or o.
<span id="mwAos"></span><span class="k" id="mwAow">my</span><span class="w" id="mwAo0"> </span><span class="o" id="mwAo4">&</span><span class="n" id="mwAo8">foo</span><span class="w" id="mwApA"> </span><span class="o" id="mwApE">=</span><span class="w" id="mwApI"> </span><span class="o" id="mwApM">&</span><span class="n" id="mwApQ">f</span><span class="w" id="mwApU"> </span><span class="err" id="mwApY">∘</span><span class="w" id="mwApc"> </span><span class="o" id="mwApg">&</span><span class="n" id="mwApk">g</span><span class="p" id="mwApo">;</span>
Also like Haskell you could define the operator yourself. In fact the following is the Raku code used to define it in the Rakudo implementation.
<span id="mwAqA"></span><span class="c1" id="mwAqE"># the implementation has a slightly different line here because it cheats</span> <span class="n" id="mwAqI">proto</span><span class="w" id="mwAqM"> </span><span class="k" id="mwAqQ">sub</span><span class="w" id="mwAqU"> </span><span class="nf" id="mwAqY">infix</span><span class="p" id="mwAqc">:<∘> (&?, &?) is equiv(&[~]) is assoc<left> {</span><span class="o" id="mwAqg">*</span><span class="p" id="mwAqk">}</span> <span class="n" id="mwAqo">multi</span><span class="w" id="mwAqs"> </span><span class="k" id="mwAqw">sub</span><span class="w" id="mwAq0"> </span><span class="nf" id="mwAq4">infix</span><span class="p" id="mwAq8">:<∘> () {</span><span class="w" id="mwArA"> </span><span class="o" id="mwArE">*.</span><span class="n" id="mwArI">self</span><span class="w" id="mwArM"> </span><span class="p" id="mwArQ">}</span><span class="w" id="mwArU"> </span><span class="c1" id="mwArY"># allows `[∘] @array` to work when `@array` is empty</span> <span class="n" id="mwArc">multi</span><span class="w" id="mwArg"> </span><span class="k" id="mwArk">sub</span><span class="w" id="mwAro"> </span><span class="nf" id="mwArs">infix</span><span class="p" id="mwArw">:<∘> (&f) {</span><span class="w" id="mwAr0"> </span><span class="o" id="mwAr4">&</span><span class="n" id="mwAr8">f</span><span class="w" id="mwAsA"> </span><span class="p" id="mwAsE">}</span><span class="w" id="mwAsI"> </span><span class="c1" id="mwAsM"># allows `[∘] @array` to work when `@array` has one element</span> <span class="n" id="mwAsQ">multi</span><span class="w" id="mwAsU"> </span><span class="k" id="mwAsY">sub</span><span class="w" id="mwAsc"> </span><span class="nf" id="mwAsg">infix</span><span class="p" id="mwAsk">:<∘> (&f, &g --> Block) {</span> <span class="w" id="mwAso"> </span><span class="p" id="mwAss">(</span><span class="o" id="mwAsw">&</span><span class="n" id="mwAs0">f</span><span class="p" id="mwAs4">)</span><span class="o" id="mwAs8">.</span><span class="n" id="mwAtA">count</span><span class="w" id="mwAtE"> </span><span class="o" id="mwAtI">></span><span class="w" id="mwAtM"> </span><span class="mi" id="mwAtQ">1</span> <span class="w" id="mwAtU"> </span><span class="p" id="mwAtY">??</span><span class="w" id="mwAtc"> </span><span class="o" id="mwAtg">-></span><span class="w" id="mwAtk"> </span><span class="o" id="mwAto">|</span><span class="n" id="mwAts">args</span><span class="w" id="mwAtw"> </span><span class="p" id="mwAt0">{</span><span class="w" id="mwAt4"> </span><span class="n" id="mwAt8">f</span><span class="w" id="mwAuA"> </span><span class="o" id="mwAuE">|</span><span class="n" id="mwAuI">g</span><span class="w" id="mwAuM"> </span><span class="o" id="mwAuQ">|</span><span class="n" id="mwAuU">args</span><span class="w" id="mwAuY"> </span><span class="p" id="mwAuc">}</span> <span class="w" id="mwAug"> </span><span class="o" id="mwAuk">!!</span><span class="w" id="mwAuo"> </span><span class="o" id="mwAus">-></span><span class="w" id="mwAuw"> </span><span class="o" id="mwAu0">|</span><span class="n" id="mwAu4">args</span><span class="w" id="mwAu8"> </span><span class="p" id="mwAvA">{</span><span class="w" id="mwAvE"> </span><span class="n" id="mwAvI">f</span><span class="w" id="mwAvM"> </span><span class="n" id="mwAvQ">g</span><span class="w" id="mwAvU"> </span><span class="o" id="mwAvY">|</span><span class="n" id="mwAvc">args</span><span class="w" id="mwAvg"> </span><span class="p" id="mwAvk">}</span> <span class="p" id="mwAvo">}</span> <span class="c1" id="mwAvs"># alias it to the "Texas" spelling ( everything is bigger, and ASCII in Texas )</span> <span class="k" id="mwAvw">my</span><span class="w" id="mwAv0"> </span><span class="o" id="mwAv4">&</span><span class="n" id="mwAv8">infix:</span><span class="sr" id="mwAwA"><o></span><span class="w" id="mwAwE"> </span><span class="p" id="mwAwI">:</span><span class="o" id="mwAwM">=</span><span class="w" id="mwAwQ"> </span><span class="o" id="mwAwU">&</span><span class="n" id="mwAwY">infix:</span><span class="sr" id="mwAwc"><∘></span><span class="p" id="mwAwg">;</span>Nim
Nim supports uniform function call syntax, which allows for arbitrary function composition through the method syntax . operator.
<span id="mwAxM"></span><span class="k" id="mwAxQ">func</span><span class="w" id="mwAxU"> </span><span class="nf" id="mwAxY">foo</span><span class="p" id="mwAxc">(</span><span class="n" id="mwAxg">a</span><span class="p" id="mwAxk">:</span><span class="w" id="mwAxo"> </span><span class="nb" id="mwAxs">int</span><span class="p" id="mwAxw">):</span><span class="w" id="mwAx0"> </span><span class="nb" id="mwAx4">string</span><span class="w" id="mwAx8"> </span><span class="o" id="mwAyA">=</span><span class="w" id="mwAyE"> </span><span class="o" id="mwAyI">$</span><span class="n" id="mwAyM">a</span> <span class="k" id="mwAyQ">func</span><span class="w" id="mwAyU"> </span><span class="nf" id="mwAyY">bar</span><span class="p" id="mwAyc">(</span><span class="n" id="mwAyg">a</span><span class="p" id="mwAyk">:</span><span class="w" id="mwAyo"> </span><span class="nb" id="mwAys">string</span><span class="p" id="mwAyw">,</span><span class="w" id="mwAy0"> </span><span class="n" id="mwAy4">count</span><span class="p" id="mwAy8">:</span><span class="w" id="mwAzA"> </span><span class="nb" id="mwAzE">int</span><span class="p" id="mwAzI">):</span><span class="w" id="mwAzM"> </span><span class="nb" id="mwAzQ">seq</span><span class="o" id="mwAzU">[</span><span class="nb" id="mwAzY">string</span><span class="o" id="mwAzc">]</span><span class="w" id="mwAzg"> </span><span class="o" id="mwAzk">=</span> <span class="w" id="mwAzo"> </span><span class="k" id="mwAzs">for</span><span class="w" id="mwAzw"> </span><span class="n" id="mwAz0">i</span><span class="w" id="mwAz4"> </span><span class="ow" id="mwAz8">in</span><span class="w" id="mwA0A"> </span><span class="mi" id="mwA0E">0</span><span class="w" id="mwA0I"> </span><span class="p" id="mwA0M">..</span><span class="o" id="mwA0Q"><</span><span class="w" id="mwA0U"> </span><span class="n" id="mwA0Y">count</span><span class="p" id="mwA0c">:</span> <span class="w" id="mwA0g"> </span><span class="n" id="mwA0k">result</span><span class="p" id="mwA0o">.</span><span class="n" id="mwA0s">add</span><span class="p" id="mwA0w">(</span><span class="n" id="mwA00">a</span><span class="p" id="mwA04">)</span> <span class="k" id="mwA08">func</span><span class="w" id="mwA1A"> </span><span class="nf" id="mwA1E">baz</span><span class="p" id="mwA1I">(</span><span class="n" id="mwA1M">a</span><span class="p" id="mwA1Q">:</span><span class="w" id="mwA1U"> </span><span class="nb" id="mwA1Y">seq</span><span class="o" id="mwA1c">[</span><span class="nb" id="mwA1g">string</span><span class="o" id="mwA1k">]</span><span class="p" id="mwA1o">)</span><span class="w" id="mwA1s"> </span><span class="o" id="mwA1w">=</span> <span class="w" id="mwA10"> </span><span class="k" id="mwA14">for</span><span class="w" id="mwA18"> </span><span class="n" id="mwA2A">i</span><span class="w" id="mwA2E"> </span><span class="ow" id="mwA2I">in</span><span class="w" id="mwA2M"> </span><span class="n" id="mwA2Q">a</span><span class="p" id="mwA2U">:</span> <span class="w" id="mwA2Y"> </span><span class="n" id="mwA2c">echo</span><span class="w" id="mwA2g"> </span><span class="n" id="mwA2k">i</span> <span class="c" id="mwA2o"># equivalent!</span> <span class="n" id="mwA2s">echo</span><span class="w" id="mwA2w"> </span><span class="n" id="mwA20">foo</span><span class="p" id="mwA24">(</span><span class="mi" id="mwA28">5</span><span class="p" id="mwA3A">).</span><span class="n" id="mwA3E">bar</span><span class="p" id="mwA3I">(</span><span class="mi" id="mwA3M">6</span><span class="p" id="mwA3Q">).</span><span class="n" id="mwA3U">baz</span><span class="p" id="mwA3Y">()</span> <span class="n" id="mwA3c">echo</span><span class="w" id="mwA3g"> </span><span class="n" id="mwA3k">baz</span><span class="p" id="mwA3o">(</span><span class="n" id="mwA3s">bar</span><span class="p" id="mwA3w">(</span><span class="mi" id="mwA30">6</span><span class="p" id="mwA34">,</span><span class="w" id="mwA38"> </span><span class="n" id="mwA4A">foo</span><span class="p" id="mwA4E">(</span><span class="mi" id="mwA4I">5</span><span class="p" id="mwA4M">)))</span>
Python
In Python, a way to define the composition for any group of functions, is using functools.reduce function:
<span id="mwA4s"></span><span class="kn" id="mwA4w">from</span><span class="w" id="mwA40"> </span><span class="nn" id="mwA44">functools</span><span class="w" id="mwA48"> </span><span class="kn" id="mwA5A">import</span> <span class="n" id="mwA5E">reduce</span> <span class="kn" id="mwA5I">from</span><span class="w" id="mwA5M"> </span><span class="nn" id="mwA5Q">typing</span><span class="w" id="mwA5U"> </span><span class="kn" id="mwA5Y">import</span> <span class="n" id="mwA5c">Callable</span> <span class="k" id="mwA5g">def</span><span class="w" id="mwA5k"> </span><span class="nf" id="mwA5o">compose</span><span class="p" id="mwA5s">(</span><span class="o" id="mwA5w">*</span><span class="n" id="mwA50">funcs</span><span class="p" id="mwA54">)</span> <span class="o" id="mwA58">-></span> <span class="n" id="mwA6A">Callable</span><span class="p" id="mwA6E">[[</span><span class="nb" id="mwA6I">int</span><span class="p" id="mwA6M">],</span> <span class="nb" id="mwA6Q">int</span><span class="p" id="mwA6U">]:</span> <span class="w" id="mwA6Y"> </span><span class="sd" id="mwA6c">"""Compose a group of functions (f(g(h(...)))) into a single composite func."""</span> <span class="k" id="mwA6g">return</span> <span class="n" id="mwA6k">reduce</span><span class="p" id="mwA6o">(</span><span class="k" id="mwA6s">lambda</span> <span class="n" id="mwA6w">f</span><span class="p" id="mwA60">,</span> <span class="n" id="mwA64">g</span><span class="p" id="mwA68">:</span> <span class="k" id="mwA7A">lambda</span> <span class="n" id="mwA7E">x</span><span class="p" id="mwA7I">:</span> <span class="n" id="mwA7M">f</span><span class="p" id="mwA7Q">(</span><span class="n" id="mwA7U">g</span><span class="p" id="mwA7Y">(</span><span class="n" id="mwA7c">x</span><span class="p" id="mwA7g">)),</span> <span class="n" id="mwA7k">funcs</span><span class="p" id="mwA7o">)</span> <span class="c1" id="mwA7s"># Example</span> <span class="n" id="mwA7w">f</span> <span class="o" id="mwA70">=</span> <span class="k" id="mwA74">lambda</span> <span class="n" id="mwA78">x</span><span class="p" id="mwA8A">:</span> <span class="n" id="mwA8E">x</span> <span class="o" id="mwA8I">+</span> <span class="mi" id="mwA8M">1</span> <span class="n" id="mwA8Q">g</span> <span class="o" id="mwA8U">=</span> <span class="k" id="mwA8Y">lambda</span> <span class="n" id="mwA8c">x</span><span class="p" id="mwA8g">:</span> <span class="n" id="mwA8k">x</span> <span class="o" id="mwA8o">*</span> <span class="mi" id="mwA8s">2</span> <span class="n" id="mwA8w">h</span> <span class="o" id="mwA80">=</span> <span class="k" id="mwA84">lambda</span> <span class="n" id="mwA88">x</span><span class="p" id="mwA9A">:</span> <span class="n" id="mwA9E">x</span> <span class="o" id="mwA9I">-</span> <span class="mi" id="mwA9M">3</span> <span class="c1" id="mwA9Q"># Call the function x=10 : ((x - 3) * 2) + 1 = 15</span> <span class="nb" id="mwA9U">print</span><span class="p" id="mwA9Y">(</span><span class="n" id="mwA9c">compose</span><span class="p" id="mwA9g">(</span><span class="n" id="mwA9k">f</span><span class="p" id="mwA9o">,</span> <span class="n" id="mwA9s">g</span><span class="p" id="mwA9w">,</span> <span class="n" id="mwA90">h</span><span class="p" id="mwA94">)(</span><span class="mi" id="mwA98">10</span><span class="p" id="mwA-A">))</span>
JavaScript
In JavaScript we can define it as a function which takes two functions f and g, and produces a function:
<span id="mwA-g"></span><span class="kd" id="mwA-k">function</span><span class="w" id="mwA-o"> </span><span class="nx" id="mwA-s">o</span><span class="p" id="mwA-w">(</span><span class="nx" id="mwA-0">f</span><span class="p" id="mwA-4">,</span><span class="w" id="mwA-8"> </span><span class="nx" id="mwA_A">g</span><span class="p" id="mwA_E">)</span><span class="w" id="mwA_I"> </span><span class="p" id="mwA_M">{</span> <span class="w" id="mwA_Q"> </span><span class="k" id="mwA_U">return</span><span class="w" id="mwA_Y"> </span><span class="kd" id="mwA_c">function</span><span class="p" id="mwA_g">(</span><span class="nx" id="mwA_k">x</span><span class="p" id="mwA_o">)</span><span class="w" id="mwA_s"> </span><span class="p" id="mwA_w">{</span> <span class="w" id="mwA_0"> </span><span class="k" id="mwA_4">return</span><span class="w" id="mwA_8"> </span><span class="nx" id="mwBAA">f</span><span class="p" id="mwBAE">(</span><span class="nx" id="mwBAI">g</span><span class="p" id="mwBAM">(</span><span class="nx" id="mwBAQ">x</span><span class="p" id="mwBAU">));</span> <span class="w" id="mwBAY"> </span><span class="p" id="mwBAc">}</span> <span class="p" id="mwBAg">}</span> <span class="c1" id="mwBAk">// Alternatively, using the rest operator and lambda expressions in ES2015</span> <span class="kd" id="mwBAo">const</span><span class="w" id="mwBAs"> </span><span class="nx" id="mwBAw">compose</span><span class="w" id="mwBA0"> </span><span class="o" id="mwBA4">=</span><span class="w" id="mwBA8"> </span><span class="p" id="mwBBA">(...</span><span class="nx" id="mwBBE">fs</span><span class="p" id="mwBBI">)</span><span class="w" id="mwBBM"> </span><span class="p" id="mwBBQ">=></span><span class="w" id="mwBBU"> </span><span class="p" id="mwBBY">(</span><span class="nx" id="mwBBc">x</span><span class="p" id="mwBBg">)</span><span class="w" id="mwBBk"> </span><span class="p" id="mwBBo">=></span><span class="w" id="mwBBs"> </span><span class="nx" id="mwBBw">fs</span><span class="p" id="mwBB0">.</span><span class="nx" id="mwBB4">reduceRight</span><span class="p" id="mwBB8">((</span><span class="nx" id="mwBCA">acc</span><span class="p" id="mwBCE">,</span><span class="w" id="mwBCI"> </span><span class="nx" id="mwBCM">f</span><span class="p" id="mwBCQ">)</span><span class="w" id="mwBCU"> </span><span class="p" id="mwBCY">=></span><span class="w" id="mwBCc"> </span><span class="nx" id="mwBCg">f</span><span class="p" id="mwBCk">(</span><span class="nx" id="mwBCo">acc</span><span class="p" id="mwBCs">),</span><span class="w" id="mwBCw"> </span><span class="nx" id="mwBC0">x</span><span class="p" id="mwBC4">)</span>C#
In C# we can define it as an Extension method which takes Funcs f and g, and produces a new Func:
<span id="mwBDg"></span><span class="c1" id="mwBDk">// Call example:</span> <span class="c1" id="mwBDo">// var c = f.ComposeWith(g);</span> <span class="c1" id="mwBDs">//</span> <span class="c1" id="mwBDw">// Func<int, bool> g = _ => ...</span> <span class="c1" id="mwBD0">// Func<bool, string> f = _ => ...</span> <span class="k" id="mwBD4">public</span><span class="w" id="mwBD8"> </span><span class="k" id="mwBEA">static</span><span class="w" id="mwBEE"> </span><span class="n" id="mwBEI">Func</span><span class="o" id="mwBEM"><</span><span class="n" id="mwBEQ">T1</span><span class="p" id="mwBEU">,</span><span class="w" id="mwBEY"> </span><span class="n" id="mwBEc">T3</span><span class="o" id="mwBEg">></span><span class="w" id="mwBEk"> </span><span class="n" id="mwBEo">ComposeWith</span><span class="o" id="mwBEs"><</span><span class="n" id="mwBEw">T1</span><span class="p" id="mwBE0">,</span><span class="w" id="mwBE4"> </span><span class="n" id="mwBE8">T2</span><span class="p" id="mwBFA">,</span><span class="w" id="mwBFE"> </span><span class="n" id="mwBFI">T3</span><span class="o" id="mwBFM">></span><span class="p" id="mwBFQ">(</span><span class="k" id="mwBFU">this</span><span class="w" id="mwBFY"> </span><span class="n" id="mwBFc">Func</span><span class="o" id="mwBFg"><</span><span class="n" id="mwBFk">T2</span><span class="p" id="mwBFo">,</span><span class="w" id="mwBFs"> </span><span class="n" id="mwBFw">T3</span><span class="o" id="mwBF0">></span><span class="w" id="mwBF4"> </span><span class="n" id="mwBF8">f</span><span class="p" id="mwBGA">,</span><span class="w" id="mwBGE"> </span><span class="n" id="mwBGI">Func</span><span class="o" id="mwBGM"><</span><span class="n" id="mwBGQ">T1</span><span class="p" id="mwBGU">,</span><span class="w" id="mwBGY"> </span><span class="n" id="mwBGc">T2</span><span class="o" id="mwBGg">></span><span class="w" id="mwBGk"> </span><span class="n" id="mwBGo">g</span><span class="p" id="mwBGs">)</span><span class="w" id="mwBGw"> </span><span class="o" id="mwBG0">=></span><span class="w" id="mwBG4"> </span><span class="n" id="mwBG8">x</span><span class="w" id="mwBHA"> </span><span class="o" id="mwBHE">=></span><span class="w" id="mwBHI"> </span><span class="n" id="mwBHM">f</span><span class="p" id="mwBHQ">(</span><span class="n" id="mwBHU">g</span><span class="p" id="mwBHY">(</span><span class="n" id="mwBHc">x</span><span class="p" id="mwBHg">));</span>
Ruby
Languages like Ruby let you construct a binary operator yourself:
<span id="mwBH4"></span><span class="k" id="mwBH8">class</span><span class="w" id="mwBIA"> </span><span class="nc" id="mwBIE">Proc</span> <span class="w" id="mwBII"> </span><span class="k" id="mwBIM">def</span><span class="w" id="mwBIQ"> </span><span class="nf" id="mwBIU">compose</span><span class="p" id="mwBIY">(</span><span class="n" id="mwBIc">other_fn</span><span class="p" id="mwBIg">)</span> <span class="w" id="mwBIk"> </span><span class="o" id="mwBIo">-></span><span class="p" id="mwBIs">(</span><span class="o" id="mwBIw">*</span><span class="n" id="mwBI0">as</span><span class="p" id="mwBI4">)</span><span class="w" id="mwBI8"> </span><span class="p" id="mwBJA">{</span><span class="w" id="mwBJE"> </span><span class="n" id="mwBJI">other_fn</span><span class="o" id="mwBJM">.</span><span class="n" id="mwBJQ">call</span><span class="p" id="mwBJU">(</span><span class="n" id="mwBJY">call</span><span class="p" id="mwBJc">(</span><span class="o" id="mwBJg">*</span><span class="n" id="mwBJk">as</span><span class="p" id="mwBJo">))</span><span class="w" id="mwBJs"> </span><span class="p" id="mwBJw">}</span> <span class="w" id="mwBJ0"> </span><span class="k" id="mwBJ4">end</span> <span class="w" id="mwBJ8"> </span><span class="n" id="mwBKA">alias_method</span><span class="w" id="mwBKE"> </span><span class="ss" id="mwBKI">:+</span><span class="p" id="mwBKM">,</span><span class="w" id="mwBKQ"> </span><span class="ss" id="mwBKU">:compose</span> <span class="k" id="mwBKY">end</span> <span class="n" id="mwBKc">f</span><span class="w" id="mwBKg"> </span><span class="o" id="mwBKk">=</span><span class="w" id="mwBKo"> </span><span class="o" id="mwBKs">-></span><span class="p" id="mwBKw">(</span><span class="n" id="mwBK0">x</span><span class="p" id="mwBK4">)</span><span class="w" id="mwBK8"> </span><span class="p" id="mwBLA">{</span><span class="w" id="mwBLE"> </span><span class="n" id="mwBLI">x</span><span class="w" id="mwBLM"> </span><span class="o" id="mwBLQ">*</span><span class="w" id="mwBLU"> </span><span class="mi" id="mwBLY">2</span><span class="w" id="mwBLc"> </span><span class="p" id="mwBLg">}</span> <span class="n" id="mwBLk">g</span><span class="w" id="mwBLo"> </span><span class="o" id="mwBLs">=</span><span class="w" id="mwBLw"> </span><span class="o" id="mwBL0">-></span><span class="p" id="mwBL4">(</span><span class="n" id="mwBL8">x</span><span class="p" id="mwBMA">)</span><span class="w" id="mwBME"> </span><span class="p" id="mwBMI">{</span><span class="w" id="mwBMM"> </span><span class="n" id="mwBMQ">x</span><span class="w" id="mwBMU"> </span><span class="o" id="mwBMY">**</span><span class="w" id="mwBMc"> </span><span class="mi" id="mwBMg">3</span><span class="w" id="mwBMk"> </span><span class="p" id="mwBMo">}</span> <span class="p" id="mwBMs">(</span><span class="n" id="mwBMw">f</span><span class="w" id="mwBM0"> </span><span class="o" id="mwBM4">+</span><span class="w" id="mwBM8"> </span><span class="n" id="mwBNA">g</span><span class="p" id="mwBNE">)</span><span class="o" id="mwBNI">.</span><span class="n" id="mwBNM">call</span><span class="p" id="mwBNQ">(</span><span class="mi" id="mwBNU">12</span><span class="p" id="mwBNY">)</span><span class="w" id="mwBNc"> </span><span class="c1" id="mwBNg"># => 13824</span>However, a native function composition operator was introduced in Ruby 2.6:
<span id="mwBOA"></span><span class="n" id="mwBOE">f</span><span class="w" id="mwBOI"> </span><span class="o" id="mwBOM">=</span><span class="w" id="mwBOQ"> </span><span class="nb" id="mwBOU">proc</span><span class="p" id="mwBOY">{</span><span class="o" id="mwBOc">|</span><span class="n" id="mwBOg">x</span><span class="o" id="mwBOk">|</span><span class="w" id="mwBOo"> </span><span class="n" id="mwBOs">x</span><span class="w" id="mwBOw"> </span><span class="o" id="mwBO0">+</span><span class="w" id="mwBO4"> </span><span class="mi" id="mwBO8">2</span><span class="p" id="mwBPA">}</span> <span class="n" id="mwBPE">g</span><span class="w" id="mwBPI"> </span><span class="o" id="mwBPM">=</span><span class="w" id="mwBPQ"> </span><span class="nb" id="mwBPU">proc</span><span class="p" id="mwBPY">{</span><span class="o" id="mwBPc">|</span><span class="n" id="mwBPg">x</span><span class="o" id="mwBPk">|</span><span class="w" id="mwBPo"> </span><span class="n" id="mwBPs">x</span><span class="w" id="mwBPw"> </span><span class="o" id="mwBP0">*</span><span class="w" id="mwBP4"> </span><span class="mi" id="mwBP8">3</span><span class="p" id="mwBQA">}</span> <span class="p" id="mwBQE">(</span><span class="n" id="mwBQI">f</span><span class="w" id="mwBQM"> </span><span class="o" id="mwBQQ"><<</span><span class="w" id="mwBQU"> </span><span class="n" id="mwBQY">g</span><span class="p" id="mwBQc">)</span><span class="o" id="mwBQg">.</span><span class="n" id="mwBQk">call</span><span class="p" id="mwBQo">(</span><span class="mi" id="mwBQs">3</span><span class="p" id="mwBQw">)</span><span class="w" id="mwBQ0"> </span><span class="c1" id="mwBQ4"># -> 11; identical to f(g(3))</span> <span class="p" id="mwBQ8">(</span><span class="n" id="mwBRA">f</span><span class="w" id="mwBRE"> </span><span class="o" id="mwBRI">>></span><span class="w" id="mwBRM"> </span><span class="n" id="mwBRQ">g</span><span class="p" id="mwBRU">)</span><span class="o" id="mwBRY">.</span><span class="n" id="mwBRc">call</span><span class="p" id="mwBRg">(</span><span class="mi" id="mwBRk">3</span><span class="p" id="mwBRo">)</span><span class="w" id="mwBRs"> </span><span class="c1" id="mwBRw"># -> 15; identical to g(f(3))</span>Research survey
Notions of composition, including the principle of compositionality and composability, 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.
- Steele (1994) directly applied function composition to the assemblage of building blocks known as 'monads' in the Haskell programming language.
- Meyer (1988) addressed the software reuse problem in terms of composability.
- Abadi & Lamport (1993) formally defined a proof rule for functional composition that assures a program's safety and liveness.
- Kracht (2001) identified a strengthened form of compositionality by placing it into a semiotic system and applying it to the problem of structural ambiguity frequently encountered in computational linguistics.
- van Gelder & Port (1993) examined the role of compositionality in analog aspects of natural language processing.
- According to a review by Gibbons (2002), formal treatment of composition underlies validation of component assembly in visual programming languages like IBM's Visual Age for the Java 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 allowing easy composition of filters were so successful that they became a design pattern of operating systems.
Imperative procedures with side effects violate referential transparency 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 formalism uses this idea to incorporate side effects and input/output (I/O) into functional languages.

