One significant problem is that {-# INLINE #-} functions are not actually always inlined! Specifically, if an inline-function is not passed all of its arguments, it will not be inlined. This poses a problem for levity-polymorphic functions, and GHC already does some special handling of the few levity-polymorphic primitives, in case they are ever used without all of their arguments.
As for boxing levity-polymorphic arguments: that's plausible, but then I think you've defeated the programmer's intended aim. The solution to me is some kind of so-called template polymorphism <https://gitlab.haskell.org/ghc/ghc/-/issues/14917#note_151678>. This might work, but it would take a fair amount of design work first. Richard > On Oct 7, 2021, at 7:36 PM, Clinton Mead <clintonm...@gmail.com> wrote: > > Hi All > > Not sure if this belongs in ghc-users or ghc-devs, but it seemed devy enough > to put it here. > > Section 6.4.12.1 > <https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/levity_polymorphism.html> > of the GHC user manual points out, if we allowed levity polymorphic > arguments, then we would have no way to compile these functions, because the > code required for different levites is different. > > However, if such a function is {-# INLINE #-} or {-# INLINABLE #-} there's no > need to compile it as it's full definition is in the interface file. Callers > can just compile it themselves with the levity they require. Indeed callers > of inline functions already compile their own versions even without levity > polymorphism (for example, presumably inlining function calls that are known > at compile time). > > The only sticking point to this that I could find was that GHC will only > inline the function if it is fully applied > <https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/pragmas.html#inline-pragma>, > which suggests that the possibility of partial application means we can't > inline and hence need a compiled version of the code. But this seems like a > silly restriction, as we have the full RHS of the definition in the interface > file. The caller can easily create and compile it's own partially applied > version. It should be able to do this regardless of levity. > > It seems to me we're okay as long as the following three things aren't true > simultaneously: > > 1. Blah has levity polymorphic arguments > 2. Blah is exported > 3. Blah is not inline > > If a function "Blah" is not exported, we shouldn't care about levity > polymorphic arguments, because we have it's RHS on hand in the current module > and compile it as appropriate. And if it's inline, we're exposing it's full > RHS to other callers so we're still fine also. Only when these three > conditions combine should we give an error, say like: > > "Blah has levity polymorphic arguments, is exported, and is not inline. > Please either remove levity polymorphic arguments, not export it or add an > {-# INLINE #-} or {-# INLINABLE #-} pragma. > > I presume however there are some added complications that I don't understand, > and I'm very interested in what they are as I presume they'll be quite > interesting. > > Thanks, > Clinton > > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs