A Compact contains fully evaluated, pure, immutable data.
Compact serves two purposes:
Data stored in a Compact has no garbage collection overhead. The garbage collector considers the whole Compact to be alive if there is a reference to any object within it.
A Compact can be serialized, stored, and deserialized again. The serialized data can only be deserialized by the exact binary that created it, but it can be stored indefinitely before deserialization.
Compacts are self-contained, so compacting data involves copying it; if you have data that lives in two Compacts, each will have a separate copy of the data.
The cost of compaction is fully evaluating the data + copying it. However, because compact does not stop-the-world, retaining internal sharing during the compaction process is very costly. The user can choose whether to compact or compactWithSharing.
When you have a Compact a, you can get a pointer to the actual object
in the region using getCompact. The Compact type
serves as handle on the region itself; you can use this handle
to add data to a specific Compact with compactAdd or
compactAddWithSharing (giving you a new handle which corresponds
to the same compact region, but points to the newly added object
in the region). At the moment, due to technical reasons,
it's not possible to get the Compact a if you only have an a,
so make sure you hold on to the handle as necessary.
Data in a compact doesn't ever move, so compacting data is also a way to pin arbitrary data structures in memory.
There are some limitations on what can be compacted:
Functions. Compaction only applies to data.
Pinned ByteArray# objects cannot be compacted. This is for a good reason: the memory is pinned so that it can be referenced by address (the address might be stored in a C data structure, for example), so we can't make a copy of it to store in the Compact.
Objects with mutable pointer fields (e.g. IORef,
GHC.Array.MutableArray) also cannot be compacted, because subsequent mutation would destroy the property that a compact is self-contained.
If compaction encounters any of the above, a CompactionFailed exception will be thrown by the compaction operation.