
Malcolm Wallace
Alastair Reid
writes: The FFI spec says that the operations called 'shift' and 'rotate', shift and rotate their argument to the right. However, the GHC implementation in CVS shifts and rotates to the left, and is documented to do so. [..] This makes the specification come out nice and clean - you're multiplying the number by 2^n instead of 2^{-n}.
Errm, but then right shift comes out as dividing by 2^{-n}, instead of 2^n. For a unified shift operation, I don't think there is any good reason to prefer one direction over the other, since there is no precedent in another language (AFAIK).
I have no idea why I did it other than in GHC's libs. I think, it is a typo, because my intention was to duplicate the Bits interface of GHC's libs. So, I would propose to change the FFI spec. The main reason being that there is already plenty of code which relies on the current definition in GHC's Bits and there is no good reason to break that code. Objections?
However, while I'm on the subject, I'd like to request that the operations
shiftL, shiftR, -- :: a -> Int -> a rotateL, rotateR, -- :: a -> Int -> a
should become members of the class, with new default implementations
x `shift` i | i<0 = x `shiftL` i | i==0 = x | i>0 = x `shiftR` i x `rotate` i | i<0 = x `rotateL` i | i==0 = x | i>0 = x `rotateR` i
x `shiftL` i = x `shift` (-i) x `shiftR` i = x `shift` i x `rotateL` i = x `rotate` (-i) x `rotateR` i = x `rotate` i
(or with the directions the other way round if you insist.)
As I already noted, languages such as C provide only left and right shift (with no unified variant), and it would be nice to have the ability to override the default implementations of shiftL etc for specific types where we can call C directly. At the moment, a right shift turns into two negations in Haskell followed by the primitive call, and I'd like to squeeze the extra efficiency in if I can.
The FFI Addendum actually doesn't commit to which operations are in the class. It just says defines all these ops to have a context `Bits a', which is definitely the case. In other words, you proposed implementation is valid by the spec and your argument for it makes sense to me. Cheers, Manuel