pseq strictness properties

Duncan Coutts duncan.coutts at
Thu Nov 20 15:39:27 EST 2008

I don't think I'm just speaking for myself when I say that pseq is
confusing and the docs similarly.

Given the type

a -> b -> b

we would assume that it is lazy in it's first arg and strict in the
second. (Even in the presence of seq we know that it really really must
be strict in it's second arg since it returns it or _|_ in which case
it's still strict).

Of course we know of the seq primitive with this type that is strict in
both. However we also now have pseq that has the _opposite_ "static"
strictness to the original expected strictness.

Statically, pseq claims that it's strict in the first but lazy in the
parameter that it _returns_. At runtime of course it is strict in both

Given the need for pseq I would have expected pseq to statically be lazy
in it's first argument (and actually be strict at runtime). I expected
it'd statically be strict in the second arg.

So I'm wondering if there is a good explanation for pseq having the
opposite strictness properties to that which I expected. At first, even
after reading the docs I assumed that it was just a typo and that it
really meant it was lazy in the first arg (statically). I was just
recording a patch to "fix" the documentation when I checked the
underlying code and found to my surprise that the original docs are

I also think the docs need to be clarified to make this distinction
between the actual strictness behaviour and what the compiler thinks it
is during strictness analysis. Since they are different I think it's an
important distinction to make.

Now that I look at it, par has the same property, of statically being
lazy in the second parameter that it returns (and thus is really
strict). Again, this is not documented.

Summary: why is it that way round, and can we think of a way to explain
it better.


More information about the Glasgow-haskell-users mailing list