
#10047: inconsistency in name binding between splice and quasiquotation -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: 7.12.1 Component: Template Haskell | Version: 7.8.4 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: th/T10047 Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by spinda): Firstly, at least as far as I've seen, the scoping restriction is one of the most common complaints about Template Haskell splices, as using them at all suddenly causes order of declaration to matter where it didn't before. This contributes to the stigma and avoidance of Template Haskell usage. It would be a shame to see quasiquoters get shackled with this issue as well. Then, I think it's important to consider the role of quasiquoters as enabling extensions to the language without requiring compiler plugins, external preprocessors, or what have you, while keeping them contained from the rest of the Haskell source around them. As a specific example, I'll pull from my current GSoC project, which is impacted by this change (and, to be honest, is the reason I ran into this). I have an {{{lq}}} quasiquoter which allows for LiquidHaskell type signatures and specifications to be attached to variables and types. In the declaration context, it parses a subset of Haskell with LiquidHaskell extensions and emits declarations and annotations. Take some vanilla Haskell code: {{{ module Test () where type Nat = Int add :: Nat -> Nat -> Nat add x y = id' $ x + y id' :: a -> a id' x = x }}} A little contrived, but not too far from what you'd run into in sufficiently complex real-world projects. Under the current (or, previous) quasiquoter implementation, extending this existing code with custom annotations is a fairly straightforward translation: {{{ {-# LANGUAGE QuasiQuotes #-} module Test () where import LiquidHaskell [lq| type Nat = { v:Int | 0 <= v } |] [lq| add :: Nat -> Nat -> Nat |] add x y = id' $ x + y [lq| id' :: x:a -> { v:a | v == a } |] id' x = x }}} But after this change, introducing these annotations suddenly makes order of declaration matter. What were lightweight inline extensions to the language now require restructuring of code, either reordering the functions themselves or moving all signatures and specifications to the top of every file. Needless to say, this makes the whole thing much less attractive. And, frankly, this is what quasiquoters are all about: lightweight, inline language extensions that don't interfere with the rest of the code. This intent is reflected in the original paper. With this restriction imposed, anything using quasiquoters suddenly brings in a lot more baggage than it used to, discouraging use. It's not just a matter of modifying some existing code to fit, it's that this hampers a whole set of use-cases for which quasiquoters (a) used to fit quite nicely and (b) are the only real solution at present. Quietly breaking this behavior of 12 years now in a tangentially related bugfix strikes me as, well, wrong, especially when there isn't an alternative available. Excuse me if I seem rather passionate about this issue. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10047#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler