# Difference between revisions of "Function composition"

Line 1: | Line 1: | ||

− | '''Function composition''' refers to the "gluing" together of two [[function]]s using a [[dyadic operator]] such that the functions are applied to the [[argument]](s) as normal, but in a particular pattern specific to the used [[operator]]. The term [[wikipedia:function composition|function composition]] comes from [[traditional mathematics]] where it is used for a function <math>h(x)=f(g(x))</math> when written as <math> h(x) = (f \circ g)(x)</math>. APL generalises this idea to [[dyadic function]]s, allowing various patterns of application in addition to the simple application of one [[monadic function]] to the result of another monadic function. The | + | '''Function composition''' refers to the "gluing" together of two or more [[function]]s using a [[dyadic operator]] or a [[train]] such that the functions are applied to the [[argument]](s) as normal, but in a particular pattern specific to the used [[operator]]. The term [[wikipedia:function composition|function composition]] comes from [[traditional mathematics]] where it is used for a function <math>h(x)=f(g(x))</math> when written as <math> h(x) = (f \circ g)(x)</math>. APL generalises this idea to [[dyadic function]]s, allowing various patterns of application in addition to the simple application of one [[monadic function]] to the result of another monadic function. The patterns represented by the operators [[Atop (operator)|Atop]], [[Beside]], and [[Over]] can be visualised as follows: |

− | :[[File: | + | {| class=wikitable |

− | + | ! Atop !! Beside !! Over | |

+ | |- | ||

+ | |[[File:F⍤g.png|frameless|200px]]||[[File:F∘g.png|frameless|200px]]||[[File:F⍥g.png|frameless|200px]] | ||

+ | |} | ||

+ | |||

+ | The patterns represented by [[Tacit_programming#trains|trains]], the 2-train Atop and the 3-train Fork, can be visualised as follows: | ||

+ | {| class=wikitable | ||

+ | ! 2-train !! 3-train | ||

+ | |- | ||

+ | |[[File:Fg.png|frameless|200px]]||[[File:Fgh.png|frameless|200px]] | ||

+ | |} | ||

+ | |||

+ | The <source lang=apl inline>∘</source> operator (in this context called [[Bind]]) and the 3-train can also be used with constant arrays, then treating the arrays (<source lang=apl inline>A</source>) as constant functions, much as if they were used as operands to the [[Constant]] operator (<source lang=apl inline>A⍨</source>): | ||

+ | {| class=wikitable | ||

+ | ! Bind !! 3-train | ||

+ | |- | ||

+ | |[[File:A∘g;g∘A.png|frameless|200px]]||[[File:Agh.png|frameless|200px]] | ||

+ | |} | ||

+ | === Summary of rules === | ||

+ | |||

+ | These are the rules applied in [[Dyalog APL]]: | ||

+ | |||

+ | <source lang=apl inline> ( g∘h) ⍵</source> {{←→}} <source lang=apl inline> g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ ( g∘h) ⍵</source> {{←→}} <source lang=apl inline> ⍺ g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline> (A∘g ) ⍵</source> {{←→}} <source lang=apl inline> A g ⍵ </source><br> | ||

+ | <source lang=apl inline> ( g∘A) ⍵</source> {{←→}} <source lang=apl inline> ⍵ g A </source><br> | ||

+ | <source lang=apl inline> ( g⍤h) ⍵</source> {{←→}} <source lang=apl inline> g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ ( g⍤h) ⍵</source> {{←→}} <source lang=apl inline> g (⍺ h ⍵)</source><br> | ||

+ | <source lang=apl inline> ( g⍥h) ⍵</source> {{←→}} <source lang=apl inline> g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ ( g⍥h) ⍵</source> {{←→}} <source lang=apl inline>( h ⍺) g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline> (f g h) ⍵</source> {{←→}} <source lang=apl inline>( f ⍵) g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ (f g h) ⍵</source> {{←→}} <source lang=apl inline>(⍺ f ⍵) g (⍺ h ⍵)</source><br> | ||

+ | <source lang=apl inline> (A g h) ⍵</source> {{←→}} <source lang=apl inline> A g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ (A g h) ⍵</source> {{←→}} <source lang=apl inline> A g (⍺ h ⍵)</source><br> | ||

+ | <source lang=apl inline> (g h) ⍵</source> {{←→}} <source lang=apl inline> g ( h ⍵)</source><br> | ||

+ | <source lang=apl inline>⍺ (g h) ⍵</source> {{←→}} <source lang=apl inline> g (⍺ h ⍵)</source> | ||

== Additional compositions == | == Additional compositions == |

## Revision as of 18:31, 30 June 2022

**Function composition** refers to the "gluing" together of two or more functions using a dyadic operator or a train such that the functions are applied to the argument(s) as normal, but in a particular pattern specific to the used operator. The term function composition comes from traditional mathematics where it is used for a function when written as . APL generalises this idea to dyadic functions, allowing various patterns of application in addition to the simple application of one monadic function to the result of another monadic function. The patterns represented by the operators Atop, Beside, and Over can be visualised as follows:

Atop | Beside | Over |
---|---|---|

The patterns represented by trains, the 2-train Atop and the 3-train Fork, can be visualised as follows:

2-train | 3-train |
---|---|

The `∘`

operator (in this context called Bind) and the 3-train can also be used with constant arrays, then treating the arrays (`A`

) as constant functions, much as if they were used as operands to the Constant operator (`A⍨`

):

Bind | 3-train |
---|---|

### Summary of rules

These are the rules applied in Dyalog APL:

` ( g∘h) ⍵`

` g ( h ⍵)`

`⍺ ( g∘h) ⍵`

` ⍺ g ( h ⍵)`

` (A∘g ) ⍵`

` A g ⍵ `

` ( g∘A) ⍵`

` ⍵ g A `

` ( g⍤h) ⍵`

` g ( h ⍵)`

`⍺ ( g⍤h) ⍵`

` g (⍺ h ⍵)`

` ( g⍥h) ⍵`

` g ( h ⍵)`

`⍺ ( g⍥h) ⍵`

`( h ⍺) g ( h ⍵)`

` (f g h) ⍵`

`( f ⍵) g ( h ⍵)`

`⍺ (f g h) ⍵`

`(⍺ f ⍵) g (⍺ h ⍵)`

` (A g h) ⍵`

` A g ( h ⍵)`

`⍺ (A g h) ⍵`

` A g (⍺ h ⍵)`

` (g h) ⍵`

` g ( h ⍵)`

`⍺ (g h) ⍵`

` g (⍺ h ⍵)`

## Additional compositions

Additional compositions are possible, even without using an argument more than once or applying a function to its own result. However, most of these are rather trivial shuffled-around versions of the above three. For example, one could define an operator identical to Atop, only that it applies the right operand to the result of the left operand, that is `{⍵⍵ ⍺ ⍺⍺ ⍵}`

.

When Dyalog added Atop and Over, it was with the reasoning that these were the only compositions where the leftmost function acted as the "root" function in the evaluation tree, while the arguments were used each on their respective sides of the constituent functions:

Of note here is `f⍨∘g⍨`

which is equivalent to — although with swapped operands — Reverse-compose `⍛`

(also called *Before*), and the mirrored version of Beside `∘`

(also known as *Compose* and *After*), because it is the only such variation that has been implemented, namely in dzaima/APL and Extended Dyalog APL.

A compositional operator that isn't just a shuffled around version of the basic three, is one that applies one operand between the other operand's dyadic result and the result of that other operand's result when swapped: `{(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}`

. This operator can for example be used to implement three-way comparison:

```
S ← {(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}
cmp ← -S≤
2 cmp 3
¯1
3 cmp 3
0
4 cmp 3
1
```

## External links

- Dyalog '19: Tacit Techniques with Dyalog version 18.0 Operators
- Dyalog webinar: Language Features of Dyalog version 18.0 in Depth

APL features [edit]
| |
---|---|

Built-ins | Primitives (functions, operators) ∙ Quad name |

Array model | Shape ∙ Rank ∙ Depth ∙ Bound ∙ Index (Indexing) ∙ Axis ∙ Ravel ∙ Ravel order ∙ Element ∙ Scalar ∙ Vector ∙ Matrix ∙ Simple scalar ∙ Simple array ∙ Nested array ∙ Cell ∙ Major cell ∙ Subarray ∙ Empty array ∙ Prototype |

Data types | Number (Boolean, Complex number) ∙ Character (String) ∙ Box ∙ Namespace |

Concepts and paradigms | Conformability (Scalar extension, Leading axis agreement) ∙ Scalar function (Pervasion) ∙ Identity element ∙ Complex floor ∙ Total array ordering ∙ Tacit programming (Function composition, Close composition) ∙ Glyph |

Errors | LIMIT ERROR ∙ RANK ERROR ∙ SYNTAX ERROR ∙ DOMAIN ERROR ∙ LENGTH ERROR ∙ INDEX ERROR ∙ VALUE ERROR |