Bang patterns, ~ patterns, and lazy let

Ben Rudiak-Gould Benjamin.Rudiak-Gould at
Tue Feb 7 09:06:00 EST 2006

John Hughes wrote:
> * ! on the left hand side of a let or where *has a different meaning to !
> in a pattern* -- it means that the ~ that would have been implicitly 
> inserted by the previous rule, is not inserted after all!

I wish it were that simple, but I don't think it is.

     let { !x = const undefined y ; !y = const 'a' x } in y

desugars in the current proposal to

     let { x = const undefined y ; y = const 'a' x } in x `seq` y `seq` y

which is _|_, but absent implicit ~,

     let { x = const undefined y ; y = const 'a' x } in y

had better (and does) mean 'a'. It's also not that case that !x has the same 
meaning in both proposals, e.g.

     let { !x = y ; !y = const 'a' x } in x

means 'a' in the current proposal but _|_ in yours.

My experience is that "top-level" strictness information has a very 
different nature from "nested" strictness information, and it's not 
generally possible to find a single interpretation that covers both. The 
reason is that strictness is a relationship between a value and its 
continuation (i.e. context). Nested strictness annotations connect data to a 
datatype context; top-level strictness annotations in this case connect data 
to either a case context or a let context. Each of the three situations has 
to be considered separately.

> This is not the same as banging the pattern with the implicit ~, because
> as I remarked above, !~p is not the same as p.

Actually if ! patterns were handled consistently in let they would come out 
as ~!p = ~p, so the ! would have no effect. The current proposal effectively 
borrows the ! notation, which would otherwise be useless, for a different 
purpose in this case.

-- Ben

More information about the Haskell-prime mailing list