For monitoring memory, there are tools such as ekg: Remote monitoring of processes that can help. As for “deploy in production and hope you get a hint”: if all else fails, then I guess that’s an option, but obviously not ideal. But this is no different to any other kind of bug. You don’t add assertions or print statements to your production code and hope to get a hint of where the bug is; instead, you have a test suite for this purpose. This is the main way in which I recommend the use of nothunks: use (state-based) property based testing so that you get minimal counter-examples of (a series of) API commands that introduce the unwanted thunks.
I absolutely agree with you that “making everything strict everywhere” is not the way to go, but it’s a tricky thing to balance, no matter whether you use a dynamic approach with nothunks or a static approach with th-deepstrict. For fields for which you have made a conscious decision that they really should be strict, you can exclude them from checks with either approach, but if you haven’t, and there is a field somewhere that has an unexpected thunk, I think with either approach you will need to start annotating, potentially quite a bit.
if a function has N (lifted) parameters, there are 2N possible combinations of strictness annotations for those parameters;
(and in Haskell, data constructors are also functions e.g. Just :: a -> Maybe a). So merely “banging” constructor fields isn’t enough; arguments of functions may also have to be “banged” too. Now if this “bang-a-thon” is tiring for Haskell professionals to the point of needing bespoke support libraries, spare a thought for Haskell beginners…
…meanwhile, back in 2003:
What a great idea - we build these nifty things called computers to do the boring stuff, so we’ll just have them deal with this boring stuff as well! Then Haskell beginners and professionals alike can attend to their actual tasks with less distractions: nice. There’s already a seven-year transition plan for Agda to be remade into Haskell’ dependent types to be implanted into Haskell, so how about a similar transition arrangement for the (Glasgow) Haskell implementation?