
Hi, Is there a way to determine the order in which thunks are created and expanded/evaluated in Haskell (GHC)? I'm looking mainly at some existing interface but if there is only something in the GHC source it will suffice. Thanks, -- Mihai

On Thu, Oct 14, 2010 at 1:53 PM, Mihai Maruseac
Hi,
Is there a way to determine the order in which thunks are created and expanded/evaluated in Haskell (GHC)? I'm looking mainly at some existing interface but if there is only something in the GHC source it will suffice.
You'll want to look at STG (spineless tagless G-Machine). See here and the linked paper: http://www.haskell.org/haskellwiki/Ministg I don't know of any way to examine this for a running program. You can get GHC to spit out core and STG using -ddump-core and -ddump-stg flags: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/options-debugging.ht... I hope that helps, Jason

I don't know of any way to examine this for a running program. You can get GHC to spit out core and STG using -ddump-core and -ddump-stg flags:
There's no -ddump-core flag. I was puzzled about the proper way to get "final" core, and have been using -ddump-simpl, but I don't know if that's correct.

On Thu, Oct 14, 2010 at 2:52 PM, Evan Laforge
I don't know of any way to examine this for a running program. You can get GHC to spit out core and STG using -ddump-core and -ddump-stg flags:
There's no -ddump-core flag. I was puzzled about the proper way to get "final" core, and have been using -ddump-simpl, but I don't know if that's correct.
Indeed, I meant -ddump-simpl. That's why I tried to link to the GHC manual, I make typos and it has extra info and enumerates the flags available :) Just search that page for -ddump. Sorry about the confusing typo, Jason

On Fri, Oct 15, 2010 at 1:19 AM, Jason Dagit
On Thu, Oct 14, 2010 at 2:52 PM, Evan Laforge
wrote: I don't know of any way to examine this for a running program. You can get GHC to spit out core and STG using -ddump-core and -ddump-stg flags:
There's no -ddump-core flag. I was puzzled about the proper way to get "final" core, and have been using -ddump-simpl, but I don't know if that's correct.
Indeed, I meant -ddump-simpl. That's why I tried to link to the GHC manual, I make typos and it has extra info and enumerates the flags available :) Just search that page for -ddump. Sorry about the confusing typo, Jason
Thanks, will look into the debugging dump flags. I should have done this before asking :) -- Mihai

On 15 October 2010 07:53, Mihai Maruseac
Hi,
Is there a way to determine the order in which thunks are created and expanded/evaluated in Haskell (GHC)? I'm looking mainly at some existing interface but if there is only something in the GHC source it will suffice.
You can use side effects to observe the order of evaluation, by wrapping observed expressions (thunks) with some IO computation inside unsafePerformIO. This is roughly what HOOD does, and it can be used to provide some clues about evaluation order, and maybe even GHood can help you visualise it. I've no idea if they work at the moment, but Hood and GHood are available on Hackage. You have to be careful of "observer effects" whereby the observation wrappers change the evaluation order of the observed code. Cheers, Bernie.

Bernie Pope
You can use side effects to observe the order of evaluation, by wrapping observed expressions (thunks) with some IO computation inside unsafePerformIO.
Not what OP asks for, but I've used a variant of this as a rather hackish to provide progress reporting. I take a list that is lazily generated, and wrap the elements with an IO action that outputs the count every 'step' elements. When the list is evaluated, the IO actions are executed. Code below. -k -- | Output (to stderr) progress while evaluating a lazy list. -- Useful for generating output while (conceptually, at least) in pure code countIO :: String -> String -> Int -> [a] -> IO [a] countIO msg post step xs = sequence' $ map unsafeInterleaveIO ((blank >> outmsg (0::Int) >> c):cs) where (c:cs) = ct 0 xs output = hPutStr stderr blank = output ('\r':take 70 (repeat ' ')) outmsg x = output ('\r':msg++show x) >> hFlush stderr ct s ys = let (a,b) = splitAt (step-1) ys next = s+step in case b of [b1] -> map return a ++ [outmsg (s+step) >> hPutStr stderr post >> return b1] [] -> map return (init a) ++ [outmsg (s+length a) >> hPutStr stderr post >> return (last a)] _ -> map return a ++ [outmsg s >> return (head b)] ++ ct next (tail b) -- | A lazier version of 'Control.Monad.sequence' in "Control.Monad", needed by 'countIO' above. sequence' :: [IO a] -> IO [a] sequence' ms = foldr k (return []) ms where k m m' = do { x <- m; xs <- unsafeInterleaveIO m'; return (x:xs) } -k -- If I haven't seen further, it is by standing in the footprints of giants
participants (5)
-
Bernie Pope
-
Evan Laforge
-
Jason Dagit
-
Ketil Malde
-
Mihai Maruseac