# MethSharing fail

Simon Peyton-Jones simonpj at microsoft.com
Wed Nov 17 16:20:40 EST 2010

```|  > Why has the behavior changed?  Because it depends whether eta-expansion happens
|  before float-out.  Now it does.  I could change that back.  The eta expander knows that
|  (sc_sel d) is cheap, so it turns it into this
|  > exp = /\a. \d.\x.  let d1 = sc_sel d in  ....(fromInteger d1 3)....
|  > and now again the floater can do nothing.
|
|  Couldn't this be handled by what you suggested for

Eh? I see no connection.

|  I'm not sure it's that unusual. I remember complaining about GHC not floating method
|  months ago.

We *do* now float method selections out of loops.  Eg

f :: Num a => a -> a
f = /\a. \(d:Num a). \x:a.
letrec g = \v -> ....(fromInteger a d 1)..(negate a d v).....g....
in blah

Here we will float the (fromInteger a d 1) and (negate a d) out of the g-loop, to give

f = /\a. \(d:Num a). \x:a.
let fi = fromInteger a d 1
nd = negate a d
letrec g = \v -> ....fi..(nd v).....g....
in blah

But we will *not* float here:

f =/\a. \(d:Num a). \v:a.   ...(fromInteger a d a1) ...(negate a d v)....

You could imagine we could get this

f = /\a. \(d:Num a).
let fi = fromInteger a d 1
nd = negate a d
in \v. ...fi...(nd v)...

It is conceivable this could be a win, as in
map (f a d) xs
(and that is the case in the MethSharing performance test) but it seldom is.  GHC's heuristic is never to float out *between* two value lambdas.

We could change that, but it's been that way for a long time.

Simon

```