Changes between Version 4 and Version 5 of Commentary/Compiler/SeqMagic


Ignore:
Timestamp:
Jun 29, 2011 2:56:26 PM (4 years ago)
Author:
simonmar
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/SeqMagic

    v4 v5  
    163163
    164164Here's our new plan.
    165  * Introduce a new primop `seq# :: a -> State# s -> (# a, State# s #)`
    166  * An application of the primop is not considered cheap.
    167  * Desugar `seq` thus:
     165 * Introduce a new primop `seq# :: a -> State# s -> (# a, State# s #)` (see be5441799b7d94646dcd4bfea15407883537eaaa)
     166 * Implement `seq#` by turning it into the obvious eval in the backend.  In fact, since the return convention for `(# State# s, a #)` is exactly the same as for `a`, we can implement `seq# s a` by `a` (even when it appears as a case scrutinee).  Currenntly
     167 * Define `evaluate` thus
     168{{{
     169  evaluate :: a -> IO a
     170  evaluate x = IO $ \s -> seq# x s
     171}}}
     172
     173That fixes problem 4.
     174
     175We could go on and desugar `seq` thus:
    168176{{{
    169177   x  `seq` e2 ==> case seq# x RW of (# x, _ #) -> e2    -- Note shadowing!
    170178   e1 `seq` e2 ==> case seq# x RW of (# _, _ #) -> e2
    171179}}}
    172  * Define `evaluate` thus
    173 {{{
    174   evaluate :: a -> IO ()
    175   evaluate x = IO (\s -> case seq# x s of
    176                            (# _, s' #) -> (# (), s' #)
    177 }}}
    178 
    179 All the same equations hold as with the old defn for `seq`, but the problems
    180 go away:
    181   * Problem 1: (seq x y) is elaborated in the desugarer
    182   * Problem 2: problem largely unaffected
    183   * Problem 3: if we regard `(seq# a b)` as expensive, we won't eta expand.
    184   * Problem 4: unchanged
     180
     181and if we consider `seq#` to be expensive, then we won't eta-expand around it, and that would fix problem 3.
     182
     183However, there is a concern that this might lead to performance regressions in examples like this:
     184
     185{{{
     186f :: Int -> Int -> IO Int
     187f x y | x `seq` False = undefined
     188f x 3 = do
     189  ... some IO monad code here ...
     190}}}
     191
     192so `f` turns into
     193
     194{{{
     195f = \x . \y . case seq# x RW of (# _, x #) -> case y of 3 -> \s . some IO monad code
     196}}}
     197
     198and we won't get to eta-expand the `\s` as we would normally do (this is pretty important for getting good performance from IO and ST monad code).
     199
     200Arguably `f` should be rewritten with a bang pattern, and we should treat bang patterns as the eta-expandable seq and translate them directly into `case`, not `seq#`.  But this would be a subtle difference between `seq` and bang patterns.
     201
     202Furthermore, we already have `pseq`, which is supposed to be a "strictly ordered seq", that is it preserves evaluation order.  So perhaps `pseq` should be the one that more accurately implements the programmer's intentions, leaving `seq` as it currently is.
     203
     204We are currently pondering what to do here.
     205