Changes between Version 3 and Version 4 of BangPatterns

Feb 6, 2006 11:03:52 AM (9 years ago)



  • BangPatterns

    v3 v4  
    135135the module initialisation is performed. 
    137 But it's not clear why it would be necessary or useful.  Conservative 
    138 conclusion: no top-level bang-patterns. 
     137But it's not clear why it would be necessary or useful.  '''Conservative 
     138conclusion''': no top-level bang-patterns. 
    140140== Recursive let and where bindings == 
    155155But (a) it must be unusual, and (b) I have found it very hard to 
    156156come up with a plausible translation (that deals with all the tricky  
    157 points).   
    159 Conservative conclusion: bang-pattern bindings must be non-recursive. 
    161 === Tricky point: syntax === 
     157points below).   
     159'''Conservative conclusion''': bang-pattern bindings must be non-recursive. 
     161== Tricky point: syntax == 
    163163What does this mean? 
    176 === Tricky point: nested bangs === 
     176Another point that came up in implementation is this.  In GHC, at least, 
     177''patterns'' are initially parsed as ''expressions'', because Haskell's syntax 
     178doesn't let you tell the two apart until quite late in the day.   
     179In expressions, the form {{{(! x)}}} is a right section, and parses fine. 
     180But the form {{{(!x, !y)}}} is simply illegal.  Solution:  
     181in the syntax of expressions, allow sections without the wrapping parens  
     182in explicit lists and tuples.  Actually this would make sense generally: 
     183what could {{{(+ 3, + 4)}}} mean apart from a tuple of two sections? 
     185== Tricky point: nested bangs == 
    178187Consider this: 
    188197not evaluated; but `y` '''is''' evaluated. 
     199This means that you can't give the obvious alternative translation that uses 
     200just let-bindings and {{{seq}}.  For example, we could attempt to translate 
     201the example to: 
     203  let  
     204    t = <rhs> 
     205    x = case t of (x, Just !y) -> x 
     206    y = case t of (x, Just !y) -> y 
     207  in 
     208  t `seq` <body> 
     210This won't work, because using `seq` on `t` won't force `y`. 
     211You could build an intermediate tuple, thus: 
     213  let  
     214    t = case <rhs> of (x, Just !y) -> (x,y) 
     215    x = fst t 
     216    y = snd t 
     217  in 
     218  t `seq` <body> 
     220But that seems a waste when the patttern is itself just a tuple; 
     221and it needs adjustment when there is only one bound variable. 
     223Bottom line: for non-recursive bindings, the straightforward translation 
     224to a `case` is, well, straightforward.   Recursive bindings could probably 
     225be handled, but it's more complicated. 
     227== Tricky point: pattern-matching semantics == 
     229A bang is part of a ''pattern''; matching a bang forces evaluation.  
     230So the exact placement of bangs in equations matters. For example, 
     231there is a difference between these two functions: 
     233  f1 x  True  = True 
     234  f1 !x False = False 
     236  f2 !x True  = True 
     237  f2  x False = False 
     239Since pattern matching goes top-to-bottom, left-to-right,  
     240{{{(f1 bottom True)}}} is {{{True}}}, whereas {{{(f2 bottom True)}}}  
     241is {{{bottom}}}. 
    190243== Tricky point: polymorphism == 
    204257But if this is Haskell source, then `f` won't be polymorphic. 
     259One could say that the translation isn't required to preserve the static 
     260semantics, but GHC, at least, translates into System F, and being able 
     261to do so is a good sanity check.  If we were to do that, then we would 
     264    <rhs> :: Maybe (forall a. Num a => a -> a) 
     266so that the case expression works out in System F: 
     268   case <rhs> of {  
     269     Just (f :: forall a. Num a -> a -> a) 
     270        -> (f Int dNumInt (1::Int), f Integer dNumInteger (2::Integer) } 
     272The trouble is that `<rhs>` probably has a type more like 
     274    <rhs> :: forall a. Num a => Maybe (a -> a) 
     276...and now the dictionary lambda may get in the way 
     277of forcing the pattern. 
     279This is a swamp.  '''Conservative conclusion''': no generalisation (at all) 
     280for bang-pattern bindings. 
    207282== Changes to the Report == 
    209 The changes to the Report would be these 
     284The changes to the Report would be these.  (Incomplete.) 
    211286 * Section 3.17, add pat ::= !pat to the syntax of patterns.