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


Ignore:
Timestamp:
Jun 29, 2011 2:56:26 PM (3 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