Function composition: Difference between revisions

Jump to navigation Jump to search
4,791 bytes added ,  21:12, 10 September 2022
m
Text replacement - "<source" to "<syntaxhighlight"
(Created page with "'''Function composition''' refers to the "gluing" together of two functions using a dyadic operator such that the functions are applied to the argument(s) as norma...")
 
m (Text replacement - "<source" to "<syntaxhighlight")
 
(15 intermediate revisions by 2 users not shown)
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 the 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 three main patterns, represented by [[Atop]], [[Beside]], and [[Over]] can be visualised as follows:
'''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. 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.
== Common compositions ==
[[Reverse Compose]] and [[Beside]] treat their arguments in an asymmetric way. They can be seen as using a [[monadic function]] to pre-process the left or right argument, respectively, before proceeding to apply a main function. Their patterns can be visualised as follows:


:[[File:Compositions.png|frameless]]
{| class=wikitable
When any of these are applied monadically, the dotted branch falls away, and they are all equivalent to each other and to <math>(f \circ g)(x)</math> of traditional mathematics.
! Reverse Compose !! Beside
|-
|[[File:F⍛g.png|frameless|200px]]||[[File:F∘g.png|frameless|200px]]
|}
 
[[Atop (operator)|Atop]] and [[Over]] treat their arguments in a symmetric way. They can be seen as using a monadic function to post-process the result or pre-process the argument(s) of a main function. Their patterns can be visualised as follows:
{| class=wikitable
! Atop !! Over
|-
|[[File:F⍤g.png|frameless|200px]]||[[File:F⍥g.png|frameless|200px]]
|}
 
[[Tacit_programming#trains|Trains]] provide a way to apply a function to the result(s) of one (for 2-trains) or two (for 3-trains) other functions. These patterns are also called Atop and Fork, and can be visualised as follows:
{| class=wikitable
! 2-train !! 3-train
|-
|[[File:Fg.png|frameless|200px]]||[[File:Fgh.png|frameless|200px]]
|}
 
The operator represented by [[Jot]] (<syntaxhighlight lang=apl inline>∘</syntaxhighlight>, in this context called [[Bind]]) and the 3-train can also be used with constant arrays, then treating the arrays (<syntaxhighlight lang=apl inline>A</syntaxhighlight>) as constant functions, much as if they were used as operands to the [[Constant]] operator (<syntaxhighlight lang=apl inline>A⍨</syntaxhighlight>):
{| class=wikitable
! Bind !! 3-train
|-
|[[File:A∘g;g∘A.png|frameless|200px]]||[[File:Agh.png|frameless|200px]]
|}
=== Summary of rules ===
 
The above compositions can be summarised as follows:
 
<syntaxhighlight lang=apl inline>  (f⍛g  ) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>(  f ⍵) g      ⍵ </syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (f⍛g  ) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>(  f ⍺) g      ⍵ </syntaxhighlight><br>
<syntaxhighlight lang=apl inline>  (  g∘h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (  g∘h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>   ⍺    g (  h ⍵)</syntaxhighlight><br>
 
<syntaxhighlight lang=apl inline>  (  g⍤h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (  g⍤h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (⍺ h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>  (  g⍥h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (  g⍥h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>(  h ⍺) g (  h ⍵)</syntaxhighlight><br>
 
<syntaxhighlight lang=apl inline>  (  g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (  g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>        g (⍺ h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>  (f g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>(  f ⍵) g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>(f g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>(⍺ f ⍵) g (⍺ h ⍵)</syntaxhighlight><br>
 
<syntaxhighlight lang=apl inline>  (A∘g  ) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>   A    g      ⍵ </syntaxhighlight><br>
<syntaxhighlight lang=apl inline>  (  g∘A) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>   ⍵    g      A </syntaxhighlight><br>
<syntaxhighlight lang=apl inline>  (A g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>   A    g (  h ⍵)</syntaxhighlight><br>
<syntaxhighlight lang=apl inline>⍺ (A g h) ⍵</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>   A    g (⍺ h ⍵)</syntaxhighlight><br>


== Additional compositions ==
== 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 <source lang=apl inline>{⍵⍵ ⍺ ⍺⍺ ⍵}</source>.
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 <syntaxhighlight lang=apl inline>{⍵⍵ ⍺ ⍺⍺ ⍵}</syntaxhighlight>.
 
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:
 
[[File:AllCompositions.png|427px]]


Of note is [[Reverse-compose]] <source lang=apl inline>⍛</source> (also called ''Before''), which is the mirrored version of Beside <source lang=apl inline>∘</source> (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]].
Of note here is <syntaxhighlight lang=apl inline>f⍨∘g⍨</syntaxhighlight> which is equivalent to — although with swapped operands — [[Reverse-compose]] <syntaxhighlight lang=apl inline>⍛</syntaxhighlight> (also called ''Before''), and the mirrored version of Beside <syntaxhighlight lang=apl inline>∘</syntaxhighlight> (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 operands [[swap]]ped result: <source lang=apl inline>{(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}</source>. This operator can for example be used to implement [[wikipedia:three-way comparison|three-way comparison]]:
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 [[swap]]ped: <syntaxhighlight lang=apl inline>{(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}</syntaxhighlight>. This operator can for example be used to implement [[wikipedia:three-way comparison|three-way comparison]]:
[https://tio.run/##SyzI0U2pTMzJT///P1jhUdsEhWqNR71bFYAYQu3SBBFApKABIuDiWzVruZJzC8BadIMfdS7hetQ3FcQxUjBWMFEASRn//w8A Try it online!]<source lang=apl>
[https://tio.run/##SyzI0U2pTMzJT///P1jhUdsEhWqNR71bFYAYQu3SBBFApKABIuDiWzVruZJzC8BadIMfdS7hetQ3FcQxUjBWMFEASRn//w8A Try it online!]<syntaxhighlight lang=apl>
       S ← {(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}
       S ← {(⍵ ⍵⍵ ⍺) ⍺⍺ (⍺ ⍵⍵ ⍵)}
       cmp ← -S≤
       cmp ← -S≤
Line 20: Line 73:
       4 cmp 3
       4 cmp 3
1
1
</source>{{Works in|[[Dyalog APL]], [[NARS2000]], [[ngn/apl]]}}
</syntaxhighlight>{{Works in|[[Dyalog APL]], [[NARS2000]], [[ngn/apl]]}}


== External links ==
== External links ==
* [[Dyalog '19]]: [https://dyalog.tv/Dyalog19/?v=czWC4tjwzOQ Tacit Techniques with Dyalog version 18.0 Operators]
* [[Dyalog '19]]: [https://dyalog.tv/Dyalog19/?v=czWC4tjwzOQ Tacit Techniques with Dyalog version 18.0 Operators]
* [[Dyalog webinar]]: [https://dyalog.tv/Webinar/?v=Hln3zryunsw Language Features of Dyalog version 18.0 in Depth]
* [[Dyalog webinar]]: [https://dyalog.tv/Webinar/?v=Hln3zryunsw Language Features of Dyalog version 18.0 in Depth]
{{APL built-ins}}[[Category:Composition operators]][[Category:Tacit programming]]
* Conor Hoekstra: [https://raw.githubusercontent.com/codereport/Content/main/Publications/Combinatory_Logic_and_Combinators_in_Array_Languages.pdf Combinatory Logic and Combinators in Array Languages]
{{APL features}}[[Category:Composition operators]][[Category:Tacit programming]]

Navigation menu