Function-operator overloading: Difference between revisions
Faun Locke (talk | contribs) mNo edit summary |
(apl+) |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
In [[APL syntax]], '''function-operator overloading''' (archaic epithet: '''schizophrenia'''<ref>The term ''schizophrenia'' used to be associated with [[wikipedia:split personality|''split personality'']] by the general population but that usage went into decline when it became known as a separate disorder. The term was used for duality of programming language constructs as early 1978, for example in [https://dl.acm.org/doi/10.1145/800025.1198354 the transcript] of [[Alan Perlis]]'s [[HOPL]] I entry on [[wikipedia:ALGOL 58|ALGOL 58]]. The informal usage | In [[APL syntax]], '''function-operator overloading''' (archaic epithet: '''schizophrenia'''<ref>The term ''schizophrenia'' used to be associated with [[wikipedia:split personality|''split personality'']] by the general population but that usage went into decline when it became known as a separate disorder. The term was used for duality of programming language constructs as early as 1978, for example in [https://dl.acm.org/doi/10.1145/800025.1198354 the transcript] of [[Alan Perlis]]'s [[HOPL]] I entry on [[wikipedia:ALGOL 58|ALGOL 58]]. The informal usage lives on in APL circles when referring to the exhibited behaviour in primitives affected by function-operator overloading.</ref>) 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+]], [[GNU APL]], and previously [[APL+Win]]. Most commonly it refers to one of the slash glyphs <syntaxhighlight lang=apl inline>/⌿\⍀</syntaxhighlight> (for example, <syntaxhighlight lang=apl inline>/</syntaxhighlight> is both [[Replicate]] and [[Reduce]]), and dialects [[APL2]] and [[APLX]], which [[Replicate#Operator or function?|define Replicate and Expand to be operators]], don't use it. [[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. Overloading may apply only to the glyphs themselves, or to their values and derivations as well: for example, in [[Dyalog APL]] the assignments <syntaxhighlight lang=apl inline>r←/</syntaxhighlight> and even <syntaxhighlight lang=apl inline>r←/[3]</syntaxhighlight> cause <syntaxhighlight lang=apl inline>r</syntaxhighlight> to exhibit overloading. | ||
== Occurrence == | == Occurrence == | ||
The following glyphs may be subject to function-operator overloading: | The following glyphs may be subject to function-operator overloading: | ||
Line 35: | Line 35: | ||
4 | 4 | ||
</syntaxhighlight>{{Works in|[[Dyalog APL]], with version [[Dyalog APL 18.0|18.0]] for [[Atop]]}} | </syntaxhighlight>{{Works in|[[Dyalog APL]], with version [[Dyalog APL 18.0|18.0]] for [[Atop]]}} | ||
None of the above techniques are possible in [[APL+Win]], so [[system function]]s <syntaxhighlight lang=apl inline>⎕REPL</syntaxhighlight> and <syntaxhighlight lang=apl inline>⎕COMPRESS</syntaxhighlight> are provided instead. APL+Win previously allowed parenthesising a hybrid (for example <syntaxhighlight lang=apl inline>(/)</syntaxhighlight>) to force function interpretation, although this is disabled when the [[evolution level]] is set to maximise [[APL2]]-compatibility. | |||
== References == | == References == |
Latest revision as of 12:53, 13 February 2024
In APL syntax, function-operator overloading (archaic epithet: 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+, GNU APL, and previously APL+Win. Most commonly it refers to one of the slash glyphs /⌿\⍀
(for example, /
is both Replicate and Reduce), and dialects APL2 and APLX, which define Replicate and Expand to be operators, don't use it. 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. Overloading 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]
cause r
to exhibit overloading.
Occurrence
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
None of the above techniques are possible in APL+Win, so system functions ⎕REPL
and ⎕COMPRESS
are provided instead. APL+Win previously allowed parenthesising a hybrid (for example (/)
) to force function interpretation, although this is disabled when the evolution level is set to maximise APL2-compatibility.
References
- ↑ 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 term was used for duality of programming language constructs as early as 1978, for example in the transcript of Alan Perlis's HOPL I entry on ALGOL 58. The informal usage lives on in APL circles when referring to the exhibited behaviour in primitives affected by function-operator overloading.
- ↑ Lochbaum, Marshall. "Tacit Techniques with Dyalog version 18.0 Operators". Dyalog '19.
External links
- GNU APL: Design Decisions — APL symbols that can be functions or operators
- Dyalog APL: Function Trains — Binding Strengths