
Simon, one more thing. `lubUse` has this:
-- lubUse (UProd {}) Used = Used
lubUse (UProd ux) Used = UProd (map (`lubArgUse` useTop) ux)
lubUse Used (UProd ux) = UProd (map (`lubArgUse` useTop) ux)
And then somewhere around that code there's this:
Note [Used should win]
~~~~~~~~~~~~~~~~~~~~~~
Both in lubUse and bothUse we want (Used `both` UProd us) to be Used.
Why? Because Used carries the implication the whole thing is used,
box and all, so we don't want to w/w it. If we use it both boxed and
unboxed, then we are definitely using the box, and so we are quite
likely to pay a reboxing cost. So we make Used win here.
...
It seems like at some point the note was valid, but now the code seems to be
doing the opposite. Any ideas which one needs an update?
I'm also a bit confused about why both and lub are not commutative, or if
they're commutative, why do they have redundant cases. For example, lubUse has
this:
lubUse UHead u = u
lubUse (UCall c u) UHead = UCall c u
instead of something like:
lubUse UHead u = u
lubUse u UHead = u
I didn't check all the cases to see if it's really commutative or not, but can
I assume that they need to be commutative and simplify the code? Otherwise
let's add a note about why they're not commutative?
Thanks..
2016-03-02 1:07 GMT-05:00 Ömer Sinan Ağacan
Could I ask that you add this example as a Note to the relevant functions, so that the next time someone asks this question they'll find the answer right there?
Yep, I'll do that soon.
2016-03-01 12:01 GMT-05:00 Simon Peyton Jones
: Omer
Joachim is right. The strictness analyser just looks inside casts, so these unexpectedly ill-typed cases could show up. For example
f :: T a -> a -> Int f x y = case x of P1 -> case y of (a,b,c) -> a+b+c P2 -> case y of (p,q) -> p+q
data T a where P1 :: T (Int,Int,Int) P2 :: T (Int,Int)
In the P1 branch we have that y::(Int,Int,Int), so we'll get a demand S(SSS). And similarly in the P2 branch. Now we combine them. And there you have it.
Could I ask that you add this example as a Note to the relevant functions, so that the next time someone asks this question they'll find the answer right there?
Thanks
Simon
| -----Original Message----- | From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of Ömer | Sinan Agacan | Sent: 19 February 2016 17:27 | To: ghc-devs
| Subject: 'lub' and 'both' on strictness - what does it mean for | products to have different arity? | | I was looking at implementations of LUB and AND on demand signatures | and I found this interesting case: | | lubStr (SProd s1) (SProd s2) | | length s1 == length s2 = mkSProd (zipWith lubArgStr s1 s2) | | otherwise = HeadStr | | The "otherwise" case is interesting, I'd expect that to be an error. | I'm trying to come up with an example, let's say I have a case | expression: | | case x of | P1 -> RHS1 | P2 -> RHS2 | | and y is used in RHS1 with S(SS) and in RHS2 with S(SSS). This seems to | me like a type error leaked into the demand analysis. | | Same thing applies to `bothDmd` too. Funnily, it has this extra comment | on this same code: | | bothStr (SProd s1) (SProd s2) | | length s1 == length s2 = mkSProd (zipWith bothArgStr s1 s2) | | otherwise = HyperStr -- Weird | | Does "Weird" here means "type error and/or bug" ? | | Should I try replacing these cases with panics and try to validate? | _______________________________________________ | ghc-devs mailing list | ghc-devs@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc- | devs&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cdd8ae326a8e14ef8 | 9e8608d339520cb9%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=sRFRKgj3y | zQdEZT4y7KLk18cP43Rv1J%2bx8oPZyr1QzA%3d