How does method sharing interact with the ability of the rules engine to "look through" lets? Wouldn't an f rule kick in when fint is seen, by looking through the fint binding?<br><br>I've been wondering: will pattern matching look through a let even when the let-bound variable is used more than once? I chose "yes" in Pan, though somewhat nervously, since all but one of the uses are free anyway.<br>
<br>Cheers, - Conal<br><br><div class="gmail_quote">On Mon, Jun 9, 2008 at 2:38 AM, Simon Peyton-Jones <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div link="blue" vlink="purple" lang="EN-GB">
<div>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">The -fno-method-sharing flag was supposed to be a bit
experimental, which is why it takes the cheap-and-cheerful route of being a
static flag. (Only dynamic flags can go in OPTIONS_GHC.)</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">What it does is this. When you call an overloaded function f ::
C a => a -> a, in a function</span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);">g = ...f...f...</span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">you normally get something like this</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);">fint :: Int -> Int</span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);">fint = f Int dCInt</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);">g = ...fint...fint...</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">That is, 'fint' extracts the 'f' method
from dCInt::C Int, and it's then used repeatedly. </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">With -fno-method-sharing you get</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p style="text-indent: 36pt;"><span style="font-size: 11pt; color: rgb(31, 73, 125);">g = ...(f Int dCInt)
... (f Int dCInt)...</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">So the record selection is duplicated. It shouldn't
make much difference, but of course it *<b>does</b>* when rules are involved,
because there are no rules for fint (it's a fresh, local function).
</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);">Simon</span></p>
<p><span style="font-size: 11pt; color: rgb(31, 73, 125);"> </span></p>
<div style="border-style: none none none solid; border-color: -moz-use-text-color -moz-use-text-color -moz-use-text-color blue; border-width: medium medium medium 1.5pt; padding: 0cm 0cm 0cm 4pt;">
<div>
<div style="border-style: solid none none; border-color: rgb(181, 196, 223) -moz-use-text-color -moz-use-text-color; border-width: 1pt medium medium; padding: 3pt 0cm 0cm;">
<p><b><span style="font-size: 10pt;" lang="EN-US">From:</span></b><span style="font-size: 10pt;" lang="EN-US"> <a href="mailto:glasgow-haskell-users-bounces@haskell.org" target="_blank">glasgow-haskell-users-bounces@haskell.org</a>
[mailto:<a href="mailto:glasgow-haskell-users-bounces@haskell.org" target="_blank">glasgow-haskell-users-bounces@haskell.org</a>] <b>On Behalf Of </b>Conal
Elliott<br>
<b>Sent:</b> 07 June 2008 17:26<br>
<b>To:</b> <a href="mailto:glasgow-haskell-users@haskell.org" target="_blank">glasgow-haskell-users@haskell.org</a><br>
<b>Subject:</b> Re: desperately seeking RULES help</span></p>
</div>
</div><div><div></div><div>
<p> </p>
<p style="margin-bottom: 12pt;">Is it by intention that
-fno-method-sharing works only from the command line, not in an OPTIONS_GHC
pragma? </p>
<div>
<p>On Sat, Jun 7, 2008 at 9:23 AM, Conal Elliott <<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>> wrote:</p>
<p>Thanks a million, Lennart! -fno-method-sharing was the
missing piece. - Conal</p>
<div>
<div>
<p style="margin-bottom: 12pt;"> </p>
<div>
<p>On Sat, Jun 7, 2008 at 5:07 AM, Lennart Augustsson <<a href="mailto:lennart@augustsson.net" target="_blank">lennart@augustsson.net</a>>
wrote:</p>
<p>Here's something that actually works. You need to pass<br>
-fno-method-sharing on the command line.<br>
Instead of using rules on methods it uses rules on global functions,<br>
and these global functions don't get inlined until late (after the<br>
rule has fired).<br>
<br>
-- Lennart</p>
<div>
<p style="margin-bottom: 12pt;"><br>
module F where<br>
<br>
-- | Domain of a linear map.<br>
class AsInt a where<br>
toInt' :: a -> Int<br>
fromInt' :: Int -> a</p>
</div>
<p>{-# INLINE[1] toInt #-}<br>
toInt :: (AsInt a) => a -> Int<br>
toInt = toInt'<br>
<br>
{-# INLINE[1] fromInt #-}<br>
fromInt :: (AsInt a) => Int -> a<br>
fromInt = fromInt'</p>
<div>
<p><br>
{-# RULES<br>
"toInt/fromInt" forall m . toInt (fromInt m) = m<br>
#-}<br>
<br>
{-# INLINE onInt #-}<br>
onInt :: AsInt a => (Int -> Int) -> (a -> a)</p>
</div>
<p>onInt f x = fromInt (f (toInt x))</p>
<div>
<p style="margin-bottom: 12pt;"><br>
test :: AsInt a => (Int -> Int) -> (Int -> Int) -> (a -> a)<br>
test h g = onInt h . onInt g<br>
<br>
<br>
</p>
</div>
<div>
<p>2008/6/7 Conal Elliott <<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>>:</p>
</div>
<div>
<div>
<p>> I'm trying to do some fusion in ghc, and I'd greatly
appreciate help with<br>
> the code below (which is simplified from fusion on linear maps).
I've tried<br>
> every variation I can think of, and always something prevents the fusion.<br>
><br>
> Help, please! Thanks, - Conal<br>
><br>
><br>
> {-# OPTIONS_GHC -O2 -Wall -fglasgow-exts -ddump-simpl -ddump-simpl-stats
#-}<br>
> -- {-# OPTIONS_GHC -ddump-simpl-iterations #-}<br>
><br>
> module F where<br>
><br>
> -- | Domain of a linear map.<br>
> class AsInt a where<br>
> toInt :: a -> Int<br>
> fromInt :: Int -> a<br>
><br>
> {-# RULES<br>
> "toInt/fromInt" forall m. toInt (fromInt m) = m<br>
> #-}<br>
><br>
> {-# INLINE onInt #-}<br>
> onInt :: AsInt a => (Int -> Int) -> (a -> a)<br>
> onInt f = fromInt . f . toInt<br>
><br>
> test :: AsInt a => (Int -> Int) -> (Int -> Int) -> (a ->
a)<br>
> test h g = onInt h . onInt g<br>
><br>
> -- The desired result:<br>
> --<br>
> -- test h g<br>
> -- == onInt h . onInt g<br>
> -- == (fromInt . h . toInt) . (fromInt . g . toInt)<br>
> -- == \ a -> (fromInt . h . toInt) ((fromInt . g . toInt)
a)<br>
> -- == \ a -> (fromInt . h . toInt) (fromInt (g (toInt
a)))<br>
> -- == \ a -> fromInt (h (toInt (fromInt (g (toInt a)))))<br>
> -- == \ a -> fromInt (h (g (toInt a)))<br>
><br>
><br>
></p>
</div>
</div>
<div>
<div>
<p>> _______________________________________________<br>
> Glasgow-haskell-users mailing list<br>
> <a href="mailto:Glasgow-haskell-users@haskell.org" target="_blank">Glasgow-haskell-users@haskell.org</a><br>
> <a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users" target="_blank">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
><br>
></p>
</div>
</div>
</div>
<p> </p>
</div>
</div>
</div>
<p> </p>
</div></div></div>
</div>
</div>
</blockquote></div><br>