Changes between Version 3 and Version 4 of BangPatterns

Feb 6, 2006 11:03:52 AM (10 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.