Implicit reboxing of unboxed tuple in let-patterns

2020-08-28 Thread Spiwack, Arnaud
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

:

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!
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Implicit reboxing of unboxed tuple in let-patterns

2020-08-28 Thread Carter Schonwald
Have you tried using do notation for bindings you want to keep strict, with
Eg the identity monad?  That doesn’t address  the design critique but gives
you a path forward ?

I do agree that the semantics / default recursivity Of let bindings  can be
inappropriate for non recursive code , but would any other non uniform
semantics or optimization be safe?

On Fri, Aug 28, 2020 at 9:05 AM Spiwack, Arnaud 
wrote:

> 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
> 
> :
>
>
>
>
> 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 = hx
>
> in ..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!
>
>
>
>
> ___
>
> ghc-devs mailing list
>
> ghc-devs@haskell.org
>
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Implicit reboxing of unboxed tuple in let-patterns

2020-08-28 Thread Spiwack, Arnaud
Hi Carter,

We are using let !(#x,y#) = … actually. Having the strict behaviour is not
particularly difficult. You can even use case … of (#x, y#) ->… directly,
it’s not too bad. My complaint, as it were, is solely about the potential
for mistakes.

On Fri, Aug 28, 2020 at 3:20 PM Carter Schonwald 
wrote:

> Have you tried using do notation for bindings you want to keep strict,
> with Eg the identity monad?  That doesn’t address  the design critique but
> gives you a path forward ?
>
> I do agree that the semantics / default recursivity Of let bindings  can
> be inappropriate for non recursive code , but would any other non uniform
> semantics or optimization be safe?
>
> On Fri, Aug 28, 2020 at 9:05 AM Spiwack, Arnaud 
> wrote:
>
>> 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
>> 
>> :
>>
>>
>>
>>
>> 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 = hx
>>
>> in ..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!
>>
>>
>>
>>
>> ___
>>
>> ghc-devs mailing list
>>
>> ghc-devs@haskell.org
>>
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>
>>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Parsing funny arrows

2020-08-28 Thread Csongor Kiss
Hello devs,

I am trying to modify GHC's parser to allow the following syntax in types:

  a -> @m b

but my naive attempt was unsuccessful:

type :: { LHsType GhcPs }
: btype{ $1 }
| btype '->' PREFIX_AT btype ctype  ...

For example when I try to parse the following code (and turn on the lexer debug 
log):
  
  test :: a -> @m b
  test = undefined

I get the following 

token: ITvarid "test"
token: ITdcolon NormalSyntax
token: ITvarid "a"
token: ITrarrow NormalSyntax
token: ITtypeApp
token: ITvarid "m"
token: ITvarid "b"
token: ITsemi

Parse.hs:2:1: error:
parse error (possibly incorrect indentation or mismatched brackets)
  |
2 | test = undefined


I don't have much experience with hacking on the parser so I'm likely missing 
something obvious.
Could someone please point at what I might be doing wrong?

Thanks in advance.

Cheers,
Csongor___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Parsing funny arrows

2020-08-28 Thread Vladislav Zavialov
Hi Csongor,

I believe the reason for this failure is that  a -> @m b  gets parsed as  a -> 
@(m b).
Why is that? Because a ‘btype’ includes type-level application.

If you replace the ‘btype’ after PREFIX_AT with an ‘atype’, this particular 
issue should go away. At least that’s my hypothesis, I haven’t tested it.

- Vlad

> On 29 Aug 2020, at 01:32, Csongor Kiss  wrote:
> 
> Hello devs,
> 
> I am trying to modify GHC's parser to allow the following syntax in types:
> 
>   a -> @m b
> 
> but my naive attempt was unsuccessful:
> 
> type :: { LHsType GhcPs }
> : btype{ $1 }
> | btype '->' PREFIX_AT btype ctype  ...
> 
> For example when I try to parse the following code (and turn on the lexer 
> debug log):
>   
>   test :: a -> @m b
>   test = undefined
> 
> I get the following 
> 
> token: ITvarid "test"
> token: ITdcolon NormalSyntax
> token: ITvarid "a"
> token: ITrarrow NormalSyntax
> token: ITtypeApp
> token: ITvarid "m"
> token: ITvarid "b"
> token: ITsemi
> 
> Parse.hs:2:1: error:
> parse error (possibly incorrect indentation or mismatched brackets)
>   |
> 2 | test = undefined
> 
> 
> I don't have much experience with hacking on the parser so I'm likely missing 
> something obvious.
> Could someone please point at what I might be doing wrong?
> 
> Thanks in advance.
> 
> Cheers,
> Csongor
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Parsing funny arrows

2020-08-28 Thread Shayne Fletcher
On Fri, Aug 28, 2020 at 7:38 PM Vladislav Zavialov 
wrote:

> Hi Csongor,
>
> I believe the reason for this failure is that  a -> @m b  gets parsed as
> a -> @(m b).
> Why is that? Because a ‘btype’ includes type-level application.
>
> If you replace the ‘btype’ after PREFIX_AT with an ‘atype’, this
> particular issue should go away. At least that’s my hypothesis, I haven’t
> tested it.
>
>
I confirm that this is correct and with that change the example string
reduces as hoped.


- Vlad
>

-- 
Shayne Fletcher
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Parsing funny arrows

2020-08-28 Thread Shayne Fletcher
On Fri, Aug 28, 2020 at 7:48 PM Shayne Fletcher <
shayne.fletcher...@gmail.com> wrote:

>
>
> On Fri, Aug 28, 2020 at 7:38 PM Vladislav Zavialov 
> wrote:
>
>> Hi Csongor,
>>
>> I believe the reason for this failure is that  a -> @m b  gets parsed as
>> a -> @(m b).
>> Why is that? Because a ‘btype’ includes type-level application.
>>
>> If you replace the ‘btype’ after PREFIX_AT with an ‘atype’, this
>> particular issue should go away. At least that’s my hypothesis, I haven’t
>> tested it.
>>
>>
> I confirm that this is correct and with that change the example string
> reduces as hoped.
>
>
> - Vlad
>>
>
Also, with that correction there are no new shift/reduce conflicts. The
original rule gave rise to 3.

-- 
Shayne Fletcher
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs