4,587
edits
No edit summary |
m (Text replacement - "<source" to "<syntaxhighlight") |
||
Line 1: | Line 1: | ||
In [[APL syntax]], '''function-operator overloading''' (sometimes '''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 has lived on in APL circles when referring to the "split personality" exhibited 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+]], and [[GNU APL]]. Most commonly it refers to one of the slash glyphs < | In [[APL syntax]], '''function-operator overloading''' (sometimes '''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 has lived on in APL circles when referring to the "split personality" exhibited 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+]], and [[GNU APL]]. Most commonly it refers to one of the slash glyphs <syntaxhighlight lang=apl inline>/⌿\⍀</source> (for example, <syntaxhighlight lang=apl inline>/</source> 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←/</source> and even <syntaxhighlight lang=apl inline>r←/[3]</source> cause <syntaxhighlight lang=apl inline>r</source> 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 5: | Line 5: | ||
! Glyph !! Function !! Operator | ! Glyph !! Function !! Operator | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>/</source> ||rowspan=2| [[Replicate]] ||rowspan=2| [[Reduce]] | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>⌿</source> | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>\</source> ||rowspan=2| [[Expand]] ||rowspan=2| [[Scan]] | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>⍀</source> | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>←</source> || [[Assignment]] || [[Modified assignment]] | ||
|} | |} | ||
This form of overloading relies on the fact that an expression like < | This form of overloading relies on the fact that an expression like <syntaxhighlight lang=apl inline>a / b</source> can be disambiguated based on whether <syntaxhighlight lang=apl inline>a</source> is a function or not: if so, <syntaxhighlight lang=apl inline>/</source> should be an operator. This assumption is violated when [[function train]]s are part of the syntax, because a train such as <syntaxhighlight lang=apl inline>= / +</source> could be interpreted either as the two-train <syntaxhighlight lang=apl inline>(=/) +</source>, [[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 function]]s: for instance, the snippet < | 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 <syntaxhighlight lang=apl inline>-⍨/</source> is treated as a [[reduction]] with operand <syntaxhighlight 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)|Atop]] operator provides a way to obtain the other interpretation: < | The [[Atop (operator)|Atop]] operator provides a way to obtain the other interpretation: <syntaxhighlight lang=apl inline>⊢⍤/</source> is identical to <syntaxhighlight 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]]. | ||
< | <syntaxhighlight lang=apl> | ||
(2=2 1) / (2+2 1) ⍝ Desired result | (2=2 1) / (2+2 1) ⍝ Desired result | ||
4 | 4 |