What is the difference between `traceIO` and` hPutStrLn stderr`?

Looking at the description of traceIO , I feel that it does exactly what hPutStrLn stderr does. However, when I looked at its source code:

 traceIO :: String -> IO () traceIO msg = do withCString "%s\n" $ \cfmt -> do -- NB: debugBelch can't deal with null bytes, so filter them -- out so we don't accidentally truncate the message. See Trac #9395 let (nulls, msg') = partition (=='\0') msg withCString msg' $ \cmsg -> debugBelch cfmt cmsg when (not (null nulls)) $ withCString "WARNING: previous trace message had null bytes" $ \cmsg -> debugBelch cfmt cmsg 

It seems to be using an external routine called debugBelch , which I did not find any documentation about. So, what does traceIO do that cannot be done with hPutStrLn stderr ?

+5
source share
1 answer

One thing I can think of is that it can guarantee that the string will be printed as a unit, without any other trace messages inside. Indeed, the experiment seems to confirm this:

 Prelude Debug.Trace System.IO> traceIO $ "1" ++ trace "2" "3" 2 13 Prelude Debug.Trace System.IO> hPutStrLn stderr $ "1" ++ trace "2" "3" 12 3 

Another difference is that characters that cannot be safely printed to stderr seem to be deleted:

 Prelude Debug.Trace System.IO> hPutStrLn stderr "\9731" *** Exception: <stderr>: hPutChar: invalid argument (invalid character) Prelude Debug.Trace System.IO> traceIO "\9731" Prelude Debug.Trace System.IO> 

As @dfeuer reminds me, none of these features are writable in Haskell. Thus, the decisive factor is probably the following: debugBelch already a predefined function of C, it is used everywhere in the GHC runtime system, which is written in C and C--, and not in Haskell.

+4
source

Source: https://habr.com/ru/post/1233443/


All Articles