Train: Difference between revisions

Jump to navigation Jump to search
279 bytes added ,  10:58, 11 September 2022
m
Text replacement - "</source>" to "</syntaxhighlight>"
m (Text replacement - "<source" to "<syntaxhighlight")
m (Text replacement - "</source>" to "</syntaxhighlight>")
Line 3: Line 3:
== Definition ==
== Definition ==


Below, <syntaxhighlight lang=apl inline>⍺</source> and <syntaxhighlight lang=apl inline>⍵</source> refer to the arguments of the train. <syntaxhighlight lang=apl inline>f</source>, <syntaxhighlight lang=apl inline>g</source>, and <syntaxhighlight lang=apl inline>h</source> are functions (which themselves can be tacit or not), and <syntaxhighlight lang=apl inline>A</source> is an array. The arguments are processed by the following rules:
Below, <syntaxhighlight lang=apl inline>⍺</syntaxhighlight> and <syntaxhighlight lang=apl inline>⍵</syntaxhighlight> refer to the arguments of the train. <syntaxhighlight lang=apl inline>f</syntaxhighlight>, <syntaxhighlight lang=apl inline>g</syntaxhighlight>, and <syntaxhighlight lang=apl inline>h</syntaxhighlight> are functions (which themselves can be tacit or not), and <syntaxhighlight lang=apl inline>A</syntaxhighlight> is an array. The arguments are processed by the following rules:


=== 3-trains ===
=== 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:
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:
{|
{|
|<syntaxhighlight lang=apl>  (f g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>(  f ⍵) g (  h ⍵)</source>
|<syntaxhighlight lang=apl>  (f g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>(  f ⍵) g (  h ⍵)</syntaxhighlight>
|-
|-
|<syntaxhighlight lang=apl>⍺ (f g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>(⍺ f ⍵) g (⍺ h ⍵)</source>
|<syntaxhighlight lang=apl>⍺ (f g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>(⍺ f ⍵) g (⍺ h ⍵)</syntaxhighlight>
|}
|}
The ''left tine'' of a fork can be an array:
The ''left tine'' of a fork can be an array:
{|
{|
|<syntaxhighlight lang=apl>  (A g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>A g (  h ⍵)</source>
|<syntaxhighlight lang=apl>  (A g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>A g (  h ⍵)</syntaxhighlight>
|-
|-
|<syntaxhighlight lang=apl>⍺ (A g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>A g (⍺ h ⍵)</source>
|<syntaxhighlight lang=apl>⍺ (A g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>A g (⍺ h ⍵)</syntaxhighlight>
|}
|}


Line 22: Line 22:
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:
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:
{|
{|
|<syntaxhighlight lang=apl>  (g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>g (  h ⍵)</source>
|<syntaxhighlight lang=apl>  (g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>g (  h ⍵)</syntaxhighlight>
|-
|-
|<syntaxhighlight lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>g (⍺ h ⍵)</source>
|<syntaxhighlight lang=apl>⍺ (g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>g (⍺ h ⍵)</syntaxhighlight>
|}
|}


Only [[dzaima/APL]] allows <syntaxhighlight lang=apl inline>(A h)</source>, which it treats as <syntaxhighlight 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]].
Only [[dzaima/APL]] allows <syntaxhighlight lang=apl inline>(A h)</syntaxhighlight>, which it treats as <syntaxhighlight lang=apl inline>A∘h</syntaxhighlight>.<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:
[[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:
{|
{|
|<syntaxhighlight lang=apl>  (g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>⍵ g (h ⍵)</source>
|<syntaxhighlight lang=apl>  (g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>⍵ g (h ⍵)</syntaxhighlight>
|-
|-
|<syntaxhighlight lang=apl>⍺ (g h) ⍵</source>|| {{←→}} ||<syntaxhighlight lang=apl>⍺ g (h ⍵)</source>
|<syntaxhighlight lang=apl>⍺ (g h) ⍵</syntaxhighlight>|| {{←→}} ||<syntaxhighlight lang=apl>⍺ g (h ⍵)</syntaxhighlight>
|}
|}


Line 39: Line 39:
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.
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]] <syntaxhighlight lang=apl inline>f/h</source> is actually parsed as the [[#2-trains|atop]] <syntaxhighlight lang=apl inline>(f/)h</source> and the attempted atop <syntaxhighlight 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 <syntaxhighlight lang=apl inline>f⊢⍤/h</source> and the atop can be enforced by using the explicit Atop operator instead of a 2-train; <syntaxhighlight lang=apl inline>f⍤/</source>.
For example, the attempted [[#3-trains|fork]] <syntaxhighlight lang=apl inline>f/h</syntaxhighlight> is actually parsed as the [[#2-trains|atop]] <syntaxhighlight lang=apl inline>(f/)h</syntaxhighlight> and the attempted atop <syntaxhighlight lang=apl inline>f/</syntaxhighlight> 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 <syntaxhighlight lang=apl inline>f⊢⍤/h</syntaxhighlight> and the atop can be enforced by using the explicit Atop operator instead of a 2-train; <syntaxhighlight lang=apl inline>f⍤/</syntaxhighlight>.


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, <syntaxhighlight lang=apl inline>1 0 1/⌽</source> and <syntaxhighlight lang=apl inline>/,⊃</source> are parsed as forks.
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, <syntaxhighlight lang=apl inline>1 0 1/⌽</syntaxhighlight> and <syntaxhighlight lang=apl inline>/,⊃</syntaxhighlight> are parsed as forks.


== History ==
== History ==

Navigation menu