[ghc-steering-committee] Proposal #46: NOUNPACK pragmas for function arguments

Simon Marlow marlowsd at gmail.com
Mon May 8 08:51:33 UTC 2017


https://github.com/ghc-proposals/ghc-proposals/pull/46

I tentatively propose that we accept this proposal.

Briefly, the proposal is to allow a NOUNPACK pragma in a *type signature*
to indicate that a value should not be unpacked by the worker-wrapper
transformation, e.g.:

insertR :: Ord k => {-# NOUNPACK #-} k -> v -> Map k v -> Map k v
insertR k v m = go k k v m
  where
    go :: Ord k => {-# NOUNPACK #-} k -> k -> v -> Map k v -> Map k v
    go kp k v m = ...

The idea is that sometimes unpacking a strict argument leads to worse code
because the repacking doesn't get simplified away, and it's hard for
worker-wrapper to tell that up front. It's quite difficult for the
programmer to avoid this problem currently - the one trick we have
available is the `lazy` pseudo-function, but that's difficult to use for
this purpose because you have to ensure that *all* uses of the argument are
made lazy, and there can be collateral damage.  It's the wrong tool to
solve this problem, but it's the only tool we have.

I've had this issue personally, and I've worked around it with `lazy`, but
it's an ugly and brittle workaround, and something better is needed.

If we assume that NOUNPACK can only occur on the left of an arrow (rather
like UNPACK/NOUNPACK in a GADT signature), then it's a fairly
straightforward extension, and just requires plumbing the information
through to the demand analyser / worker-wrapper.

The dual UNPACK annotation also makes sense, I think, although it's not
part of this proposal.  I can imagine it being a future extension.

Drawbacks I see:
- It doesn't let you say anything more detailed than just "no", e.g. you
can't say "don't unpack the first field of the record"
- It requires a type signature, which you wouldn't otherwise need.  I
suppose you could use PartialTypeSignatures.
- It doesn't let you say anything about strictness, only unpacking.  If a
NOUNPACK argument is inferred by the demand analyser to be strict, callers
can use call-by-value.

Overall I don't see any fatal flaws and there are benefits. It's not a
beautiful extension by any means, but I don't think it's expensive or
complicated to implement.  I suggest we accept it.  Thoughts?

Cheers
Simon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-steering-committee/attachments/20170508/372793c6/attachment.html>


More information about the ghc-steering-committee mailing list