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

Iavor Diatchki iavor.diatchki at gmail.com
Thu Sep 10 17:45:02 UTC 2020


I am not sure what you'd expect this to do, but under what I was suggesting
it would be equivalent to
`let ~(x,y) = undefined in x `seq` y `seq ()`

Obviously it would be nice to warn/report error that this is probably a
mistake, which seems pretty easy to do.
What useful functionality do you think is lost by this?

The main tricky case I can think of is the interaction with pattern
synonyms, as one would have to keep track of
strict bindings in those.




On Thu, Sep 10, 2020 at 10:12 AM Chris Smith <cdsmith at gmail.com> wrote:

> 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/2ae223f1/attachment.html>


More information about the ghc-devs mailing list