Anonymous Functions/Operators/Hyperators: Difference between revisions

From NARS2000
Jump to navigationJump to search
No edit summary
No edit summary
Line 1: Line 1:
Anonymous functions and operators are a one-line grouping of one or more statements all enclosed in braces such as <apll>{(+⌿⍵)÷≢⍵}</apll>.  This syntax is useful for one-line functions and operators to complement the existing definition types of user-defined:  <apll>∇ Z←avg R</apll>, trains:  <apll>(+⌿ ÷ ≢)</apll>, and derived:  <apll>,∘⍋∘⍋∘,</apll>.
Anonymous functions and operators are a one-line grouping of one or more statements all enclosed in braces such as <apll>{(+⌿⍵)÷≢⍵}</apll>.  This syntax is useful for one-line functions and operators to complement the existing definition types of user-defined:  <apll>∇ Z←avg R</apll>, trains:  <apll>(+⌿ ÷ ≢)</apll>, and derived:  <apll>,∘⍋∘⍋∘,</apll>.
These objects may be named as in <apll>avg←{(+⌿⍵)÷≢⍵}</apll>, and they may be used in place of any APL function (primitive, operator operand, derived, train, user-defined) including within another anonymous function/operator.


<h3>Function Arguments</h3>
<h3>Function Arguments</h3>
Line 5: Line 7:
To define an anonymous function, use <apll>⍺</apll> as the (optional) left argument, <apll>∇</apll> as the name of the anonymous function (for recursion), and <apll>⍵</apll> as the name of the right argument.  For example,
To define an anonymous function, use <apll>⍺</apll> as the (optional) left argument, <apll>∇</apll> as the name of the anonymous function (for recursion), and <apll>⍵</apll> as the name of the right argument.  For example,


<apll>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3{√+/⍺ ⍵*2}4 ⍝ Pythagorean theorem<br />
<apll>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3{√+/⍺ ⍵*2}4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ⍝ Pythagorean theorem<br />
5<br />
5<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{s←(+/⍵)÷2 ⋄ √×/s-0,⍵}3 4 5 ⍝ Heron's formula for triangle's area<br />  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{s←(+/⍵)÷2 ⋄ √×/s-0,⍵}3 4 5 ⍝ Heron's formula for triangle area<br />  
6</apll>
6</apll>


Line 57: Line 59:
</table>
</table>


<h3>Default Value For Left Argument</h3>
<h3>Ambivalent Anonymous Functions/Operators</h3>


User-defined functions allow you to specify in their headers that the left argument is optional as in <apll>∇ Z←{L} foo R</apll>.  This behavior is also available to anonymous functions/operators by including a statement that assigns a value to <apll>⍺</apll>.  If <apll>⍺</apll> does not have a value when that statement is encountered, the statement is executed; if not, that entire statement is ignored including any side effects.  This behavior obviates using <apll>0=⎕NC '⍺'</apll> to test for a value in <apll>⍺</apll>.
User-defined functions allow you to specify in their headers that the left argument is optional as in <apll>∇ Z←{L} foo R</apll>.  This behavior is also available to anonymous functions/operators by including a statement that assigns a value to <apll>⍺</apll>.  If <apll>⍺</apll> does not have a value when that statement is encountered, the statement is executed; otherwise, that entire statement is ignored including any side effects.  This behavior obviates using <apll>0=⎕NC '⍺'</apll> to test for a value in <apll>⍺</apll>.


For example,
For example,
Line 83: Line 85:


<h3>Valences</h3>
<h3>Valences</h3>
An anonymous function/operator may be ambivalent (may be called with one or two arguments), dyadic-only (must be called with two arguments), or monadic-only (must be called with one argument only), depending upon which of the special symbols are present in its definition.


For anonymous functions (and operators), if <apll>⍺←</apll> appears as a sequence of tokens (outside of character constants), then the object is an ambivalent (derived) function; otherwise, if <apll>⍺</apll> appears as a token (outside of character constants), the function is a dyadic-only (derived) function; otherwise (<apll>⍺</apll> doesn't appear at all) it is a monadic-only (derived) function.
For anonymous functions (and operators), if <apll>⍺←</apll> appears as a sequence of tokens (outside of character constants), then the object is an ambivalent (derived) function; otherwise, if <apll>⍺</apll> appears as a token (outside of character constants), the function is a dyadic-only (derived) function; otherwise (<apll>⍺</apll> doesn't appear at all) it is a monadic-only (derived) function.
Line 106: Line 110:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3{⍺←2 ⋄ ⍺+⍵}2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3{⍺←2 ⋄ ⍺+⍵}2<br />
5</apll>
5</apll>
<h3>Shy Results</h3>


<h3>Guards</h3>
<h3>Guards</h3>
Guards are used to test for a condition and execute a statement or not depending upon the value of the conditional expression.  This behavior is identical to the control structure <apll>:if Cond ⋄ :then CondStmt ⋄ :return ⋄ :end</apll>.
Guards appear as an APL expression followed by a colon, followed by a single APL statement as in
<apll>{... ⋄ Cond:CondStmt ⋄ ....}</apll>
which executes <apll>CondStmt</apll> and terminates the anonymous function/operator iff and only if <apll>Cond</apll> is TRUE.
For example,
<apll>{... ⋄ 0∊⍴⍵:'empty right argument' ⋄ ....}</apll>
As many guard statements may appear in an anonymous function/operator as desired.  They are evaluated in turn until one of them is TRUE, at which time the statement following the colon is executed and the function terminates with the result of that conditional statement as the result of the anonymous function/operator.
If <apll>Cond</apll> does not evaluate to a Boolean-valued singleton, a <apll>DOMAIN ERROR</apll> is signalled.


<h3>Scoping</h3>
<h3>Scoping</h3>


<h3>Recursion</h3>
<h3>Recursion</h3>
Line 117: Line 146:
* Anonymous functions/operators may not assign anything to any of the special names (<apll>∇</apll>, <apll>⍵</apll>, <apll>⍺⍺</apll>, <apll>∇∇</apll>, <apll>⍵⍵</apll>) except for <apll>⍺</apll>.  Any attempt to do so signals a <apll>SYNTAX ERROR</apll>.
* Anonymous functions/operators may not assign anything to any of the special names (<apll>∇</apll>, <apll>⍵</apll>, <apll>⍺⍺</apll>, <apll>∇∇</apll>, <apll>⍵⍵</apll>) except for <apll>⍺</apll>.  Any attempt to do so signals a <apll>SYNTAX ERROR</apll>.
* For the moment, anonymous functions/operators may be written on one line only.
* For the moment, anonymous functions/operators may be written on one line only.
* As a consequence of the above one-line restriction, anonymous functions/operator may not contain comments.
* As a consequence of the above one-line restriction, anonymous functions/operators may not contain comments.
* None of the special names may be erased, via <apll>⎕EX</apll> or otherwise.
* None of the special names may be erased, via <apll>⎕EX</apll> or otherwise.
* Goto statements (including <apll>→</apll>, <apll>→0</apll>, and <apll>→⍬</apll>) are not allowed in anonymous functions/operators, and signal a <apll>SYNTAX ERROR</apll>.
* All variables to which an assignment is made are automatically localized to the anonymous function/operator, so (unlike user-defined functions) a direct assignment inside an anonymous function/operator cannot affect the value of a variable defined higher up in the execution chain unless it is made via a user-defined function or execute as in
* All variables to which an assignment is made are automatically localized to the anonymous function/operator, so (unlike user-defined functions) a direct assignment inside an anonymous function/operator cannot affect the value of a variable defined higher up in the execution chain unless it is made via a user-defined function or execute as in



Revision as of 19:17, 5 July 2013

Anonymous functions and operators are a one-line grouping of one or more statements all enclosed in braces such as {(+⌿⍵)÷≢⍵}. This syntax is useful for one-line functions and operators to complement the existing definition types of user-defined: ∇ Z←avg R, trains: (+⌿ ÷ ≢), and derived: ,∘⍋∘⍋∘,.

These objects may be named as in avg←{(+⌿⍵)÷≢⍵}, and they may be used in place of any APL function (primitive, operator operand, derived, train, user-defined) including within another anonymous function/operator.

Function Arguments

To define an anonymous function, use as the (optional) left argument, as the name of the anonymous function (for recursion), and as the name of the right argument. For example,

      3{√+/⍺ ⍵*2}4                ⍝ Pythagorean theorem
5
      {s←(+/⍵)÷2 ⋄ √×/s-0,⍵}3 4 5 ⍝ Heron's formula for triangle area
6

Operator Operands

To define an anonymous operator, use the above special names along with ⍺⍺ as the name of the left operand, ∇∇ as the name of the operator (for recursion), and ⍵⍵ as the name of the right operand. If neither ⍺⍺ nor ⍵⍵ appears as a token (outside of character constants) between the braces, then the object is a function, not an operator. For example,

f←{∘.⍺⍺⍨⍳⍵}

   =f 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

   ⌈f 4
1 2 3 4
2 2 3 4
3 3 3 4
4 4 4 4

   *f 4
1  1  1   1
2  4  8  16
3  9 27  81
4 16 64 256

   ≤f 4
1 1 1 1
0 1 1 1
0 0 1 1
0 0 0 1

Ambivalent Anonymous Functions/Operators

User-defined functions allow you to specify in their headers that the left argument is optional as in ∇ Z←{L} foo R. This behavior is also available to anonymous functions/operators by including a statement that assigns a value to . If does not have a value when that statement is encountered, the statement is executed; otherwise, that entire statement is ignored including any side effects. This behavior obviates using 0=⎕NC '⍺' to test for a value in .

For example,

      f←{⍺←2 ⋄ ⍺√⍵}
      f 16
4
      3 f 27
3
      f←{⎕←⍺←⍵ ⋄ (⍳⍺)∘.⍺⍺⍳⍵}
      ⌊f 4
4
1 1 1 1
1 2 2 2
1 2 3 3
1 2 3 4
      3⌊f 4
1 1 1 1
1 2 2 2
1 2 3 3

As a consequence of this rule, regardless of whether the anonymous function is called monadically or dyadically, any second or subsequent statements that assign a value to are always ignored.

Valences

An anonymous function/operator may be ambivalent (may be called with one or two arguments), dyadic-only (must be called with two arguments), or monadic-only (must be called with one argument only), depending upon which of the special symbols are present in its definition.

For anonymous functions (and operators), if ⍺← appears as a sequence of tokens (outside of character constants), then the object is an ambivalent (derived) function; otherwise, if appears as a token (outside of character constants), the function is a dyadic-only (derived) function; otherwise ( doesn't appear at all) it is a monadic-only (derived) function.

For anonymous operators, if ⍵⍵ appears as a token (outside of character constants), then the operator is dyadic, otherwise it is monadic.

For example,

      {⍵}2
2
      1{⍵}2
VALENCE ERROR
      1{⍵}2
       ^
      1{⍺+⍵}2
3
      {⍺+⍵}2
VALENCE ERROR
      {⍺+⍵}2
      ∧
      {⍺←2 ⋄ ⍺+⍵}2
4
      3{⍺←2 ⋄ ⍺+⍵}2
5

Shy Results



Guards

Guards are used to test for a condition and execute a statement or not depending upon the value of the conditional expression. This behavior is identical to the control structure :if Cond ⋄ :then CondStmt ⋄ :return ⋄ :end.

Guards appear as an APL expression followed by a colon, followed by a single APL statement as in

{... ⋄ Cond:CondStmt ⋄ ....}

which executes CondStmt and terminates the anonymous function/operator iff and only if Cond is TRUE.

For example,

{... ⋄ 0∊⍴⍵:'empty right argument' ⋄ ....}

As many guard statements may appear in an anonymous function/operator as desired. They are evaluated in turn until one of them is TRUE, at which time the statement following the colon is executed and the function terminates with the result of that conditional statement as the result of the anonymous function/operator.

If Cond does not evaluate to a Boolean-valued singleton, a DOMAIN ERROR is signalled.

Scoping



Recursion

Restrictions

  • Anonymous functions/operators may not assign anything to any of the special names (, , ⍺⍺, ∇∇, ⍵⍵) except for . Any attempt to do so signals a SYNTAX ERROR.
  • For the moment, anonymous functions/operators may be written on one line only.
  • As a consequence of the above one-line restriction, anonymous functions/operators may not contain comments.
  • None of the special names may be erased, via ⎕EX or otherwise.
  • Goto statements (including , →0, and →⍬) are not allowed in anonymous functions/operators, and signal a SYNTAX ERROR.
  • All variables to which an assignment is made are automatically localized to the anonymous function/operator, so (unlike user-defined functions) a direct assignment inside an anonymous function/operator cannot affect the value of a variable defined higher up in the execution chain unless it is made via a user-defined function or execute as in

      L←⍳9 ⋄ ⎕←{L←"abc" ⋄ ⍵}23
23
      L
1 2 3 4 5 6 7 8 9
      L←⍳9 ⋄ ⎕←{⍎'L←"abc"' ⋄ ⍵}23
23
      L
abc