title: Eta-conversion changes semantics in a strict language
body: <p>Take this OCaml code:</p>
  
  <pre class="lang-ml prettyprint-override"><code>let silly (g : (int -&gt; int) -&gt; int) (f : int -&gt; int -&gt; int) =
          g (f (print_endline "evaluated"; 0))
  
  silly (fun _ -&gt; 0) (fun x -&gt; fun y -&gt; x + y)
  </code></pre>
  
  <p>It prints <code>evaluated</code> and returns <code>0</code>. But if I eta-expand <code>f</code> to get <code>g (fun x -&gt; f (print_endline "evaluated"; 0) x)</code>, <code>evaluated</code> is no longer printed.</p>
  
  <p>Same holds for this SML code:</p>
  
  <pre class="lang-ml prettyprint-override"><code>fun silly (g : (int -&gt; int) -&gt; int, f : int -&gt; int -&gt; int) : int =
          g (f (print "evaluated" ; 0));
  
  silly ((fn _ =&gt; 0), fn x =&gt; fn y =&gt; x + y);
  </code></pre>
  
  <p>On the other hand, this Haskell code doesn't print <code>evaluated</code> even with the strict pragma:</p>
  
  <pre class="lang-hs prettyprint-override"><code>{-# LANGUAGE Strict #-}
  
  import Debug.Trace
  
  silly :: ((Int -&gt; Int) -&gt; Int) -&gt; (Int -&gt; Int -&gt; Int) -&gt; Int
  silly g f = g (f (trace "evaluated" 0))
  
  main = print $ silly (const 0) (+)
  </code></pre>
  
  <p>(I can make it, though, by using <code>seq</code>, which makes perfect sense for me)</p>
  
  <p>While I understand that OCaml and SML do the right thing theoretically, are there any practical reason to prefer this behaviour to the "lazier" one? Eta-contraction is a common refactoring tool and I'm totally scared of using it in a strict language. I feel like I should paranoically eta-expand everything, just because otherwise arguments to partially applied functions can be evaluated when they're not supposed to. When is the "strict" behaviour useful?</p>
  
  <p>Why and how does Haskell behave differently under the <code>Strict</code> pragma? Are there any references I can familiarize myself with to better understand the design space and pros and cons of the existing approaches?</p>