Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it common to mark record fields with UNPACK and strictness?

Tags:

haskell

ghc

I noticed this pattern is very common in Haskell libraries:

data Foo = Foo { field :: {-# UNPACK #-} !Sometype } 

e.g. UNPACKing a field's type and making it strict.

I understand what's the effect of the pragma and annotation but I don't understand why it is so pervasive: I have been programming in Haskell for 15 years and seldom used strictness annotation, and never UNPACK pragma.

If this idiom is so useful, why not make it less "ugly"?

like image 739
insitu Avatar asked May 22 '18 05:05

insitu


1 Answers

The pragma may be a bit ugly, but it avoids a lot more ugliness elsewhere. When performance is critical, programmers often need to choose a particular shape for a data constructor. Suppose I have

data Point = Point Int Int
data Segment = Segment Point Point

That makes good logical sense, but it has a bunch of extra indirection: one Segment consists of seven heap objects. If I'm working with a lot of segments, that's pretty bad.

I could squash this flat by hand:

data Segment = Segment Int# Int# Int# Int#

but now I've lost the fact that the numbers represent points, and everything I do with a segment will have to involve rather inconvenient and weird unboxed operations.

Fortunately, there's a better way:

-- The small strict Int fields will be unpacked by default
-- with any reasonably recent GHC version.
data Point = Point !Int !Int

data Segment = Segment {-# UNPACK #-} !Point {-# UNPACK #-} !Point

This still gives me one heap object per segment, but I can use Points and Ints and (generally) rely on the compiler unboxing everything nicely.

like image 130
dfeuer Avatar answered Oct 25 '22 22:10

dfeuer