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 <[email protected]> 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
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________
ghc-devs mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs