#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

 (#) :: (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

Reply via email to