Changes between Version 2 and Version 3 of BangPatterns

Feb 2, 2006 4:57:58 PM (10 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 ==