💾 Archived View for blitter.com › apl-books › RationalizedAPL › www.jsoftware.com › papers › Rationa… captured on 2024-08-25 at 04:12:33.

View Raw

More Information

⬅️ Previous capture (2022-07-17)

-=-=-=-=-=-=-

<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Rationalized APL</title>
<link href="adoc.css" rel=stylesheet>
</head>

<body>

<br>

<table width=520 align=center><tr><td>

<p align=center><font size=+2>Rationalized APL</font><br><br>
<b>Kenneth E. Iverson<br>
I.P. Sharp Associates<br>Toronto</b></p>

<p align=center>I.P. Sharp Research Report #1<br>
Rev. 1 - 4 April 1983</p>



<br><hr>

<a name="intro"></a>
<p>Certain aspects of <b>conventional</b> APL (as defined in the IBM 
publication <b>APL Language</b> 
<acronym title="APL Language (IBM Corporation, GC26-3847)">[1]</acronym>)
violate some of the fundamental characteristics of the language, 
and the definitions of some other aspects are too limited 
to provide clear guidance for systematic extensions. 
The present paper proposes convenient replacements 
for the anomalous facilities, and a systematic scheme 
for extensions, a scheme that does not invalidate 
the facilities defined in 
<acronym title="APL Language (IBM Corporation, GC26-3847)">Reference 1</acronym>, 
nor, indeed, those incorporated in many other systems, 
specifically SHARP APL.</p>

<p>The main aspects to be treated are:</p>

<table>
<tr><td>A)</td><td>&nbsp;</td><td>Bracket and semicolon indexing, and indexed assignment.</td></tr>
<tr><td>B)</td><td>&nbsp;</td><td>Name assignment.</td></tr>
<tr><td>C)</td><td>&nbsp;</td><td>Function valence.</td></tr>
<tr><td>D)</td><td>&nbsp;</td><td>Function definition.</td></tr>
<tr><td>E)</td><td>&nbsp;</td><td>Syntax and order of execution.</td></tr>
<tr><td>F)</td><td>&nbsp;</td><td>Extensions to higher rank arrays.</td></tr>
<tr><td>G)</td><td>&nbsp;</td><td>Operators on non-scalar functions.</td></tr>
<tr><td>H)</td><td>&nbsp;</td><td>Miscellaneous.</td></tr>
</table>

<p>Items in the foregoing list can be used to illustrate the main point. 
For example, the indexing<tt> a[i;j] </tt>cannot 
(without the use of<tt> ⍎</tt>&nbsp;)<tt> </tt>be applied 
to an array<tt> a </tt>of arbitrary rank, 
the list expression<tt> (i;j) </tt>
must be treated as a monolithic whole (i.e., not as a sequence of normal 
APL functions), and a name cannot be assigned to the resulting list. 
The reduction and inner and outer product operators are limited to scalar 
functions and could be extended in a variety of ways. 
For example, the reduction<tt> f⌿a </tt>could (as it is in 
<acronym title="APL*PLUS Nested Array System (STSC, Inc., 1981)">[2]</acronym>) 
be assumed to apply<tt> f </tt>over each vector along the 
leading axis of<tt> a</tt>&nbsp;,<tt> </tt>
or it could (as defined in 
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">[3]</acronym>), 
apply<tt> f </tt>over the set of 
subarrays obtained by splitting<tt> a </tt>along the first axis. 
Both are consistent with the conventional definition, 
but only the latter allows the matrix product over a rank 
three array to be expressed as<tt> +.×⌿a</tt>&nbsp;.</p>

<p>A section will be devoted to each 
of the eight items listed above, 
and additional sections will treat a number of new functions 
and operators defined according to the schemes developed 
in the earlier sections. Two appendices summarize the ranks 
assigned to existing primitive functions 
(to systematize all extensions to higher-rank arrays), 
and the definitions of dyadic operators.</p>

<p>Any problems attendant upon the use of 
implicit arguments such as<tt> ⎕io </tt>are exacerbated 
by the more general uses of operators. 
Consequently, all new functions and operators 
to be defined will be <b>independent of</b><tt> ⎕io</tt>&nbsp;,<tt> </tt>  
<b>and will be defined in origin</b><tt> 0</tt>&nbsp;. 
Moreover,<tt> 0</tt>-origin will be used throughout this paper.</p>

<p>Consider, for example, the operator<tt> ⍥ </tt>which we will 
define so that the function<tt> g←f⍥i </tt>applies<tt> f </tt> 
to its argument after transposing to the rear end 
those axes specified by<tt> i</tt>&nbsp;.<tt> </tt>   
If the operator is independent of<tt> ⎕io </tt>(and uses fixed origin 0), 
then a function<tt> g </tt>that moves the leading axis 
to the rear is obtained from the expression<tt> g←f⍥0</tt>&nbsp;.<tt> </tt> 
However, if dependence on<tt> ⎕io </tt>were to be adopted, 
which value of<tt> ⎕io </tt>should apply, that in effect 
when<tt> g </tt>is specified, or when it is used? 
If the former, what advantage does the dependence offer, 
and if the latter, how could one specify the desired behaviour 
in the unknown environment?</p>

<p>The reader is assumed to be familiar 
with the functions <b>enclose</b>, <b>disclose</b>, 
and <b>match</b> (<tt>< > ≡</tt>)<tt> </tt>as defined in 
<acronym title="Robert Bernecky and Kenneth E. Iverson, 
Operators and Enclosed Arrays 
(I.P. Sharp, Proceedings of the User Meeting, 1980)">[4]</acronym>, 
Moreover, we will assume that the symbol<tt> ∘ </tt>denotes the 
constant<tt> <''</tt>&nbsp;;<tt> </tt>that is<tt> ∘≡<''</tt>&nbsp;.<tt> </tt> 
This provides a convenient notation for a &ldquo;fill&rdquo; element 
appropriate to a non-simple array, just as<tt> 0 </tt>and<tt> ' ' </tt>
provide fill elements for simple arrays. 
Moreover, it rationalizes the use of 
the symbol<tt> ∘ </tt> 
in the outer product, so that the expression<tt> a.b </tt>
may be used with<tt> a←∘ </tt>(or<tt> a←<''</tt>&nbsp;)<tt> </tt>
and<tt> b←×</tt>&nbsp;,<tt> </tt> 
just as it may be used with<tt> a←+ </tt>and<tt> b←×</tt>&nbsp;.</p>

<p>An interpreter for the language as extended here 
(written in APL) has proved invaluable in developing the design, 
and it has been used to produce the examples used herein. 
Any reader having access to this interpreter 
(in workspace<tt> 705 model </tt>on the I.P. Sharp system) 
will find it helpful in studying the present paper. 
An early version of the interpreter has been presented in 
<acronym title="K.E. Iverson, 
APL Syntax and Semantics (ACM, APL83)">[5]</acronym>; 
except as it may prove useful in the treatment 
of language questions, the interpreter 
itself will not be discussed here.</p>

<p>To obviate repetitions of phrases such as 
&ldquo;if<tt> a </tt>is an array of rank<tt> 3</tt> &rdquo;,<tt> </tt> 
we will adopt the following 
convention:<tt> a0</tt>&nbsp;,<tt> b0</tt>&nbsp;,<tt> </tt>etc., 
denote scalars,<tt> a1</tt>&nbsp;,<tt> b1</tt>&nbsp;,<tt> </tt>
etc., denote vectors, and so forth.</p>

<p><b>Appendices.</b> The body of the paper is devoted 
to definitions of the proposed extensions, 
and does not include examples of their use. 
Such examples are provided in <a href="RationalizedAPL1.htm#xc">Appendix C</a>, 
and many readers will find it more fruitful 
to go directly to this appendix before studying the 
complete definitions. 
In order to make such a course feasible, 
simplified definitions are included in the appendix.</p>

<p><a href="RationalizedAPL1.htm#xa">Appendices A</a> and <a href="RationalizedAPL1.htm#xb">B</a> 
show a table of ranks assigned 
to existing primitive functions, 
and a table of the new dyadic operators proposed. 
A final appendix (<a href="RationalizedAPL1.htm#xd">D</a>) 
provides a general comparison of APL2
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">[3]</acronym>
with a restricted subset of the proposals in this paper.</p>



<br><a name="a"></a>
<p><b>A. Indexing and Indexed Assignment</b></p>

<p>The enclose function as defined in 
<acronym title="Robert Bernecky and Kenneth E. Iverson, 
Operators and Enclosed Arrays 
(I.P. Sharp, Proceedings of the User Meeting, 1980)">[4]</acronym> 
has made it possible to produce by straightforward APL functions 
the &ldquo;index lists&rdquo; required in indexing expressions 
of the form<tt> a[i;j]</tt>&nbsp;,<tt> </tt>   
and therefore makes it possible to define 
a corresponding indexing function, which will be denoted by<tt> { </tt>
and called <b>from</b>:</p>

<pre>
      i{a ←→ a[>i[0];>i[1]; ...]
</pre>

<p>Since the disclose function<tt> > </tt>is permissive, 
the selection of any single element of<tt> a </tt> 
can be written without enclosures as, 
for example,<tt> 1 2 3{a3</tt>&nbsp;.<tt> </tt>   
Moreover, the left rank of<tt> { </tt>is<tt> 1 </tt>
and its right rank is infinite, so that 
(as discussed in <a href="RationalizedAPL1.htm#f">Section F</a>) 
a simple left argument<tt> i </tt>of rank 
greater than<tt> 1 </tt>produces an array 
of shape<tt> ¯1↓⍴i </tt>of elements chosen 
by the index vectors along its last axis, 
yielding what is sometimes called &ldquo;scattered&rdquo; indexing. 
For examp1e:</pre>

<pre>
      (3 2⍴⍳6){a2 ←→ a2[0;1],a2[2;3],a2[4;5]
</pre>

<p>Each index<tt> >i[k] </tt>must be of the 
form<tt> s </tt>or<tt> &lt;s</tt>&nbsp;,<tt> </tt>
where<tt> s </tt>is a simple array. If<tt> >i[k] </tt>is 
of the form<tt> &lt;s</tt>&nbsp;,<tt> </tt>   
then the indexing along axis<tt> k </tt>is complementary, 
selecting all elements except those whose indices 
occur in<tt> >>i[k]</tt>&nbsp;.<tt> </tt> 
In particular, if<tt> i[k]≡<<⍳0</tt>&nbsp;,<tt> </tt> 
the entire axis is selected.</p>

<p>In forming the left arguments of the indexing function, 
it will often be convenient to use the link 
function<tt> ⊃ </tt>defined as follows:</p>

<table>
<tr><td><tt> &nbsp; &nbsp; &nbsp; ⊃b ←→ &lt;b </tt>if<tt> b </tt>is simple</td></tr>
<tr><td><tt> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b </tt>if<tt> b </tt>is non-simple</td></tr>
<tr><td>&nbsp;</td></tr>
<tr><td><tt> &nbsp; &nbsp; &nbsp;a⊃b ←→ (&lt;a),⊃b</tt></td></tr>
</table>

<p>For example,<tt> (2&nbsp;3⊃4⊃∘⊃5&nbsp;6){a4 ←→ a[2&nbsp;3;4;;5&nbsp;6]</tt>&nbsp;.</p>

<p>The indexing function<tt> { </tt>as defined thus far provides 
all of the facilities provided by conventional indexing, 
and &ldquo;scattered&rdquo; and &ldquo;complementary&rdquo; indexing as well. 
Its power is further enhanced by allowing <b>negative</b> indexing 
(with the completely disclosed element<tt> e </tt>
in position<tt> k</tt>&nbsp;,<tt> </tt>   
either<tt> >k{i </tt>or<tt> >>k{i</tt>&nbsp;,<tt> </tt>
replaced by<tt> (k{⍴a)|e</tt>&nbsp;)<tt> </tt> 
and <b>abbreviated</b> indexing 
(with<tt> i{a </tt>equivalent 
to<tt> (i,((⍴⍴a)-⍴i)⍴<∘){a</tt>&nbsp;).<tt> </tt> 
For example,<tt> 2&nbsp;3{a3 ←→ (2⊃3⊃<∘){a3 </tt>
and, if<tt> ⍴a </tt>is<tt> 2&nbsp;3&nbsp;4</tt>&nbsp;,<tt> </tt> 
then<tt> 1&nbsp;¯1&nbsp;1 {a ←→ a[1;2;1]</tt>&nbsp;.<tt> </tt>   
Each index<tt> j </tt>along an axis of length<tt> n </tt>
is limited by<tt> (j&lt;n)∧(n≥-j)</tt>&nbsp;.</p>

<p>Indexed assignment of the form<tt> a[j;k]←b </tt>is anomalous, 
or at least awkward; the result of the expression 
(as received by<tt> c </tt>in<tt> c←a[j;k]←b</tt>&nbsp;)<tt> </tt> 
is merely<tt> b</tt>&nbsp;,<tt> </tt>   
and the merged result normally wanted must be obtained 
by a separate reference to<tt> a</tt>&nbsp;.</p>

<p>What is desired is a merge of<tt> a </tt>and<tt> b </tt>  
controlled by an index<tt> i </tt>and by the particular 
selection function employed. 
A simple solution is provided by the <b>with</b> operator<tt> ¨ </tt>
(described in 
<acronym title="K.E. Iverson, Operators and Functions 
(IBM Corporation, RC7091, 1978)">[6]</acronym> 
as<tt> a¨f x ←→ a f x</tt>&nbsp;)<tt> </tt>  
combined with the observation (made by Arthur Whitney) 
that a dyadic case of the derived function<tt> i¨{ </tt>  
could be defined to produce the desired merge. Thus if:</p>

<pre>
      r←b i¨{ a
</pre>

<p>then<tt> (⍴r)≡⍴a</tt>&nbsp;,<tt> </tt>and<tt> b≡i{r</tt>&nbsp;,<tt> </tt>
and &ldquo;the rest&rdquo; of<tt> r </tt> 
agrees with the rest of<tt> a</tt>&nbsp;,<tt> </tt>Thus:</p>

<pre>
      a2[j;k]←b ⋄ a2←⍉a2 ←→ a2←⍉b (j⊃k)¨{a2
</pre>

<p>In order to avoid the questions raised 
by expressions such as<tt> x[1 1]←2 3</tt>&nbsp;,<tt> </tt>
it might be desirable to restrict the domain 
of the expression<tt> b i¨{a </tt>
to a &ldquo;proper&rdquo; index<tt> i </tt>
containing no repeated elements. 
On the other hand, a permissive definition may be harmless, 
and could probably be implemented more easily.</p>



<br><a name="b"></a>
<p><b>B. Name Assignment</b></p>

<p>In conventional APL, the arrow used for assigning a name 
to a variable is not permitted for naming functions. 
Instead, a function name is assigned indirectly by 
characters embedded in its representation, 
and there is no direct way for assigning a name 
to a derived function such as<tt> +.×</tt>&nbsp;.</p>

<p>The solution is to allow the arrow to assign 
a name to any entity &mdash; variable, function, 
or operator (as in<tt> x←⍳5 </tt>
and<tt> ip←+.× </tt>and<tt> red←/</tt>&nbsp;) &mdash;  
and to provide means for function definition that 
do not embed the function name in its representation. 
This is discussed in <a href="RationalizedAPL1.htm#d">Section D</a>.</p>



<br><a name="c"></a>
<p><b>C. Function Valence</b></p>

<p>In conventional APL, functions are generally considered 
to be ambivalent, with the actual valence 
of application being determined by context. 
Many, however, are assigned a fixed valence &mdash; 
some primitives (e.g., monadic<tt> ~ </tt>and dyadic<tt> ∊</tt>&nbsp;),<tt> </tt> 
most derived functions 
(with one exception,<tt> ⌽[i]</tt>&nbsp;),<tt> </tt>   
and all defined functions.</p>

<p>The introduction of ambivalent defined functions 
in many APL systems has proved very convenient to the user, 
and the admission of ambivalent derived functions 
opens up many new possibilities, 
one of which has been exploited in the use of<tt> -.×m </tt>
for the determinant 
<acronym title="K.E. Iverson, Determinant-Like Functions 
Produced by the Dot Operator 
(I.P. Sharp Technical Notes - SATN-42, April 1982)">[7]</acronym>.</p>

<p>It is now proposed that 
(except for niladic functions, 
which must be treated separately), 
all functions be assumed to be ambivalent, 
and that any undefined case (such as<tt> ∊x</tt>) 
be treated as a proper function which has an empty domain. 
An unfortunate consequence of this is that 
<b>some change will occur</b> 
in the behaviour of existing programs, 
but only in replacing a syntax error message 
by a domain error message, 
or (as in the case of<tt> ~/3</tt>&nbsp;)<tt> </tt>by a result. 
However, this is a single, general change that would prevent 
further changes occasioned by each function extension introduced. 
Niladic functions must, of course, retain their fixed valence.</p>

<p>A further consequence of the ambivalence of all functions 
is that no operator can have its behaviour defined in terms 
of the valence of the function to which it is applied, 
since all have the same valence. 
This matter was anticipated in 
<acronym title="Robert Bernecky and Kenneth E. Iverson, 
Operators and Enclosed Arrays 
(I.P. Sharp, Proceedings of the User Meeting, 1980)">[4]</acronym>
in the definition of two distinct composition operators, 
one to apply a function<tt> f </tt>
dyadically to the results of monadic applications of<tt> g </tt>
(as in<tt> ⍺ f⍤g ⍵ ←→ (g⍺) f (g⍵)</tt>&nbsp;),<tt> </tt>
and one to apply<tt> f </tt>monadically to the result 
of a dyadic application 
of<tt> g </tt>(as in<tt> ⍺ f⍥g ⍵ ←→ f ⍺g⍵</tt>&nbsp;).</p>



<br><a name="d"></a>
<p><b>D. Function Definition</b></p>

<p>Although the operators are the entities generally 
used to produce functions in APL, 
the only language facility 
(as opposed to the<tt> ∇</tt>-editing facility based upon it 
but not usable in programs) 
provided for producing defined functions 
(i.e.,<tt> ⎕fx</tt>&nbsp;),<tt> </tt>is itself a <b>function</b>, 
and one which produces as an explicit result 
only the <b>name</b> of the function, 
producing the function itself as a side-effect. 
Moreover, although many APL systems allow<tt> ⎕fx </tt> 
to produce ambivalent functions, none provide true ambivalence, 
with, for example, independent localization 
of variables for the two cases.</p>

<p>The proposed replacement for<tt> ⎕fx </tt>is a modification of the 
direct definition operator<tt> ∇ </tt>defined in 
<acronym title="Kenneth E. Iverson and Peter K. Wooster, 
A Function Definition Operator 
(APL Quote Quad, Volume 12, Number 1, Proceedings of APL81, 
ACM September 1981)">[8]</acronym>, 
and is defined as follows:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
<tt>m∇d </tt>produces a function, 
with<tt> m </tt>and<tt> d </tt> 
being the representations of the monadic and dyadic cases.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
The general form of each representation is a vector<tt> r </tt>  
of enclosed <b>segments</b>, 
the segments being executed in an order determined 
by a <b>sequence control</b> vector. 
It is initially set to<tt> 1+⍳⍴r </tt>
(the segment indices beginning at<tt> 1 </tt>as do the indices 
in conventional definition), and is reset by any branch statement 
having a non-empty argument. 
Termination occurs upon exhaustion of the sequence control vector, 
or upon an index out of range.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
A label in the first element of<tt> r </tt>is assigned the 
value<tt> 1+⍳⍴r</tt>&nbsp;,<tt> </tt> 
one in the second is assigned<tt> 1↓1+⍳⍴r</tt>&nbsp;,<tt> </tt>etc. 
A label is indicated by a right parenthesis rather than a colon, 
freeing the colon for use as a variant operator as suggested in 
<acronym title="K.E. Iverson, Operators and Functions 
(IBM Corporation, RC7091, 1978)">[6]</acronym>.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
The symbols<tt> ⍺ </tt>and<tt> ⍵ </tt>denote 
the left and right arguments, 
and<tt> ∆ </tt>is used for <b>self-reference</b> 
to the function itself, 
being used in recursive definitions as well as 
for defining one of the two cases in terms of the other.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
A name is localized if it occurs <b>immediately</b> to the left 
of an assignment arrow in any segment; 
for example,<tt> 3×a←4+b ←⍵ </tt>
localizes<tt> a </tt>but not<tt> b</tt>&nbsp;.<tt> </tt>   
Name localizations for the monadic and dyadic cases are independent.
 <br>&nbsp;</td></tr>
<tr><td valign=top>6.</td><td>&nbsp;</td><td>
The explicit result of a function is the result 
of the last statement executed 
which produced an explicit result, 
where expressions such as<tt> x←3+4 </tt>or<tt> 3+4 </tt>are assumed 
to produce explicit results, but<tt> →a </tt>
and<tt> ⍎'' </tt>and<tt> ⊣a </tt>  
(as defined in <a href="RationalizedAPL1.htm#j">Section J</a>) are not. 
Automatic output is not produced by an expression 
such as<tt> 3+4</tt>&nbsp;;<tt> </tt> 
such output is produced only by expressions using<tt> ⎕←</tt>&nbsp;.
 <br>&nbsp;</td></tr>
<tr><td valign=top>7.</td><td>&nbsp;</td><td>
Every vector<tt> v </tt>is treated as<tt> ,⊃v</tt>&nbsp;,<tt> </tt>that is, 
a simple vector is treated as a single segment. 
Single segments may therefore be written in the 
form<tt> '0⌈⍵'&nbsp;∇&nbsp;'⍺||⍵' </tt>.
 </td></tr>
</table>

<p>A function produced by the operator<tt> ∇ </tt>
may be assigned a name (as in<tt> f←m∇d </tt>
or in<tt> a(f←m∇d)b</tt>&nbsp;),<tt> </tt>
but it may also be used without assigning a name, 
as in <tt> y←''∇'⍺+÷⍵'/x</tt>&nbsp;.</p>



<br><a name="e"></a>
<p><b>E. Syntax and Order of Evaluation</b></p>

<p>Although the order of execution 
of functions and operators in conventional APL 
is well-defined, the order of <b>evaluation of names</b> is not, 
and ambiguity therefore occurs not only in an expression such 
as<tt> (a←2)÷a←3</tt>&nbsp;,<tt> </tt>but also 
(if<tt> a </tt>is a shared variable) 
in the simpler expression<tt> a÷a</tt>&nbsp;.<tt> </tt>
The matter is further complicated by allowing 
the direct assignment of names, as 
in<tt> (f←3×⍳4)(f←×.-)f←⍳4</tt>&nbsp;.</p>

<p>Although the precedence of operators over functions 
is established in conventional APL, 
the fact that operators are not applied 
to derived functions implies 
that the syntax and order of execution 
of a sequence of operators is not established. 
The syntax and order of evaluation and execution 
that is now widely accepted (and is proposed here) 
may be summarized as follows:</p>

<table>
<tr><td valign=top>a)</td><td>&nbsp;</td><td>
Parentheses are obeyed as usual, 
and are permitted around function names, 
as in<tt> a(+)b <tt>and<tt> a(+.×)b</tt>&nbsp;.
 <br>&nbsp;</td></tr>
<tr><td valign=top>b)</td><td>&nbsp;</td><td>
Names are evaluated in order from right to left, 
and the values produced are detached 
from the original names.
 <br>&nbsp;</td></tr>
<tr><td valign=top>c)</td><td>&nbsp;</td><td>
An operator may be either monadic or dyadic, 
but is not ambivalent.
 <br>&nbsp;</td></tr>
<tr><td valign=top>d)</td><td>&nbsp;</td><td>
An operator applies to the result 
of the entire operator sequence to its left, 
much as a function applies to the result 
of the entire expression to its right. Thus<br><br>
<tt>* +.×/t ←→ *(+.×)/t</tt>&nbsp;.
 </td></tr>
</table>

<p>More precisely:</p>

<p>1.  The tokens (i.e., the indivisible names such 
as<tt> abc </tt>or<tt> ¯2.4e5 </tt>or<tt> + </tt>
or<tt> ¯2.4e5&nbsp;3&nbsp;2</tt>&nbsp;)<tt> </tt> 
are examined in order from 
right to left; each is evaluated immediately and 
the representation of the result (whether variable, function, or operator) 
is appended at the beginning of a (<b>right</b>) <b>stack</b> vector 
and is immediately dissociated from the name 
whose evaluation yielded it.</p>

<p>2.  The evaluation of tokens may be interrupted 
by the execution of a function or operator in the stack 
applied to one or two adjacent arguments in the stack.</p>

<p>3.  The syntax and order of execution are further 
specified by a set of rules that determine what 
segment of the stack is to be executed, 
or whether evaluation of tokens is to proceed. 
The rules are based upon the class 
(variable, operator, function, assignment arrow) of each 
of the first four elements of the stack.</p>

<p>4.  A right parenthesis invokes the execution 
of the entire expression up to the matching left parenthesis, 
the result being then transferred to the right stack.</p>

<p>5.  Because conventional APL uses name assignment 
in the form<tt> ab←x </tt>rather than in the possible, 
but more awkward, form<tt> 'ab'←x</tt>&nbsp;,<tt> </tt> 
rule 1 above must be modified as follows: 
if the leading element in the right stack is 
an assigment arrow, the next token is transferred 
directly without evaluation.</p>

<p>6.  Items 4 and 5 conflict in the 
case<tt> (n)←3</tt>&nbsp;,<tt> </tt> 
a conflict resolved by giving precedence to item 4. 
The consequence (as elaborated in 
<acronym title="K.E. Iverson, 
APL Syntax and Semantics (ACM, APL83)">[5]</acronym>) 
is to provide &ldquo;indirect&rdquo; assignment. 
For example, if<tt> n←'asd' </tt>and<tt> (n)←3 </tt>&nbsp;,<tt> </tt> 
then<tt> n </tt>retains the value<tt> 'asd'</tt>&nbsp;,<tt> </tt>
and<tt> asd </tt>becomes<tt> 3</tt>&nbsp;.</p>

<p>7.  The rules referred to in item 3 are summarized 
in the following table taken directly from the interpreter:</p>

<pre>
vmf←l  vf    d     vf  L S(1↑R),(R[2]RE R[1 3]),4↓R
vmf←l  v     f     v   L S(1↑R),(R[2]RE R[1 3]),4↓R
vmf←l  vf    m         L S(1↑R),(R[2]RE R[1]),3↓R
mf←l   f     v         L S(1↑R),(R[1]RE R[2]),3↓R
d      v     f     v   L S(2↑R),(R[2]RE R[3]),4↓R
v      ←     vmdf  r   L S,R[0] IS R[2]
l      vmdf  r         R[1]
vmdfr                  (>''⍴Z)S(1↓Z←L LE 0),R
←                      (>''⍴Z)S(1↓Z←L LE 1),R
                       R not single∊
</pre>

<p>Each of the first four columns above specifies 
the classes to which the corresponding element of<tt> R </tt>  
may belong to invoke the corresponding action 
specified by the final column.  
The symbols<tt> v</tt>&nbsp;,<tt> m</tt>&nbsp;,<tt> d</tt> 
,<tt> f</tt>&nbsp;,<tt> ←</tt>&nbsp;,<tt> l</tt>&nbsp;,<tt> </tt>
and<tt> r </tt>denote the classes 
<b>variable</b>, <b>monadic operator</b>, 
<b>dyadic operator</b>, <b>function</b>, <b>assignment</b>, 
<b>left</b> (a filler introduced when the left stack is exhausted), 
and a <b>right filler</b> implicitly introduced to extend 
a short right stack to four elements.</p>

<p>Thus the first line specifies the action to 
be taken (replacing elements<tt> 1</tt> 
,<tt> 2</tt>&nbsp;,<tt> 3 </tt>of the stack 
by the result of applying element<tt> 2 </tt>[a dyadic operator] 
to elements<tt> 1 </tt>and<tt> 3</tt>&nbsp;)<tt> </tt> 
in the case that<tt> R[0] </tt>
belongs to any one of the classes<tt> vmf←l</tt>&nbsp;,<tt> </tt>
and<tt> R[1] </tt>belongs to<tt> vf </tt>and<tt> R[2] </tt>belongs 
to<tt> d</tt>&nbsp;,<tt> </tt>   
and<tt> R[3] </tt>belongs to<tt> vf</tt>&nbsp;.</p>

<p>No special treatment is required 
for a niladic function 
(represented in the usual way) since it is executed 
(exactly as a variable is) 
before being transferred to the right stack. 
Further entries could be added 
at the head of the syntax table to catch 
invalid sequences in the right stack 
as soon as they occur, 
rather than allowing them all 
to appear as a single error due 
to the fact that the stack has 
the wrong form upon termination.</p>



<br><a name="f"></a>
<p><b>F. Extensions to Higher Rank Arrays</b></p>

<p>In conventional APL, the scalar functions 
(which apply to scalar elements and produce scalar results) 
extend to higher rank arrays according to simple general rules; 
no corresponding general rules exist 
for the remaining so-called mixed functions. 
We will now define a systematic scheme of 
extensions based on two attributes of a function: 
<b>rank</b>, and <b>conformance</b>.</p>

<a name="f1"></a>
<p><b>Rank.</b> For a general function<tt> f</tt>&nbsp;,<tt> </tt>
the axes of an argument<tt> ⍵ </tt>will be split at some point<tt> k </tt>
such that<tt> f </tt>is applied to each subarray of 
shape<tt> k↓⍴⍵</tt>&nbsp;,<tt> </tt>producing a result of shape<tt> (k↑⍴⍵),sir</tt>&nbsp;,<tt> </tt>
where<tt> sir </tt>is the (necessarily common) 
shape of the individual results produced 
by applying<tt> f </tt>to each subarray.</p>

<p>Each function<tt> f </tt>is assigned a monadic rank<tt> mf </tt>
which determines the value of<tt> k </tt>as follows:</p>

<table>
<tr><td><tt>&nbsp; &nbsp; &nbsp; k←0⌈(⍴⍴⍵)-mf</tt></td><td>&nbsp;</td><td>if<tt> mf≥0</tt></td></tr>
<tr><td><tt>&nbsp; &nbsp; &nbsp; k←(⍴⍴⍵)⌊|mf</tt></td><td>&nbsp;</td><td>if<tt> mf&lt;0</tt></td></tr>
</table>

<p>Consequently, a positive or zero value of<tt> mf </tt>
determines the rank of the subarrays 
to which<tt> f </tt>applies, 
and a negative value determines 
the <b>complementary</b> rank, 
the number of <b>leading</b> axes excluded 
in each application of<tt> f</tt>&nbsp;.</p>

<p>Because of the definition of<tt> k</tt>&nbsp;,<tt> </tt>   
the rank of a function imposes 
only an upper limit on the rank 
of the subarrays to which<tt> f </tt>applies, 
and does not prohibit the application of<tt> f </tt>to <b>degenerate</b> 
cases of lower rank. 
For example, the function<tt> ⌹ </tt>has rank<tt> 2</tt>&nbsp;,<tt> </tt>
but if its argument is a vector it is applied to the vector. 
Because the function<tt> ⌹ </tt>is defined on vectors, 
it yields a result, although another rank<tt> 2 </tt>function, 
such as the determinant, might be defined 
to yield a domain error in such a degenerate case.</p>

<p>Similar remarks apply to the dyadic case, 
with each function being assigned independent left and right ranks, 
and yielding outer shapes<tt> ol←kl↑⍴⍺ </tt>and<tt> or←kr↑⍴⍵</tt>&nbsp;.<tt> </tt> 
The agreement required between these outer shapes 
will be discussed under the heading &ldquo;conformance&rdquo;.</p>

<p>Certain functions, such as ravel, are of <b>infinite</b>, 
or <b>unbounded</b> rank; consistently 
with the foregoing definition, 
such a rank will be assigned an infinite value (denoted by<tt> ¯</tt>&nbsp;).</p>

<p>The utility of the notion of rank 
will now be illustrated briefly 
by introducing the <b>rank operator</b>, 
which yields a derived function of specified rank. 
Thus<tt> f⍤2 ¯1 1 </tt>yields a derived function 
of monadic rank<tt> 2</tt>&nbsp;,<tt> </tt> 
of complementary left rank<tt> 1</tt>&nbsp;,<tt> </tt>
and right rank <tt> 1</tt>&nbsp;.<tt> </tt> 
Moreover,<tt> f⍤r ←→ f⍤(⌽3⌽⍴⌽r)</tt>&nbsp;,<tt> </tt>
so that abbreviated forms such as<tt> f⍤2 </tt>
(all ranks are<tt> 2</tt>&nbsp;),<tt> </tt>and<tt> f⍤2 3 </tt>  
(left rank is 2 and both right ranks 
are<tt> 3</tt>&nbsp;)<tt> </tt> may be used. 
For example,<tt> ,⍤2⍵ </tt>ravels the last two axes of the 
argument,<tt> ,⍤¯2⍵ </tt>ravels all but the first two, 
and<tt> ,⍤0⍵ </tt>adds a final unit axis 
to the axes of the argument.</p>

<p>A necessary first step in establishing the use 
of ranks is to define the ranks of all existing functions. 
Because of the treatment of degenerate cases, 
it is possible to do this in a manner compatible 
with existing definitions 
by simply assigning infinite ranks to all. 
However, it is generally more useful 
to assign the lowest rank 
which will ensure compatibility 
with existing definitions, 
since this leads to simpler definitions of the functions, 
and greater utilization of the general scheme of extension. 
In particular, the scalar functions can, 
and will, be assigned rank<tt> 0</tt>&nbsp;.</p>

<p>The argument for assigning to a function<tt> f </tt>
the lowest compatible rank is somewhat weakened 
by the fact that a corresponding function of lower rank<tt> r </tt>
is so easily obtained from the expression<tt> f⍤r</tt>&nbsp;.<tt> </tt> 
Thus, although<tt> ⌽ </tt>could be assigned 
monadic rank<tt> 1</tt>&nbsp;,<tt> </tt>
it might instead be assigned infinite rank, 
so as not to make it dissimilar to<tt> ⊖</tt>&nbsp;,<tt> </tt> 
which must be assigned infinite monadic rank.</p>

<p><a href="RationalizedAPL1.htm#xa">Appendix A</a> shows a table of the proposed 
rank assignments, together with notes on the less obvious choices. 
The scalar functions are not included in the table.</p>

<a name="f2"></a>
<p><b>Conformance.</b> In the application 
of a dyadic function<tt> f</tt>&nbsp;,<tt> </tt>   
the outer shapes<tt> ol </tt>and<tt> or </tt>
are each split into two sets 
of axes (called <b>bound</b> and <b>free</b>) 
such that<tt> ol=bl,fl </tt>and<tt> or=br,fr</tt>&nbsp;;<tt> </tt>
the shape of the overall result 
is<tt> b,fl,fr,sir</tt>&nbsp;,<tt> </tt>   
where<tt> b </tt>is one of<tt> bl </tt>
and<tt> br</tt>&nbsp;,<tt> </tt>and<tt> sir </tt> 
is the shape of the individual results 
of applying the function to its cells.</p>

<p>A shape<tt> s </tt>is said to be <b>single</b>
if<tt> 1=×/s</tt>&nbsp;;<tt> </tt>if <b>one</b>
of<tt> bl </tt>and<tt> br </tt>
is single, then<tt> b </tt>equals the other; if both are, 
then<tt> b </tt>equals the one of greater length; 
if neither is single, then<tt> bl </tt>and<tt> br </tt>must agree, 
and<tt> b </tt>is chosen as either one.</p>

<p>The number of bound axes 
(that is, the lengths of<tt> bl </tt>and of<tt> br</tt>&nbsp;)<tt> </tt>   
is limited by the <b>conformance</b> of the function<tt> f</tt>&nbsp;;<tt> </tt>  
all primitive functions have infinite conformance, 
and the <b>conformance operator</b>, denoted by<tt> f.k </tt>  
(where<tt> k </tt>is a non-negative integer), 
produces a derived function equivalent to<tt> f </tt> 
but having conformance<tt> k</tt>&nbsp;.<tt> </tt>For example:</p>

<pre>
      ⍴(a←2 3 4⍴⍳24)×. 0(b←2 3 5⍴⍳30)
2 3 4 2 3 5
      ⍴a ×. 1 b
2 3 4 3 5
      ⍴a ×. 2 b
2 3 4 5
      ⍴a ×. 3 b
length error
      ⍴a×. 1 (1 1 4⍴9)
2 3 4
      ⍴a×. 2 (3 4⍴9)
2 3 4
      ⍴(1 1 1⍴8)+1 1⍴9)
1 1 1
</pre>

<p>The case of zero conformance<tt> </tt>( <tt>f. 0</tt>&nbsp;)<tt> </tt> 
is equivalent to outer product<tt> </tt>( <tt>∘.f</tt>&nbsp;).<tt> </tt>   
Except for the conformance operator itself, 
every operator produces derived functions 
having infinite conformance.</p>

<p>If<tt> 1=×/s</tt>&nbsp;,<tt> </tt>then the shape<tt> s </tt>
is said to be (the shape of) a <b>singleton</b>. 
Singleton bound shapes are given special treatment that formalizes, 
and extends to non-scalar functions, 
the use of scalar and other singleton arguments 
in expressions such as<tt> 2&nbsp;3&nbsp;+&nbsp;4 </tt>
and<tt> 2&nbsp;3&nbsp;+&nbsp;,4 </tt>
and<tt> 2&nbsp;3&nbsp;+&nbsp;1&nbsp;1&nbsp;1&nbsp;1⍴4</tt>&nbsp;.<tt> </tt> 
Thus, if <b>one</b> of<tt> bl </tt>and<tt> br </tt>is a singleton, 
conformance is satisfied and the bound part of the shape of the result 
is determined by the other; if both are singletons, 
then the bound part of the shape is determined 
by the one of larger rank. 
For example,<tt> ⍴(1&nbsp;1&nbsp;1⍴4)+1&nbsp;1⍴2 </tt>
is<tt> 1&nbsp;1&nbsp;1</tt>&nbsp;.</p>



<br><a name="g"></a>
<p><b>G. Operators and Nonscalar Functions</b>

<p>The reduction operator can, as remarked 
in the introduction, be consistently extended 
to non-scalar functions in at least two different ways, 
and similar variety is possible 
for the remaining conventional operators. 
We will now present a systematic scheme of extension 
(based upon the notion of function rank) 
which applies to all of the existing operators except the 
(bracket) axis operator. 
This operator is excluded because of its anomalous syntax, 
and because its purpose can be conveniently served 
by the rank operator, sometimes in conjunction 
with the transpose operator.</p>

<p>The cases of reduction are 
straightforward:<tt> f⌿⍵ </tt>splits the argument<tt> ⍵ </tt>
along the leading axis and applies<tt> f </tt>between 
the resulting subarrays;<tt> f/⍵ </tt>   
splits along the final axis.</p>

<p>The outer and inner products are conveniently 
defined in terms of conformance:</p>

<pre>
      ⍺ ∘.g ⍵ ←→ ⍺ g. 0 ⍵

      ⍺ f.g ⍵ ←→ f⌿(¯1⍥⊢⍺)g. 1 ⍵
</pre>

<p>(The transpose operator<tt> ⍥ </tt>is fully defined in 
<a href="RationalizedAPL1.htm#k">Section K</a>; 
the effect of<tt> ¯1⍥⊢⍺ </tt>used above is to move the last axis 
of<tt> ⍺ </tt>to the leading position). 
The left and right ranks of the derived inner product are infinite.</p>

<p>A notable result of this definition of inner product is that, 
(because of the permissive treatment of the conformance of singletons) 
the conventional permissive definition of inner product is preserved. 
For example, if<tt> 3&nbsp;2&nbsp;4≡⍴a</tt>
and<tt> 1&nbsp;5&nbsp;6≡⍴b</tt>&nbsp;,<tt> </tt> 
then<tt> a&nbsp;f.g&nbsp;b ←→ a&nbsp;f.g&nbsp;4&nbsp;5&nbsp;6⍴b </tt>.</p>

<p>A scan applies reduction over each of a set of partitions 
of one axis of the argument, 
and the result therefore includes a <b>supernumerary</b> axis 
corresponding to this set. 
The scan<tt> f\⍵ </tt>partitions along the <b>last</b> axis, 
and places the supernumerary axis <b>last</b>, 
after the (necessarily common) shape of the individual reductions. 
The scan<tt> f⍀⍵ </tt>partitions along the <b>first</b> axis, 
and places the supernumerary axis <b>first</b>, 
before the common shape of the individual reductions. 
Supernumerary axes are discussed more fully 
in <a href="RationalizedAPL1.htm#k">Section K</a>.</p>



<br><a name="h"></a>
<p><b>H. Miscellaneous</b></p>

<p>This section treats three matters, a rationalization of the 
jot<tt> </tt>(<tt>∘</tt>)<tt> </tt>   
used in the outer product and of the <b>type</b> attribute of 
an array used in expansion and overtake, 
and some illustrations of the assertion 
(made in <a href="RationalizedAPL1.htm#g">Section G</a>) 
that the rank operator can fulfill the functions 
of the anomalous bracket operator.</p>

<a name="h1"></a>
<p><b>The type attribute.</b> For most purposes an 
APL array<tt> a </tt>  
is completely determined by its shape (which can be obtained 
by applying the function<tt> ⍴</tt>&nbsp;)<tt> </tt>
and by the value of each of its elements 
(which can be obtained by indexing), 
and the array incorporates no other attributes 
which determine the result of applying functions to it. 
However, conventional APL includes two functions, 
the <b>overtake</b><tt> </tt>(<tt>↑ </tt>with a sufficiently 
large left argument), 
and the derived function 
<b>expansion</b><tt> </tt>(<tt>u\</tt>&nbsp;,<tt> </tt>
where<tt> u </tt>is boolean) 
which do depend on an attribute associated 
with neither the value of an element nor the shape: 
if<tt> n←⍳0 </tt>and<tt> c←''</tt>&nbsp;,<tt> </tt>
then<tt> n </tt>and<tt> c </tt>agree in shape 
and differ in no element, 
but<tt> 0\n </tt>and<tt> 0\c </tt>produce different 
results<tt> </tt>(<tt>,0 </tt>and<tt> ,' '</tt>),<tt> </tt>
as do<tt> 1↑n </tt>and<tt> 1↑c</tt>&nbsp;.</p>

<p>This anomalous behaviour of overtake 
and expansion arose as follows: 
they are essentially &ldquo;selection&rdquo; functions, 
but they depend upon a parameter 
not explicitly specified by their arguments, 
namely, the <b>filler</b> quantity to be inserted 
in each of the &ldquo;new positions&rdquo; produced. 
Moreover the domain of the catenate function 
was limited to arguments 
of the same <b>class</b> (numeric or character) 
so as to preclude the introduction 
of heterogeneous arrays of mixed classes. 
Consequently, the filler could not be a
fixed quantity, but had to be drawn from the same 
class as the argument 
of the overtake or expansion function.</p>

<p>For any argument<tt> a </tt>that contains 
at least one element (i.e.,<tt> 1≤×/⍴a</tt>&nbsp;),<tt> </tt>   
the filler can be determined from the class 
of any one of the elements, 
but for an empty array, 
no element can provide this information. 
The definition of overtake and expansion 
on empty arrays 
therefore required either the choice 
of a single filler for all, 
or the introduction of an attribute, 
usually referred to as the <b>type</b> 
of an empty array.</p>

<p>In conventional APL, arguments for the convenience 
provided by the type attribute 
(in maintaining the class of an argument 
in expressions such as<tt> u\u/a </tt>
[for<tt> 0=∨/u</tt>&nbsp;]<tt> </tt>   
and<tt> k↑j↓a </tt>[for <tt>j≥⍴a</tt>&nbsp;])<tt> </tt>
won the day. 
Although compatibility requires 
that the type attribute be maintained 
to continue the present behaviour 
of expansion and overtake, 
it does not require any further extension 
of its use in the definition of new 
or existing functions and operators.</p>

<p>There are two classes of argument 
against further extension of the use 
of the type attribute of empty arrays: 
the complexity of the rules required for extension, 
and the possibility of providing the same 
(or nearly the same, or greater) 
convenience aimed at in the design of conventional APL, 
by means not then available.</p>

<p>Some of the complexity can be glimpsed from the following:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
The need for rules for the types resulting 
from the expressions<tt> '',⍳0 </tt>
and<tt> (⍳0),''</tt>&nbsp;.</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
The need for further type rules for any new 
classes that may be introduced, 
such as enclosed and heterogeneous 
[<acronym title="APL*PLUS Nested Array System 
(STSC, Inc., 1981)">2</acronym>,
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">3</acronym>].</td></tr>
</table>

<p>Further indications of the complexity 
can be seen in the rather extensive discussions 
of types and prototypes in APL systems
[<acronym title="APL*PLUS Nested Array System 
(STSC, Inc., 1981)">2</acronym>,
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">3</acronym>].</p>

<p>The introduction of dyadic cases 
for derived functions has made it easy to 
provide extra parameters, 
as in the merge produced 
by the expression<tt> b i¨{ a</tt>&nbsp;.<tt> </tt>  
Moreover, an associated dyadic case of compression 
as discussed in <a href="RationalizedAPL1.htm#k">Section K</a> 
provides for the specification 
of fillers for expansion. 
Not only would<tt> 0&nbsp;u\&nbsp;n </tt> 
and<tt> '&nbsp;'&nbsp;u\&nbsp;c </tt>specify the normal fillers 
for vectors<tt> n </tt>and<tt> c </tt>(empty or not), 
but<tt> 1&nbsp;u\&nbsp;n </tt>and<tt> '*'&nbsp;u\&nbsp;c </tt>  
would provide useful generalizations.</p>

<p>Since <b>take</b> is a selection function, 
a dyadic case<tt> b&nbsp;j¨↑&nbsp;a </tt>could be defined 
to provide a merge analogous to<tt> b&nbsp;j¨{&nbsp;a</tt>&nbsp;.<tt> </tt>  
Moreover, the derived function<tt> ↑¨a </tt>
(defined by<tt> ↑¨a&nbsp;i ←→ i↑a</tt>&nbsp;)<tt> </tt> 
could be provided by an associated dyadic case: 
thus<tt> i&nbsp;↑¨a&nbsp;b </tt>
would employ a filler specified by<tt> b</tt>&nbsp;.<tt> </tt> 
Since the &ldquo;new positions&rdquo; 
need not even form a rectangular array,<tt> b </tt>
should be a scalar, that is, the right rank of<tt> ↑¨a </tt>
would be<tt> 0</tt>&nbsp;.</p>

<p>In conclusion:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
Expressions such as<tt> f&nbsp;u/⍵ </tt>
and<tt> i&nbsp;{¨⍵  f </tt>  
should be introduced to permit convenient specification 
of a filler quantity<tt> f</tt>&nbsp;.
 </td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
For any non-empty argument, 
a suitable filler should be defined for any new class 
of argument introduced. 
The filler<tt> <'' </tt>(denoted by<tt> ∘</tt>&nbsp;)<tt> </tt>
will be used for enclosed arrays.
 </td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
For empty arrays, compatibility 
requires the continuation of 
two distinct fillers, 
but no new fillers should be introduced. 
In particular, the result of<tt> 1↑0⍴<'a' </tt>
should be defined as <b>zero</b>, 
with a view to eventually eliminating 
the type distinction and making <b>all</b> 
such fillers <b>zero</b>.
 </td></tr>
</table>

<a name="h2"></a>
<p><b>The bracket axis operator.</b> The following 
remarks about the bracket axis operator 
are based upon unpublished suggestions by
Arthur Whitney:

<pre>
        +⍀⍤¯2⍵ ←→ +⍀[2]⍵ ←→ +\[2]⍵
         ⊖⍤¯2⍵ ←→ ⊖[2]⍵  ←→ ⌽[2]⍵
      ⍺,¨⍉⍤¯2⍵ ←→ ⍺,[2]⍵
      ⍺,¨<⍤¯2⍵ ←→ ⍺,[1.5]⍵
</pre>

<p>In the foregoing identities, 
0-origin indexing is assumed, 
and the identities do not hold for all degenerate cases 
of catenation that involve arguments of differing ranks. 
The function<tt> ,¨⍉ </tt>catenates along the leading axis, 
and<tt> ,¨< </tt>produces lamination along a new leading axis. 
Note that lamination to introduce a new axis 
at any position can be achieved 
without the use of fractional indices.</p>



<br><a name="i"></a>
<p><b>I. New Operators</b></p>

<p>This section treats only those new operators 
that will be used directly in the definition 
of new functions in <a href="RationalizedAPL1.htm#j">Section J</a>; 
others are deferred to <a href="RationalizedAPL1.htm#k">Section K</a>. 
To facilitate distinctions between the cases distinguished 
by argument types (function-function, function-variable, 
variable-function, and variable-variable), 
we will use the names<tt> f </tt>and<tt> g </tt> 
exclusively for functions.</p>

<p>This section treats three dyadic operators 
(denoted by<tt> ⍤</tt>&nbsp;,<tt> ⍥</tt>&nbsp;,<tt> </tt>and<tt> ¨</tt>&nbsp;,<tt> </tt> 
and called <b>on</b>, <b>upon</b>, and <b>with</b>), 
although the cases<tt> f¨i</tt>&nbsp;,<tt> i¨f</tt>&nbsp;,<tt> </tt>
and,<tt> i¨j </tt>
are deferred to <a href="RationalizedAPL1.htm#k">Section K</a>. 
It also treats the monadic operator<tt> ⊂</tt>&nbsp;,<tt> </tt>
called <b>con</b>.</p>

<p>The monadic operator<tt> ⊂ </tt>is defined as 
follows:<tt> ⍺f⊂⍵ ←→ ⍵f⍺</tt>&nbsp;,<tt> </tt>
and the right and left ranks of<tt> f⊂ </tt>
are therefore the left and right ranks 
of<tt> f</tt>&nbsp;.<tt> </tt> 
Moreover, the monadic case<tt> f⊂⍵ </tt>
is the function inverse to<tt> f</tt>&nbsp;;<tt> </tt> 
the definition of this inverse (including its rank) 
is an <b>attribute</b> of the function<tt> f</tt>&nbsp;,<tt> </tt>
that is, it is part of the definition 
of<tt> f</tt>&nbsp;.<tt> </tt>   
For example, the inverse of the scalar function<tt> * </tt>
is the scalar function<tt> ⍟</tt>&nbsp;,<tt> </tt>   
and the inverse of the infinite rank 
function<tt> < </tt>is the rank<tt> 0 </tt>
function<tt> ></tt>&nbsp;.</p>

<p>The name <b>con</b> (meaning <b>in opposition to</b>) 
is chosen to suggest both the function inversion 
of the monadic case, and the argument inversion of the dyadic case; 
the symbol<tt> ⊂ </tt>resembles the letter c, 
the initial letter of both con and commute.</p>

<p>The composition<tt> f⍤g </tt>is defined as in 
<a href="RationalizedAPL1.htm#c">Section C</a>, with the added proviso 
that the composition is &ldquo;close&rdquo; in the sense defined in 
<acronym title="K.E. Iverson, Operators and Functions 
(IBM Corporation, RC7091, 1978)">[6]</acronym>. 
In terms of function rank, 
this proviso may be stated very simply by declaring 
that the three ranks of the derived function<tt> f⍤g </tt>
each equal the monadic rank of<tt> g</tt>&nbsp;.</p>

<p>The &ldquo;dual&rdquo;<tt> f¨g </tt>has 
the same ranks as<tt> f⍤g</tt>&nbsp;,<tt> </tt>   
the definitions being<tt> (g⊂)f g⍵ </tt>
and<tt> (g⊂)(g⍺)f g⍵</tt>&nbsp;</tt>&nbsp;.<tt> </tt> 
The derived function<tt> f⍥g </tt>
has the same ranks as<tt> g</tt>&nbsp;.</p>

<p>The cases<tt> f⍤i </tt>and<tt> f⍥i </tt>
and<tt> i⍥f </tt>will be defined 
so that together they provide the facility provided 
by the axis operator defined in
<acronym title="Robert Bernecky and Kenneth E. Iverson, 
Operators and Enclosed Arrays 
(I.P. Sharp, Proceedings of the User Meeting, 1980)">
Reference 4</acronym>, 
but in a simpler and more flexible manner.</p>

<p>The case<tt> f⍤i </tt>was defined in <a href="RationalizedAPL1.htm#f">Section F</a>, 
where it was referred to as the <b>rank</b> operator. 
The case<tt> f⍥i⍵ </tt>applies<tt> f </tt>
to a transpose of<tt> ⍵ </tt>  
that moves axes<tt> i </tt>to the tail end. 
For example, if<tt> ⍴⍵ </tt>
is<tt> 3&nbsp;4&nbsp;5&nbsp;6&nbsp;7</tt>&nbsp;,<tt> </tt>
then<tt> ⍴⊢⍤2&nbsp;1⍵ </tt>
is<tt> 3&nbsp;6&nbsp;7&nbsp;5&nbsp;4</tt>&nbsp;,<tt> </tt>   
and<tt> ⍴⊢⍤0⍵ </tt>
is<tt> 4&nbsp;5&nbsp;6&nbsp;7&nbsp;3</tt>&nbsp;. 
(The identity function<tt> ⊢ </tt>is 
defined in <a href="RationalizedAPL1.htm#j">Section J</a>.)</p>

<p>In the general case, the right argument 
of<tt> ⍥ </tt>has three elements, 
one to specify the transpose to be applied to 
each of the argument cases: monadic, left, and right. 
Each is enclosed, and a simple or abbreviated argument 
is extended as 
follows:<tt> f⍥i ←→ f⍥(⌽3⍴⌽⊃i)</tt>&nbsp;.<tt> </tt> 
Negative indexing of <b>axes</b> can be used, 
as, for example, 
in<tt> ⊢⍤¯2⍵ </tt>to interchange the last two axes.</p>

<p>The case<tt> i⍥f </tt>is defined similarly, 
except that the indicated axes are moved to the front. 
In conjunction with the identity function, 
the operator<tt> ⍥ </tt>can, as illustrated above, 
provide transpositions that would be much more 
awkward to write using the transpose function<tt> ⍉</tt>&nbsp;.</p>
<p>Derived functions produced 
by the function definition operator<tt> ∇ </tt>
are defined to have infinite rank.</p>



<br><a name="j"></a>
<p><b>J. New Functions</b></p>

<p>This section defines a number of new functions, 
most of which have been proposed in earlier papers. 
The main point is to illustrate the ease of definition 
provided by the joint use of direct definition 
and rank specification. 
The symbol<tt> ¯ </tt>is used to denote infinity:</p>

<table>
<tr><td valign=top><b>Name</b></td><td valign=top><b>Symbol</b></td>
 <td><b> &nbsp; &nbsp; &nbsp; Definition</b></td>
<tr><td valign=top>Dex     </td><td valign=top align=center><tt>⊢</tt></td>
 <td><tt>'⍵'∇'⍵'</tt></td></tr>
<tr><td valign=top>Lev     </td><td valign=top align=center><tt>⊣</tt></td>
 <td><tt>''∇'⍺'</tt></td></tr>
<tr><td valign=top>Nub/Cup </td><td valign=top align=center><tt>∪</tt></td>
 <td><tt>'((⍵⍳⍵)=⍳⍴⍵)/⍵←,⍵'∇'⍺,⍵' ⍤ ¯ 1 1</tt></td></tr>
<tr><td valign=top>Member  </td><td valign=top align=center><tt>∊</tt></td>
 <td><tt>'(∪⍵)∘.(∆⍤0)⍵'∇'∨/⍺≡⍤0,⍵' ⍤ ¯ 0 ¯</tt></td></tr>
<tr><td valign=top>Onub/Cap</td><td valign=top align=center><tt>∩</tt></td>
 <td><tt>'(,⍤0⍋∪⍵){∪⍵'∇'(⍺∊⍵)/⍺' ⍤ ¯ 1 1</tt></td></tr>
<tr><td valign=top>Not     </td><td valign=top align=center><tt>~</tt></td>
 <td><tt>'1-⍵'∇'(∆⍺∊⍵)/⍵' ⍤ 0 1 1</tt></td></tr>
<tr><td valign=top>CP/From </td><td valign=top align=center><tt>{</tt></td>
 <td><tt>m←'>∘.(,⍤0&nbsp;1)¨>/(<⍤>⍵),∘'
d←'>(⍳0)⍴⍤1(s⊥⍤1(s←n↑⍴⍵)|⍤1∆⍺)⌽⍤0&nbsp;1<br> &nbsp; &nbsp; &nbsp; ,<⍤((⍴⍴⍵)-n←⍴,⍺)⍵'<br>
m∇d⍤1 1 ¯
</tt></td></tr>
</table>

<p>The monadic case defined for<tt> ∊ </tt>is 
the <b>distribution</b> function defined in 
<acronym title="K.E. Iverson, Operators and Functions 
(IBM Corporation, RC7091, 1978)">[6]</acronym>; 
the function<tt> ≡ </tt>used in its definition is defined in 
<acronym title="K.E. Iverson, 
APL Syntax and Semantics (ACM, APL83)">[5]</acronym>, 
and yields a<tt> 1 </tt>if its arguments agree. 
The dyadic case of<tt> ~ </tt>is the set difference function.</p>

<p>The monadic case of<tt> { </tt>is the <b>Cartesian</b> 
product over the enclosed elements of its argument, 
and yields a result whose shape is the catenation 
of the shapes of<tt> (⍴¨>⍵),<⍴⍵</tt>&nbsp;.<tt> </tt>
For example:</p>

<pre>
      { 1 2 ⊃ 3 4 ⊃ 5
1 3 5
1 4 5

2 3 5 
2 4 5
</pre>

<p>The self-reference<tt> </tt>(<tt>∆</tt>)<tt> </tt>in the definition 
of the dyadic case is used to define the 
from function discussed in <a href="RationalizedAPL1.htm#a">Section A</a>; 
except for the complementary indexing 
provided by the use of doubly enclosed elements, 
this definition is complete.</p>



<br><a name="k"></a>
<p><b>K. Further Operators</b></p>

<p>The operators discussed in this section are 
not essential to the rationalization program 
for existing functions and operators carried out in Sections A-H. 
They do, however, constitute important extensions, 
and introduce one further notion, the placement of 
&ldquo;supernumerary&rdquo; axes produced in scans 
and similar &ldquo;partitionings&rdquo; along an axis. 
They also help to illuminate the
mnemonic schemes employed in the choice of 
operator symbols and in the disposition of operator arguments.</p>

<p>Because of the large number of functions 
required in a language, 
the adoption of mnemonic schemes 
(such as the use of a single symbol 
for related monadic and dyadic cases, 
for application to arrays of any rank and class, 
real or complex, as well as the use 
of a single operator with existing functions 
to obtain sums, products and maxima over arrays) 
can be an important aid to the user. 
Because a large number of operators will also be required, 
care should also be exercised in assigning symbols to them.</p>

<p>Since each argument of a dyadic operator 
may belong to either of two classes 
(function or variable), and since each derived function produced 
is ambivalent, each operator symbol can produce 
as many as eight classes of functions; 
various kinds of similarities can be employed 
to group these functions in mnemonically useful ways.</p>

<p>For example, the symbol<tt> ⍤ </tt>is called <b>on</b>, 
and the first entry in <a href="RationalizedAPL1.htm#xb">Appendix B</a> 
shows the use of different interpretations 
of the meaning of &ldquo;on&rdquo;: 
the case<tt> f⍤g </tt>is the application 
of<tt> f </tt>on the result of<tt> g </tt>   
(called <b>composition</b> in mathematics); 
the case<tt> f⍤i </tt>is the application of<tt> f </tt>  
on each of the pieces obtained 
by splitting the argument into subarrays 
of ranks determined by<tt> i</tt>&nbsp;;<tt> </tt>  
the case<tt> i⍤f </tt>is the application of<tt> f </tt>  
on pieces obtained by splitting the argument 
<b>along</b> an axis or axes 
in a manner determined by<tt> i</tt>&nbsp;<tt> </tt> 
and<tt> i⍤j </tt>is the <b>constant function</b> 
whose value is<tt> i</tt>&nbsp;,<tt> </tt> 
applied on subarrays of ranks 
determined by<tt> j</tt>&nbsp;.</p>

<p>In cases such as<tt> f⍤i </tt>
and<tt> i⍤f</tt>&nbsp;,<tt> </tt>
it is preferable to assign<tt> f⍤i </tt>
to the more commonly used case, because<tt> f </tt>
itself will often be a derived function, 
and an expression such as<tt> i⍤(+.×) </tt> 
requires parentheses, whereas<tt> +.×⍤i </tt>does not.</p>

<p>The symbol<tt> ⍥ </tt>in the second entry of 
<a href="RationalizedAPL1.htm#xb">Appendix B</a> is called upon: 
the case<tt> f⍥g </tt>denotes application 
of the monadic function<tt> f </tt>
upon the result of the dyadic function<tt> g</tt>&nbsp;,<tt> </tt>
the larger circle (as compared to<tt> ⍤</tt>&nbsp;),<tt> </tt>   
indicating the larger valence in the application 
of<tt> g</tt>&nbsp;;<tt> </tt>   
the cases<tt> f⍥i </tt>and<tt> i⍥f </tt>
concern the application of<tt> f </tt>
upon the result of a transpose 
(a function that also employs<tt> ○ </tt>in its symbol), 
the transpose moving the axes designated 
by<tt> i </tt>to the front if<tt> i </tt>
precedes the operator, 
and to the back if it follows.</p>

<p>Some of the relations among the cases 
of the operator denoted by the dot can 
be appreciated only by understanding 
that the inner product<tt> f.g </tt>is 
(except for a transposition of the left argument) 
a very special case of <b>tensor contraction</b> produced 
by combined use of the monadic and dyadic cases 
of the form<tt> f.i</tt>&nbsp;,<tt> </tt>   
as in<tt> +. 2 ⍺ ×. 2 ⍵</tt>&nbsp;,<tt> </tt> 
which &ldquo;runs together&rdquo; the first two axes 
of<tt> ⍺ </tt>and<tt> ⍵ </tt>
(forming an outer product between the rest), 
and then applies<tt> + </tt>reduction 
over axis<tt> 1 </tt>and axis<tt> 0</tt>&nbsp;,<tt> </tt> 
in that order. 
The equivalence of<tt> f. 0 </tt>and<tt> ∘.f </tt>
has already been remarked. For example:</p>

<pre>
      r←(2 3 4⍴⍳24)×. 2(2 3 5⍴⍳30)

      ⍴r
2 3 4 5

      -. 2 r
¯300 ¯312 ¯324 ¯336 ¯348
¯315 ¯327 ¯339 ¯351 ¯363
¯330 ¯342 ¯354 ¯366 ¯378
¯345 ¯357 ¯369 ¯381 ¯393

      -⌿-⌿⍤¯1  r
¯300 ¯312 ¯324 ¯336 ¯348
¯315 ¯327 ¯339 ¯351 ¯363
¯330 ¯342 ¯354 ¯366 ¯378
¯345 ¯357 ¯369 ¯381 ¯393
</pre>


<a name="k1"></a>
<p><b>Til.</b> <a href="RationalizedAPL1.htm#xb">Appendix B</a>
shows two cases for the <b>til</b> operator, 
denoted by<tt> }</tt>&nbsp;.<tt> </tt> 
The case<tt> f}i ⍵ </tt>is the<tt> i</tt>th power 
of<tt> f</tt>&nbsp;,<tt> </tt>
and<tt> f}(-j) ←→ f⊂}j</tt>&nbsp;,<tt> </tt>   
so that negative values of<tt> j </tt>
give powers of the inverse function. 
Moreover, if<tt> i≥0</tt>&nbsp;,<tt> </tt>
then<tt> f}i </tt>has rank<tt> mf</tt>&nbsp;;<tt> </tt>   
if<tt> i<0 </tt>it has the rank of the inverse 
function<tt> f⊂</tt>&nbsp;.</p>

<p>The second case<tt> f}g </tt>has 
ranks<tt> mg</tt>&nbsp;,<tt> rf</tt>&nbsp;,<tt> </tt>
and<tt> mg</tt>&nbsp;,<tt> </tt>  
and is defined as follows:</p>

<pre>
      ⍺ f}g ⍵ ←→ (g⍵)f⍺
        f}g ⍵ ←→ (g⍵)f⍵
</pre>

<p>As remarked in 
<acronym title="Arthur Whitney and Kenneth E. Iverson, 
Practical Uses of a Model of APL,
(APL Quote Quad, Volume 13, Number 1, 
Proceedings of APL82, ACM, New York 1982)">[9]</acronym>, 
the case a<tt> f}g}h ⍵ </tt> 
is equivalent to<tt> (g⍵)f(h⍵) </tt>
and is therefore very useful. 
It was also stated that<tt> ⍺f}⊢⍵ </tt>
is equivalent to<tt> ⍺f⊂⍵</tt>&nbsp;;<tt> </tt>
although true in some instances, 
this is not true in general 
because the rank of the identity function<tt> ⊢ </tt>
(which is infinite) may differ 
from the left rank of<tt> f</tt>&nbsp;.</p>

<a name="k2"></a>
<p><b>Dot.</b> In <a href="RationalizedAPL1.htm#f">Section F</a>, 
the dot operator, conventionally 
defined only for the case<tt> f.g</tt>&nbsp;,<tt> </tt>
was extended to the case<tt> f.k</tt>&nbsp;,<tt> </tt>   
but only the dyadic case 
of the derived function was defined. 
The monadic case<tt> f.k ⍵ </tt> 
is defined as<tt> k </tt>  
successive reductions of the 
form<tt> f⌿⍤r</tt>&nbsp;.<tt> </tt>
For example:<tt> f.&nbsp;3 ⍵ ←→ f⌿ f⌿⍤¯1 f⌿⍤¯2 ⍵</tt>&nbsp;.<tt> </tt>
It should be noted that this definition 
ensures that the reduction must take place 
over the<tt> k </tt>successive axes, 
whereas any one of a succession 
of reductions of the form<tt> f/⍥0 f/⍥1 f/⍥2 </tt>
might (because of the characteristics 
of the arbitrary function<tt> f</tt>&nbsp;)<tt> </tt>   
entirely change all axes of its argument.</p>

<p>As noted earlier, the monadic and 
dyadic cases of<tt> f.k </tt>
together provide the contraction 
used in tensor analysis.</p>


<a name="k3"></a>
<p><b>Supernumerary axes.</b> Certain operators 
produce derived functions that may introduce 
one or more <b>supernumerary</b> axes 
in addition to the axes produced 
by the particular function to which 
the particular operator is applied. 
These supernumerary axes may be defined either 
to precede or follow the normal result axes 
of the function, the whole collection following, 
of course, the outer axes of the argument 
to which the derived function is applied.</p>

<p>For example, scan introduces 
one extra axis contributed 
by applying reduction to each of a set of 
partitions of the argument, 
and a general derivative operator applied 
to a function of rank<tt> r </tt>
introduces<tt> r </tt>extra axes 
(for differentiation with respect 
to each element of the argument).</p>

<a name="k4"></a>
<p><b>Scan.</b> Each scan operator behaves like the 
corresponding reduction operator, 
and places the supernumerary axis first if the split 
(in the reduction) is along the first axis, 
and last if the split is along the last axis. 
This definition provides conformity with conventional APL.</p>

<a name="k5"></a>
<p><b>Cut Operator.</b> With an integer left 
argument<tt> k</tt>&nbsp;,<tt> </tt>
the operator<tt> ⍤ </tt>provides 
a family of derived functions 
such that<tt> k⍤f </tt>applies<tt> f </tt>to 
pieces cut from its right argument, 
the pieces being determined by the left argument or, 
in the monadic case, by the right argument itself. 
The right ranks of all cases are infinite.</p>

<p>There are seven cases:<tt> k=0 </tt>
provides the general case, 
in terms of which each of the others 
can be expressed rather easily. 
Its left rank is<tt> 2</tt>&nbsp;,<tt> </tt>and<tt> f </tt>
is applied to a rectangle of size<tt> |1{⍺ </tt>
beginning at<tt> 0{⍺ </tt>or, more precisely, 
to the rectangle<tt> r </tt>selected as follows:</p>

<pre>
      r←((((¯1↑⍴⍺)↑⍴⍵)|0{⍺)+¨>⍳¨>|1{⍺){⍵
</pre>

<p>Before applying<tt> f</tt>&nbsp;,<tt> </tt>the piece<tt> r </tt>is 
reversed along each axis for which the specified size 
(that is,<tt> 1{⍺</tt>&nbsp;)<tt> </tt>is negative.</p>

<p>Note that both negative and abbreviated 
indexing may be used in<tt> 0{⍺ </tt>
to specify the position of the selected rectangle, 
and that reversals may be specified 
by negative elements in<tt> 1{⍺</tt>&nbsp;.</p>

<p>The degenerate  case of a vector left argument<tt> ⍺ </tt>
is treated as<tt> ⍉0,⍤0⍺</tt>&nbsp;,<tt> </tt>
so as to select a piece of size<tt> ⍺ </tt>
beginning at the origin. 
The monadic case<tt> 0⍤f ⍵ </tt>is equivalent 
to<tt> (⍴⍴⍵)⍴⌊/⍴⍵)0⍤f ⍵</tt>&nbsp;,<tt> </tt> 
that is, it selects the &ldquo;maximal cube&rdquo; 
from<tt> ⍵</tt>&nbsp;.</p>

<p>The cases<tt> ⍺ 1⍤f ⍵ </tt>and<tt> ⍺ ¯1⍤f ⍵ </tt> 
both apply<tt> f </tt>to pieces obtained 
by splitting<tt> ⍵</tt>&nbsp;,<tt> </tt> 
along the leading axis, into segments
<b>beginning</b> at each<tt> 1 </tt>
in the boolean vector left 
argument<tt> ⍺</tt>&nbsp;,<tt> </tt>
the element at each cutpoint being included in the case 
of<tt> 1⍤f</tt>&nbsp;,<tt> </tt>and excluded in the 
case<tt> ¯1⍤f</tt>&nbsp;.<tt> </tt>
The supernumerary axis introduced is 
placed before the individual results. 
A &ldquo;short&rdquo; left argument<tt> ⍺ </tt>
is extended cyclically by<tt> (1↑⍴⍵)⍴⍺</tt>&nbsp;.</p>

<p>The left ranks of the functions<tt> 1⍤f </tt>and<tt> ¯1⍤f </tt>
are<tt> 1</tt>&nbsp;,<tt> </tt>and extension 
to higher ranks is made in the usual way. 
The monadic cases are equivalent to the dyadics 
with a left argument of<tt> (0{⍵)≡⍤¯ ¯1 ⍵</tt>&nbsp;,<tt> </tt>   
that is, splits begin at occurrences of the 
&ldquo;delimiter&rdquo; specified by the leading subarray 
of<tt> ⍵</tt>&nbsp;.</p>

<p>The cases<tt> 2⍤f </tt>and<tt> ¯2⍤f </tt>differ 
from the foregoing only in that each<tt> 1 </tt>
in the left argument 
determines the <b>end</b> of a segment, 
and that the delimiter in the monadic case 
is the <b>last</b> subarray of<tt> ⍵</tt>&nbsp;,<tt> </tt>
namely,<tt> ¯1{⍵</tt>&nbsp;.</p>

<p>The remaining cases,<tt> 3⍤f </tt>
and<tt> ¯3⍤f</tt>&nbsp;,<tt> </tt> 
provide (possibly overlapping) tessellations. 
The left rank is<tt> 2</tt>&nbsp;,<tt> </tt> 
and the expression<tt> ⍺ ¯3⍤f ⍵ </tt>applies<tt> f </tt>
to each <b>complete</b> rectangle of size<tt> |1{⍺ </tt>obtained 
by beginning at all positions obtained 
as integer multiples of (each element of) 
the <b>movement</b> vector<tt> 0{⍺</tt>&nbsp;.<tt> </tt>
As in the case<tt> O⍤f</tt>&nbsp;,<tt> </tt> 
reversal of each piece occurs along the axis 
for which the &ldquo;window&rdquo;<tt> 1{⍺ </tt>is negative.</p>

<p>The degenerate case of a vector<tt> ⍺ </tt> 
is equivalent to the left 
argument<tt> ⍉1,⍤0⍺</tt>&nbsp;,<tt> </tt> 
and therefore provides a complete tessellation 
of size<tt> ⍺</tt>&nbsp;.<tt> </tt> 
The monadic case provides tessellation 
by &ldquo;maximal cubes&rdquo; 
having the size<tt> (⍴⍴⍵)⍴⌊/⍴⍵</tt>&nbsp;.</p>

<p>The case<tt> 3⍤f </tt>differs from<tt> ¯3⍤f </tt>
only in that any &ldquo;shards&rdquo; of sizes 
less than<tt> |1{⍺ </tt>are included.</p>


<a name="k6"></a>
<p><b>With.</b> If the ranks of the arguments<tt> i </tt>
and<tt> j </tt>in the expressions<tt> i¨f ⍵ </tt>
and<tt> f¨j ⍵ </tt>are equal to the left and right 
ranks of<tt> f</tt>&nbsp;,<tt> </tt>   
then the definitions are straightforward:</p>

<pre>
      i¨f ⍵ ←→ i f ⍵  
      f¨j ⍵ ←→ ⍵ f j 
</pre>

<p>However, arguments<tt> i </tt>and<tt> j </tt>
of greater rank introduce axes which are placed 
before the individual results. 
Consequently, the derived functions behave 
more like outer products of<tt> f </tt>
than like direct applications of<tt> f</tt>&nbsp;.<tt> </tt> 
For example, if<tt> a←1&nbsp;2&nbsp;3</tt>&nbsp;,<tt> </tt>
then<tt> a¨+a ←→ a∘.+a</tt>&nbsp;.</p>


<a name="k7"></a>
<p><b>Compression.</b> The definitions of the derived 
functions<tt> i/ </tt>and<tt> i⌿ </tt>
(called <b>compression</b> or <b>replication</b>) 
are based upon a vector argument<tt> i</tt>&nbsp;.<tt> </tt>   
The effect of<tt> i⌿⍵ </tt>is to split<tt> ⍵ </tt>  
along its <b>first</b> axis, select subarrays determined 
by<tt> i</tt>&nbsp;,<tt> </tt> 
and array them along a supernumerary axis 
that is placed <b>first</b>; the effect of<tt> i/⍵ </tt>  
is to split along the <b>last</b> axis 
and to place the supernumerary axis <b>last</b>.</p>

<p>An argument<tt> i </tt>of rank greater than<tt> 1 </tt>
will introduce further axes that are placed <b>first</b> in 
both<tt> i/⍵ </tt>and<tt> i⌿⍵</tt>&nbsp;.<tt> </tt> 
Dyadic cases of<tt> i/ </tt>and<tt> i⌿ </tt>
should also be defined, with negative values 
in<tt> i </tt>providing selection from the left argument
<acronym title="APL2 Introduction Manual 
(IBM Corporation, SB21 3039, June 1982)">[10]</acronym>.</p>



<br><a name="l"></a>
<p><b>L. Summary</b></p>

<p>The proposals essential to the rationalization program 
described in the introduction can be summarized as follows:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
The enclose function<tt> < </tt>provides lists 
which are used as arguments to a normal indexing function 
(<tt>{</tt>&nbsp;,<tt> </tt>called <b>from</b>) to provide 
&ldquo;scattered&rdquo;, &ldquo;complementary&rdquo;, 
&ldquo;abbreviated&rdquo;, 
and &ldquo;negative&rdquo; indexing, 
as well as all of the facilities provided 
by conventional indexing. 
The dyadic case of<tt> i¨{ </tt>provides a merge 
that obviates indexed assignment.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
The extension of<tt> ← </tt>to allow any APL entity 
to its right provides convenient name assignment 
for functions and operators as well as variables.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
The definition operator<tt> ∇ </tt>provides 
convenient definition of independent 
monadic and dyadic cases of functions.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
The syntax rules are extended to operators 
(to give them &ldquo;long left scope&rdquo;) 
by a table shown in <a href="RationalizedAPL1.htm#e">Section E</a>. 
The recognition of cases, and the corresponding evaluations, 
involve only the first four elements of the execution stack.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
<p>A uniform scheme for extending functions to 
higher-rank arrays is provided by assigning to 
each function<tt> f </tt>four primary attributes 
that determine its application to any arguments: 
a monadic rank<tt> mf</tt>&nbsp;,<tt> </tt>
a left rank<tt> lf</tt>&nbsp;,<tt> </tt>    
a right rank<tt> rf</tt>&nbsp;,<tt> </tt>
and a conformance<tt> cf</tt>&nbsp;.</p>

<p>In the normal case of arguments 
of sufficiently high rank, the function applies 
to the &ldquo;low-order&rdquo; subarrays of appropriate rank 
to produce individual results of a common 
shape<tt> sir</tt>&nbsp;,<tt> </tt>   
the shape of the overall result of<tt> ⍺ f ⍵ </tt>being:</p>

<p><tt>&nbsp; (cf↑⍴⍺),(cf↓(-lf)↓⍴⍺),(cf↓(-rf)↓⍴⍵),sir</tt></p>

<p>The conformability imposed on the arguments 
is that<tt> cf↑⍴⍺ </tt>must 
equal<tt> cf↑⍴⍵</tt>&nbsp;,<tt> </tt>   
or that at least one must be <b>single</b>, 
(i.e., having a shape<tt> s </tt>
such that<tt> 1=×/s</tt>&nbsp;).</p>
</td></tr>
</table>
<br>



<br><a name="xa"></a>
<p><b>Appendix A. Ranks of Primitive Functions</b></p>

<p>The following table shows the proposed ranks for 
all primitive APL functions except the scalar functions, 
whose ranks are all zero. 
The ranks are shown in the order monadic, left, and right, 
with an overbar denoting infinite rank. 
The indices in the left column refer to 
notes following the table. 
The notes employ<tt> aO </tt>and<tt> bO </tt>to denote 
scalars,<tt> a1 </tt>and<tt> b1 </tt>to denote vectors, etc.</p>

<p>The proposed ranks were chosen in the light 
of the following general considerations:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
<b>Infinite</b>, or <b>unbounded</b> rank will always allow 
compatibility with existing definitions, 
since the <b>degenerate</b> cases 
(of arguments having rank less than the maximum 
imposed by the stated rank of the function) 
can be defined as desired. 
Wherever necessary, infinite rank is chosen.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
The minimum possible rank is preferred 
because it allows the simplest definition 
of the function, 
the definition for arguments of higher rank 
following from the general extension rule.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
Questions concerning the possibly differing shapes 
of individual results (which, for example, 
precluded the inclusion of dyadic 
query<tt> </tt>(<tt>?</tt>)<tt> </tt>
among the scalar functions) are ignored 
because <b>close composition</b> can be used 
to produce individual results of a common shape. 
For example,<tt> a<⍥?b </tt>produces 
individual scalar results 
which are enclosed vectors of (possibly) 
differing lengths.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
Because of anomalies in its syntax and its definition, 
the &ldquo;bracket axis operator&rdquo; is not 
included among operators whose definitions 
depend upon the ranks of their function arguments. 
Consequently, the definitions of expressions 
involving the bracket operator are left strictly unchanged, 
and their behaviour does not figure 
in the choice of ranks made here.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
Because of anomalies in its syntax and its definition, 
the &ldquo;bracket indexing function&rdquo; is not included 
among the functions to which operators apply, 
and no attempt will be made to define its rank.
</td></tr>
</table>

<br>

<table align=center><tr><td valign=top><table>
<tr><td align=right>Note</td><td>&nbsp; &nbsp;</td><td align=right><tt>f</tt></td><td>&nbsp; &nbsp;</td>
 <td><tt>m</tt></td><td>&nbsp;</td><td><tt>l</tt></td><td>&nbsp;</td><td><tt>r</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>< </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>0</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>> </tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>0</tt></td></tr>
<tr><td align=right>1</td> <td>&nbsp;</td><td align=right><tt>⍴ </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>2</td> <td>&nbsp;</td><td align=right><tt>, </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>3</td> <td>&nbsp;</td><td align=right><tt>⌽ </tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>2</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>⊖ </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>4</td> <td>&nbsp;</td><td align=right><tt>⍉ </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>5</td> <td>&nbsp;</td><td align=right><tt>↑↓</tt></td><td>&nbsp;</td><td>&nbsp;</td>    <td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>6</td> <td>&nbsp;</td><td align=right><tt>⍳ </tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>0</tt></td></tr>

</table></td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</tt></td><td valign=top><table>

<tr><td align=right>Note</td><td>&nbsp; &nbsp;</td><td align=right><tt>f</tt></td><td>&nbsp; &nbsp;</td>
 <td><tt>m</tt></td><td>&nbsp;</td><td><tt>l</tt></td><td>&nbsp;</td><td><tt>r</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>∊ </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>⍋⍒</tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>7</td> <td>&nbsp;</td><td align=right><tt>? </tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>0</tt></td><td>&nbsp;</td><td><tt>0</tt></td></tr>
<tr><td align=right>8</td> <td>&nbsp;</td><td align=right><tt>⌹ </tt></td><td>&nbsp;</td><td><tt>2</tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>2</tt></td></tr>
<tr><td align=right>9</td> <td>&nbsp;</td><td align=right><tt>⊥ </tt></td><td>&nbsp;</td><td>&nbsp;</td>    <td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>⊤ </tt></td><td>&nbsp;</td><td>&nbsp;</td>    <td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
<tr><td align=right>10</td><td>&nbsp;</td><td align=right><tt>⍕ </tt></td><td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>2</tt></td><td>&nbsp;</td><td><tt>1</tt></td></tr>
<tr><td align=right>11</td><td>&nbsp;</td><td align=right><tt>⍎ </tt></td><td>&nbsp;</td><td><tt>1</tt></td><td>&nbsp;</td><td>&nbsp;</td>    <td>&nbsp;</td><td>&nbsp;</td>    </tr>
<tr><td>&nbsp;</td>        <td>&nbsp;</td><td align=right><tt>≡ </tt></td><td>&nbsp;</td><td>&nbsp;</td>    <td>&nbsp;</td><td><tt>¯</tt></td><td>&nbsp;</td><td><tt>¯</tt></td></tr>
</table></td></tr></table>


<p align=center><b>Ranks of Primitive Functions<br>Table 1</b></p> 

<p><b>Notes</b></p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
The degenerate case<tt> a0⍴b </tt>is defined as in conventional APL.
 <br>&nbsp;</td></tr>

<tr><td valign=top>2.</td><td>&nbsp;</td><td>
Ranks<tt> 1 1 </tt>for dyadic 
could have been considered 
because they work for all cases 
of the form<tt> a2,b2 </tt> 
and<tt> a3,b3</tt>&nbsp;,<tt> </tt>
but they would not agree 
with the present definition of cases such 
as<tt> a2,b1 <tt>and<tt> a3,b2</tt>&nbsp;.
 <br>&nbsp;</td></tr>

<tr><td valign=top>3.</td><td>&nbsp;</td><td>
Ranks<tt> 0 1 </tt>for dyadic would be preferable, 
but would require a change in the present definition, 
since<tt> ((k⍴1)⍴s)⌽⍳n </tt>is now permitted, 
and yields a result of shape<tt> n </tt>rather 
than<tt> (kp1),n</tt>&nbsp;.<tt> </tt> 
Ranks<tt> 1 2 </tt>could provide compatibility 
with the most commonly used case 
of<tt> k=1</tt>&nbsp;.<tt> </tt>   
Either choice clearly shows the unit 
difference in rank required of arguments to the function.
 <br>&nbsp;</td></tr>

<tr><td valign=top>4.</td><td>&nbsp;</td><td>
The degenerate case<tt> a0⍉bk </tt>
will remain as it is.
 <br>&nbsp;</td></tr>

<tr><td valign=top>5.</td><td>&nbsp;</td><td>
The degenerate cases<tt> a0↓b1 </tt>and<tt> a0↑b1 </tt>
will remain as in conventional APL.
 <br>&nbsp;</td></tr>
<tr><td valign=top>6.</td><td>&nbsp;</td><td>
<p>Rank<tt> 0 </tt>for the monadic case would introduce 
an unmanageable anomaly in the present 
permissive treatment of the case<tt> ⍳a1←,a0 </tt>  
since the result would necessarily have 
an outer shape of<tt> 1</tt>&nbsp;.</p>

<p>Moreover, rank<tt> 1 </tt>would allow (or even suggest) 
the extension to the &ldquo;odometer&rdquo; 
function such that<tt> ⍳a1 </tt>yields 
a result of shape<tt> a1,⍴a1 </tt> 
containing (along its last axis) 
all indices of an array of 
shape<tt> a1</tt>&nbsp;.<tt> </tt>
The present anomalous treatment 
of the case where<tt> ⍴a1 </tt>is<tt> 1 </tt>
could be maintained.</p>

<p>For the dyadic case, the ranks<tt> ¯ 0 </tt>
would allow the production of vector indices 
to an array of any rank. 
For example,<tt> (3&nbsp;3⍴⍳9)⍳2&nbsp;3&nbsp;4 </tt>
would (in<tt> 0</tt>-origin) produce the 
matrix<tt> 3&nbsp;2⍴0&nbsp;2&nbsp;1&nbsp;0&nbsp;1&nbsp;1</tt>&nbsp;.<tt> </tt> 
However, this would imply that the indices 
to a vector should produce an array 
of one-element vectors, and 
that the shape of<tt> a1⍳ak </tt>
would be<tt> (⍴ak),1 </tt>
rather than<tt> ⍴ak </tt>as it now is. 
Compatibility could, of course, 
be obtained by treating a vector left argument 
as a special degenerate case.<br>&nbsp;</p>
 </td></tr>

<tr><td valign=top>7.</td><td>&nbsp;</td><td>
<p>Rank<tt> 0&nbsp;0 </tt>is preferred for the dyadic case, 
but may be precluded by the permissive use 
of one-element vector arguments, 
since it would make the 
cases<tt> a0?b1</tt>&nbsp;,<tt> a1?b0</tt>&nbsp;,<tt> </tt>
and<tt> a1?b1 </tt>  
differ from<tt> a0?b0 </tt>by an added<tt> 1 </tt>
in the shape vector. 
However, it is possible that the use 
of the deal function is as yet infrequent enough 
to permit the necessary change in its definition.</p>

<p>The choice of rank<tt> 1&nbsp;1 </tt>would make it possible 
to continue the present anomalies for degenerate cases. 
Although this choice makes the function less versatile, 
it should be noted that the &ldquo;correct&rdquo; behaviour 
would be easily obtained in the derived 
function<tt> ?⍤0</tt>&nbsp;.<br>&nbsp;</p>
 </td></tr>

<tr><td valign=top>8.</td><td>&nbsp;</td><td>
Since<tt> a2⌹b2 ←→ (⌹b2)+.×a2</tt>&nbsp;,<tt> </tt> 
the result is a collection of results 
for the columns of<tt> a2</tt>&nbsp;,<tt> </tt>   
and a left rank of<tt> 1 </tt>cannot, therefore, 
be compatible with the conventional definition.
 <br>&nbsp;</td></tr>

<tr><td valign=top>9.</td><td>&nbsp;</td><td>
Because<tt> ⊥ </tt>applies to vectors 
along the leading (rather than the trailing) 
axis of the right argument, 
a bounded right rank cannot 
give compatible results.
 <br>&nbsp;</td></tr>

<tr><td valign=top>10.</td><td>&nbsp;</td><td>
A left rank of<tt> 2 </tt>will accomodate a matrix 
whose two columns specify decimal point and width. 
The degenerate vector case would be treated 
as in conventional APL.
 <br>&nbsp;</td></tr>

<tr><td valign=top>11.</td><td>&nbsp;</td><td>
Treating execute as a normal function 
of rank<tt> 1 </tt>could be very useful. 
For example, if<tt> a2 </tt>is numeric, 
then<tt> ⍎b2←⍕a2 </tt>would 
yield<tt> a2</tt>&nbsp;.<tt> </tt>   
However, since the arguments 
of<tt> ⍎ </tt>may be expressions 
which produce side-effects, 
and since the order of applying any function 
to its cells is not prescribed, 
the results could be unpredictable. 
Similar remarks apply to the 
function<tt> ? </tt>
because of the side-effect produced 
by the re-specification of<tt> ⎕rl</tt>&nbsp;.
 <br>&nbsp;</td></tr>
</table>



<br><a name="xb"></a>
<p><b>Appendix B. Table of Dyadic Operators</b></p>

<p>The following conventions are used:</p>

<p><tt>i </tt>and<tt> j </tt>denote variables, 
and<tt> f </tt>and<tt> g </tt>functions.</p>

<p><tt>mf</tt>&nbsp;,<tt> lf</tt>&nbsp;,<tt> </tt>
and<tt> rf </tt>denote monadic, left, 
and right ranks of<tt> f </tt>and<tt> af </tt>
denotes all ranks of<tt> f</tt>.</p>

<p>The monadic derived function is shown 
to the left of the dyadic.</p>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt> &nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>⍤</tt><br>On</td><td><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td valign=top align=center width=130>Constant<tt> i </tt>on<br><tt> j </tt>cells</td>
 <td width=260><table>
  <tr><td colspan=5 align=center>Cuts</td></tr>
  <tr><td>Cube</td><td>&nbsp; &nbsp; &nbsp;</td><td><tt>&nbsp; &nbsp;0</tt></td>
   <td>&nbsp; &nbsp; &nbsp;</td><td>General</td></tr>
  <tr><td>Begin at<tt> 0{⍵</tt></td><td>&nbsp;</td><td><tt>1 ¯1</tt></td>
   <td>&nbsp;</td><td>Begin at<tt> 1</tt>&rsquo;s</td></tr>
  <tr><td>End at&nbsp;<tt> ¯1{⍵</tt></td><td>&nbsp;</td><td><tt>2 ¯2</tt></td>
   <td>&nbsp;</td><td>End at<tt> 1</tt>&rsquo;s</td></tr>
  <tr><td>Cubic</td><td>&nbsp;</td><td><tt>3 ¯3</tt></td>
   <td>&nbsp;</td><td>Tesselation</td></tr>
  <tr><td colspan=5 align=center>Include shards or cutpoints<br>
    if<tt> i </tt>is positive</td></tr>
 </table></td></tr>
<tr><td valign=top align=center><tt>f </tt>on rank<tt> j </tt>
<br>cells</td>
 <td><table align=center>
  <tr><td align=center width=120><tt>f g ⍵ </tt></td><td>|</td><td align=center width=120><tt>(g⍺)f(g⍵)</tt></td></tr>
  <tr><td align=center width=120>&nbsp;</td>         <td>|</td><td align=center width=120>&nbsp;</td></tr>
  <tr><td colspan=3 align=center>Ranks are<tt> mg</tt></td></tr>
 </table></td></tr>
</table></td></tr>
<tr><td><tt>f</tt></td></tr>
</table>

<br>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>⍥</tt><br>Upon</td><td>&nbsp;<br><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td valign=top width=130>&nbsp;</td>
 <td align=center>Axis<tt> i </tt>to front and<br>apply<tt> g </tt></td></tr>
<tr><td valign=top align=center>Axis<tt> j </tt>to rear and<br>apply<tt> f </tt></td>
 <td width=260><table align=center>
  <tr><td align=center width=120><tt>f g ⍵ </tt></td><td>|</td><td align=center width=120><tt>f ⍺ g ⍵</tt></td></tr>
  <tr><td align=center width=120>&nbsp;</td>         <td>|</td><td align=center width=120>&nbsp;</td></tr>
  <tr><td colspan=3 align=center>Ranks are<tt> ag</tt></td></tr>
 </table></td></tr>
</table></td></tr>
<tr><td><br>&nbsp;<br><tt>f</tt><br>&nbsp;<br>&nbsp;</td></tr>
</table>

<br>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>¨</tt><br>With</td><td>&nbsp;<br><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td valign=top width=130>&nbsp;</td>
 <td><table align=center>
  <tr><td align=center width=120><tt>i g ⍵</tt></td>     <td>|</td><td align=center width=120>Some special</td></tr>
  <tr><td align=center width=120>Rank is<tt> rg</tt></td><td>|</td><td align=center width=120>cases:<tt> i¨{</tt></td></tr>
  </table></td></tr>
<tr><td><table align=center>
  <tr><td align=center><tt>⍵ f j &nbsp;</tt></td><td>|</td><td>&nbsp;</td></tr>
  <tr><td align=center>&nbsp;</td>               <td>|</td><td>&nbsp;</td></tr>
  <tr><td colspan=3 align=center>Rank is<tt> lf </tt></td></tr>
  </table></td>
 <td width=260><table align=center>
  <tr><td align=center width=120><tt>(g⊂)f g ⍵</tt></td><td>|</td><td align=center width=120><tt>(g⊂)(g⍺)f g ⍵</tt></td></tr>
  <tr><td align=center width=120>&nbsp;</td>            <td>|</td><td align=center width=120>&nbsp;</td></tr>
  <tr><td colspan=3 align=center>Rank is<tt> mg</tt></td></tr>
 </table></td></tr>
</table></td></tr>
<tr><td><br>&nbsp;<br><tt>f</tt><br>&nbsp;<br>&nbsp;</td></tr>
</table>

<br>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>.</tt><br>Dot</td><td>&nbsp;<br><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td valign=top width=130>&nbsp;</td>
 <td><table align=center>
  <tr><td width=120>&nbsp;</td><td>|</td><td align=center width=120><tt>∘.g</tt></td></tr>
  </table></td></tr>
<tr><td><table align=center>
  <tr><td align=center><tt>j</tt> Reductions:</td><td>|</td><td align=center>Conform-</td></tr>
  <tr><td align=center><tt>f⌿f⌿⍤1f⌿...</tt></td>  <td>|</td><td align=center>ance<tt> j</tt></td></tr>
  </table></td>
 <td width=260><table align=center>
  <tr><td align=center width=120>Determinant</td><td>|</td><td align=center width=120>Inner</td></tr>
  <tr><td align=center width=120>&nbsp;</td>     <td>|</td><td align=center width=120>Product</td></tr>
 </table></td></tr>
</table></td></tr>
<tr><td><br>&nbsp;<br><tt>f</tt><br>&nbsp;<br>&nbsp;</td></tr>
</table>

<br>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>}</tt><br>Til</td><td>&nbsp;<br><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td valign=top width=130>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><table align=center>
  <tr><td align=center><tt>j</tt>th power of<tt> f</tt></td><td>|</td><td>&nbsp;</td></tr>
  <tr><td align=center>&nbsp;</td>                          <td>|</td><td>&nbsp;</td></tr>
  <tr><td align=center>&nbsp;</td>                          <td>|</td><td>&nbsp;</td></tr>
  </table></td>
 <td width=260><table align=center>
  <tr><td align=center width=120><tt>(g⍵)f ⍵</tt></td><td>|</td><td align=center width=120><tt>(g⍵)f ⍺</tt></td></tr>
  <tr><td align=center width=120>rank<tt> mg</tt></td><td>|</td><td align=center width=120>right<tt> mg</tt></td></tr>
  <tr><td align=center width=120>&nbsp;</td>          <td>|</td><td align=center width=120>left<tt> rf</tt></td></tr>
 </table></td></tr>
</table></td></tr>
<tr><td><br>&nbsp;<br><tt>f</tt><br>&nbsp;<br>&nbsp;</td></tr>
</table>

<br>

<table>
<tr><td>&nbsp;</td><td>&nbsp;</td><td><tt>&nbsp; &nbsp; &nbsp; &nbsp; j &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g</td></tr>
<tr><td rowspan=2 valign=top width=60><tt>∇</tt><br>Del</td><td><tt>i</tt></td>
 <td rowspan=2>
<table border=1 cellspacing=0 cellpadding=5>
<tr><td align=center width=130>Direct Definition</td><td width=260>&nbsp;</td></tr>
<tr><td align=center><tt>j</tt>th derivative</td><td>&nbsp;</td></tr>
</table></td></tr>
<tr><td><tt>f</tt></td></tr>
</table>

<br>


<br><a name="xc"></a>
<p><b>Appendix C. Examples and Brief Definitions</b></p>

<p>This appendix provides loose definitions 
and numerous examples of use of the functions 
and operators defined more formally in the body of the paper. 
This appendix may be read first, 
although it is probably best to make concurrent reference 
to the body as desired. 
The ideas introduced in Sections B to E 
(<a href="RationalizedAPL1.htm#b">Name Assignment</a>, 
<a href="RationalizedAPL1.htm#c">Function Valence</a>, 
<a href="RationalizedAPL1.htm#d">Function Definition</a>, 
and <a href="RationalizedAPL1.htm#e">Syntax and Order of Execution</a>) 
will be treated only indirectly 
by using them in the discussion of other topics.</p>

<p>The following functions will be used in examples:</p>

<table>
<tr><td valign=top>Enclose</td><td>&nbsp;</td>
 <td valign=top><tt>&lt;</tt>&nbsp;</td><td>&nbsp;</td>
 <td valign=top><tt>⍴⍴&lt;a ←→ 0</tt>&nbsp;,<tt> </tt>
and<tt> >&lt;a ←→ a</tt>&nbsp;,<tt> </tt>   
and<tt> &lt;a </tt>is called a <b>non-simple</b> array.
 <br>&nbsp;</td></tr>
<tr><td valign=top>Disclose</td><td>&nbsp;</td>
 <td valign=top><tt>&gt;</tt>&nbsp;</td><td>&nbsp;</td>
 <td valign=top>Inverse of<tt> <</tt>&nbsp;,<tt> </tt>
but applies to each element of its argument.
 <br>&nbsp;</td></tr>
<tr><td valign=top>Link</td><td>&nbsp;</td>
 <td valign=top><tt>⊃</tt>&nbsp;</td><td>&nbsp;</td>
 <td valign=top><table>
  <tr><td><tt>⊃⍵</tt>&nbsp;</td> <td>&nbsp;<tt>←→</tt>&nbsp;<td><tt>&lt;⍵ </tt>if<tt> ⍵ </tt>is simple</td></tr>
  <tr><td>&nbsp;</td>            <td>&nbsp;<tt>←→</tt>&nbsp;<td><tt>&nbsp;⍵ </tt>if<tt> ⍵ </tt>is non-simple</td></tr>
  <tr><td><tt>⍺⊃⍵</tt>&nbsp;</td><td>&nbsp;<tt>←→</tt>&nbsp;<td><tt>(<⍺),⊃⍵</tt>&nbsp;</td></tr>
 </table>
 </td></tr>
</table>

<p>The examples shown in this appendix were executed by 
the function<tt> apl </tt>in workspace<tt> 705 model</tt>&nbsp;.<tt> </tt>   
<tt>0</tt>-origin indexing is assumed thoughout, 
and infinity is denoted by the overbar<tt> ¯</tt>&nbsp;.</p>


<a name="xc1"></a>
<p><b>Function Ranks and Disposition of Axes</b></p>

<p>Function rank is the most important notion 
needed to provide a simple and systematic basis 
for the uniform treatment of all &ldquo;mixed&rdquo; 
or non-scalar functions. 
It is also relatively difficult to grasp: 
although the rules for rank are simple, 
their consequences are neither obvious 
nor inconsequential, and the reader unfamiliar 
with function rank should carefully 
study the simple examples of its use, 
in preparation for the more complex 
and more rewarding uses in dyadic functions 
and in conjunction with operators such as composition and dual.</p>

<p>If<tt> f </tt>has rank<tt> r</tt>&nbsp;,<tt> </tt>
then<tt> f⍵ </tt>is determined by applying<tt> f </tt> 
to each of the &ldquo;cells&rdquo; 
of shape<tt> (-r)↑⍴⍵</tt>&nbsp;,<tt> </tt> 
producing a common shape<tt> s </tt>for each, 
and assembling the whole into a result of 
shape<tt> ((-r)↓⍴⍵),s</tt>&nbsp;.<tt> </tt> 
In other words, the argument<tt> ⍵ </tt>is treated as 
an array of <b>outer shape</b><tt> (-r)↓⍴⍵ </tt>of cells 
of shape<tt> (-r)↑⍴⍵</tt>&nbsp;,<tt> </tt>
and the (common) shape of the result 
of applying<tt> f </tt> 
to any cell is placed last in the shape 
of the overall result.</p>

<p>Every function has an assigned rank. 
Thus<tt> &lt; </tt>has rank<tt> 0 </tt>
(i.e., applies to each scalar), 
and<tt> &gt; </tt>has <b>infinite</b>, or <b>unbounded</b> rank, 
applying to its entire argument. For example:</p>

<pre>
    a←1 2 3 ⊃ 4 5 6
    a
|1 2 3| |4 5 6|

    b←>a 
    b
1 2 3
4 5 6
    ⍴b
2 3
    &lt;b
|1 2 3|
|4 5 6|
</pre>

<p>The <b>rank</b> operator<tt> ⍤ </tt>produces a function 
of rank specified by its right argument. Thus:</p>

<pre>
    &lt;⍤1 b
|1 2 3| |4 5 6|
</pre>

<p>Moreover, the ravel function has infinite rank and:</p>

<pre>
    c←2 3 4⍴⍳24
    ,c
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
    ,⍤2 c
 0  1  2  3  4  5  6  7  8  9 10 11
12 13 14 15 16 17 18 19 20 21 22 23

    &gt;,&lt;⍤1 c
 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
</pre>

<p>A negative argument of the rank operator 
specifies the <b>complementary</b> rank, 
that is the rank of the outer shape. For example:</p>

<pre>
    ,⍤¯1 c
 0  1  2  3  4  5  6  7  8  9 10 11
12 13 14 15 16 17 18 19 20 21 22 23
</pre>

<p>In some instances, a primitive in conventional APL 
extends usefully by simply making an explicit assignment 
of the ranks implicit in its definition. 
For example,<tt> ⌹ </tt>is presently limited
to rank<tt> 2 </tt>arguments, 
but extends usefully according 
to the general rules. 
More interestingly,<tt> ⍎ </tt>is defined on vectors, 
and if assigned rank<tt> 1</tt>&nbsp;,<tt> </tt>
can be used in the manner illustrated below:</p>

<pre>
    ⍎ch←⍕2 2⍴⍳4
0 1
2 3
</pre>


<a name="xc2"></a>
<p><b>The Transpose Operator</b></p>

<p>It is sometimes necessary to move certain axes of the argument 
before applying a function. 
Although the dyadic transpose function can perform this, 
it is much more convenient to use the transpose operator 
defined as follows:</p>

<p><tt>&nbsp; f⍥k⍵ &nbsp;</tt>Applies<tt> f </tt>
after moving axes<tt> k </tt>to the rear.</p>

<p><tt>&nbsp; k⍥f⍵ &nbsp;</tt>Applies<tt> f </tt>
after moving axes<tt> k </tt>to the front.</p>

<p>For example:</p>

<pre>
    ,⍥0 c
0 12 1 13 2 14 3 15 4 16 5 17 6 18 7 19 8 20 9 21 10 22 11 23

    1 2⍥, c
0 12 1 13 2 11 3 15 4 16 5 17 6 18 7 19 8 20 9 21 10 22 11 23

    ,⍤2⍥0 c
 0 12  1 13  2 14  3 15
 4 16  5 17  6 18  7 19
 8 20  9 21 10 22 11 23

    <⍤2⍥0 c
| 0 12| | 4 16| | 8 20|
| 1 13| | 5 17| | 9 21|
| 2 14| | 6 18| |10 22|
| 3 15| | 7 19| |11 23|
</pre>

<p>The last two examples above involve a sequence 
of operators, and it should be noted that an operator 
has &ldquo;long left scope&rdquo;, 
applying to the result of the entire 
operator sequence to its left. 
Thus,<tt> ,⍤2⍥0 </tt>is equivalent 
to<tt> (,⍤2)⍥0</tt>&nbsp;,<tt> </tt>
not to<tt> ,⍤(2⍥0)</tt>&nbsp;.<tt> </tt> 
This may be emphasized by assigning a name 
to the intermediate (function) result produced:</p>

<pre>
    r2←,⍤2
    r2 c
 0  1  2  3  4  5  6  7  8  9 10 11
12 13 14 15 16 17 18 19 20 21 22 23

    r2⍥0
 0 12  1 13  2 14  3 15
 4 16  5 17  6 18  7 19
 8 20  9 21 10 22 11 23
</pre>

<p>For transpositions on an argument of arbitrary rank, 
the transpose operator used in conjunction 
with the identity function<tt> ⊢ </tt>
can often be much more convenient 
than the transpose function. 
For example, to move axes<tt> k </tt>to the rear:</p>

<pre>
    ⊢⍥⍵k ←→ (⍋((~a∊k)/a←⍳⍴⍴⍵),k)⍉⍵
</pre>


<a name="xc3"></a>
<p><b>Dyadic Functions</b></p>

<p>If the function<tt> g←f⍤r </tt>is 
to be applied dyadically 
as well as monadically 
(the only cases addressed in the preceding sections), 
then it is necessary 
that<tt> r </tt>specify three independent ranks, 
the monadic, the left, and the right. 
The general argument<tt> r </tt>is therefore a three-element vector 
that specifies the ranks in the order just indicated. 
Moreover,<tt> r </tt>is extended by reshape if necessary, 
so that<tt> f⍤r ←→ f⍤(⌽3⍴⌽r)</tt>&nbsp;.</p>

<p>The following example shows the behaviour 
of a useful catenation function 
that has differing left and right ranks:</p>

<pre>
    g←,⍤¯ 0 1
    a←2 3⍴⍳6
    7 8 g a
7 0 1 2
8 3 4 5
   7 8 ∘.g a
7 0 1 2
7 3 4 5

8 0 1 2
8 3 4 5
   h←∘.g
   ⍴b←3 4 5 h 7 8 h a
3 2 2 5
   0 0{b
3 7 0 1 2
3 7 3 4 5
</pre>

<p>If<tt> h←f⍤r </tt>is a function 
of higher rank than<tt> f</tt>&nbsp;,<tt> </tt>   
then<tt> f </tt>and<tt> h </tt>may be indistinguishable 
when used in the expressions<tt> ⍺f⍵ </tt>
and<tt> ⍺h⍵</tt>&nbsp;,<tt> </tt>  
but may produce quite different results 
under the application of an operator. 
More precisely, if<tt> i </tt>and<tt> j </tt> 
are non-negative scalars and if the rank 
of<tt> f </tt>is<tt> i</tt>&nbsp;,<tt> </tt>
then<tt> h←f⍤(i+j) </tt>agrees 
with<tt> f </tt>in direct application, 
but may differ from it under application 
of an operator.</p>

<p>For example, the rank of the scalar 
function<tt> × </tt>is<tt> 0</tt>&nbsp;,<tt> </tt>and:</p>

<pre>
    t1←×⍤1
    a←2 3⍴⍳6
    (a×a)-:a t a
1
    ⍴a∘.×a
2 3 2 3
    a ∘.t1 a
0  1  4
0  4 10

0  4 10
9 16 25
</pre>

<p>The left brace denotes a dyadic indexing 
function called <b>from</b>. 
Its left and right ranks are<tt> 1 </tt>
and<tt> ¯</tt>&nbsp;,<tt> </tt>and:</p>

<pre>
    1 2 3{a3 ←→ a3[1;2;3]
</pre>

<p>For example:</p>

<pre>
    a←2 3 4⍴⍳24
    1 2 3{a
23
</pre>

<p>If the left argument of<tt> { </tt>
is of rank greater than<tt> 1</tt>&nbsp;,<tt> </tt> 
then the normal rules of extension apply, 
giving the useful &ldquo;scattered&rdquo; indexing:</p>

<pre>
    i←?4 3⍴2
    i
1 1 0
0 0 0
1 1 1
1 1 0
    i{a
16 0 17 16
</pre>

<p>If<tt> j </tt>is a non-simple vector 
(i.e., including one or more elements produced 
by the enclose function<tt> &lt;</tt>&nbsp;),<tt> </tt> 
then the disclosed elements of<tt> i </tt>apply as follows:</p>

<pre>
    i{a3 ←→ a3[>i[0];>i[1];>i[2]]
</pre>

<p>For example, using the link function<tt> ⊃ </tt>
(that encloses its left argument and catenates 
it to the right, first enclosing the right if it is simple):</p>

<pre>
    i←1⊃1 2⊃0 3
    i{a
16 19
20 23
</pre>

<p>This generalization may also be written as:</p>

<pre>
    ⍺{⍵ ←→ ({⍺){⍵
</pre>

<p>using the monadic case of<tt> {</tt>&nbsp;,<tt> </tt>
the cartesian product 
discussed in the following section. For example:</p>

<pre>
    {i
1 1 0
1 1 3

1 2 0
1 2 3
    ({i){a
16 19
20 23
</pre>


<a name="xc4"></a>
<p><b>The Cartesian Product</b></p>

<p>The asymmetric catenation 
function<tt> g←,⍤¯ 0 1 </tt>illustrated earlier can be used 
to add a unit final axis. Thus:</p>

<pre>
    8 9 ∘.g '' 
8 
9
    ⍴8 9 ∘.g ''
2 1
</pre>

<p>It can also be used to form a cartesian product of arrays:</p>

<pre>
    c←2+b←2+a←1 2
    r←a ∘.g b ∘.g c ∘.g ''
    r
1 3 5
1 3 6

1 4 5
1 4 6


2 3 5
2 3 6

2 4 5
2 4 6
</pre>

<p>Finally, if<tt> i </tt>is the 
vector<tt> i←a⊃b⊃c</tt>&nbsp;,<tt> </tt>   
then the reduction of<tt> i,∘ </tt>by<tt> ∘.g¨> </tt>produces 
the enclosed cartesian product of the elements 
of<tt> i</tt>&nbsp;.<tt> </tt>Thus:</p>

<pre>
    i←a⊃b⊃c
    r≡> ∘.g¨>/i,∘
1
</pre>

<p>The operator<tt> ¨ </tt>(<b>dual</b>) 
used in the foregoing expression is defined by:</p>

<pre>
    f¨g⍵ ←→ g⊂ f g ⍵
   ⍺f¨g⍵ ←→ g⊂ (g⍺)f g  ⍵
</pre>

<p>where<tt> ⊂ </tt>(<b>con</b>) denotes 
the inverse operator. 
The effect of<tt> f¨>⍵ </tt>is to apply<tt> f </tt>  
to (the disclose of) each of the<tt> ×/⍴⍵ </tt>
enclosed elements of<tt> ⍵</tt>&nbsp;,<tt> </tt>
and to enclose each result.</p>

<p>The cartesian product function 
will be defined as the monadic case 
of<tt> {</tt>&nbsp;.<tt> </tt>Formally:</p>

<pre>
    {⍵ ←→ > ∘.(,⍤¯ 0 1)¨>/(<⍤>⍵),∘
</pre>

<p>Its use in the definition of the dyadic case 
was shown in the preceding section, namely:</p>

<pre>
    ⍺{⍵ ←→ ({⍺){⍵
</pre>

<p>Since<tt> { </tt>applied to a simple vector yields 
the vector unchanged, the definition applies (trivially) 
to a simple vector left argument as well as to a vector 
of enclosed elements. 
Note that it is the case of a simple argument 
that required the expression<tt> (<⍤>⍵) </tt>
instead of<tt> ⍵ </tt>in the definition of<tt> {⍵ </tt>above.</p>

<p>The definition of<tt> ⍺{⍵ </tt>is extended further to 
allow <b>abbreviated</b>, <b>negative</b>, and <b>complementary</b> 
indexing. For example:</p>

<pre>
    a←2 3 4⍴⍳24 
    1 2{a 
20 21 22 23

    1 ¯1{a
20 21 22 23
    i←1⊃(<2)⊃0 3
    i
|1| ||2|| |0 3|

    i{a
12 15 
16 19
</pre>

<p>Because an element of the form<tt> <<'' </tt>
will select all along the corresponding axis, 
an expression such as<tt> ((3⍴<<''),&lt;k){a4 </tt> 
can be used to select an index<tt> k </tt> 
along the last axis. 
However, if it is also desirable to bring 
the last axis to the front, 
it is more convenient to use 
the &ldquo;display&rdquo; 
function<tt> d</tt>&nbsp;,<tt> </tt>   
defined and illustrated below:</p>

<pre>
    d←¯1⍥{
    1 d 3 3 3⍴⍳27  
 1  4  7
10 13 16
19 22 25
    0 d 3 3 1⍴⍳9 
0 1 2
3 4 5
6 7 8
</pre>

<p>The last example above shows the production of 
an easily readable display of an array with a final unit axis. 
This will be used later in the discussion of permutations.</p>


<a name="xc5"></a>
<p><b>Operators on Non-Scalar Functions</b></p>

<p>Some examples of the application of operators 
(such as the outer product and the rank) 
have already appeared in earlier sections. 
We will here provide further examples 
involving the reduction 
operators<tt> / </tt>and<tt> ⌿</tt>&nbsp;,<tt> </tt> 
as well as the scans<tt> \ </tt>
and<tt> ⍀</tt>&nbsp;,<tt> </tt>   
which introduce supernumerary axes.</p>

<p>The expression<tt> f⌿⍵ </tt>splits<tt> ⍵ </tt>  
along its leading axis, and applies<tt> f </tt>
between the resulting subarrays. Thus, 
if<tt> a←?3&nbsp;4&nbsp;5⍴9 </tt>then</p>

<pre>
    f⌿a ←→ (0{a) f (1{a) f 2{A
</pre>

<p>For example:</p> 

<pre>
   a←3 3⍴⍳9
   ∘.×⌿a
 0  0  0
 0  0  0
 0  0  0

18 21 24
24 28 32
30 35 40

36 42 48
48 56 64
60 70 80

    p←3 3 1⍴1 0 2 2 0 1 2 1 0
    d←¯1⍥{
    0 d p
1 0 2
2 0 1
2 1 0
    ,{⌿p
2 0 1
</pre>

<p>The last result above is the 
&ldquo;product of the permutations&rdquo; 
represented by the rows of<tt> p</tt>&nbsp;.</p>

<p>The other reduction<tt> </tt>(<tt>f/</tt>)<tt> </tt> 
splits along the last axis. For example:</p>

<pre>
    a←i∘.×10*i←⍳3
    a
0  0   0
1 10 100
2 20 200
    ⍴r←∘.(,⍤0)/a
3 3 3 2 2
    1 2 { r
  1  20
  1   0

  1  20
  1 100

  1  20
  1 200
</pre>

<p>A scan of the form<tt> f⍀⍵ </tt>applies<tt> f⌿⍵ </tt>
to each of a set of subarrays<tt> (,⍤0⍳k){⍵</tt>&nbsp;,<tt> </tt> 
for each<tt> k∊1+⍳1↑⍴⍵</tt>&nbsp;,<tt> </tt> 
and the supernumerary axis (of length<tt> 1↑p⍵</tt>&nbsp;)<tt> </tt>
is placed <b>before</b> the axes contributed 
by the individual results. 
This will be illustrated in the scan<tt> {⍀p</tt>&nbsp;,<tt> </tt> 
where<tt> p </tt>is the permutation matrix used 
above to illustrate the reduction<tt> {⌿</tt>&nbsp;:</p>

<pre>
    0 (d←¯1⍥{) p 
1 0 2 
2 0 1 
2 1 0
</pre>

<p>The subarrays involved in the scan<tt> {⍀ </tt>
may be produced and displayed as follows:</p>

<pre>
    g←,⍤0⍤⍳

    0 d (g 1){p
1 0 2

    0 d (g 2){p
1 0 2
2 0 1

    0 d (g 3){p
1 0 2
2 0 1
2 1 0
</pre>

<p>The scan<tt> {⍀p </tt>therefore gives all 
of the permutations produced by reductions 
over these subarrays:</p>

<pre>
    0 d {⍀p
1 0 2
0 2 1
2 0 1
</pre>

<p>The alternate scan<tt> f\ </tt>is defined analogously, 
with the split occurring along the <b>last</b> axis, 
and with the supernumerary axis placed <b>last</b>. 
For example:</p>

<pre>
    ×\3 3⍴⍳9
0   0   0
3  12  60
6  42 336
</pre>


<a name="xc6"></a>
<p><b>Til, Cut, and Bind</b></p>

<p>The operators discussed in this section 
are not essential to the rationalization program, 
but they can be used to further exploit, 
and therefore to demonstrate, 
the power of the essential facilities. 
In what follows, we will use the fact that 
the <b>con</b> operator<tt> ⊂ </tt>is 
(in the dyadic use of the resulting 
derived function) a commutation, that is:</p>

<pre>
    ⍺ f⊂ ⍵ ←→ ⍵ f ⍺
</pre>

<p>The til operator, defined by

<pre>
    ⍺ f}g ⍵ ←→ (g ⍵) f ⍺ 
      f}g ⍵ ←→ (g ⍵) f ⍵
</pre>

<p>can be used in a variety of ways. For example:</p>

<pre>
    f←÷⍤1
    g←⌽
    a←2 4 5
    b←10 2 4
    a f}g b               Reverse b and divide by a
2 0.5 2
 
    a f}g⊂ b              Reverse a and divide by b
0.5 2 0.5                 (a “left composition” in which g 
                          applies only to the left argument)
 
    a f⊂}g b              Right composition
0.5 2 0.5
</pre>

<p>If<tt> f </tt>is commutative, 
then right composition 
can be obtained more simply by the 
expression<tt> f}g</tt>&nbsp;.<tt> </tt>   
For example:</p>

<pre>
    a +}÷ b
2.1 4.5 5.25
    +}÷/c←2 4 5 6 
2.23846
    +}÷\c
2 2.25 2.2381 2.23846
</pre>

<p>The case<tt> +}÷/c </tt>is equivalent 
to<tt> 2+÷4+÷5+÷6</tt>&nbsp;,<tt> </tt> 
and is called the continued fraction 
represented by<tt> c</tt>&nbsp;;<tt> </tt> 
the case<tt> +}÷\c </tt>yields the &ldquo;convergents&rdquo; 
to the continued fraction.</p>

<p>The most important property of the til operator 
remains to be stated, namely:</p>

<pre>
    f}g}h ⍵ ←→ (g⍵) f (h⍵)
</pre>

<p>In other words,<tt> f}g}h ⍵ </tt>applies 
a dyadic function<tt> f </tt>to the results of 
the monadic functions<tt> g </tt>and<tt> h</tt>&nbsp;.<tt> </tt>
For example:</p>

<pre>
    f←'⍵*2'∇∘⍤0
    g←'⍵*3'∇∘⍤0
 
    +}f}g 1 2 3           Often denoted by f+g without 
2 12 36                   indicating that + is an operator 
                          rather than a function
    -}f}g 1 2 3
0 ¯4 ¯18

    i←'⍵=⌊⍵'∇∘⍤0
    p←'⍵>0'∇∘⍤0
    n←¯1 ¯.5 0 .5 1
    
    ∧}i}p n
0 0 0 0 1
    ∨}i}p n
1 0 1 1 1
    ≠}i}p n
1 0 1 1 0
</pre>

<p>The <b>cut</b> operator takes an integer left argument 
and a function right argument and 
applies it to pieces cut from the right argument 
of the derived function, 
putting the supernumerary axes contributed 
by the set of pieces in first place. 
The type of cut is determined by the left argument 
of the operator, and the points of cutting 
by the left argument of the derived function. 
The cuts are along the leading axis. For example:</p>

<pre>
    t←'abcdefghij'
    b←0 0 1 0 0 0 1 1 0 0

    b ¯1⍤< t              A ¯1-cut begins pieces at 1's
|def| || |ij|             and excludes cut points

    b 1⍤< t               A 1-cut begins at 1's 
|cdef| |g| |hij|          and includes cut points

    b ¯2⍤< t              (2 ¯2)-cuts end at 1's
|ab| |def| ||

    b 2⍤< t 
|abc| |defg| |h|

    b ¯1⍤(+/) ⍳10
12 0 17

    b 1⍤(+/) ⍳10
14 6 24

    m←⍉2 10⍴'abcdefghijk'
    m
ak
ba
cb
dc
ed
fe
gf
hg
ih
ji
    (4↑1) ¯1⍤< m
|ak| |ed| |ih|
|ba| |fe| |ji|
|cb| |gf|
|dc| |hg|

    s←'now it is'

    ¯1⍤< ' ',s            Monadic (1 ¯1)-cuts use the
|now| |it| |is|           leading element as a delimiter

    1⍤< ' ',s
| now| | it| | is|

    ¯2⍤< s,' '            Monadic (2 ¯2)-cuts use the last
|now| |it| |is|           element as delimiter

    2⍤< s,' '
|now | |it | |is |
</pre>

<p>The <b>general</b> cut<tt> 0⍤f </tt>has 
left rank<tt> 2 </tt>and infinite right rank, 
so that a left argument of rank greater 
than<tt> 2 </tt>produces a set of cuts. 
The first row of the left argument specifies 
the beginning point, 
and the magnitudes of the last row specify 
the size of the window, with a negative value 
producing a reversal along the corresponding axis. 
For example (using the identity 
function<tt> ⊢</tt>&nbsp;):</p>

<pre>
   a←>1 1⊃2 2
   a
1 1
2 2
   a 0⍤⊢ m←4 4$i.16
5  6
9 10
   (>1 1⊃¯2 2) 0⍤< m
| 9 10|
| 5  6|
</pre>

<p>The<tt> ¯3</tt>-cut<tt> ⍺ ¯3⍤f ⍵ </tt>
provides a tessellation, 
with the movement specified by<tt> ⍺[0;]</tt>&nbsp;,<tt> </tt> 
and the window again by<tt> ⍺[1;]</tt>&nbsp;.<tt> </tt> 
For example (with<tt> ⎕ps </tt>
set to<tt> -1&nbsp;1&nbsp;3&nbsp;3</tt>&nbsp;):</p>

<pre>
    a←2 2⍴2
    a ¯3⍤< m
 ___     ___
|   |   |   |
|0 1|   |2 3|
|4 5|   |6 7|
|___|   |___|
 _____   _____
|     | |     |
| 8  9| |10 11|
|12 13| |14 15|
|_____| |_____|
   
    a←>1 1⊃2 2
    ⍴r←a ¯3⍤⊢ m
3 3 2 2

    1{r
 4  5
 8  9

 5  6
 9 10

 6  7
10 11
</pre>

<p>In the expression<tt> ⍺ f.k ⍵</tt>&nbsp;,<tt> </tt>
the operator causes<tt> f </tt>to be applied 
to the arguments with their first<tt> k </tt>
axes &ldquo;bound&rdquo; (and necessarily agreeing), 
and with the remaining free axes 
(exclusive of those demanded by cells 
as determined by the ranks 
of<tt> f</tt>&nbsp;)<tt> </tt> 
forming an outer product. 
The main point is best illustrated 
by a scalar function<tt> f </tt> 
in which no axes are demanded by cells:</p>

<pre>
    a←10×b←2 3⍴⍳6

    a +. 2 b
 0 11 22
33 44 55

    a +. 1 b
 0  1  2
10 11 12
20 21 22

33 34 35
43 44 45
53 54 55

    ⍴r←a +. 0 b
2 3 2 3
    r≡a∘.+b
1
</pre>

<p>The monadic case of<tt> f.k </tt>provides<tt> k </tt> 
successive reductions by<tt> f </tt>over the leading axes. 
For example:</p>

<pre>
    a←2 3 4 5⍴⍳120
    +. 2 a
300 306 312 318 324
330 336 342 348 354
360 366 372 378 384
390 396 402 408 414
</pre>

<p>For many functions 
(particularly for non-scalar functions) 
it is important to note that the reductions 
are carried out in the manner illustrated 
by<tt> f. 3 ⍵ ←→ f⌿ f⌿⍤¯1 f⌿⍤¯2 ⍵ </tt></p>



<br><a name="xd"></a>
<p><b>Appendix D. APL2 versus a Comparable Subset</b></p>

<p>This section presents comparisons 
between the facilities of APL2
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">[3]</acronym>
and a roughly equivalent subset 
of the facilities defined in this paper. 
The restricted subset (to be referred to as RS) embraces:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
The functions<tt> <</tt>&nbsp;,<tt> ></tt>&nbsp;,<tt> </tt>and<tt> ≡ </tt> 
(enclose, disclose, and match), and the 
operators<tt> ⍤</tt>&nbsp;,<tt> ⍥</tt>&nbsp;,<tt> </tt>and<tt> ¨ </tt>
as defined (for function arguments only) in
<acronym title="Robert Bernecky and Kenneth E. Iverson, 
Operators and Enclosed Arrays 
(I.P. Sharp, Proceedings of the User Meeting, 1980)">[4]</acronym>.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
Argument ranks assigned to all primitive functions, 
and a rank operator (used in the form<tt> f⍤r</tt>&nbsp;)<tt> </tt>   
that assigns rank<tt> r </tt>to a derived function.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
A single rule, common to all functions, 
for extending them to arguments of higher rank; 
the result shape is the catenation of the <b>outer shape</b>
(exclusive of the <b>cell</b> shapes demanded 
by the ranks of the function ranks) 
with the common result shape produced 
by applying the function to individual cells.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
The functions link<tt> </tt>(<tt>⊃</tt>)<tt> </tt>
and from<tt> </tt>(<tt>{</tt>),<tt> </tt>
including the dyadic case of<tt> i¨{ </tt>  
(which provides a merge equivalent to indexed assignment.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
The transpose operator, which applies a function<tt> f </tt>
after effecting a transpose;<tt> f⍥i </tt>moves axes<tt> i </tt> 
to the rear, and<tt> i⍥f </tt>to the front.
 <br>&nbsp;</td></tr>
<tr><td valign=top>6.</td><td>&nbsp;</td><td>
Use of the form<tt> a←exp </tt>to assign a name 
to a function or operator as well as to a variable, 
and of the function definition operator<tt> ∇ </tt>
which applies to vectors representing 
(in direct definition form) the monadic 
and dyadic cases of a function.
 </td></tr>
</table>

<p>The functions from<tt> </tt>(<tt>{</tt>)<tt> </tt>and 
merge<tt> </tt>(<tt>i¨{</tt>&nbsp;),<tt> </tt>   
and the rank and transpose operators 
obviate all uses of brackets and semicolons. 
The <b>discussion</b> of RS will therefore be based 
on the assumption that their use is excluded, 
even though, for reasons of compatibility, 
they will continue to function as in conventional APL.</p>

<p>The comparisons made in this section are 
more theoretical than practical, 
concentrating on general questions 
such as implications for syntax, function classifications, 
and domains of operators. 
More practical comparisons of convenience, 
ease of learning, etc. are better made by the reader, 
either by drawing from his own applications, 
or from definitions and examples given in the APL2 manual 
<acronym title="APL2 Language Manual 
(IBM Corporation, SB21 3015, June 1982)">[3]</acronym>
and the companion Introduction manual 
<acronym title="APL2 Introduction Manual 
(IBM Corporation, SB21 3039, June 1982)">[10]</acronym> 
as well as from this paper.</p>

<p>For example, one might take examples of strands 
and of heterogeneous arrays from the APL2 publications 
and write them completely in RS, 
and take function definitions such as<tt> r←,⍤2 </tt>
and write them completely in APL2.</p>

<a name="xd1"></a>
<p><b>Syntax.</b> A useful measure of the complexity 
of a set of syntax rules is the required <b>scope</b>, 
that is, the maximum number of elements 
in the execution stack which must either be involved 
in the determination of the next action to be taken, 
or be used in that action. 
This measure is meaningful only on the assumption 
that each element is a normal operator, function, or variable, 
that is, an element does not incorporate further information 
relevant to another element or elements.</p>

<p>We will further assume that parentheses 
are handled by recursion on any segment enclosed 
by matching parentheses, 
and that parentheses are therefore 
not considered in assessing scope. 
However, this exclusion can not apply 
to an &ldquo;unusual&rdquo; 
use of parentheses, such as the 
usage<tt> (c\[a]v)←x </tt>in APL2, 
in which the result of the parenthesized expression 
is a &ldquo;qualified&rdquo; name.</p>

<p>Under the foregoing assumptions, the scope in RS 
is<tt> 4</tt>&nbsp;.<tt> </tt>In APL2:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
Strands impose infinite scope.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
The scope requirements of bracketed axis operators remain, 
or are further exaggerated by the introduction 
of semicolons within them.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
Although the index function 
(denoted by the composite symbol &ldquo;squad&rdquo;) 
shows some similarity to<tt> { </tt>in RS, 
it is not clear that an expression such 
as<tt> (1&nbsp;2⊃?3&nbsp;4⍴2){a3 </tt>could be conveniently 
expressed without the use of bracket indexing, 
and it may be reasonable to assume 
that bracket indexing is not superseded by squad.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
Although the use of bracket indexing 
in indexed assignment 
may be partly (or even wholly) superseded 
by constructs such as<tt> (1&nbsp;1⍉v)←c</tt>&nbsp;,<tt> </tt>
this special use of parentheses 
to enclose a &ldquo;qualified name&rdquo; would appear 
to have the same implications for syntax 
as the use of bracket-index assignment.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
The introduction of <b>ambiguous symbols</b> 
(that is<tt> /</tt>&nbsp;,<tt> ⌿</tt>&nbsp;,<tt> \</tt>&nbsp;,<tt> </tt>
and<tt> ⍀</tt>&nbsp;)<tt> </tt>
to denote both a monadic operator and a dyadic function, 
would appear to complicate the syntax. 
Thus, although the 
expressions<tt> +/1&nbsp;2 </tt>and<tt> //1&nbsp;2 </tt>
are analyzed similarly, the 
expressions<tt> ⍴+/1&nbsp;2 </tt>and<tt> ⍴//1&nbsp;2 </tt>are not.
 </td></tr>
</table>


<a name="xd2"></a>
<p><b>Function Classes.</b> In conventional APL, 
functions are, explicitly or implicitly, 
divided into a number of overlapping classes, 
and the behaviour of a function depends, 
in significant ways, on the classes to which it belongs. 
Thus:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
Scalar functions are all of rank<tt> 0</tt>&nbsp;,<tt> </tt>
but, more significantly, they alone are in the domain of the 
operators<tt> /</tt>&nbsp;,<tt> ⌿</tt>&nbsp;
,<tt> \</tt>&nbsp;,<tt> ⍀</tt>&nbsp;,<tt> </tt>
and<tt> . </tt>(dot).
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
&ldquo;Bracket&rdquo; functions, which include certain 
derived functions such as<tt> +/ </tt>and<tt> +⍀ </tt> 
as well as the functions<tt> ⌽ </tt>and<tt> ⊖ </tt>
are in the domain of the &ldquo;bracket axis specification&rdquo;.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
Some functions (such 
as<tt> ~</tt>&nbsp;,<tt> ↓</tt>&nbsp;,<tt> ↑</tt>&nbsp;,<tt> ⊥</tt>&nbsp;,<tt> ⊤</tt>&nbsp;,<tt> </tt>
and<tt> ⍎</tt>&nbsp;)<tt> </tt>
are fixed in valence, and produce syntax errors 
when used inappropriately.
 <br>&nbsp;</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
Defined functions are included in class 3 above, 
but excluded from classes<tt> 1 </tt>and<tt> 2</tt>.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
Derived functions are excluded from class<tt> 1</tt>,<tt> </tt>
and some, but not all, are excluded from class<tt> 2</tt>.
 </td></tr>
</table>

<p>In RS all such class distinctions are removed. 
However, each function is assigned a set of ranks, 
the ranks for all primitives of conventional APL 
being<tt> 0</tt>,<tt> 1</tt>,<tt> 2</tt>,<tt> </tt>or unbounded.</p>

<p>In APL2, some of these distinctions 
are removed in that operators 
such as reduction and inner product apply to non-scalar 
and defined and derived functions.</p>

<p>However, class<tt> 2 </tt>is not only retained, but extended 
(to scalar functions, to<tt> ↑</tt>&nbsp;,<tt> </tt>etc.), 
and class<tt> 3 </tt>(fixed valence) 
is also retained and extended, as evidenced by entries under 
&ldquo;monadic&rdquo; and &ldquo;dyadic&rdquo; in the glossary, 
by references to dyadic functions in the definitions 
of certain operators, and by the fact 
that the new bracket axis operator 
(distinct from the conventional 
&ldquo;bracket axis specification&rdquo; 
referred to in the definition of class<tt> 2</tt>)<tt> </tt>
produces a function which is specifically monadic or dyadic.</p>

<p>Two further classes are introduced in APL2, 
called <b>pervasive</b> and <b>selection</b>: 
members of the former applying down 
through any structure of enclosures, 
and members of the latter being permitted to the left of assignment. 
No provision appears to be made for making a defined 
or derived function a member of either of these classes.</p>


<a name="xd3"></a>
<p><b>Depth Functions.</b> APL2 provides 
two significant facilities which apply 
at &ldquo;depth&rdquo; in the enclosure structure of an argument, 
the dyadic <b>pick</b> function, and the pervasive functions. 
RS provides no primitive corresponding to <b>pick</b>; 
it could be defined recursively by:</p>

<pre>
      pick←''∇('→2+0=⍴⍺'⊃'(>0{⍺){(1↓⍺)∆⍵'⊃'⍵')
</pre>

<p>If frequent use demands greater 
convenience and efficiency, 
the pick function could be incorporated as a primitive. 
If so, the dyadic case of<tt> i¨pick </tt>
should provide the merge corresponding to the 
&ldquo;selective specification&rdquo; of the 
form<tt> (l⊃r)←x </tt>provided in APL2.</p>

<p>Since pervasiveness is a property 
assigned to functions, it would, 
in the framework of RS, be provided by an operator. 
Such an operator could be applied to any function 
(defined or derived as well as primitive) and, 
if defined to be dyadic, could provide greater variety. 
Thus a variable<tt> p </tt>in<tt> f op p </tt>
could provide application at any depth from the top, 
or any distance from the leaves; 
a <b>function</b><tt> p </tt>  
(that is, a proposition) could specify 
the condition at the level where<tt> f </tt>is to apply.</p>


<a name="xd4"></a>
<p><b>Array Formation.</b> If each essential space in an expression 
is counted as a character, then the link function and strand notation 
used to form non-simple vectors from simple vectors require expressions 
of nearly identical length. For example:</p>

<table>
<tr><td>Strand</td><td>&nbsp;</td><td>Link</td></tr>
<tr><td><tt>(1 2)(3 4)(5 6)7 8</tt></td>  <td>&nbsp;</td><td><tt>1 2⊃3 4⊃5 6⊃7 8</tt></td></tr>
<tr><td><tt>((1 2)3 4)((5 6)7 8)</tt></td><td>&nbsp;</td><td><tt>(1 2⊃3 4)⊃<5 6⊃7 8</tt></td></tr>
<tr><td><tt>a b c d e f g h</tt></td>     <td>&nbsp;</td><td><tt>a⊃b⊃c⊃d⊃e⊃f⊃g⊃h</tt></td></tr>
<tr><td><tt>(a b)(c d)(e f)(g h)</tt></td><td>&nbsp;</td><td><tt>(a⊃b)⊃(c⊃d)⊃(e⊃f)⊃<(g⊃h)</tt></td></tr>
<tr><td><tt>a(b(c(d(e f))))</tt></td>     <td>&nbsp;</td><td><tt>a⊃&lt;b⊃&lt;c⊃&lt;d⊃&lt;e⊃f</tt></td></tr>
</table>

<p>In conventional APL, the precedence o£ operators obviated 
parentheses around operator expressions, 
as in<tt> a+.×b</tt>&nbsp;,<tt> </tt> 
and in RS the precedence and scope rules for operators 
extend this convenience to expressions such 
as<tt> f⍤a b</tt>&nbsp;,<tt> </tt> 
regardless of whether<tt> a </tt>
is a function or a variable. 
APL2 adopts the same rule for operators, 
but because strands take precedence over everything, 
an operator expression 
with a variable right argument must be parenthesized.</p>

<p>In conventional APL, two vector constants are never juxtaposed. 
In both RS and APL2, however, 
juxtaposition may occur in the case of 
any operator having a variable right argument 
(necessarily a user-defined operator in the case of APL2). 
In that event, the divide between the constants 
must be indicated by some delimiter. Thus:</p>

<pre>
      f⍤1 2 (3 4 5)
      f⍤(1 2) 3 4 5
      f⍤1 2 a← 3 4 5
      (f⍤1 2) 3 4 5
      f⍤1 2⊢3 4 5
</pre>

<p>In RS, any one of these may be used, 
the first two being preferred 
because they clearly indicate 
the purpose of the parentheses, 
and the third being used 
if there are extraneous reasons 
for naming the right argument. 
In APL2, strands limit the choice to the fourth.</p>

<p>Retention of a valence classification 
for functions may have some implication for strands. 
Thus, if<tt> f </tt>is strictly monadic, 
the expression<tt> a~b </tt>might be considered 
identical to<tt> a(~b)</tt>&nbsp;,<tt> </tt>
since the strictly monadic function 
would presumably be executed first.</p>

<p>Although the valence classification is made 
in conventional APL 
(with<tt> a~b </tt>yielding a syntax error 
rather than a domain error) 
the valence classification has no serious consequences, 
because the juxtaposition of the two variables 
occasions an immediate error. 
Paradoxically, the function<tt> ~ </tt>is actually treated 
as ambivalent in the sense that the name<tt> a </tt>
in the expression<tt> a~b </tt>
is evaluated <b>before</b> the syntax error is reported, 
as may be seen by making<tt> a </tt>a shared variable 
(perhaps<tt> ⎕</tt>&nbsp;)<tt> </tt> 
or a niladic function that specifies a global variable.</p>


<a name="xd5"></a>
<p><b>Domains of Operators.</b> In conventional APL, 
the domains of operators are defined by one general rule 
(which excludes all defined functions), 
and by specific lists, the list of &ldquo;scalar primitives&rdquo; 
for all but the bracket axis operator, and a second list 
(which includes some derived functions) for it.</p>

<p>Moreover, the domains of the derived functions produced 
are limited in ways which depend 
upon the arguments of the operators, 
depending upon the normal definition of the argument 
(as in<tt> ÷/4 0</tt>&nbsp;),<tt> </tt> 
or upon an &ldquo;attribute&rdquo; 
that it may possess (as in<tt> ⍲/⍳0</tt>&nbsp;).</p>

<p>In RS, the domains of operators are unrestricted, 
although the domains of the resulting derived functions 
continue to be restricted in ways 
analogous to those in conventional APL. 
Thus the domain of<tt> f¨g </tt>
will be restricted by the domains 
of<tt> g</tt>&nbsp;,<tt> f</tt>&nbsp;,<tt> </tt>and<tt> g⊂ </tt>  
(that is<tt> g </tt>inverse). In particular, 
the domain of<tt> f¨g </tt>is empty 
if the domain of<tt> g⊂ </tt>is empty.</p>

<p>In APL2, the domains of most operators are unrestricted. 
However, the list of functions subject to (bracket) 
axis specification is not only maintained 
(as required for compatibility, even in RS), 
but is extended, 
as in<tt> a+[2]b</tt>&nbsp;,<tt> </tt>and 
in<tt> a↑[2]b</tt>&nbsp;.<tt> </tt> 
In the latter case of<tt> ↑</tt>&nbsp;,<tt> </tt>
the &ldquo;default&rdquo; axis used when the
axis specification is absent is not the final axis 
used for similar cases, but <b>all</b> axes.</p>

<p>Although the bracket notation used to represent it 
in conventional 
APL tends to obscure the matter, the axis operator is, 
in effect, dyadic, applying to a function &ldquo;left argument&rdquo; 
and a variable &ldquo;right argument&rdquo;. 
In APL2, the bracket axis operator is defined to be monadic, 
seeming to imply that there is an indeterminate number of such operators, 
such as<tt> [1;1]</tt>&nbsp;,<tt> </tt>
and<tt> [1;2]</tt>&nbsp;,<tt> </tt>etc.</p>


<a name="xd6"></a>
<p><b>Prototypes.</b> Prototypes in APL2 are an extension 
of the notion (implicit in the difference in the results 
of<tt> 1↑⍳O </tt>and<tt> 1↑''</tt>&nbsp;)<tt> </tt> 
that an array<tt> a </tt>incorporates some information 
other than its shape and the values of each of its elements.</p>

<p>In RS, compatibility with conventional APL is maintained, 
but no new distinctions are introduced. 
Specifically,<tt> 1↑0⍴1j1 </tt>and<tt> 1↑0⍴(1&nbsp;2&nbsp;3⊃'ab') </tt>
both yield<tt> 0</tt>&nbsp;.</p>

<p>This is a fundamental difference that cannot be eliminated 
(as can the lack of a pervasive class of functions) 
by the introduction of an appropriate operator.</p>


<a name="xd7"></a>
<p><b>Heterogeneous Arrays.</b> RS does not include 
the heterogeneous arrays of APL2, 
and the production of equivalent constructs 
requires greater use of enclosure. 
However, the structure of RS does not 
preclude their introduction.</p>


<a name="xd8"></a>
<p><b>Permissive Enclose.</b> The monadic enclose functions 
defined in RS<tt> </tt>(<tt><</tt>)<tt> </tt>
and in APL2<tt> </tt>(<tt>⊂</tt>)<tt> </tt>differ in one respect: 
if<tt> s </tt>is a simple scalar, 
then<tt> s≡⊂s</tt>&nbsp;,<tt>  </tt>but<tt> ~s≡&lt;s</tt>&nbsp;.<tt> </tt> 
Although<tt> < </tt>can therefore produce some structures 
not producible by<tt> ⊂</tt>&nbsp;,<tt> </tt> 
the differences between them 
(in the contexts of the respective systems) cannot, 
in most cases, be discerned.</p>

<p>The function<tt> { </tt>in RS provides an example 
where the difference is significant: 
because a doubly enclosed element of the left argument 
provides <b>complementary</b> indexing, 
the value of<tt> &lt;&lt;k </tt>must be distinguishable 
from<tt> &lt;k</tt>&nbsp;,<tt> </tt>   
even in the case of a scalar<tt> k</tt>&nbsp;.</p>

<p>A similar situation would arise in the definition 
of an indexing function<tt> f </tt> 
in which<tt> a&nbsp;f&nbsp;i </tt>selects elements from<tt> a </tt> 
and incorporates them in the same &ldquo;enclosure structure&rdquo; 
as<tt> I</tt>&nbsp;.<tt> </tt> 
However, the difference would be 
discernible only in the case 
of some scalar element of<tt> i </tt>
<b>and</b> a non-simple argument<tt> a</tt>&nbsp;.</p>


<a name="xd9"></a>
<p><b>General Remarks.</b> The following general contrasts may be noted:</p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td>
The definitions of function rank and of the disposition of result axes 
in RS permit the handling of constructs that would be handled 
by explicit encloses in APL2, and APL2 provides more facilities 
(such as pervasiveness) for operating &ldquo;at depth&rdquo;.
 <br>&nbsp;</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td>
RS provides facilities which obviate 
the use of brackets and semicolons 
in both indexing and in operators; 
although alternative indexing functions 
in APL2 could supersede bracket indexing, 
the use of brackets as operators is not 
only retained, but extended.
 <br>&nbsp;</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td>
<p>By assigning specified ranks to all functions, 
and by declaring all functions to be ambivalent, 
RS subsumes all in a single class, 
eliminating distinctions in the treatments 
of the classes (such as defined, derived, mixed) 
which occur in conventional APL.</p>

<p>Although APL2 removes the confining distinction 
between primitives and defined and derived functions 
in the application of operators, 
it retains other function class distinctions 
of conventional APL, and introduces two further classes, 
pervasiveness, and &ldquo;selectivity&rdquo;.<br>&nbsp;</p>
 </td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>
APL2 retains and extends the use of indexed assignment, 
whereas RS provides equivalent merge functions 
based upon the indexing function.
 <br>&nbsp;</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>
RS restricts the scope of syntax rules 
to<tt> 4</tt>&nbsp;,<tt> </tt> 
whereas APL2 makes no corresponding restriction.
</td></tr>
</table>



<br><a name="ref"></a>
<p><b>References</b></p>

<table>
<tr><td valign=top>1.</td><td>&nbsp;</td><td><b>APL Language</b> 
 (IBM Corporation, GC26-3847).</td></tr>
<tr><td valign=top>2.</td><td>&nbsp;</td><td><b>APL*PLUS Nested Array System</b> 
 (STSC, Inc., 1981).</td></tr>
<tr><td valign=top>3.</td><td>&nbsp;</td><td><b>APL2 Language Manual</b>   
 (IBM Corporation, SB21 3015, June 1982).</td></tr>
<tr><td valign=top>4.</td><td>&nbsp;</td><td>Robert Bernecky and Kenneth E. Iverson,   
 <a target=_parent href="http://www.jsoftware.com/papers/opea.htm"><b>Operators and Enclosed Arrays</b></a>
  (I.P. Sharp, Proceedings  of the User Meeting, 1980).</td></tr>
<tr><td valign=top>5.</td><td>&nbsp;</td><td>K.E. Iverson, 
 <a target=_parent href="http://www.jsoftware.com/papers/APLSyntaxSemantics.htm"><b>APL Syntax and Semantics</b></a> (ACM, APL83).</td></tr>
<tr><td valign=top>6.</td><td>&nbsp;</td><td>
 <a target=_parent href="http://www.jsoftware.com/papers/opfns.htm"><b>Operators and Functions</b></a>
 (IBM Corporation, RC7091, 1978).</td></tr>
<tr><td valign=top>7.</td><td>&nbsp;</td><td>K.E. Iverson,   
 <a target=_parent href="http://www.jsoftware.com/papers/satn42.htm"><b>Determinant-Like Functions Produced by the Dot Operator</b></a> 
 (I.P. Sharp Technical Notes - SATN-42, April 1982).</td></tr>
<tr><td valign=top>8.</td><td>&nbsp;</td><td>Kenneth E. Iverson 
 and Peter K. Wooster,   
 <b>A Function Definition Operator</b> 
 (APL Quote Quad, Volume 12, Number 1, 
 Proceedings of APL81, ACM September 1981).</td></tr>
<tr><td valign=top>9.</td><td>&nbsp;</td><td>Arthur Whitney and Kenneth E. Iverson,   
 <a target=_parent href="http://www.jsoftware.com/papers/APLModel.htm"><b>Practical Uses of a Model of APL</b></a> (Apl Quote Quad, Volume 13, Number 1, 
 Proceedings of APL82, ACM, New York 1982).</td></tr>
<tr><td valign=top>10.</td><td>&nbsp;</td><td><b>APL2 Introduction Manual</b>   
 (IBM Corporation, SB21 3039, June 1982).</td></tr>
</table>



<br><a name="ack"></a>
<p><b>Acknowledgements</b></p>

<p>I am indebted to a number of my colleagues at 
I.P. Sharp Associates for many helpful discussions 
and suggestions, particularly to 
R. Bernecky, E.B. Iverson, E.E. McDonnell,   
R. Pesch, J.H. Schueler, D.L. Forkes, and L.H. Goldsmith.</p>



<br><hr>

<a name="err"></a>
<p align=center><font size=+2>Errata</font></p>

<table>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section A, just before the last displayed example,
it should be &ldquo;with the rest 
of<tt> a</tt>&nbsp;.<tt> </tt>Thus:&rdquo;
instead of &ldquo;with the rest 
of<tt> a</tt>&nbsp;,<tt> </tt>Thus:&rdquo;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section E, there should not be a blank line just before
the last line of item d.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section F, in the paragraph that introduced the rank operator,
it should say &ldquo;both the right rank and 
the monadic rank are<tt> 3</tt> &rdquo;
instead of &ldquo;both right ranks are<tt> 3</tt> &rdquo;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section F, in the displayed examples of the Conformance subsection:
The result of<tt> ⍴a×.&nbsp;1&nbsp;(1&nbsp;1&nbsp;4⍴9) </tt>
should be<tt> 2&nbsp;3&nbsp;4&nbsp;1&nbsp;4 </tt>
instead of<tt> 2&nbsp;3&nbsp;4</tt>&nbsp;;<tt> </tt>
the next expression<tt> ⍴a×.&nbsp;2&nbsp;(3&nbsp;4⍴9) </tt>
should signal<tt> length&nbsp;error </tt>
instead of giving a result of<tt> 2&nbsp;3&nbsp;4</tt>&nbsp;;<tt> </tt>
finally, the last expression should not have a trailing right parenthesis.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section G, in the paragraph following the definition
of outer product and inner product, it should say
&ldquo;leading position.)&rdquo; instead of
&ldquo;leading position).&rdquo;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section H, item 1 of the conclusion should 
say<tt> i&nbsp;↑¨⍵&nbsp;f </tt>instead 
of<tt> i&nbsp;{¨⍵&nbsp;f</tt>&nbsp;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section K, in the paragraph 
introducing<tt> ⍥</tt>&nbsp;,<tt> </tt> 
the first instance of the word &ldquo;upon&rdquo; 
should be in bold.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Section K, in the Cut Operator subsection,
the expression for the monadic case of<tt> 0⍤f ⍵ </tt>
is missing a leading left parenthesis.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Appendix C, in the Til, Cut, and Bind subsection,
the example should be<tt> (4↑1) 1⍤&lt; m </tt>instead 
of<tt> (4↑1) ¯1⍤&lt; m</tt>&nbsp;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Appendix D, item 4 of the description of RS
is missing a closing right parenthesis.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
In Appendix D, in the third paragraph of 
the Domains of Operators subsection,
the comma is missing from
&ldquo;(that is,<tt> g </tt>inverse)&rdquo;.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
Reference 6 should have K.E. Iverson as the author.
 </td></tr>
<tr><td valign=top>&#149;</td><td>&nbsp;</td><td>
Reference 9 should say &ldquo;APL Quote Quad&rdquo; 
instead of &ldquo;Apl Quote Quad&rdquo;.
 </td></tr>
</table>



<br><hr>
<font size=-1>
<p>Originally appeared as I.P. Sharp Research Report #1, Revision 1, 1983-04-04.</p>

<p><script src="https://www.jsoftware.com/papers/apldisplay.js" type="text/javascript"></script></p>
</font>

<table>
<tr><td><font size="-1">created: &nbsp;</font></td><td><font size="-1">2008-07-18 07:15</font></td></tr>
<tr><td><font size="-1">updated:</font></td><td><font size="-1">2017-11-07 17:20</font></td></tr>
</table>

</td></tr></table>
<br><br><br>
</body>
</html>