Function-operator overloading: Difference between revisions

Jump to navigation Jump to search
m
Text replacement - "</source>" to "</syntaxhighlight>"
m (Text replacement - "<source" to "<syntaxhighlight")
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 <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.
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>/⌿\⍀</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 5: Line 5:
! Glyph                              !! Function                !! Operator
! Glyph                              !! Function                !! Operator
|-
|-
| <syntaxhighlight lang=apl inline>/</source> ||rowspan=2| [[Replicate]] ||rowspan=2| [[Reduce]]
| <syntaxhighlight lang=apl inline>/</syntaxhighlight> ||rowspan=2| [[Replicate]] ||rowspan=2| [[Reduce]]
|-
|-
| <syntaxhighlight lang=apl inline>⌿</source>
| <syntaxhighlight lang=apl inline>⌿</syntaxhighlight>
|-
|-
| <syntaxhighlight lang=apl inline>\</source> ||rowspan=2| [[Expand]]    ||rowspan=2| [[Scan]]
| <syntaxhighlight lang=apl inline>\</syntaxhighlight> ||rowspan=2| [[Expand]]    ||rowspan=2| [[Scan]]
|-
|-
| <syntaxhighlight lang=apl inline>⍀</source>
| <syntaxhighlight lang=apl inline>⍀</syntaxhighlight>
|-
|-
| <syntaxhighlight lang=apl inline>←</source> || [[Assignment]]          || [[Modified assignment]]
| <syntaxhighlight lang=apl inline>←</syntaxhighlight> || [[Assignment]]          || [[Modified assignment]]
|}
|}


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.
This form of overloading relies on the fact that an expression like <syntaxhighlight lang=apl inline>a / b</syntaxhighlight> can be disambiguated based on whether <syntaxhighlight lang=apl inline>a</syntaxhighlight> is a function or not: if so, <syntaxhighlight lang=apl inline>/</syntaxhighlight> 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>= / +</syntaxhighlight> could be interpreted either as the two-train <syntaxhighlight lang=apl inline>(=/) +</syntaxhighlight>, [[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 <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.
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>-⍨/</syntaxhighlight> is treated as a [[reduction]] with operand <syntaxhighlight lang=apl inline>-⍨</syntaxhighlight>. 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: <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]].
The [[Atop (operator)|Atop]] operator provides a way to obtain the other interpretation: <syntaxhighlight lang=apl inline>⊢⍤/</syntaxhighlight> is identical to <syntaxhighlight lang=apl inline>/</syntaxhighlight> 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>
<syntaxhighlight lang=apl>
       (2=2 1) / (2+2 1)  ⍝ Desired result
       (2=2 1) / (2+2 1)  ⍝ Desired result
Line 34: Line 34:
       2 (= {⍺/⍵} +) 2 1  ⍝ Resolved with dfn
       2 (= {⍺/⍵} +) 2 1  ⍝ Resolved with dfn
4
4
</source>{{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]]}}


== References ==
== References ==

Navigation menu