Ambivalent function: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
m (Text replacement - "</source>" to "</syntaxhighlight>")
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
In [[APL syntax]], a [[function]] is '''ambivalent''', or '''variadic''', if it can be called with either [[monadic]] or [[dyadic]] [[valence]]. While every non-[[niladic]] function can be written with one or two arguments, some functions give a [[SYNTAX ERROR]] when called with two arguments (these functions are called monadic) or with only one (these are called dyadic). Ambivalent functions do not give a [[SYNTAX ERROR]] immediately in either case.
In [[APL syntax]], a [[function]] is '''ambivalent''' (sometimes '''variadic''' or '''nomadic'''), if it can be called with either [[monadic]] or [[dyadic]] [[valence]]. While every non-[[niladic]] function can be written with one or two arguments, some functions give a [[SYNTAX ERROR]] when called with two arguments (these functions are called monadic) or with only one (these are called dyadic). Ambivalent functions do not give a [[SYNTAX ERROR]] immediately in either case.


Being ambivalent, or not, is an inherent property of a function. This contrasts with the terms "monadic" and "dyadic" which may refer either to the function's inherent properties as described above or to the context in which it is used. When an ambivalent function is invoked it has either one argument or two: we would say for example it is an ambivalent function ''called monadically''.
Being ambivalent, or not, is an inherent property of a function. This contrasts with the terms "monadic" and "dyadic" which may refer either to the function's inherent properties as described above or to the context in which it is used. When an ambivalent function is invoked it has either one argument or two: we would say for example it is an ambivalent function ''called monadically''.
Line 5: Line 5:
=== Tradfns ===
=== Tradfns ===


In some APLs, for example [[APL*PLUS]], [[tradfn]]s that declare a left argument in the [[function header]] are always ambivalent, and the code needs to check whether a left argument was supplied by the left argument name's [[name class]]; <source lang=apl inline>0 ≠ ⎕NC 'leftArg'</source>. Other APLs, for example [[Dyalog APL]], will not allow calling such a function monadically, unless the header has curly braces around the left argument name to indicate that it is optional; <source lang=apl inline> result ← {leftArg} FnName rightArg</source>. Then too, they need to query the name class, or, unique for Dyalog APL, use a specialised ''Called Monadically'' [[I-beam]], <source lang=apl inline>900⌶⍬</source>.<ref>[[Dyalog APL]] Language Reference Guide > The I-Beam Operator > [http://help.dyalog.com/latest/#Language/Primitive%20Operators/Called%20Monadically.htm Called Monadically]</ref>
In some APLs, for example [[APL*PLUS]], [[tradfn]]s that declare a left argument in the [[function header]] are always ambivalent, and the code needs to check whether a left argument was supplied by the left argument name's [[name class]]; <syntaxhighlight lang=apl inline>0 ≠ ⎕NC 'leftArg'</syntaxhighlight>. Other APLs, for example [[Dyalog APL]], will not allow calling such a function monadically, unless the header has curly braces around the left argument name to indicate that it is optional; <syntaxhighlight lang=apl inline> result ← {leftArg} FnName rightArg</syntaxhighlight>. Then too, they need to query the name class, or, unique for Dyalog APL, use a specialised ''Called Monadically'' [[I-beam]], <syntaxhighlight lang=apl inline>900⌶⍬</syntaxhighlight>.<ref>[[Dyalog APL]] Language Reference Guide > The I-Beam Operator > [https://help.dyalog.com/latest/#Language/I%20Beam%20Functions/Called%20Monadically.htm Called Monadically]</ref>


=== Dfns ===
=== Dfns ===


[[Dfn]]s are always ambivalent, even if they reference <source lang=apl inline>⍺</source>. (This is in contrast with [[dop]]s which have a fixed [[operator valence]] determined by the presence of an unquoted <source lang=apl inline>⍵⍵</source> in their code.) Like tradfns, the dfn can check the name class (<source lang=apl inline>0 ≠ ⎕NC '⍺'</source>).
[[Dfn]]s are always ambivalent, even if they reference <syntaxhighlight lang=apl inline>⍺</syntaxhighlight>. (This is in contrast with [[dop]]s which have a fixed [[operator valence]] determined by the presence of an unquoted <syntaxhighlight lang=apl inline>⍵⍵</syntaxhighlight> in their code.) Like tradfns, the dfn can check the name class (<syntaxhighlight lang=apl inline>0 ≠ ⎕NC '⍺'</syntaxhighlight>).


However, most APLs that support dfns also allow a statement of the structure <source lang=apl inline>⍺ ← defaultValue</source> which skipped if the function was called dyadically.<ref>[[Dyalog APL]] Programming Reference Guide > Defined Functions & Operators > Direct Functions & Operators > [http://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Default%20Left%20Argument.htm Default Left Argument]</ref> This syntax also allows assigning a function, or even an operator, to <source lang=apl inline>⍺</source>, thus streamlining many ambivalent definitions. For example, we can create a Nth root function which defaults to being the square root when used monadically:
However, most APLs that support dfns also allow a statement of the structure <syntaxhighlight lang=apl inline>⍺ ← defaultValue</syntaxhighlight> which skipped if the function was called dyadically.<ref>[[Dyalog APL]] Programming Reference Guide > Defined Functions & Operators > Direct Functions & Operators > [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Default%20Left%20Argument.htm Default Left Argument]</ref> This syntax also allows assigning a function, or even an operator, to <syntaxhighlight lang=apl inline>⍺</syntaxhighlight>, thus streamlining many ambivalent definitions. For example, we can create a Nth root function which defaults to being the square root when used monadically:


[https://tio.run/##SyzI0U2pTMzJT///Pyg/v@RR24RqLgUgeNS7C8g2grK3KmgpHN4OFOOqhahTMDQw4DJWADONzAE Try it online!]
[https://tio.run/##SyzI0U2pTMzJT///Pyg/v@RR24RqLgUgeNS7C8g2grK3KmgpHN4OFOOqhahTMDQw4DJWADONzAE Try it online!]
<source lang=apl>
<syntaxhighlight lang=apl>
Root←{
Root←{
     ⍺←2
     ⍺←2
     ⍵ * ÷⍺
     ⍵ * ÷⍺
}
}
</source>
</syntaxhighlight>


We can also define the [[Over]] operator with <source lang=apl inline>⍺</source> defaulting to be an operator that skips its operand:
We can also define the [[Over]] operator with <syntaxhighlight lang=apl inline>⍺</syntaxhighlight> defaulting to be an operator that skips its operand:


[https://tio.run/##SyzI0U2pTMzJT///378stehR24RqLgUgeNS7C8R@1LtV4VF3C5jbu6sWLKUBFASL9@7ShEogiW3V5Kr9/19XAWSagsbh6Y96V2gqGHOZKqAJmQAA Try it online!]
[https://tio.run/##SyzI0U2pTMzJT///378stehR24RqLgUgeNS7C8R@1LtV4VF3C5jbu6sWLKUBFASL9@7ShEogiW3V5Kr9/19XAWSagsbh6Y96V2gqGHOZKqAJmQAA Try it online!]
<source lang=apl>
<syntaxhighlight lang=apl>
Over←{
Over←{
     ⍺←{⍵ ⋄ ⍺⍺}
     ⍺←{⍵ ⋄ ⍺⍺}
     (⍵⍵ ⍺) ⍺⍺ (⍵⍵ ⍵)
     (⍵⍵ ⍺) ⍺⍺ (⍵⍵ ⍵)
}
}
</source>
</syntaxhighlight>


== External links ==
== External links ==
=== Tutorials ===
* John 'Jake' Jacob. [https://optima-systems.co.uk/pervasion-of-ambivalence-in-apl-functions/ Pervasion of Ambivalence in APL Functions]. Optima Systems. July 9, 2020.
* John 'Jake' Jacob. [https://optima-systems.co.uk/pervasion-of-ambivalence-in-apl-functions/ Pervasion of Ambivalence in APL Functions]. Optima Systems. July 9, 2020.
=== Documentation ===
* [http://microapl.com/apl_help/ch_020_010_070.htm APLX]
* [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/TradFns/Model%20Syntax.htm Dyalog]
== References ==
== References ==
<references/>
<references/>


{{APL syntax}}[[Category:Kinds of functions]]
{{APL syntax}}[[Category:Kinds of functions]]

Latest revision as of 22:17, 10 September 2022

In APL syntax, a function is ambivalent (sometimes variadic or nomadic), if it can be called with either monadic or dyadic valence. While every non-niladic function can be written with one or two arguments, some functions give a SYNTAX ERROR when called with two arguments (these functions are called monadic) or with only one (these are called dyadic). Ambivalent functions do not give a SYNTAX ERROR immediately in either case.

Being ambivalent, or not, is an inherent property of a function. This contrasts with the terms "monadic" and "dyadic" which may refer either to the function's inherent properties as described above or to the context in which it is used. When an ambivalent function is invoked it has either one argument or two: we would say for example it is an ambivalent function called monadically.

Tradfns

In some APLs, for example APL*PLUS, tradfns that declare a left argument in the function header are always ambivalent, and the code needs to check whether a left argument was supplied by the left argument name's name class; 0 ≠ ⎕NC 'leftArg'. Other APLs, for example Dyalog APL, will not allow calling such a function monadically, unless the header has curly braces around the left argument name to indicate that it is optional; result ← {leftArg} FnName rightArg. Then too, they need to query the name class, or, unique for Dyalog APL, use a specialised Called Monadically I-beam, 900⌶⍬.[1]

Dfns

Dfns are always ambivalent, even if they reference . (This is in contrast with dops which have a fixed operator valence determined by the presence of an unquoted ⍵⍵ in their code.) Like tradfns, the dfn can check the name class (0 ≠ ⎕NC '⍺').

However, most APLs that support dfns also allow a statement of the structure ⍺ ← defaultValue which skipped if the function was called dyadically.[2] This syntax also allows assigning a function, or even an operator, to , thus streamlining many ambivalent definitions. For example, we can create a Nth root function which defaults to being the square root when used monadically:

Try it online!

Root←{
    ⍺←2
    ⍵ * ÷⍺
}

We can also define the Over operator with defaulting to be an operator that skips its operand:

Try it online!

Over←{
    ⍺←{⍵ ⋄ ⍺⍺}
    (⍵⍵ ⍺) ⍺⍺ (⍵⍵ ⍵)
}

External links

Tutorials

Documentation

References

  1. Dyalog APL Language Reference Guide > The I-Beam Operator > Called Monadically
  2. Dyalog APL Programming Reference Guide > Defined Functions & Operators > Direct Functions & Operators > Default Left Argument


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