Class op rules

Christiaan Baaij christiaan.baaij at gmail.com
Sat Mar 7 08:53:15 UTC 2020


Thanks for explaining Simon!

So I personally could live with a situation where it is controllable for
each classop individually - and I'd do the work to get that in.
Where if the developer doesn't specify an INLINE pragma, it defaults to
AlwaysActive.
That way, the change only affects users who have currently annotated their
class op with an {-# INLINE[N] op #-}
(I would have to scour hackage to see if anyone has currently doing that...
I hope not...)

But now that this has been brought up: currently, does adding an {-# INLINE
op #-} (with or without phase) for a class op actually do anything?
Or is it basically superfluous because the class op already gets a
BuiltInRule that's equal to INLINE AlwaysActive?
Or does it affect whether a default implementation for the method gets
inlined into the dictionary?
If the latter, I guess we should use SPECIALIZE instead of INLINE for
controlling the rule phase of the class op... unless that SPECIALIZE also
has an effect on the class op default implementation...

Thanks,
Christiaan


On Sat, 7 Mar 2020 at 00:02, Simon Peyton Jones <simonpj at microsoft.com>
wrote:

> Here’s how it works:
>
>
>
>    - The rewrite from    opi (D m1 … mn)   à   mi
>
> is done by a BuiltinRule: see MkId.mkDictSelId, and the BuiltinRule that
> is made there.
>
>
>
>    - At the moment, BuiltinRules are always active (in all phases), see
>    GHC.Core.ruleActivation.  To allow them to be selectively active, we’d have
>    to give them a ru_act fiels, like ordinary Rules.  That would not be hard.
>
>
>
>    - The phases go
>       - InitialPhase
>       - 2
>       - 1
>       - 0
>
>
>
>    - We could make classop rules active only in phase 1 and 0, say.   I
>    don’t know what the consequences would be; running the classop to pick a
>    method out of a dictionary in turn reveals new function applications that
>    might want to work in phase 2, say.
>
>
>
>    - Of course you can always add more phases, but that adds compile time.
>
>
>
>    - Would you want the classop phase to be fixed for every classop? Or
>    controllable for each classop individually.  E.g.   class C a where {  op
>    :: <bype>  {-# INLINE [2] op #-} }
>
> Here the intent is that, since the pragmas is in the class decl, the
> pragma applies to the method selector.
>
>
>
> I remember Conal raising this before, but I’ve forgotten the resolution.
> I’m entirely open to changes here, if someone is willing to do the work,
> including checking for consequences.
>
>
>
> Simon
>
>
>
> *From:* ghc-devs <ghc-devs-bounces at haskell.org> *On Behalf Of *Conal
> Elliott
> *Sent:* 06 March 2020 17:37
> *To:* Christiaan Baaij <christiaan.baaij at gmail.com>
> *Cc:* ghc-devs <ghc-devs at haskell.org>
> *Subject:* Re: Class op rules
>
>
>
> Thank you for raising this issue, Christiaan! The current policy (very
> early class-op inlining) is a major difficulty and the main source of
> fragility in my compiling-to-categories implementation. I have a tediously
> programmed and delicately balanced collection of techniques to intercept
> and transform class ops to non-ops early and then transform back late for
> elimination, but it doesn't work in all situations. Since class operations
> roughly correspond to operations in various algebraic
> abstractions---interfaces with laws---I often want to exploit exactly those
> laws as rewrite rules, and yet those rules currently cannot be used
> dependably.  - Conal
>
>
>
> On Fri, Mar 6, 2020 at 7:22 AM Christiaan Baaij <
> christiaan.baaij at gmail.com> wrote:
>
> Hello,
>
>
>
> The other day I was experimenting with RULES and got this warning:
>
>
>
> src/Clash/Sized/Vector.hs:2159:11: warning: [-Winline-rule-shadowing]
>     Rule "map Pack" may never fire
>       because rule "Class op pack" for ‘pack’ might fire first
>     Probable fix: add phase [n] or [~n] to the competing rule
>      |
> 2159 | {-# RULES "map Pack" map pack = id #-}
>
>
>
> The warning seems to suggests two things:
>
> 1. "Class op" -> "dictionary projection" are implemented as rewrite rules
> and executed the same way as other user-defined RULES
>
> 2. These rules run first, and you cannot run anything before them
>
>
>
> Now my question is, is 1. actually true? or is that warning just a (white)
> lie?
>
> If 1. is actually true, would there be any objections to adding a "-1"
> phase: where RULES specified to start from phase "-1" onward fire before
> any of the Class op rules.
>
> I'm quite willing to implement the above if A) Class op rules are actually
> implemented as builtin RULES; B) there a no objections to this "-1" phase.
>
>
>
> Thanks,
>
> Christiaan
>
>
>
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20200307/24775ebd/attachment.html>


More information about the ghc-devs mailing list