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

Reply via email to