How does 'lazy' work?

Posted by Matt Fenwick on Stack Overflow See other posts from Stack Overflow or by Matt Fenwick
Published on 2012-10-24T22:52:45Z Indexed on 2012/10/24 23:00 UTC
Read the original article Hit count: 428

Filed under:
|
|
|

What is the difference between these two functions? I see that lazy is intended to be lazy, but I don't understand how that is accomplished.

-- | Identity function.
id                      :: a -> a
id x                    =  x

-- | The call '(lazy e)' means the same as 'e', but 'lazy' has a 
-- magical strictness property: it is lazy in its first argument, 
-- even though its semantics is strict.
lazy :: a -> a
lazy x = x
-- Implementation note: its strictness and unfolding are over-ridden
-- by the definition in MkId.lhs; in both cases to nothing at all.
-- That way, 'lazy' does not get inlined, and the strictness analyser
-- sees it as lazy.  Then the worker/wrapper phase inlines it.
-- Result: happiness

Tracking down the note in MkId.lhs (hopefully this is the right note and version, sorry if it's not):

Note [lazyId magic] ~~~~~~~~~~~~~~~~~~~

lazy :: forall a?. a? -> a?   (i.e. works for unboxed types too)

Used to lazify pseq: pseq a b = a `seq` lazy b

Also, no strictness: by being a built-in Id, all the info about lazyId comes from here, not from GHC.Base.hi. This is important, because the strictness analyser will spot it as strict!

Also no unfolding in lazyId: it gets "inlined" by a HACK in CorePrep. It's very important to do this inlining after unfoldings are exposed in the interface file. Otherwise, the unfolding for (say) pseq in the interface file will not mention 'lazy', so if we inline 'pseq' we'll totally miss the very thing that 'lazy' was there for in the first place. See Trac #3259 for a real world example.

lazyId is defined in GHC.Base, so we don't have to inline it. If it appears un-applied, we'll end up just calling it.

I don't understand that because it refers to lazyId instead of lazy. How does lazy work?

© Stack Overflow or respective owner

Related posts about haskell

Related posts about semantic