176 | | === Tricky point: nested bangs === |
| 176 | Another point that came up in implementation is this. In GHC, at least, |
| 177 | ''patterns'' are initially parsed as ''expressions'', because Haskell's syntax |
| 178 | doesn't let you tell the two apart until quite late in the day. |
| 179 | In expressions, the form {{{(! x)}}} is a right section, and parses fine. |
| 180 | But the form {{{(!x, !y)}}} is simply illegal. Solution: |
| 181 | in the syntax of expressions, allow sections without the wrapping parens |
| 182 | in explicit lists and tuples. Actually this would make sense generally: |
| 183 | what could {{{(+ 3, + 4)}}} mean apart from a tuple of two sections? |
| 184 | |
| 185 | == Tricky point: nested bangs == |
| 199 | This means that you can't give the obvious alternative translation that uses |
| 200 | just let-bindings and {{{seq}}. For example, we could attempt to translate |
| 201 | the example to: |
| 202 | {{{ |
| 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> |
| 209 | }}} |
| 210 | This won't work, because using `seq` on `t` won't force `y`. |
| 211 | You could build an intermediate tuple, thus: |
| 212 | {{{ |
| 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> |
| 219 | }}} |
| 220 | But that seems a waste when the patttern is itself just a tuple; |
| 221 | and it needs adjustment when there is only one bound variable. |
| 222 | |
| 223 | Bottom line: for non-recursive bindings, the straightforward translation |
| 224 | to a `case` is, well, straightforward. Recursive bindings could probably |
| 225 | be handled, but it's more complicated. |
| 226 | |
| 227 | == Tricky point: pattern-matching semantics == |
| 228 | |
| 229 | A bang is part of a ''pattern''; matching a bang forces evaluation. |
| 230 | So the exact placement of bangs in equations matters. For example, |
| 231 | there is a difference between these two functions: |
| 232 | {{{ |
| 233 | f1 x True = True |
| 234 | f1 !x False = False |
| 235 | |
| 236 | f2 !x True = True |
| 237 | f2 x False = False |
| 238 | }}} |
| 239 | Since pattern matching goes top-to-bottom, left-to-right, |
| 240 | {{{(f1 bottom True)}}} is {{{True}}}, whereas {{{(f2 bottom True)}}} |
| 241 | is {{{bottom}}}. |
| 242 | |
| 259 | One could say that the translation isn't required to preserve the static |
| 260 | semantics, but GHC, at least, translates into System F, and being able |
| 261 | to do so is a good sanity check. If we were to do that, then we would |
| 262 | need |
| 263 | {{{ |
| 264 | <rhs> :: Maybe (forall a. Num a => a -> a) |
| 265 | }}} |
| 266 | so that the case expression works out in System F: |
| 267 | {{{ |
| 268 | case <rhs> of { |
| 269 | Just (f :: forall a. Num a -> a -> a) |
| 270 | -> (f Int dNumInt (1::Int), f Integer dNumInteger (2::Integer) } |
| 271 | }}} |
| 272 | The trouble is that `<rhs>` probably has a type more like |
| 273 | {{{ |
| 274 | <rhs> :: forall a. Num a => Maybe (a -> a) |
| 275 | }}} |
| 276 | ...and now the dictionary lambda may get in the way |
| 277 | of forcing the pattern. |
| 278 | |
| 279 | This is a swamp. '''Conservative conclusion''': no generalisation (at all) |
| 280 | for bang-pattern bindings. |