<p dir="ltr">Suddenly the eta reduce hlint warning becomes much more important.</p>
<p dir="ltr">Alan</p>
<div class="gmail_extra"><br><div class="gmail_quote">On 23 Aug 2016 11:22 a.m., "Tom Ellis" <<a href="mailto:tom-lists-haskell-cafe-2013@jaguarpaw.co.uk">tom-lists-haskell-cafe-2013@jaguarpaw.co.uk</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">*Very* interesting. Here is the key section of the GHC users guide:<br>
<br>
GHC will only inline the function if it is fully applied, where “fully<br>
applied” means applied to as many arguments as appear (syntactically) on<br>
the LHS of the function definition<br>
<br>
That this is a good heuristic is *extremely* counterintuitive to me. I<br>
would have supposed that being more explicit, for example<br>
<br>
{-# INLINE (.) f g #-}<br>
<br>
to inline on all static applications of at least two arguments would have<br>
been a much clearer way to communicate this message.<br>
<br>
What's the rationale behind the current behaviour?<br>
<br>
Tom<br>
<br>
<br>
On Tue, Aug 23, 2016 at 09:56:25AM +0100, Matthew Pickering wrote:<br>
> I think the point which no-one has articulated yet is that the<br>
> source-level arity of (.) affects whether GHC will decide to inline it.<br>
><br>
> Only fully saturated applications are inlined<br>
[...]<br>
><br>
> On Tue, Aug 23, 2016 at 8:33 AM, Tom Ellis<br>
> <<a href="mailto:tom-lists-haskell-cafe-2013@jaguarpaw.co.uk">tom-lists-haskell-cafe-2013@<wbr>jaguarpaw.co.uk</a>> wrote:<br>
> > On the contrary, they're exactly the same (on GHC 7.6.3):<br>
> ><br>
> > module Foo where<br>
> ><br>
> > comp1 f g x = f (g x)<br>
> ><br>
> > comp2 f g = \x -> f (g x)<br>
> ><br>
> ><br>
> > % ghc -O0 -dsuppress-all -fforce-recomp -no-link -ddump-prep test.hs<br>
> > [1 of 1] Compiling Foo ( test.hs, test.o )<br>
> ><br>
> > ==================== CorePrep ====================<br>
> > Result size of CorePrep = {terms: 24, types: 36, coercions: 0}<br>
> ><br>
> > comp2<br>
> > comp2 =<br>
> > \ @ t_aeU @ t1_aeV @ t2_aeW f_sfz g_sfy x_sfx -><br>
> > let {<br>
> > sat_sfI<br>
> > sat_sfI = g_sfy x_sfx } in<br>
> > f_sfz sat_sfI<br>
> ><br>
> > comp1<br>
> > comp1 =<br>
> > \ @ t_af5 @ t1_af6 @ t2_af7 f_sfG g_sfF x_sfE -><br>
> > let {<br>
> > sat_sfJ<br>
> > sat_sfJ = g_sfF x_sfE } in<br>
> > f_sfG sat_sfJ<br>
> ><br>
> > (the same holds for -O2, if you compile them separately)<br>
> ><br>
> > On Tue, Aug 23, 2016 at 05:19:38PM +1000, Ben wrote:<br>
> >> At the semantic level of "does my program compute correct results" they're<br>
> >> identical. At the operational level of "how fast does my program run"<br>
> >> they're different.<br>
> >><br>
> >><br>
> >> On August 23, 2016 5:09:19 PM GMT+10:00, Tom Ellis <<a href="mailto:tom-lists-haskell-cafe-2013@jaguarpaw.co.uk">tom-lists-haskell-cafe-2013@<wbr>jaguarpaw.co.uk</a>> wrote:<br>
> >> >On Mon, Aug 22, 2016 at 10:23:07PM -0700, wren romano wrote:<br>
> >> >> (.) f g = \x -> f (g x)<br>
> >> >><br>
> >> >> vs:<br>
> >> >><br>
> >> >> (.) f g x = f (g x)<br>
> >> >><br>
> >> >> has ramifications, though it's fairly easy to guess which one of<br>
> >> >those<br>
> >> >> two will be most performant.<br>
> >> ><br>
> >> >Are these not synonyms? What is the meaning of<br>
> >> ><br>
> >> > fargs var = expr<br>
> >> ><br>
> >> >if not<br>
> >> ><br>
> >> > fargs = \var -> expr<br>
> >> ><br>
> >> >?<br>
______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div></div>