Don't float out lets in between lambdsa
Consider
f = \x. let y = <blah>
in \z. let v = h x y in <stuff>
The full laziness pass will float out that v-binding thus
f = \x. let y = <blah>
v = h x y
in \z. <stuff>
And now (if h
is, say, imported) it'll stay like that.
But suppose <blah>
simlifies to Just x
. Then we allow ourselves to eta-expand thus
f = \x z. let y = <blah>
v = h x y
in <stuff>
Now (an early design choice in the let-floater) we never float the v-binding in between the \x
and \z
.
This is very non-confluent: a smal change in exactly how rapidly <blah>
simplifies can
have a big, irreversible effect on the code for f
.
IDEA: extend the let-floater's design choice to not float out between two lambdas, even if they are separated by lets/cases etc. One way to say this is to ask when a lambda gets a new level number compared to its immediately enclosing lambda.
Examples where y
gets the same level number as x
\x.\y. blah
\x. let binds in \y
\x. case scrut of pi -> \y.blah
Examples where y
gets the a level number one bigger than x
\x. let v = \y.rhs in blah
\x. f (\y.rhs)
This probably won't make a lot of difference, but it'd be worth trying
Trac metadata
Trac field | Value |
---|---|
Version | 8.4.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |