FW: [Template-haskell] RE: calling fail in Q monad gives uninformativeerror message, anderror causes panic
Dear Template Haskell colleagues I sent three messages to the TH list a month ago. Here's one of them: the others concerned the conversions TH.Syntax <-> HsSyn; I'll fwd them in the next two messages I didn't get a single reply to any of the three. Either the TH mailing list is broken, or else you are all busy with other stuff. (After all, all three did ask for volunteers, in one form or another.) Does anyone care? I'm busy implementing GADTs at the moment, so TH has a somewhat back seat. It'll probably stay that way unless there are some signs of life in the TH ranks. Simon -----Original Message----- From: template-haskell-bounces@haskell.org [mailto:template-haskell-bounces@haskell.org] On Behalf Of Simon Peyton-Jones Sent: 20 July 2004 12:19 To: Duncan Coutts; Template Haskell List Subject: [Template-haskell] RE: calling fail in Q monad gives uninformativeerror message, anderror causes panic Tim and I want to tidy up the error-reporting interface in Template Haskell. The goal is that a TH user should be able to control the error messages that appear. Here's a proposal qReport :: Severity -> String -> Q () -- Report an error or warning -- ...but carry on; use 'fail' to stop fail :: String -> Q a -- Part of Monad class qRecover :: (String -> [(Severity,Loc,String)] -> Q a) -> Q a -> Q a -- Recover from the monadic 'fail' -- The first arg is the error handler -- The first String arg to the handler is what was passed to 'fail' qReports :: [(Severity,Loc,String)] -> Q () data Severity = Error | Warning qGetLoc :: Q Loc qGetModule :: Q ModuleName qWithLoc :: Loc -> Q a -> Q a data Loc = Loc FileName LineNumber CharPos The idea is that qReport dumps a message into the monad (but does not print it yet) with an indication of severity. qReport does not cause monadic failure... you can dump in as many error messages as you like. qReport adds location information from the monad to the message. fail causes monadic failure. qRecover recovers from monadic failure, giving to the recovery routine both the string passed to fail, and the accumulated messages from the enclosed computation. It can use qReports to dump all those messages back into the monad -- or it can just discard them if it wants. At a splice point, the typechecker runs the Q computation. If the result is monadic success, it continues with the returned results. If the result is monadic failure, the splice fails too. (That does not result in any panic -- the type checker is designed to fail, and recover at some outer point.) In both cases, the messages from the Q monad are dumped into the typechecker's message pile. One open question. If you say qReport Error "Bad thing" fail "wuggle" in the Q monad, do you get two type error messages ("Bad thing" and "wuggle") or just one? I can think of three possibilities a) fail s is treated as adding an error message with Severity = Error b) fail s adds no error messages c) fail s behaves like (b) if (null s) and like (a) otherwise. The advantage of (b) and (c) is that you can add a whole bunch of error messages, and then fail, without adding yet another. Comments? Once we have an interface agreed, it won't be hard to implement. Simon | -----Original Message----- | From: glasgow-haskell-bugs-bounces@haskell.org [mailto:glasgow-haskell-bugs- | bounces@haskell.org] On Behalf Of Duncan Coutts | Sent: 23 June 2004 01:13 | To: glasgow-haskell-bugs@haskell.org | Subject: TH: calling fail in Q monad gives uninformative error message, anderror causes panic | | | ghc makes it's own type checker monad TcM an instance of the Quasi class | (which is rather cunning), however this means that if the user calls the | Monad function 'fail' then the internal TcM fail method gets called. | This monad (IOEnv) was never meant to fail (see | ghc/compiler/utils/IOEnv.hs/) so the error message is: | | Exception when trying to run compile-time code: | Code: genex_count | Exn: user error (IOEnv failure) | | Of course the user code should be using 'report', but if you're using | old code, or code that is generic in the monad it uses then people will | end up calling fail. | | Perhaps the thing to do is to wrap splices in an exception handler and | convert 'fail's into a 'report' instead. | | The same should probably be done for errors raised in pure code by | calling 'error'. At the moment it gives an overly panicky report | (although at least it passes the user's error message through): | | ghc-6.3: panic! (the `impossible' happened, GHC version 6.3): | where clauses & gaurds not yet supprted in function definitions | | The error message there is generated by my code (hence the spelling | errors :-) ). | | Duncan | | _______________________________________________ | Glasgow-haskell-bugs mailing list | Glasgow-haskell-bugs@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs _______________________________________________ template-haskell mailing list template-haskell@haskell.org http://www.haskell.org/mailman/listinfo/template-haskell
Hi Simon. I think you deserve a reply on these questions as at their heart is an important point which I believe remains unanswered. Simon Peyton-Jones wrote:
Dear Template Haskell colleagues
I sent three messages to the TH list a month ago. Here's one of them: the others concerned the conversions TH.Syntax <-> HsSyn; I'll fwd them in the next two messages
I didn't get a single reply to any of the three. Either the TH mailing list is broken, or else you are all busy with other stuff. (After all, all three did ask for volunteers, in one form or another.)
Does anyone care?
I am not using TH personally due to lack of time (as with most of my "free time" projects for the past year or two - job, family etc, etc). Never-the-less, I think TH is important because it explores, in the context of the SML family of languages and particularly non-strict Haskell, the equivalent of one of the more powerful features available in Lisp - macros. Despite all the work you and your collaborators have done I believe that it remains to be seen in a large, mature project whether the methodology of TH is of such practical benefit to Haskell as macros have been to Lisp and even templates to C++. I'm inspired particularly by the Blitz++ C++ numerical library and the beautiful exposition of how to compile Prolog into Common Lisp made by Peter Norvig in his book "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", if you need any inspiration. I also think that TH could find uses in foreign function interface marshalling.
I'm busy implementing GADTs at the moment, so TH has a somewhat back seat. It'll probably stay that way unless there are some signs of life in the TH ranks.
This email provides nothing concrete for you, for which I apologize, but I hope that you and your colleagues don't drop the topic in the longer term as I feel you have only scratched the surface in terms of practical research potential. Cheers Mike Thomas.
On Fri, Aug 20, 2004 at 04:37:16PM +0100, Simon Peyton-Jones wrote:
Does anyone care? I'm busy implementing GADTs at the moment, so TH has a somewhat back seat. It'll probably stay that way unless there are some signs of life in the TH ranks.
For what it's worth, I think one of the biggest irritations I've had with writing stuff using TH is the need to split things across module boundaries. This often leads to things that should logically be in the same module being split (and I think I even have had a case or two when I had to split something off out of the split-off module!), making the code harder to read. I think TH needs to have as small a syntactic impact as possible to take off. I understand that there can be a compile-time performance penalty if this restriction is lifted, due to the need to compile to bytecode for TH and then object code for the .o file, but I think this would easily be made up for in the increased clarity of code, especially if only those bits that were needed were compiled to bytecode. Also, I think this has got worse at some point. Going back over some of my old code it looks like this sort of thing: foo = and bar = [| foo |] in one module used to be OK whereas now it gives No instance for (Language.Haskell.TH.Syntax.Lift ([Bool] -> Bool)) Thanks Ian
On Thu, Nov 18, 2004 at 01:15:25AM +0000, Ian Lynagh wrote:
For what it's worth, I think one of the biggest irritations I've had with writing stuff using TH is the need to split things across module boundaries.
Actually, I think this is number 2 on my list, below portability. As I said recently, I've hacked something I wrote to print out TH generated code for use on a platform without ghci+TH, which is a pain but not a showstopper for myself. However, I wanted to unroll the inner loop in SHA1 (essentially says "do this for n = 0..79") for darcs, and really don't want it to get into the situation of having to maintain generated code for platforms without ghci+TH. So for the time being I have to leave it either in a slower HO form or the fast but ugly hand-unrolled form. I appreciate that this is also a hard problem to solve; I just thought I'd let you know it is an issue. (In general portability to other implementations may be an issue too, of course, although darcs currently doesn't support them anyway) Thanks Ian
participants (3)
-
Ian Lynagh -
Mike Thomas -
Simon Peyton-Jones