#7542: GHC doesn't optimize (strict) composition with id
------------------------------------+---------------------------------------
Reporter: shachaf | Owner:
Type: bug | Status: new
Priority: normal | Component: Compiler
Version: 7.6.1 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: Runtime performance bug | Blockedby:
Blocking: | Related:
------------------------------------+---------------------------------------
Newtype constructors and selectors have no runtime overhead, but some uses
of them do. For example, given `newtype Identity a = Identity {
runIdentity :: a }`, `Identity` turns into `id`, but `Identity . f` turns
into `id . f`, which is distinct from `f`, because it gets eta-expanded to
`\x -> f x`.
It would be nice to be able to compose a newtype constructor with a
function without any overhead. The obvious thing to try is strict
composition:
{{{
(#) :: (b -> c) -> (a -> b) -> a -> c
(#) f g = f `seq` g `seq` \x -> f (g x)
}}}
In theory this should get rid of the eta-expansion. In practice, the
generated Core looks like this:
{{{
foo :: (a -> b) -> [a] -> [b]
foo f = map (id # f)
-- becomes
foo = \f e -> map (case f of g { __DEFAULT -> \x -> g x }) e
}}}
Different variations of `(#)`, and turning `-fpedantic-bottoms` on, don't
seem to affect this. A simpler version, `foo f = map (f `seq` \x -> f x)`,
generates the same sort of Core.
In one library we resorted to defining a bunch of functions of the form
`identityDot :: (a -> b) -> a -> Identity b; identityDot = unsafeCoerce`.
It would be better to be able to rely on GHC to do the optimization
directly, if we use strict composition anyway.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7542>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs