Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations

Gershom B gershomb at gmail.com
Mon Sep 29 03:06:52 UTC 2014


Did I miss in this thread an actual use-case for strict and/or for Bool such that it might occur in a tight inner loop? Absent such a use case, I’m -1 on this proposal. If I wanted to use something that I felt had strict bitwise behaviour, I’d never reach for a bool, no matter what operator set I was working with. My instinct would be to reach for a Word8 or the like, since on any real implementation it would take up the same space regardless?

Essentially, to my laziness-infected brain, the current instance obeys the principle of least surprise, and the proposed instance violates the sort of wall of “abstraction intuitions” I’ve built up regarding when I should and shouldn’t expect lazy behaviour.

-g


On September 27, 2014 at 1:59:43 PM, David Feuer (david.feuer at gmail.com) wrote:
> Currently, the (.&.) and (.|.) methods for Bool are short-circuiting,
> defined like this:
>  
> instance Bits Bool where
> (.&.) = (&&)
>  
> (.|.) = (||)
>  
> Unlike the instances for Int, Word, etc., this gives short-circuiting
> behavior (conditionally lazy in the second operand). Unfortunately, this
> requires a conditional branch to implement, which can sometimes be bad.
> Since (&&) and (||) are readily available to anyone who wants
> short-circuiting, I propose that we use the following instead. Note that
> the Bits class does not specify anything about this aspect of instance
> behavior.
>  
> x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y)
>  
> x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y)
>  
> The rest of the operations look like this:
>  
> x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y)
>  
> complement x = tagToEnum# (dataToTag# x `xorI#` 1#)
>  
> shift x s = testBit x s
>  
> rotate x _ = x
>  
> -- I don't think we gain anything changing this one.
> bit 0 = True
> bit _ = False
>  
> testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#))
>  
> bitSizeMaybe _ = Just 1
>  
> bitSize _ = 1
>  
> isSigned _ = False
>  
> popCount x = I# (dataToTag# x)
>  
> instance FiniteBits Bool where
> finiteBitSize _ = 1
> countTrailingZeros x = I# (dataToTag# x `xorI#` 1#)
> countLeadingZeros x = I# (dataToTag# x `xorI#` 1#)
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
>  



More information about the Libraries mailing list