Dyalog supports the use of a negative rank parameter, while GNU APL does
not. Instead GNU APL follows the ISO spec which says that a negative value
should be clamped to 0.

However, the Dyalog model is quite useful. Here's how it's described in
their documentation:

*“The Rank operator ⍤ 1 applies function f successively to the sub-arrays
in Y specified by k. If k is positive, it selects the k-cells of Y. If k is
negative, it selects the (r+k)- cells of Y where r is its rank. If k is ¯1
it selects the major cells of Y.”*

I think it seems reasonable to adapt this to GNU APL as well?

*About the ISO specification of ⍤*

In writing the above message, I was reading the ISO specification for the
rank operator, and I find it incredibly confusing. I have quoted the
description below, and based on my reading of this text, the rank parameter
is not just a single value, but can be up to *three* values. However, no
matter how I read it, I still can't see how any but the the very first
value is actually every used.

Also, the case where LENGTH ERROR is supposed to be raised does not happen
in GNU APL.

It seems as the specification for the rank operator is just broken on
several levels in the spec. That seems to me to be reason enough to not pay
attention to the spec in this case and just adapt the way Dyalog does it.

Here's the spec for the rank operator from the ISO spec:

*Informal Description:*
The result of *f⍤y* is a function which, when applied to *B*, returns *Z*,
the result of applying the function *f* to the rank-*y* cells of *B*.

*Evaluation Sequence:*
If *y* is a scalar, set *y1* to *,y*. Otherwise set *y1* to *y*.
If *y1* is not a vector, signal *domain-error*.
If *y1* has more than *three* elements, signal *length-error*.
If any element of *y1* is not a near-integer, signal *domain-error*.
Set *y2* to *⌽3⍴⌽y1*.
Set *y3* to the first-item in *y2*.
Set *y4* to the integer-nearest-to *y3*.
If *y4* exceeds the rank of *B*, set *y5* to the rank of *B*, otherwise set
*y5* to *y4*.
If *y5* is negative, set *y6* to *0⌈y5* plus the rank of *B*, otherwise set
*y6* to *y5*.
Apply *f* to the rank-*y6* cells of *B*.
Conform the individual result cells. Let their common shape after
conforming be *q*, and let *p* be the frame of *B* with respect to *f*,
that is, (rank of *B*) minus *y6*, and
return the overall result with shape *p*,*q*.

Reply via email to