Copying over my comment from Reddit
Thanks for this talk and thanks for the nothunks
library!
One thing that confuses me about nothunks
is that it does at run time what could be done at compile time (though I take the point that the talk emphasizes that its proper use is at run time of tests). As a thought experiment, what would it look like if we used th-deepstrict
for this purpose instead? Well, I think at the definition point of UserInfo
we’d write
$(assertDeepStrict =<< [t| UserInfo |])
and it would tell us that the fields of UserInfo
are not strict. We’d then rewrite to
data UserInfo = UserInfo {
lastActive :: !UTCTime,
, visits :: !Word
}
and it would tell us that UTCTime
is not deep strict, so we’d rewrite to
data UserInfo = UserInfo {
lastActive :: !(Strict UTCTime),
, visits :: !Word
}
and then it would tell us that UserInfo
is indeed deep strict. We’re done! We’ve (made invalid laziness unrepresentable](make-invalid-laziness-unrepresentable).
N.B. Strict
is from the strict-wrapper
library, but I haven’t actually added a UTCTime
instance yet. I should!
Forbidding thunks statically seems much better than checking for them dynamically. I suppose one benefit of nothunks
is that we might want a data type to be able to contain thunks and only require them to be absent in certain situations, but that seems of marginal utility. Is there some other reason the dynamic analysis is preferable to the static one?
cc @TeofilC