4,501
edits
(apl+) |
|||
(15 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
In [[APL syntax]], '''function-operator overloading''' ( | 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 == | |||
The following glyphs may be subject to function-operator overloading: | The following glyphs may be subject to function-operator overloading: | ||
{|class=wikitable | {|class=wikitable | ||
! Glyph !! Function !! Operator | ! Glyph !! Function !! Operator | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>/</syntaxhighlight> ||rowspan=2| [[Replicate]] ||rowspan=2| [[Reduce]] | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>⌿</syntaxhighlight> | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>\</syntaxhighlight> ||rowspan=2| [[Expand]] ||rowspan=2| [[Scan]] | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>⍀</syntaxhighlight> | ||
|- | |- | ||
| < | | <syntaxhighlight lang=apl inline>←</syntaxhighlight> || [[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</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 < | 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]] 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>⊢⍤/</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> | ||
(2=2 1) / (2+2 1) ⍝ Desired result | (2=2 1) / (2+2 1) ⍝ Desired result | ||
4 | 4 | ||
Line 34: | Line 34: | ||
2 (= {⍺/⍵} +) 2 1 ⍝ Resolved with dfn | 2 (= {⍺/⍵} +) 2 1 ⍝ Resolved with dfn | ||
4 | 4 | ||
</ | </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 == | ||
<references /> | <references /> | ||
== External links == | == External links == | ||
* GNU APL: Design Decisions — [https://www.gnu.org/software/apl/apl.html#APL-symbols-that-can-be-functions-or-operators APL symbols that can be functions or operators] | * GNU APL: Design Decisions — [https://www.gnu.org/software/apl/apl.html#APL-symbols-that-can-be-functions-or-operators APL symbols that can be functions or operators] | ||
* Dyalog APL: Function Trains — [ | * Dyalog APL: Function Trains — [https://help.dyalog.com/latest/#Language/Introduction/Trains.htm#bindstr Binding Strengths] | ||
{{APL syntax}} | {{APL syntax}}[[Category:Syntactic elements]][[Category:Function characteristics]] |