Function-operator overloading: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
No edit summary
Line 20: Line 20:
Function-operator overloading works by checking to the left of a potential function or operator to see if it is a function. This includes [[derived function]]s: for instance, the snippet <source lang=apl inline>-⍨/</source> is treated as a [[reduction]] with operand <source lang=apl inline>-⍨</source>. In [[A+]], only a small set of [[scalar dyadic]] functions can be used as operands to [[Reduce]] and [[Scan]], and the language simply checks whether these glyphs appear immediately to the left of the slash. Thus, parenthesizing or assigning a name to these functions will cause overloading resolution to fail, resulting in a valence error.
Function-operator overloading works by checking to the left of a potential function or operator to see if it is a function. This includes [[derived function]]s: for instance, the snippet <source lang=apl inline>-⍨/</source> is treated as a [[reduction]] with operand <source lang=apl inline>-⍨</source>. In [[A+]], only a small set of [[scalar dyadic]] functions can be used as operands to [[Reduce]] and [[Scan]], and the language simply checks whether these glyphs appear immediately to the left of the slash. Thus, parenthesizing or assigning a name to these functions will cause overloading resolution to fail, resulting in a valence error.
==Mitigation==
==Mitigation==
The [[Atop operator]] provides a way to obtain the other interpretation: <source lang=apl inline>⊢⍤/</source> is identical to <source lang=apl inline>/</source> as a function, but forces the function-operator overloading to be resolved in favor of a function because there is a [[dyadic operator]] to its left.<ref>[[Marshall Lochbaum|Lochbaum, Marshall]]. [https://dyalog.tv/Dyalog19/?v=czWC4tjwzOQ "Tacit Techniques with Dyalog version 18.0 Operators"]. [[Dyalog '19]].</ref> When the Atop operator is not available, [[Compose]] or [[Commute]] can be used instead, but they requires an extra set of parentheses. Alternatively, the function behaviour can be forced by encapsulating the hybrid primitive in a [[dfn]].
The [[Atop operator]] provides a way to obtain the other interpretation: <source lang=apl inline>⊢⍤/</source> is identical to <source lang=apl inline>/</source> as a function, but forces the function-operator overloading to be resolved in favor of a function because there is a [[dyadic operator]] to its left.<ref>[[Marshall Lochbaum|Lochbaum, Marshall]]. [https://dyalog.tv/Dyalog19/?v=czWC4tjwzOQ "Tacit Techniques with Dyalog version 18.0 Operators"]. [[Dyalog '19]].</ref> When the Atop operator is not available, [[Beside]] or [[Commute]] can be used instead, but they require an extra set of parentheses. Alternatively, the function behaviour can be forced by encapsulating the hybrid primitive in a [[dfn]].
<source lang=apl>
<source lang=apl>
       (2=2 1) / (2+2 1)  ⍝ Desired result
       (2=2 1) / (2+2 1)  ⍝ Desired result
Line 35: Line 35:
4
4
</source>{{Works in|[[Dyalog APL]], with version [[Dyalog APL 18.0|18.0]] for [[Atop]]}}
</source>{{Works in|[[Dyalog APL]], with version [[Dyalog APL 18.0|18.0]] for [[Atop]]}}
== References ==
== References ==
<references />
<references />

Revision as of 18:31, 26 April 2020

In APL syntax, function-operator overloading (sometimes schizophrenia[1]) is the practice of using a single glyph for both a primitive function and a primitive operator, which is then characterised as a hybrid primitive. Dialects with this feature include Dyalog APL, NARS2000, A+, and GNU APL. Most commonly it refers to one of the slash glyphs (such as / for Replicate or Reduce, but not for Transpose), but assignment may also be handled in a similar manner because ordinary assignment has the form of a dyadic function while modified assignment works like a monadic operator applied dyadically. It may apply only to the glyphs themselves, or to their values and derivations as well: for example, in Dyalog APL the assignments r←/ and even r←/[3] create variables r which exhibit overloading.

The following glyphs may be subject to function-operator overloading:

Glyph Function Operator
/ Replicate Reduce
\ Expand Scan
Assignment Modified assignment

This form of overloading relies on the fact that an expression like a / b can be disambiguated based on whether a is a function or not: if so, / should be an operator. This assumption is violated when function trains are part of the syntax, because a train such as = / + could be interpreted either as the two-train (=/) +, Equals reduction atop Plus, or as a three train Equals Compress Plus. No interpretation can always give the result the user wants, but dialects with overloading always choose the first interpretation, in which the overloaded value is treated as an operator.

Function-operator overloading works by checking to the left of a potential function or operator to see if it is a function. This includes derived functions: for instance, the snippet -⍨/ is treated as a reduction with operand -⍨. In A+, only a small set of scalar dyadic functions can be used as operands to Reduce and Scan, and the language simply checks whether these glyphs appear immediately to the left of the slash. Thus, parenthesizing or assigning a name to these functions will cause overloading resolution to fail, resulting in a valence error.

Mitigation

The Atop operator provides a way to obtain the other interpretation: ⊢⍤/ is identical to / as a function, but forces the function-operator overloading to be resolved in favor of a function because there is a dyadic operator to its left.[2] When the Atop operator is not available, Beside or Commute can be used instead, but they require an extra set of parentheses. Alternatively, the function behaviour can be forced by encapsulating the hybrid primitive in a dfn.

      (2=2 1) / (2+2 1)  ⍝ Desired result
4
      2 (= / +) 2 1      ⍝ / is treated as an operator: unwanted here
0
      2 (= ⊢⍤/ +) 2 1    ⍝ Resolved with Atop
4
      2 (= (/∘⊢) +) 2 1  ⍝ Resolved with Compose
4
      2 (= (/⍨⍨) +) 2 1  ⍝ Resolved with Commute
4
      2 (= {⍺/⍵} +) 2 1  ⍝ Resolved with dfn
4
Works in: Dyalog APL, with version 18.0 for Atop

References

  1. The term schizophrenia used to be associated with split personality by the general population but that usage went into decline when it became known as a separate disorder. The informal usage has lived on in APL circles when referring to the "split personality" exhibited in primitives affected by function-operator overloading.
  2. Lochbaum, Marshall. "Tacit Techniques with Dyalog version 18.0 Operators". Dyalog '19.

External links

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