Hyperators: Difference between revisions
No edit summary |
|||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
==Object Orders== | ==Object Orders== | ||
The sequence of objects: Arrays, Functions, and Operators appear in ascending order with the property that each later object consumes one or two of the earlier objects and produces an object in the sequence one order less. For example, a Function takes | The sequence of objects: Arrays, Functions, and Operators appear in ascending order with the property that each later object consumes one or two of the earlier objects and produces an object in the sequence one order less. For example, a Function takes Array(s) and produces an Array; an Operator takes Array(s) and/or Function(s) and produces a (derived) Function. | ||
Hyperators extend this sequence by one. | Hyperators extend this sequence by one: | ||
* a '''Hyperator''' has one or two '''Hyperands''' (any of Arrays, Functions, and/or Operators) and yields ... | |||
* an '''Operator''' which has one or two '''Operands''' (any of Arrays and/or Functions) and yields ... | |||
* a '''Function''' which has zero, one, or two '''Arguments''' (Arrays) and yields... | |||
* an '''Array'''. | |||
That is, in the object hierarchy: | |||
{| border="1" cellpadding="5" cellspacing="0" | {| border="1" cellpadding="5" cellspacing="0" | ||
Line 17: | Line 24: | ||
|align="center" valign="top"|Function | |align="center" valign="top"|Function | ||
|align="center" valign="top"|0, 1, 2<br/>Arguments | |align="center" valign="top"|0, 1, 2<br/>Arguments | ||
|valign="top"|<apll>∇Z← | |valign="top"|<apll>∇Z← fn0<br/>∇Z← fn1 R<br/>∇Z←L fn2 R</apll> | ||
|- | |- | ||
|align="center" valign="top"|2 | |align="center" valign="top"|2 | ||
Line 34: | Line 41: | ||
==Anonymous Functions== | ==Anonymous Functions== | ||
Following the lead of John Scholes<ref name="Scholes">San Quirico Moot, http://archive.vector.org.uk/art10011760</ref>, | Following the lead of John Scholes<ref name="Scholes">San Quirico Moot, http://archive.vector.org.uk/art10011760</ref>, Anonymous Functions are [[Anonymous_Functions/Operators/Hyperators|extended to Hyperators]] by defining three new special symbols: | ||
* <apll>⍺⍺⍺</apll> | * <apll>⍺⍺⍺</apll> represents the Left Hyperand | ||
* <apll>⍵⍵⍵</apll> | * <apll>⍵⍵⍵</apll> represents the Right Hyperand | ||
* <apll>∇∇∇</apll> | * <apll>∇∇∇</apll> represents the Hyperator itself | ||
==Scoping== | ==Scoping== | ||
Line 58: | Line 65: | ||
but this violates the APL2 rule on Redundant Parentheses ("Parentheses surrounding a primitive or constructed name, a character string (enclosed in quotation marks), or an already parenthesized expression are always redundant."<ref name="RedundantParens">[https://www.ibm.com/downloads/cas/ZOKMYKOY APL2 Reference Manual, Second Edition, 1994, SH21-1061-01, p. 37]</ref>), so that example is equivalent to the previous one. | but this violates the APL2 rule on Redundant Parentheses ("Parentheses surrounding a primitive or constructed name, a character string (enclosed in quotation marks), or an already parenthesized expression are always redundant."<ref name="RedundantParens">[https://www.ibm.com/downloads/cas/ZOKMYKOY APL2 Reference Manual, Second Edition, 1994, SH21-1061-01, p. 37]</ref>), so that example is equivalent to the previous one. | ||
Only if Hyperators have '''short left scope''' can we pass function as a left operand and an operator as the left hyperand to a Hyperator as in the example <apll>+/mhmo</apll>. | Only if Hyperators have '''short left scope''' can we pass a function as a left operand and an operator as the left hyperand to a Hyperator as in the example <apll>+/mhmo</apll>. | ||
FWIW, there is another example with this scoping rule that also illustrates a change in Binding Strength in NARS2000: '''Vector Notation''' (a.k.a. '''Numeric Strands'''). | FWIW, there is another example with this scoping rule that also illustrates a change in [[Binding Strength]] in NARS2000: '''Vector Notation''' (a.k.a. '''Numeric Strands'''). | ||
In the same example as above with a | In the same example as above with a Monadic Hyperand Monadic Operand hyperator, how can we pass (say) a <apll>12</apll> as a left '''operand''' and a <apll>34</apll> as a left '''hyperand'''? This can be accomplished with | ||
<apll> 12 34 mhmo</apll> | <apll> 12 34 mhmo</apll> | ||
because the rules for | because the rules for Binding Strength used by NARS2000 dictate that Vector Notation has a lower Binding Strength than both a right operand to its operator and either hyperand to its hyperator. In these three cases, the scope is '''short''' which is interpreted by NARS2000 as extracting the number nearest to the operator/hyperator from the numeric strand and using it for the operand/hyperand. | ||
This yields several interesting cases: | This yields several interesting cases: | ||
* A dyadic operator written as <apll>… dop 1 2 3</apll> is interpreted as having a right operand ('''short''' right scope) of <apll>1</apll> and a right argument of <apll>2 3</apll>. | * A dyadic operator written as <apll>… dop 1 2 3 4</apll> is interpreted as having a right '''operand''' ('''short''' right scope) of <apll>1</apll> and a right '''argument''' of <apll>2 3 4</apll>. | ||
* A hyperator written as <apll>1 2 3 mhmo</apll> is interpreted as having a left | * A hyperator written as either <apll>1 2 3 4 mhmo</apll> or <apll>1 2 3 4 mhdo …</apll> is interpreted as having a left '''hyperand''' ('''short''' left scope) of <apll>4</apll> and a left '''operand''' ('''long''' left scope) of <apll>1 2 3</apll>. | ||
* A dyadic hyperator written as <apll>… dhmo 1 2 3</apll> is interpreted as having a right hyperand ('''short''' right scope) of <apll>1</apll> and a right argument of <apll>2 3</apll>. | * A dyadic hyperator written as <apll>… dhmo 1 2 3 4</apll> is interpreted as having a right '''hyperand''' ('''short''' right scope) of <apll>1</apll> and a right '''argument''' of <apll>2 3 4</apll>. | ||
* A dyadic hyperator written as <apll>… dhdo 1 2 3</apll> is interpreted as having a right hyperand ('''short''' right scope) of <apll>1</apll>, a right operand ('''short''' right scope) of <apll>2</apll>, and a right argument of <apll>3</apll>. | * A dyadic hyperator written as <apll>… dhdo 1 2 3 4</apll> is interpreted as having a right '''hyperand''' ('''short''' right scope) of <apll>1</apll>, a right '''operand''' ('''short''' right scope) of <apll>2</apll>, and a right '''argument''' of <apll>3 4</apll>. | ||
To reduce confusion, use parentheses such as <apll>(LO (LH dhdo 1) 2) 3</apll>. | |||
Abbreviations: | |||
* <apll>dop</apll> Dyadic Operator | |||
* <apll>mhmo</apll> Monadic Hyperand Monadic Operand Hyperator | |||
* <apll>mhdo</apll> Monadic Hyperand Dyadic Operand ... | |||
* <apll>dhmo</apll> Dyadic Hyperand Monadic Operand ... | |||
* <apll>dhdo</apll> Dyadic Hyperand Dyadic Operand ... | |||
==Examples== | |||
The Power Operator can be used to apply a '''function''' iteratively to an argument, such as: | |||
<apll><pre> | <apll><pre> | ||
+ | +\⍣3 ⍳4 | ||
1 5 15 35 | |||
+ | +\+\+\⍳4 | ||
1 5 15 35 | |||
</pre></apll> | </pre></apll> | ||
Applying an '''operator''' iteratively to an argument, is a task for Hyperators: | |||
<apll><pre> | <apll><pre> | ||
( | PowEach←{⍺←⊢ ⋄ ⍎'⍺ ⍺⍺ ',(∊⍵⍵⍵⍴⊂'⍺⍺⍺ '),'⍵'} ⍝ It takes a Hyperator to iterate an operator (⍺⍺⍺) | ||
,¨PowEach 3 4 ⍝ ←→ ,¨¨¨4 Here the hyperand (⍺⍺⍺←¨) is iterated and then | |||
⍝ the operand (⍺⍺←,) is bound to the iterated hyperand | |||
┌───────┐ | |||
│┌─────┐│ | |||
││┌───┐││ | |||
│││┌1┐│││ | |||
││││4││││ | |||
│││└~┘2││ | |||
││└∊──┘3│ | |||
│└∊────┘4 | |||
└∊──────┘ | |||
,¨⍣3 4 ⍝ ←→ ,¨,¨,¨4 Here the function (,¨) is iterated | |||
┌────┐ | |||
│┌1─┐│ | |||
││ 4││ | |||
│└~─┘2 | |||
└∊───┘ | |||
</pre></apll> | </pre></apll> | ||
==References== | ==References== |
Latest revision as of 17:12, 12 February 2024
Object Orders
The sequence of objects: Arrays, Functions, and Operators appear in ascending order with the property that each later object consumes one or two of the earlier objects and produces an object in the sequence one order less. For example, a Function takes Array(s) and produces an Array; an Operator takes Array(s) and/or Function(s) and produces a (derived) Function.
Hyperators extend this sequence by one:
- a Hyperator has one or two Hyperands (any of Arrays, Functions, and/or Operators) and yields ...
- an Operator which has one or two Operands (any of Arrays and/or Functions) and yields ...
- a Function which has zero, one, or two Arguments (Arrays) and yields...
- an Array.
That is, in the object hierarchy:
Order | Object | Options | User-Defined Function Example |
---|---|---|---|
0 | Array | ||
1 | Function | 0, 1, 2 Arguments |
∇Z← fn0 ∇Z← fn1 R ∇Z←L fn2 R |
2 | Operator | 0, 1, 2 Arguments and 1 or 2 Operands |
∇Z← (LO op01) ∇Z← (LO op11) R ∇Z←L (LO op21) R ∇Z← (LO op02 RO) ∇Z← (LO op12 RO) R ∇Z←L (LO op22 RO) R |
3 | Hyperator | 0, 1, 2 Arguments and 1 or 2 Operands and 1 or 2 Hyperands |
∇Z← (LO (LH hy011)) ∇Z← (LO (LH hy111)) R ∇Z←L (LO (LH hy211)) R ∇Z← (LO (LH hy021) RO) ∇Z← (LO (LH hy121) RO) R ∇Z←L (LO (LH hy221) RO) R ∇Z← (LO (LH hy012 RH)) ∇Z← (LO (LH hy112 RH)) R ∇Z←L (LO (LH hy212 RH)) R ∇Z← (LO (LH hy022 RH) RO) ∇Z← (LO (LH hy122 RH) RO) R ∇Z←L (LO (LH hy222 RH) RO) R |
Each Function, Operator, and Hyperator may have any of its lower order objects as its Arguments, Operands, or Hyperands, respectively. Missing from the above table due to lack of space is the option for both Operators and Hyperators of using a Jot (∘) for one or both Operands or Hyperands to indicate a missing element. Also missing is the usual function header enhancements such as Axis Operator, Optional Left Argument, Shy Result, Lists of Names in the Arguments, etc.
Anonymous Functions
Following the lead of John Scholes[1], Anonymous Functions are extended to Hyperators by defining three new special symbols:
- ⍺⍺⍺ represents the Left Hyperand
- ⍵⍵⍵ represents the Right Hyperand
- ∇∇∇ represents the Hyperator itself
Scoping
Similar to Operators, Hyperators have short right scope and for the same reason: so as to reduce the number of surrounding parentheses required to limit its right scope. However, unlike Operators, Hyperators must have short left scope, too. Here's why:
Because Hyperators may take an operator as a hyperand, and in particular as a left hyperand, we need a way to pass both a function left operand and an operator left hyperand. In particular, how can we pass + as a left operand and / as a left hyperand to a Hyperator?
One's first choice might be to code
+/mhmo
where mhmo is a Monadic Hyperand Monadic Operand hyperator. However, if Hyperators have long left scope, then the left hyperand in the above example is +/ and there is no left operand specified.
Another possibility is to use
+(/)mhmo
but this violates the APL2 rule on Redundant Parentheses ("Parentheses surrounding a primitive or constructed name, a character string (enclosed in quotation marks), or an already parenthesized expression are always redundant."[2]), so that example is equivalent to the previous one.
Only if Hyperators have short left scope can we pass a function as a left operand and an operator as the left hyperand to a Hyperator as in the example +/mhmo.
FWIW, there is another example with this scoping rule that also illustrates a change in Binding Strength in NARS2000: Vector Notation (a.k.a. Numeric Strands).
In the same example as above with a Monadic Hyperand Monadic Operand hyperator, how can we pass (say) a 12 as a left operand and a 34 as a left hyperand? This can be accomplished with
12 34 mhmo
because the rules for Binding Strength used by NARS2000 dictate that Vector Notation has a lower Binding Strength than both a right operand to its operator and either hyperand to its hyperator. In these three cases, the scope is short which is interpreted by NARS2000 as extracting the number nearest to the operator/hyperator from the numeric strand and using it for the operand/hyperand.
This yields several interesting cases:
- A dyadic operator written as … dop 1 2 3 4 is interpreted as having a right operand (short right scope) of 1 and a right argument of 2 3 4.
- A hyperator written as either 1 2 3 4 mhmo or 1 2 3 4 mhdo … is interpreted as having a left hyperand (short left scope) of 4 and a left operand (long left scope) of 1 2 3.
- A dyadic hyperator written as … dhmo 1 2 3 4 is interpreted as having a right hyperand (short right scope) of 1 and a right argument of 2 3 4.
- A dyadic hyperator written as … dhdo 1 2 3 4 is interpreted as having a right hyperand (short right scope) of 1, a right operand (short right scope) of 2, and a right argument of 3 4.
To reduce confusion, use parentheses such as (LO (LH dhdo 1) 2) 3.
Abbreviations:
- dop Dyadic Operator
- mhmo Monadic Hyperand Monadic Operand Hyperator
- mhdo Monadic Hyperand Dyadic Operand ...
- dhmo Dyadic Hyperand Monadic Operand ...
- dhdo Dyadic Hyperand Dyadic Operand ...
Examples
The Power Operator can be used to apply a function iteratively to an argument, such as:
+\⍣3 ⍳4 1 5 15 35 +\+\+\⍳4 1 5 15 35
Applying an operator iteratively to an argument, is a task for Hyperators:
PowEach←{⍺←⊢ ⋄ ⍎'⍺ ⍺⍺ ',(∊⍵⍵⍵⍴⊂'⍺⍺⍺ '),'⍵'} ⍝ It takes a Hyperator to iterate an operator (⍺⍺⍺) ,¨PowEach 3 4 ⍝ ←→ ,¨¨¨4 Here the hyperand (⍺⍺⍺←¨) is iterated and then ⍝ the operand (⍺⍺←,) is bound to the iterated hyperand ┌───────┐ │┌─────┐│ ││┌───┐││ │││┌1┐│││ ││││4││││ │││└~┘2││ ││└∊──┘3│ │└∊────┘4 └∊──────┘ ,¨⍣3 4 ⍝ ←→ ,¨,¨,¨4 Here the function (,¨) is iterated ┌────┐ │┌1─┐│ ││ 4││ │└~─┘2 └∊───┘
References
- Hyperators, Dyalog APL Dfns, https://dfns.dyalog.com/n_hyperators.htm
- Hyperators, Dyalog APL Example, https://dfns.dyalog.com/n_cf.htm
- Hyperators, Dyalog APL Example, https://dfns.dyalog.com/n_cond.htm