|
|
Line 1: |
Line 1: |
| '''Tacit programming''', also called '''[[wikipedia:Tacit_programming|point-free style]]''', refers to usage of tacit [[function]]s that are defined in terms of implicit [[argument]]s. This is in contrast to the explicit use of arguments in [[dfn]]s (<source inline lang=apl>⍺ ⍵</source>) and [[tradfn]]s (which have named arguments). Some APL dialects allow to combine functions into [[#trains|trains]] following a small set of rules. This allows creating complex [[derived function]]s without specifying any arguments explicitly. | | '''Tacit programming''', also called '''[[wikipedia:Tacit_programming|point-free style]]''', refers to usage of tacit [[function]]s that are defined in terms of implicit [[argument]]s. This is in contrast to the explicit use of arguments in [[dfn]]s (<source inline lang=apl>⍺ ⍵</source>) and [[tradfn]]s (which have named arguments). Some APL dialects allow to combine functions into [[train]]s following a small set of rules. This allows creating complex [[derived function]]s without specifying any arguments explicitly. |
|
| |
|
| Dialects which implement trains include [[Dyalog APL]], [[dzaima/APL]], [[ngn/apl]] and [[NARS2000]]. | | Dialects which implement trains include [[Dyalog APL]], [[dzaima/APL]], [[ngn/apl]] and [[NARS2000]]. |
Line 34: |
Line 34: |
|
| |
|
| == Trains == | | == Trains == |
| A train is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. Below, <source lang=apl inline>⍺</source> and <source lang=apl inline>⍵</source> refer to the arguments of the train. <source lang=apl inline>f</source>, <source lang=apl inline>g</source>, and <source lang=apl inline>h</source> are functions (which themselves can be tacit or not), and <source lang=apl inline>A</source> is an array. The arguments are processed by the following rules: | | A [[train]] is a series of functions in isolation. An isolated function is either surrounded by parentheses or named. |
|
| |
|
| === 3-trains ===
| | These rules are used for 3-trains: |
| A 3-train is a ''fork'', so denoted because its structure resembles a three-tines fork, or a three-pronged pitchfork. The two outer functions are applied first, and their results are used as arguments to the middle function:
| |
| {| | | {| |
| |<source lang=apl> (f g h) ⍵</source>|| {{←→}} ||<source lang=apl>( f ⍵) g ( h ⍵)</source> | | |<source lang=apl> (f g h) ⍵</source>|| {{←→}} ||<source lang=apl>( f ⍵) g ( h ⍵)</source> |
Line 50: |
Line 49: |
| |} | | |} |
|
| |
|
| === 2-trains ===
| | In APL (but not [[J]]), these rules are used for 2-trains: |
| Most dialects define a 2-train is an ''atop'', equivalent to the function derived using the [[Atop (operator)|Atop]] operator. The left function is applied [[monadic function|monadically]] on the result of the right function:
| |
| {| | | {| |
| |<source lang=apl> (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g ( h ⍵)</source> | | |<source lang=apl> (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g ( h ⍵)</source> |
Line 57: |
Line 55: |
| |<source lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g (⍺ h ⍵)</source> | | |<source lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<source lang=apl>g (⍺ h ⍵)</source> |
| |} | | |} |
|
| |
| Only [[dzaima/APL]] allows <source lang=apl inline>(A h)</source>, which it treats as <source lang=apl inline>A∘h</source>.<ref>dzaima/APL: [https://github.com/dzaima/APL/blob/ceea05e25687988ed0980a4abf4b9249b736543f/docs/differences.txt#L19 Differences from Dyalog APL]. Retrieved 09 Jan 2020.</ref> See [[Bind]].
| |
|
| |
| [[J]] instead defines the 2-train as a [[hook]], equivalent to the function derived using the [[Withe]] operator. The left function is always applied [[dyadic function|dyadically]], taking as right argument, the result of applying the right function on the right argument. If there is no left argument, the sole argument is used also as left argument:
| |
| {|
| |
| |<source lang=apl> (g h) ⍵</source>|| {{←→}} ||<source lang=apl>⍵ g (h ⍵)</source>
| |
| |-
| |
| |<source lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<source lang=apl>⍺ g (h ⍵)</source>
| |
| |}
| |
|
| |
| === Problems caused by function-operator overloading ===
| |
| Trains that use a [[Function-operator_overloading|hybrid function-operator]] in its [[function]] role can run into the problems with the hybrid being parsed as a monadic [[operator]] instead of as a function. This happens when a function appears to the immediate left of the hybrid, causing this function to be bound as the hybrid's operand — the hybrid taking on an operator role — rather than supplying a left [[argument]] or post-processing the result.
| |
|
| |
| For example, the attempted [[#3-trains|fork]] <source lang=apl inline>f/h</source> is actually parsed as the [[#2-trains|atop]] <source lang=apl inline>(f/)h</source> and the attempted atop <source lang=apl inline>f/</source> is actually parsed as a [[Windowed Reduce|Windowed Reduction]]. There are multiple [[Function-operator_overloading#Mitigation|ways to mitigate this issue]]. For example, the fork can be enforced using the [[Atop (operator)|Atop operator]] by applying identity to the hybrid's result as <source lang=apl inline>f⊢⍤/h</source> and the atop can be enforced by using the explicit Atop operator instead of a 2-train; <source lang=apl inline>f⍤/</source>.
| |
|
| |
| No problem presents when left argument is supplied as an array (literal or by name reference) and when the hybrid is the leftmost token. For example, <source lang=apl inline>1 0 1/⌽</source> and <source lang=apl inline>/,⊃</source> are parsed as forks.
| |
|
| |
|
| == Debugging == | | == Debugging == |
Line 237: |
Line 219: |
| * [[Dyalog '13]]: [https://www.youtube.com/watch?v=7-93GzDqC08 Train Spotting in Version 14.0] | | * [[Dyalog '13]]: [https://www.youtube.com/watch?v=7-93GzDqC08 Train Spotting in Version 14.0] |
| </div> | | </div> |
|
| |
| === Documentation ===
| |
| * [https://help.dyalog.com/16.0/Content/RelNotes14.0/Function%20Trains.htm Announcement]
| |
| * [https://help.dyalog.com/latest/Content/Language/Introduction/Trains.htm Dyalog]
| |
|
| |
|
| == References == | | == References == |