## _mod_() definition blocks AWLF from operating on rotate() for AKD arrays

Bugzilla Link | 1042 |

Created on | Jan 09, 2013 15:16 |

Version | svn |

OS | Linux |

Architecture | PC |

## Extended Description

I have been looking at the SAC stdlib rotate (and shift) functions, as they relate to AWLF, and this led me to look at the definition of the _mod_() primitive in SAC. I find it wanting, for several reasons. The underlying challenge is to make AWLF/WLF operate with rotate as a producer WL and as a consumer WL. The existing stdlib code uses mod() and a conditional to normalize the rotate count. I.e., map it into a non-negative integer in the range 0...(N-1), where N is the length of the rotation axis. In the common cases where the rotate count is a constant, this is not a problem. However, in APL code, we often see expressions such as this one, to drop the leading blanks from a text vector: ((vec≠' ')⍳1) ↓ vec or ((vec≠' ')⍳1) ⌽ vec I do not know what the design rationale was for the mod() primitive, but suspect it was intended to mimic the behavior of the (equally ill-defined) a%b (remainder) operation in C. 1. According to the C99 standard*, the result is defined only if "...the quotient a/b is representable". E.g., 0%0 is undefined. For rotate() arguments where the rotate count ends up being zero, this can cause the normalization of the rotate count to signal an error. In APL, where considerable thought was given to the definition of residue (aka remainder) on all integers, floats, and complex numbers, 0 | 0 ( 0%0 in C) is defined to produce 0. 2. In K&R (2nd Edition), "the sign of the result for % {is} machine-dependent for negative operands." By constrast, in APL, the definition is clearly specified for all integer (and, in fact, all numeric) arguments. NB. argument order is reversed in SAC from that of APL: ¯5 ¯4 ¯3 ¯2 ¯1 0 1 2 3 4 NB. A 0 1 2 3 4 0 1 2 3 4 NB. 5|A (AKA A%5) This is not the same as the current behavior of the SAC mod() primitive on negative A: -5 -4 -3 -2 -1 0 1 2 3 4 NB. A -5 -4 -3 -2 -1 0 1 2 3 4 NB. A%5 Note that the APL definition maps a negative rotate count into the correct non-negative count. The SAC behavior requires checking for a negative count and then adding b to the count for negatives. This often inhibits the ability to perform AWLF on rotated arguments/results, because of problems around partition/index vector intersect calculation. Furthermore, it may be that the SAC definition is "implementation-dependent", in which case we are left in a position of not being able even to specify the behavior of the stdlib rotate() function. It could screw anyone running on an implementation (e.g., Windows?) that produces different results. If we are going to define stdlib functions on SAC primitives, then we need to define the precise semantics of those primitives, and eschew "implementation-dependent" behavior. So, a few questions,and a few proposals for redefinition: Q1: Does anybody depend on the result of SAC mod() on negative or zero arguments? Q2: Are there concrete objections to extending the definition of SAC mod() to handle zeros and negative arguments in the same way that APL does, thereby avoiding any arguments about "implementation-defined" behavior there and in the stdlib? P0: If the answers to Q1 and Q2 are No, I propose to change sac2c mod() to operate as APL does, and to change the stdlib rotate() functions to rely on that definition. 2013-01-09: I have not heard any response from sacdev or others on this topic. Silence is consent, in my book, so I am going to proceed with the above implementation, as proposed. * This is a draft of same: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information