!RE: Implicit reboxing of unboxed tuple in let-patterns

Chris Smith cdsmith at gmail.com
Thu Sep 10 17:12:01 UTC 2020


I agree that the strictness there was surprising, but I think this may be a
case where what is superficially expected is, in the end, inconsistent.

What about:

let ~(!x, !y) = undefined in ()

If nested bang patterns implied strictness of their parents, this valid
expression seems not to make any sense.  I can see a few ways to deal with
that, but none of them seem intuitive to me.

One could disallow it, and only allow strictness annotations on variables
rather than all patterns, but this sacrifices a lot of functionality to
avoid that surprise.  Alternatively, one could say that upward propagation
of strictness is only a default, but that definitely feels like a hack.  It
might make the original example behave as expected, but it is no longer for
the expected reasons, and suddenly there is something even more complex
going on.

I don't have a strong opinion here, but I think it's important to consider
more complex cases when making the decision.

On Thu, Sep 10, 2020, 12:39 PM Iavor Diatchki <iavor.diatchki at gmail.com>
wrote:

> Ah, yes, quite right: since the projections match the whole patterns, the
> bang patterns in a constructor would be forced as soon as one of the fields
> in the constructor is used, so this also diverges:
>
> ex3 = let (x, !y) = (5,undefined) in x
>
> The rule is consistent, to me it just seems quite unintuitive.
>
>
>
> On Thu, Sep 10, 2020 at 9:18 AM Richard Eisenberg <rae at richarde.dev>
> wrote:
>
>> This whole area is clearly somewhat troublesome:
>>
>> On Sep 10, 2020, at 12:05 PM, Iavor Diatchki <iavor.diatchki at gmail.com>
>> wrote:
>>
>> 3. nested bang patterns in pattern bindings should count as "uses" of the
>> value and therefore should be strict.  For example if I write `let ( !x, !y
>> ) = undefined in ()`, I think this should be equivalent to `let (x,y) =
>> undefined in x `seq` y `seq` ()`.  With the current behavior the bang
>> patterns don't do anything, while my guess would be that most people would
>> expect the suggested behavior instead.  As usual, we should not allow that
>> at the top level.
>>
>>
>> This isn't quite right.
>>
>> Consider
>>
>> ex0 = let ( !x, !y ) = undefined in ()
>> ex1 = let ( !x, !y ) = (5, undefined) in x
>> ex2 = let ( !x, y )  = (5, undefined) in x
>>
>>
>> ex0 converges, because let-bindings are lazy by default.
>> ex1 diverges, because the bang on y means that, when the patten-match
>> happens at all, x and y are bound strictly. So bangs *do* matter in nested
>> patterns within pattern bindings. By contrast, ex2 converges.
>>
>> Again, I'm not arguing in favor of the current behavior, but I want to
>> make sure we're all as informed as possible in this debate.
>>
>> Richard
>>
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20200910/2f566165/attachment.html>


More information about the ghc-devs mailing list