Implicit reboxing of unboxed tuple in let-patterns

Spiwack, Arnaud arnaud.spiwack at tweag.io
Fri Aug 28 13:04:12 UTC 2020


Dear all,

I discovered the hard way, yesterday, that lazy let pattern
matching is allowed on unboxed tuples. And that it implicitly reboxes
the pattern.

Here is how the manual describes it, from the relevant section
<https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-UnboxedTuples>
:

You can have an unboxed tuple in a pattern binding, thus

f x = let (# p,q #) = h x in ..body..

If the types of p and q are not unboxed, the resulting binding is lazy like
any other Haskell pattern binding. The above example desugars like this:

f x = let t = case h x of { (# p,q #) -> (p,q) }
          p = fst t
          q = snd t
      in ..body..

Indeed, the bindings can even be recursive.

Notice how h x is lazily bound, hence won’t necessarily be run when
body is forced. as opposed to if I had written, for instance,

let u = hxin ..body..

My question is: are we happy with this? I did find this extremely
surprising. If I’m using unboxed tuples, it’s because I want to
guarantee to myself a strict, unboxed behaviour. But a very subtle
syntactic detail seems to break this expectation for me. My
expectation would be that I would need to explicitly rebox things
before they get lazy again.

I find that this behaviour invites trouble. But you may disagree. Let
me know!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20200828/18ed781e/attachment.html>


More information about the ghc-devs mailing list