Precedence: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
(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}}

Latest revision as of 11:19, 6 October 2022

In APL, there is no precedence hierarchy within a given name class — the role which a semantic object fulfils — for example, Arrays, Functions, and Operators have consistent binding strength and scope. Therefore, the functions ÷, ×, *, + are evaluated in a precisely identical fashion, unlike other languages, which choose to follow the traditional mathematical rules for order of operations.

Details

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:

When ↓ is adjacent to → Array Function Monadic operator
Array 4 2 3
Function 1 3
Dyadic operator 3 3

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.

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:

GNU APL Dyalog APL
⊖⍤2 2 3 4⍴⍳23 (⊖⍤2) 2 3 4⍴⍳23 or ⊖⍤2 ⊢ 2 3 4⍴⍳23
1 2 3 4⊖⍤(1 2) 2 3 4⍴⍳23 1 2 (⊖⍤0 2) 2 3 4⍴⍳23 or 1 2⊖⍤0 2 ⊢ 2 3 4⍴⍳23
(1 2 3)(4 5 6)[2](7 8 9) (1 2 3)((4 5 6)[2])(7 8 9)
((1 2 3)(4 5 6))[2](7 8 9) (1 2 3)(4 5 6)[2](7 8 9)

See also

External links

Documentation

Other

APL syntax [edit]
General Comparison with traditional mathematicsPrecedenceTacit programming (Train, Hook, Split composition)
Array Numeric literalStringStrand notationObject literalArray notation (design considerations)
Function ArgumentFunction valenceDerived functionDerived operatorNiladic functionMonadic functionDyadic functionAmbivalent functionDefined function (traditional)DfnFunction train
Operator OperandOperator valenceTradopDopDerived operator
Assignment MultipleIndexedSelectiveModified
Other Function axisBracket indexingBranchStatement separatorQuad nameSystem commandUser commandKeywordDot notationFunction-operator overloadingControl structureComment