Precedence: Difference between revisions

Jump to navigation Jump to search
2,933 bytes added ,  11:19, 6 October 2022
flesh out
(add nav box)
(flesh out)
 
Line 1: Line 1:
In APL, there is no precedence hierarchy within a given [[name class]] - the role which a semantic object fulfills - for example, [[Array]]s, [[Function]]s, and [[Operator]]s have consistent binding strength and scope. So, the APL functions <syntaxhighlight lang=apl inline>÷, ×, *, +</syntaxhighlight> are evaluated in a precisely identical fashion. Unlike other languages, which choose to follow the traditional mathematical rules of precedence.
In APL, there is no precedence hierarchy within a given [[name class]] the role which a semantic object fulfils — for example, [[Array]]s, [[Function]]s, and [[Operator]]s have consistent binding strength and scope. Therefore, the functions <syntaxhighlight lang=apl inline>÷</syntaxhighlight>, <syntaxhighlight lang=apl inline>×</syntaxhighlight>, <syntaxhighlight lang=apl inline>*</syntaxhighlight>, <syntaxhighlight lang=apl inline>+</syntaxhighlight> are evaluated in a precisely identical fashion, unlike other languages, which choose to follow the [[Comparison with traditional mathematics|traditional mathematical]] rules for [[wikipedia:order of operations|order of operations]].


However, there is disparity in relative precedence between name classes. For example, an operator binds tighter to its operand, than a function does to its argument.
== Details ==


These differences can be enumerated in a table:
Relative precedence differs between name classes. For example, an operator binds tighter to its operand than a function does to its argument. These differences can be enumerated in a table, like the following simplified example of binding strengths:


{| class="wikitable"
{| class="wikitable"
|
! When ↓ is adjacent to →
| A
! Array
| F
! Function
| M
! Monadic operator
| D
|-
|-
| A
! Array
| 4
| 4
| 2
| 2
| 3
| 3
|
|-
|-
| F
! Function
| 1
| 1
|
|
| 3
| 3
|
|-
| M
|
|
|
|
|-
|-
| D
! Dyadic operator
| 3
| 3
| 3
| 3
|
|
|
|}
|}


=== Explanation ===
In this example, Array–Array binds strongest, to produce a new array through [[stranding]]. Operator–[[Operand]] (Array or Function) binding follows, to produce a [[derived function]] (note that Dyadic operator binds its right operand, deriving a monadic operator). Finally, functions are applied to their arguments. Functions have ''long right scope'' and ''short left scope'', that is, everything to the right of a function (up until the statement or bracket end) is taken as a right argument, while only an immediately adjacent array on the left becomes the left argument to its left (and thus, functions are said to evaluate right to left). It is therefore often necessary to parenthesise left arguments. Operators have long left scope and short right scope, that is, the entire function phrase to the left of an operator becomes its left operand, while only the right-hand function to the immediate right can become the right operand (of a dyadic operator). It is therefore often necessary to parenthesise right operands.
* Categories:
** Array
** Function
** Monadic Operator
** Dyadic Operator


Array-array binds strongest, to produce an array ([[stranding]]).
Minor differences exist in binding strengths between APL implementations. For example, in [[APL2]] and its derivatives (e.g. [[APLX]] and [[GNU APL]]), Operator–Array binds stronger than Array–Array, which means that a literal vector right-operand must be parenthesised. This is opposed to Dyalog APL and its derivatives (e.g. [[ngn/apl]] and [[dzaima/APL]]) where stranding is stronger than operand binding, which means that adjacent operands and arguments must be separated by parenthesis or function application. APL2 et al. also have [[bracket indexing]] bind stronger than stranding, while the opposite is true in Dyalog APL et al. Such differences can be illustrated with the following examples:


Operator-[[Operand]] (Array or Function) binding follows, to produce a [[derived function]].
{| class=wikitable
! GNU APL !! Dyalog APL
|-
| <syntaxhighlight lang=apl inline>⊖⍤2 2 3 4⍴⍳23</syntaxhighlight> || <syntaxhighlight lang=apl inline>(⊖⍤2) 2 3 4⍴⍳23</syntaxhighlight> or <syntaxhighlight lang=apl inline>⊖⍤2 ⊢ 2 3 4⍴⍳23</syntaxhighlight>
|-
| <syntaxhighlight lang=apl inline>1 2 3 4⊖⍤(1 2) 2 3 4⍴⍳23</syntaxhighlight> || <syntaxhighlight lang=apl inline>1 2 (⊖⍤0 2) 2 3 4⍴⍳23</syntaxhighlight> or <syntaxhighlight lang=apl inline>1 2⊖⍤0 2 ⊢ 2 3 4⍴⍳23</syntaxhighlight>
|-
| <syntaxhighlight lang=apl inline>(1 2 3)(4 5 6)[2](7 8 9)</syntaxhighlight> || <syntaxhighlight lang=apl inline>(1 2 3)((4 5 6)[2])(7 8 9)</syntaxhighlight>
|-
| <syntaxhighlight lang=apl inline>((1 2 3)(4 5 6))[2](7 8 9)</syntaxhighlight> || <syntaxhighlight lang=apl inline>(1 2 3)(4 5 6)[2](7 8 9)</syntaxhighlight>
|}


Then functions are applied to their arguments. Note that functions have ''long right scope'' and ''short left scope'', that is, everything to the right of a function is taken as a right argument, and as a left argument the first array to its left. So, functions are said to evaluate right to left.
== See also ==
* [[Bind]]
== External links ==
=== Documentation ===
* [https://microapl.com/apl_help/ch_020_010_030.htm APLX]
* [https://help.dyalog.com/latest/#Language/Introduction/Binding%20Strength.htm Dyalog]
* [https://code.jsoftware.com/wiki/Help/JforC/Parsing_and_Execution_II#_Toc5414505 J]
=== Other ===
* [[dfns workspace]]: [https://dfns.dyalog.com/n_parse.htm parse] — Bunda-Gerth parsing
* [[Jim Brown]]: [https://www.softwarepreservation.org/projects/apl/Papers/DevelopmentofAPL2Syntax A development of APL2 syntax]
{{APL syntax}}
{{APL syntax}}

Navigation menu