
Hi I've compiled the Debug.Trace module to Core, but can't understand the resulting output. The original code is: trace string expr = unsafePerformIO $ do putTraceMsg string return expr The core is: Debug.Trace.trace = \ (@ a) -> __letrec { trace :: GHC.Base.String -> a -> a [] trace = \ (string :: GHC.Base.String) (expr :: a) -> GHC.Base.$ @ (GHC.IOBase.IO a) @ a (GHC.IOBase.unsafePerformIO @ a) (>> @ () @ a (Debug.Trace.putTraceMsg string) (return @ a expr)); $dMonad :: GHC.Base.Monad GHC.IOBase.IO [] $dMonad = $dMonad; return :: forall a. a -> GHC.IOBase.IO a [] return = GHC.Base.return @ GHC.IOBase.IO $dMonad; $dMonad :: GHC.Base.Monad GHC.IOBase.IO [] $dMonad = GHC.IOBase.$f16; >> :: forall a b. GHC.IOBase.IO a -> GHC.IOBase.IO b -> GHC.IOBase.IO b [] >> = GHC.Base.>> @ GHC.IOBase.IO $dMonad; } in trace; And my Haskell reformatting of that is: Debug.Trace.trace = let trace string expr = unsafePerformIO $ putTraceMsg string >> return expr $dMonad = $dMonad; return = GHC.Base.return $dMonad; $dMonad = GHC.IOBase.$f16; >> = GHC.Base.>> $dMonad; in trace However, that let expression has two bindings for $dMonad, one of which looks like a black-hole. Are the semantics of __letrec different from let in some way? Thanks Neil

On 1/5/08, Neil Mitchell
Hi
I've compiled the Debug.Trace module to Core, but can't understand the resulting output. The original code is:
trace string expr = unsafePerformIO $ do putTraceMsg string return expr
The core is:
Debug.Trace.trace = \ (@ a) -> __letrec { trace :: GHC.Base.String -> a -> a [] trace = \ (string :: GHC.Base.String) (expr :: a) -> GHC.Base.$ @ (GHC.IOBase.IO a) @ a (GHC.IOBase.unsafePerformIO @ a) (>> @ () @ a (Debug.Trace.putTraceMsg string) (return @ a expr)); $dMonad :: GHC.Base.Monad GHC.IOBase.IO [] $dMonad = $dMonad; return :: forall a. a -> GHC.IOBase.IO a [] return = GHC.Base.return @ GHC.IOBase.IO $dMonad; $dMonad :: GHC.Base.Monad GHC.IOBase.IO [] $dMonad = GHC.IOBase.$f16; >> :: forall a b. GHC.IOBase.IO a -> GHC.IOBase.IO b -> GHC.IOBase.IO b [] >> = GHC.Base.>> @ GHC.IOBase.IO $dMonad; } in trace;
And my Haskell reformatting of that is:
Debug.Trace.trace = let trace string expr = unsafePerformIO $ putTraceMsg string >> return expr $dMonad = $dMonad; return = GHC.Base.return $dMonad; $dMonad = GHC.IOBase.$f16; >> = GHC.Base.>> $dMonad; in trace
However, that let expression has two bindings for $dMonad, one of which looks like a black-hole. Are the semantics of __letrec different from let in some way?
How are you printing out the Core? It looks like the unique ids are missing (you can see them if you pass the -ppr-debug flag, which can be set using the API) -- if the unique ids were being printed, you would see that the bindings for $dMonad (likely) have different uniques. Cheers, Tim -- Tim Chevalier * http://cs.pdx.edu/~tjc * Often in error, never in doubt "...Losing your mind, like losing your car keys, is a real hassle." -- Andrew Solomon

Hi
How are you printing out the Core?
showSDoc $ ppr c where c :: [CoreBind]
It looks like the unique ids are missing (you can see them if you pass the -ppr-debug flag, which can be set using the API)
I have now set the -ppr-debug flag, but that has no effect. It's not entirely surprising, as I guess setting the flag only applies through the GHC session, and this code is being run outside that. How can I print the output (to a file) using the unique id's?
Simon Peyton-Jones says: CoreTidy makes the print-name unique too.
Can I invoke CoreTidy using the GHC API? Thanks Neil

On 1/7/08, Neil Mitchell
Hi
How are you printing out the Core?
showSDoc $ ppr c
where c :: [CoreBind]
It looks like the unique ids are missing (you can see them if you pass the -ppr-debug flag, which can be set using the API)
I have now set the -ppr-debug flag, but that has no effect. It's not entirely surprising, as I guess setting the flag only applies through the GHC session, and this code is being run outside that. How can I print the output (to a file) using the unique id's?
Good point about the session, I forgot about that. It looks like you can call showSDocDebug instead of showSDoc (see utils/Outputable.lhs), which acts as if -dppr-debug is set, but I haven't actually tried it.
Can I invoke CoreTidy using the GHC API?
Yes, but you'll need to grab a post-Dec-25 build if you haven't already, since I added this recently. Once you have, see compileToCoreSimplified in main/GHC.hs. Cheers, Tim -- Tim Chevalier * http://cs.pdx.edu/~tjc * Often in error, never in doubt "It's easy to consider women more emotional than men when you don't consider rage to be an emotion." -- Brenda Fine

Hi
I have now set the -ppr-debug flag, but that has no effect. It's not entirely surprising, as I guess setting the flag only applies through the GHC session, and this code is being run outside that. How can I print the output (to a file) using the unique id's?
Good point about the session, I forgot about that. It looks like you can call showSDocDebug instead of showSDoc (see utils/Outputable.lhs), which acts as if -dppr-debug is set, but I haven't actually tried it.
That does indeed work - and I can now see exactly why you don't leave it on all the time!
Can I invoke CoreTidy using the GHC API?
Yes, but you'll need to grab a post-Dec-25 build if you haven't already, since I added this recently. Once you have, see compileToCoreSimplified in main/GHC.hs.
/me upgrades Many thanks, Neil

If you use -dppr-debug GHC will show you the unique number of each identifier, and that'll show you that the two $dMonads are distinct even though they have the same print-name. CoreTidy makes the print-name unique too. Perhaps the Core printer should be a bit keener to print unique numbers, but it adds a lot of clutter. Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] On Behalf Of | Neil Mitchell | Sent: 05 January 2008 20:01 | To: GHC Users | Subject: GHC Core question | | Hi | | I've compiled the Debug.Trace module to Core, but can't understand the | resulting output. The original code is: | | trace string expr = unsafePerformIO $ do | putTraceMsg string | return expr | | The core is: | | Debug.Trace.trace = | \ (@ a) -> | __letrec { | trace :: GHC.Base.String -> a -> a | [] | trace = | \ (string :: GHC.Base.String) (expr :: a) -> | GHC.Base.$ | @ (GHC.IOBase.IO a) | @ a | (GHC.IOBase.unsafePerformIO @ a) | (>> @ () @ a (Debug.Trace.putTraceMsg string) (return @ a expr)); | $dMonad :: GHC.Base.Monad GHC.IOBase.IO | [] | $dMonad = $dMonad; | return :: forall a. a -> GHC.IOBase.IO a | [] | return = GHC.Base.return @ GHC.IOBase.IO $dMonad; | $dMonad :: GHC.Base.Monad GHC.IOBase.IO | [] | $dMonad = GHC.IOBase.$f16; | >> :: forall a b. | GHC.IOBase.IO a -> GHC.IOBase.IO b -> GHC.IOBase.IO b | [] | >> = GHC.Base.>> @ GHC.IOBase.IO $dMonad; | } in trace; | | And my Haskell reformatting of that is: | | Debug.Trace.trace = let | trace string expr = unsafePerformIO $ putTraceMsg string >> return expr | $dMonad = $dMonad; | return = GHC.Base.return $dMonad; | $dMonad = GHC.IOBase.$f16; | >> = GHC.Base.>> $dMonad; | in trace | | However, that let expression has two bindings for $dMonad, one of | which looks like a black-hole. Are the semantics of __letrec different | from let in some way? | | Thanks | | Neil | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (3)
-
Neil Mitchell
-
Simon Peyton-Jones
-
Tim Chevalier