Why is GHC's Int type
not guaranteed to use exactly 32 bits of precision? This document claim it has at least 30-bit signed precision. Is it somehow related to fitting Maybe Int
or similar into 32-bits?
相关问题
- Extracting from a Union Type when some have identi
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Top-level expression evaluation at compile time
- How do I get from a type to the TryParse method?
- Stuck in the State Monad
- foldr vs foldr1 usage in Haskell
- Java Generics: How to specify a Class type for a g
- List of checkboxes with digestive-functors
I think this is because of early ways to implement GC and all that stuff. If you have 32 bits available and you only need 30, you could use those two spare bits to implement interesting things, for instance using a zero in the least significant bit to denote a value and a one for a pointer.
Today the implementations don't use those bits so an
Int
has at least 32 bits on GHC. (That's not entirely true. IIRC one can set some flags to have 30 or 31 bitInt
s)It is to allow implementations of Haskell that use tagging. When using tagging you need a few bits as tags (at least one, two is better). I'm not sure there currently are any such implementations, but I seem to remember Yale Haskell used it.
Tagging can somewhat avoid the disadvantages of boxing, since you no longer have to box everything; instead the tag bit will tell you if it's evaluated etc.
The Haskell language definition states that the type
Int
covers at least the range [−229, 229−1]. There are other compilers/interpreters that use this property to boost the execution time of the resulting program.All internal references to (aligned) Haskell data point to memory addresses that are multiple of 4(8) on 32-bit(64-bit) systems. So, references need only 30bits(61bits) and therefore allow 2(3) bits for "pointer tagging".
In case of data, the GHC uses those tags to store information about that referenced data, i.e. whether that value is already evaluated and if so which constructor it has.
In case of 30-bit
Int
s (so, not GHC), you could use one bit to decide if it is either a pointer to an unevaluatedInt
or thatInt
itself.Pointer tagging could be used for one-bit reference counting, which can speed up the garbage collection process. That can be useful in cases where a direct one-to-one producer-consumer relationship was created at runtime: It would result directly in memory reuse instead of a garbage collector feeding.
So, using 2 bits for pointer tagging, there could be some wild combination of intense optimisation... In case of Ints I could imagine these 4 tags:
Int
Int
Int
itselfInt
.