[GHC] #11049: Allow CallStacks to be hidden or cut

#11049: Allow CallStacks to be hidden or cut -------------------------------------+------------------------------------- Reporter: nomeata | Owner: Type: feature | Status: new request | Priority: normal | Milestone: Component: Compiler | Version: 7.10.2 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: #11035 Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- This is a spin off of #11035. I’d like to see a way for a function `foo` * use another function `bar` with a `(?_::CallStack)` constraint so that `bar` will _not_ print a call stack, and * use another function `bar` with a `(?_::CallStack)` constraint so that if `bar` prints a call stack, it will stop at the call to `foo`. This might be possible to implement with a special `rootCallStack :: CallStack` which is a value such that {{{ x `pushCallStack` rootCallStack = rootCallStack }}} but {{{ rootCallStack `pushCallStack` x = rootCallStack “:” x }}} as before and a call stack that consists of only a rootCallStack causes no stack trace to be printed. The use case is to provide the user of a library less cluttered call stacks that do not expose unhelpful details and allow her to quickly spot the relevant information. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: | -------------------------------------+------------------------------------- Changes (by gridaphobe): * owner: => gridaphobe -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 simonpj): I'm sorry but I don't understand the Description at all. Could you elaborate it, at least with examples, both to explain and to motivate? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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

#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 gridaphobe): I think this is an interesting idea, and I think it could be implemented entirely in `base` without any additional compiler support. So I'm in favor of doing it; we can let users decide if the implementation hiding feature is useful. The one wrinkle is that this will only work when we have a full call- stack, ie every function in the path from `readConfig` to `error` '''must''' take a call-stack. Otherwise the chain will be broken (remember, call-stacks are just implicit parameters with a special rule for function calls) and we'll still see a partial call-stack. For example, if I change your example so that `readFile` does not take a call-stack {{{#!haskell readFile :: FilePath -> IO String readFile f = ... error "file not found" ... readConfig :: IO Config readConfig = do s <- let ?callstack = rootCallStack in readFile "config.txt" -- line 42 return (parseConfig s) }}} `readConfig` will still print a call-stack that leaks internals if `config.txt` does not exist. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 simonpj): That's helpful. So we make public both `rootStack` and `pushCallStack`. And we allow implicit-parameter bindings for `?loc :: CallStack`. (I suppose that's always been possible, and you can use it already to install a `CallStack` from somewhere else. I guess that's an advantage.) Would you like to turn the description, and your comment:3, and any subsequent stuff, into a wiki page (perhaps the same page as the current `CallStack` one. Otherwise we have to mentally compose all these things in our heads. Thanks! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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):
For example, if I change your example so that readFile does not take a call-stack...
Right, but that is a deliberate decision by the author of `readFile` then; I’m fine with that.
Would you like to turn the description, and your comment:3, and any subsequent stuff, into a wiki page
I can; gridaphobe, can you tell me where precisely you’d like to see this documentation? Or maybe it should rather go directly into the haddocks or the user guide? (Keeping docs good and up-to-date is tricky, so I’d aim for having just one place that documents stuff.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 simonpj): Let's initially have the overall design, movitation, examples, on a wiki page. That's what we usually do. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 gridaphobe): I've added Joachim's description and an implementation sketch to the original [https://ghc.haskell.org/trac/ghc/wiki/ExplicitCallStack/ImplicitLocations#Ex... ImplicitLocations wiki page]. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Ben Gamari

#11049: Allow CallStacks to be hidden or cut -------------------------------------+------------------------------------- Reporter: nomeata | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.10.2 Resolution: fixed | 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: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11049: Allow CallStacks to be hidden or cut -------------------------------------+------------------------------------- Reporter: nomeata | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 8.0.1 Component: Compiler | Version: 7.10.2 Resolution: fixed | 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: | -------------------------------------+------------------------------------- Changes (by bgamari): * milestone: => 8.0.1 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11049#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC