
#11049: Allow CallStacks to be hidden or cut -------------------------------------+------------------------------------- Reporter: nomeata | Owner: gridaphobe Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #11035 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by nomeata): Sure. Assume we are given a function {{{#!hs readFile :: ?callstack :: CallStack => FilePath -> IO () }}} that prints a stack trace with every IO error that happens (`bar` in the description). Now assume we want to implement a function that uses the above, for example {{{#!hs readConfig :: IO Config readConfig = do s <- readFile "config.txt" -- line 42 return (parseConfig s) }}} and we deliberately do not want that function have a `?_::CallStack` constraint. What will happen when `config.txt` will be missing? `readFile` will raise an exception that includes a call stack that tells the user that this was raised due to `readFile` being called in line 42. But as the author of the `readConfig` function, I do not want this information (which is not very helpful to the user) to be omitted. This is the first use case. The second is related. I might now allow `readConfig` to have a `?_::CallStack` constraint, e.g. {{{#!hs readConfig :: ?callstack::CallStack => IO Config readConfig = do s <- readFile "config.txt" -- line 42 return (parseConfig s) }}} But I do want to provide a polished API, and not leak any information to the users of my API about my internals. So _do_ want the `?callstack` to be passed on to `readFile` and be included in the exception, but I _don’t_ want it to mention line 42; instead it should end with the (for the user relevant) information where `readConfig` was called. This is the second use case. So now to the suggested implementation: In both cases, I want to insert a marker into the callstack that makes the call stack printer ignore anything “below” or “after” it. This is the suggested `rootCallStack` value, and it allows me to write {{{#!hs readConfig :: IO Config readConfig = do s <- let ?callstack = rootCallStack in readFile "config.txt" -- line 42 return (parseConfig s) }}} resp. {{{#!hs readConfig :: ?callstack::CallStack => IO Config readConfig = do s <- let ?callstack = rootCallStack `pushCallStack` ?callstack in readFile "config.txt" -- line 42 return (parseConfig s) }}} to implement the above. The implementation sketch is ad-hoc, and there might be more elegant variants. This is not not necessarily an advocation of such “hiding internals”, but I think it should be possible. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler