[GHC] #11049: Allow CallStacks to be hidden or cut
GHC
ghc-devs at haskell.org
Wed Nov 4 17:05:18 UTC 2015
#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
More information about the ghc-tickets
mailing list