Changes between Version 2 and Version 3 of BangPatterns

Feb 2, 2006 4:57:58 PM (9 years ago)



  • BangPatterns

    v2 v3  
    6565== Non-recursive let and where bindings == 
     67First, we deal with ''non-recursive'' bindings only. 
    6768In Haskell, let and where bindings can bind patterns.  Their semantics is given by translation to a case, with an implicit implicit tilde (~). 
    9697which evaluates the (f x), thereby giving a strict `let`. 
     99== Examples == 
    98100Here is a more realistic example, a strict version of partition: 
    120122needed in this example but often useful). 
     124== Top-level bang-pattern bindings == 
     126Does this make sense? 
     128  module Foo where 
     129    !x = factorial 1000 
     131A top-level bang-pattern binding like this would imply that 
     132the binding is evaluated when the program is started; a kind of 
     133module initialisation.  This makes some kind of sense, since  
     134(unlike unrestricted side effects) it doesn't matter in which order 
     135the module initialisation is performed. 
     137But it's not clear why it would be necessary or useful.  Conservative 
     138conclusion: no top-level bang-patterns. 
     140== Recursive let and where bindings == 
     142It is just about possible to make sense of bang-patterns in  
     143''recursive'' let and where bindings.  At first you might think they 
     144don't make sense: how can you evaluate it strictly if it doesn't exist 
     145yet?  But consider 
     147  let !xs = if funny then 1:xs else 2:xs in ... 
     149Here the binding is recursive, but makes sense to think of it 
     150as equivalent to 
     152  let xs = if funny then 1:xs else 2:xs  
     153  in xs `seq` ... 
     155But (a) it must be unusual, and (b) I have found it very hard to 
     156come up with a plausible translation (that deals with all the tricky  
     159Conservative conclusion: bang-pattern bindings must be non-recursive. 
     161=== Tricky point: syntax === 
     163What does this mean? 
     165   f ! x = True 
     167Is this a definition of `(!)` or a banged argument?   (Assuming that 
     168space is insignificant.) 
     170Proposal: resolve this ambiguity in favour of the bang-pattern. If 
     171you want to define `(!)`, use the prefix form 
     173   (!) f x = True 
     176=== Tricky point: nested bangs === 
     178Consider this: 
     180  let !(x, Just !y) = <rhs> in <body> 
     182This should be equivalent to 
     184  case <rhs> of { (x, Just !y) -> <body> } 
     186Notice that this meant that the '''entire''' pattern is matched 
     187(as always with Haskell).  The `Just` may fail; `x` is  
     188not evaluated; but `y` '''is''' evaluated. 
     190== Tricky point: polymorphism == 
     192Haskell allows this: 
     194  let f :: forall a. Num a => a->a 
     195      Just f = <rhs> 
     196  in (f (1::Int), f (2::Integer)) 
     198But if we were to allow a bang pattern, `!Just f = <rhs>`,  
     199with the translation to 
     200a case expression given earlier, we would end up with 
     202   case <rhs> of { Just f -> (f (1::Int), f (2::Integer) } 
     204But if this is Haskell source, then `f` won't be polymorphic. 
    122207== Changes to the Report ==