In working on tests for SRFI 143 (fixnums), I have discovered a massive discrepancy in the definition of the bitwise-if procedure. This procedure started its life in SRFI 33 as bitwise-merge, where it was defined as follows:
bitwise-merge mask i0 i1 -> exact-integer
Merge the bitstrings I0 and I1, with bitstring MASK determining
from which string to take each bit. That is,
RESULT[k] := if MASK[k] = 0 then I0[k] else I1[k].
So i0 is the source of bits in the result where the mask bit is 0, and i1 is the source where the mask bit is 1. So far, so plausible.
The next step is SRFI 60, which contains a procedure known as bitwise-if, also named bitwise-merge for backwards compatibility with SRFI 33:
Function: bitwise-if mask n0 n1
Function: bitwise-merge mask n0 n1
Returns an integer composed of some bits from integer n0 and some from integer n1. A bit of the result is taken from n0 if the corresponding bit of integer mask is 1 and from n1 if that bit of mask is 0.
Unfortunately (and this was apparently not noticed at the time), this function is *not* bitwise-merge from SRFI 33, because it specifies the opposite interpretation of its last two arguments. That is, n0 is the source of bits in the result where the mask bit is 1, and n1 is the source where the mask bit is 0.
Both conventions have some logic. 0 precedes 1, so making the source for 0 mask bits precede the source of 1 mask bits is sensible. But if we think of 0 as false and 1 as true, then it's reasonable for the source of true mask bits to precede the source of false mask bits, just as in the `if` syntax.
By the accidents of history, SRFI 33 was never finished, and SRFI 60 (which is based on SLIB) was. The R6RS (rnrs arithmetic bitwise) library is a subset of SRFI 60 (with some renaming), and naturally uses the SRFI 60 semantics and the name bitwise-if. The purpose of SRFI 142 was to rehabilitate SRFI 33 and add the additional procedures provided in SRFI 60 to create an all-singing, all-dancing bitwise SRFI.
The result is that SRFI 142 perpetuates the definition given by a withdrawn SRFI, and contradicts the definition used in SLIB and R6RS, which have doubtless seen far more usage. I didn't find this out until I was looking for tests for fxif (the fixnum version of bitwise-if) for SRFI 143, and noticed that they were all backwards from the viewpoint of the SRFI 33 code I was using.
I'm not sure what to do about this. It's rather dramatic for an erratum, although we have had SRFI errata on this scale before. SRFI 142 is not yet in R7RS-large ballotting and is relatively new, so I could live with deprecating it in favor of a new SRFI number with just this change. I think it would be a mistake to do nothing at all, given existing code and the fact that this is a silent breaking change from SLIB and R6RS. (We already had one similar change in R7RS-small, bytevector-copy!, but I feel confident that R6RS was simply wrong in that case.)
Comments?
--
weirdo: When is R7RS coming out?
Riastradh: As soon as the top is a beautiful golden brown and if you
stick a toothpick in it, the toothpick comes out dry.