What is really frustrating is that GHC has the machinery to do this
trivially (RULES, soon core2core phase plugins as well), only that this machinery gets applied when source location information is no longer available, so it is useless for this problem:-(

I'd be happy to be proven wrong in this, of course!-) I had the feeling
that there'd been some recent work on all this and, indeed, reddit has:

http://www.reddit.com/r/haskell/comments/8mbar/finding_the_needle_stack_traces_for_ghc_pdf/

Right on topic, and I assume the authors are on this list!-) It appears
that the bulk of the paper is concerned with performance improvements -
if we just want to recreate the user view, the mapException approach
would appear to be a lot simpler (perhaps the paper could discuss it
as a poor man's alternative, in particular since its source rewrites seem
less intrusive?).

Of course, having any support for this in GHC will be an improvement.
However, it is interesting that the paper suggests an implementation
using a core2core transformation, *with access to source location l*:

   [|x_l|]s = x deb (push l s), if x has (Debugged ’x deb) ann
   (Figure 1, page 4)

Does that mean it would be possible to add an extension to RULES
that would allow things like:

   {-# RULES "f->f_" forall x. f{SRCLOC} x = mapError SRCLOC (f_  x) #-}

ie, referring to the source location of 'f' in the right hand side? That
would seem to be the smallest possible change permitting a user-level
implementation of error stack traces. And it might be more generally
useful as well.

Attached is another example source, again doing the expansion by hand
( (f x) -> mapError SRCLOC (f x); error ".." -> errorSrc SRCLOC "..")
and relying on mapException to collect the traces, with a few recursive
examples suggested by the paper, and three variations of eliding recursive
call sites from the stack traces (note that this only elides when presenting
the trace, the real implementation from the paper elides when
constructing the trace).

Claus

------------------------------------ example output:
$ ghc -e main stacktraces.hs -DPLAIN

-- fib 5
fib with non-positive number: 0
("stacktraces.hs",46)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",36)

-- odd_ 5
odd_: no match
("stacktraces.hs",51)
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",38)

-- firstLetters2
Prelude.head: empty list
("stacktraces.hs",58)
("stacktraces.hs",62)
("stacktraces.hs",62)
("stacktraces.hs",62)

$ ghc -e main stacktraces.hs

-- fib 5
fib with non-positive number: 0
("stacktraces.hs",46)
...
("stacktraces.hs",45)
("stacktraces.hs",36)

-- odd_ 5
odd_: no match
("stacktraces.hs",51)
...
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",38)

-- firstLetters2
Prelude.head: empty list
("stacktraces.hs",58)
...
("stacktraces.hs",62)

Attachment: stacktraces.hs
Description: Binary data

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to