<p>The angst about <code>Prelude.seq</code> (frequently in association with <code>⊥</code>) is mostly attributed to a few reasons:</p>
<ol>
<li><p>it weakens <em>extensionality</em></p>
<pre><code> -- (\ x -&gt; f x) == f

seq (\ x -&gt; ⊥ x) y = y

seq ⊥ y = ⊥
</code></pre>
</li>
<li><p>it weakens <em>parametricity</em></p>
<pre><code> --  foldr k z (build g) == g k z

foldr ⊥ 0 (build seq) = foldr ⊥ 0 (seq (:) [])
                      = foldr ⊥ 0 []
                      = 0

seq ⊥ 0 = ⊥
</code></pre>
</li>
<li><p>it invalidates various laws e.g. those for the monadic interface</p>
<pre><code> --  m &gt;&gt;= return == m

seq (⊥ &gt;&gt;= return :: State s a) True = True

seq (⊥ :: State s a) True = ⊥
</code></pre>
</li>
</ol>
<p>However:</p>
<ol>
<li><p>Extensionality is also weakened by the combination of call-by-need semantics and the use of weak-head normal form, <a href="https://www.pauldownen.com/publications/first-class-call-stacks.pdf" rel="nofollow noreferrer">as noted by</a> Philip Johnson-Freyd, Paul Downen and Zena Ariola.</p>
</li>
<li><p>Parametricity is similarly weakened by the combination of GADTs and the corresponding map functions satisfying the functor laws, <a href="https://arxiv.org/pdf/2105.03389v3" rel="nofollow noreferrer">as shown by</a> Patricia Johann, Enrico Ghiorzi, and Daniel Jeffries.</p>
</li>
<li><p>The presence of the polymorphic fixed-point operator:</p>
<pre><code>yet :: (a -&gt; a) -&gt; a
yet f = f (yet f)
</code></pre>
<p>also imposes restrictions on parametricity, <a href="https://dl.acm.org/doi/pdf/10.1145/99370.99404" rel="nofollow noreferrer">as specified by</a> Philip Wadler.</p>
</li>
<li><p>That certain combinations of operators and values can invalidate basic logical or mathematical rules isn't new e.g. division and zero. Like division, <a href="https://www.janis-voigtlaender.eu/papers/TamingSelectiveStrictness.pdf" rel="nofollow noreferrer">selective strictness</a> is necessary - algorithms for determining strictness (a nontrivial property) are subject to <a href="http://kilby.stanford.edu/%7Ervg/154/handouts/Rice.html" rel="nofollow noreferrer">Rice's theorem</a>: they may not always succeed, resulting in unexpectedly-excessive memory usage (i.e. space leaks) in programs. As for the choice to use primitive operators or annotations (for <a href="https://downloads.haskell.org/%7Eghc/7.8.4/docs/html/users_guide/bang-patterns.html" rel="nofollow noreferrer">patterns</a> or <a href="https://www.haskell.org/onlinereport/haskell2010/haskellch4.html" rel="nofollow noreferrer">types</a>), that usually doesn't change the adverse impact on important theorems and laws.</p>
<p>Another option could be to use an <a href="https://www.cs.nott.ac.uk/%7Epszgmh/clairvoyant.pdf" rel="nofollow noreferrer">augmented form</a> of call-by-value semantics, but that presumes the method of augmentation being used is sufficiently <em>&quot;well-behaved&quot;</em>.</p>
</li>
</ol>
<hr />
<p>At some time in the future, perhaps there will be one or more advances in the computing sciences that resolve the matter. Until then, the most practical option is to manage the awkward interaction between useful laws and theorems and this along with other <a href="https://d-nb.info/1045276316/34" rel="nofollow noreferrer">real-world programming features</a>.</p>
Why is seq bad?
<p>Haskell has a magical function named <code>seq</code>, which takes an argument of any type and reduces it to <em>Weak Head Normal Form</em> (WHNF).</p>

<p>I've read a couple of sources [not that I can remember who they were <em>now</em>...] which claim that "polymorphic <code>seq</code> is bad". In what way are they "bad"?</p>

<p>Similarly, there is the <code>rnf</code> function, which reduces an argument to <em>Normal Form</em> (NF). But <em>this</em> is a class method; it does not work for arbitrary types. It seems "obvious" to me that one could alter the language spec to provide this as a built-in primitive, similar to <code>seq</code>. This, presumably, would be "even more bad" than just having <code>seq</code>. In what way is this so?</p>

<p>Finally, somebody suggested that giving <code>seq</code>, <code>rnf</code>, <code>par</code> and similars the same type as the <code>id</code> function, rather than the <code>const</code> function as it is now, would be an improvement. How so?</p>