Legend:

What is the semantics of an outer `t`? Given `f` with CPR `<L>tm()` and `g` with CPR `<S>tm()`? Does the latter even make sense? If so, should `f undefined` have CPR `m()` or `tm()`? Two possibilities:

48

48

1. The convergence information a function is what holds if its strictness annotations are fulfilled: So if `g x` has `tm()` if `x` has `t` (possibly because it has previously been evaluated by the caller), otherwise `m()`. `f x` always has `m ()` (presumably because `x` is _never_ entered when evaluating `f`.

49

2. The convergence information a function is what holds always. This would ineffect prevent `<S>tm()` from happening.

49

2. The convergence information a function is what holds always. This would ineffect prevent `<S>tm()` from happening.

50

50

51

51

Clearly, 1. holds strictly more information than 2.: Under variant `2`, `<S>tm()` would not occur, while under variant 1 that would be usefully different from `<S>m()`.

What about nested strictness annotations? For now the hypothesis of the demand transformer only requires the arguments (and free variables) to be terminating; if there is a `<S(S)>`, then it should not be marked as converging. Maybe this can be improved later, using nested CPR.

80

81

Some implementation implications:

82

* There is no unit for `lubDmdType` any more. So for case, use `botDmdType` for no alternatives, and `foldr1` if there are multiple.

83

* Unlifted variables (e.g. `Int#`) are tricky. Everything is strict in them, so for an *unlifted* argument, `<L>t` implies `<S>t` and hence `<S>t ⊔ <L>t = <S>t`, and we really want to make use of that stronger equation. But when lub’ing, we don’t know any more if this is the demand for an unlifted type. So instead, the demand type of `x :: Int#` itself is `{x ↦ <L>} t`, while `x :: Int` continues to have type `{x ↦ <S>} t`. Nevertheless it is important that functions (including primitive operations and constructors like `I#`) have a strict demand on their unlifted argument.