
Hi, I recently stumbled upon the issue of `reify` not being able to give information about local variables, as of GHC 7.8. For example, this won't work: foo x = $(do {xInfo <- reify 'x; ...}) The motivation for this change is described here: https://ghc.haskell.org/trac/ghc/wiki/TemplateHaskell/BlogPostChanges#PartC:.... While I agree that getting the type of local variables is going to be brittle, I also think that offering that functionality is extremely useful in certain cases, such as in the case of the language-c-inline library, that used this facility to avoid having to type verbose type annotations -- see https://github.com/mchakravarty/language-c-inline/issues/25. My two part question is: 1. would it be possible to revert to the old behavior easily, or is doing that difficult or impossible now given the overall changes to the Template Haskell code? 2. if 1, wouldn't it make more sense to allow reifying all names if the user really wants, maybe with a specific `unsafeReify` function or similar? It should be made clear in the docs that by using `unsafeReify` the user is relying on GHC internals (specifically the internals of type checking). Also, I think that post should at least be referenced in the manual, for lack of better documentation. This behavior is not mentioned anywhere else. Thanks, Francesco

| 1. would it be possible to revert to the old behavior easily, or is | doing that difficult or impossible now given the overall changes to | the Template Haskell code? I don’t think it would be difficult to recover the old behaviour, but it's not clear to me that it would be a Good Thing. A program that works today, and then does not work tomorrow because of some incidental change to the way type inference works, would not be a happy state of affairs. Perhaps if 'x' had a type annotation that would be ok. Or maybe there is something else about your intended application that makes it solidly predictable. By all means start a wiki page to sketch a design for what you think should happen, and why it should be predicable. Meanwhile, if you would care to draft the bit of user-manual material that you wish had been there, I could review it and put it in. Thanks! Simon | -----Original Message----- | From: Francesco Mazzoli [mailto:f@mazzo.li] | Sent: 13 February 2015 12:54 | To: ghc-devs@haskell.org | Cc: Simon Peyton Jones | Subject: What `reify` sees in Template Haskell | | Hi, | | I recently stumbled upon the issue of `reify` not being able to give | information about local variables, as of GHC 7.8. For example, this | won't work: | | foo x = $(do {xInfo <- reify 'x; ...}) | | The motivation for this change is described here: | <https://ghc.haskell.org/trac/ghc/wiki/TemplateHaskell/BlogPostChanges | #PartC:Reificationandtypechecking>. | | While I agree that getting the type of local variables is going to be | brittle, I also think that offering that functionality is extremely | useful in certain cases, such as in the case of the language-c-inline | library, that used this facility to avoid having to type verbose type | annotations -- see <https://github.com/mchakravarty/language-c- | inline/issues/25>. | | My two part question is: | | 1. would it be possible to revert to the old behavior easily, or is | doing that difficult or impossible now given the overall changes to | the Template Haskell code? | 2. if 1, wouldn't it make more sense to allow reifying all names if | the user really wants, maybe with a specific `unsafeReify` function or | similar? | | It should be made clear in the docs that by using `unsafeReify` the | user is relying on GHC internals (specifically the internals of type | checking). | | Also, I think that post should at least be referenced in the manual, | for lack of better documentation. This behavior is not mentioned | anywhere else. | | Thanks, | Francesco

Hi Simon,
On 13 February 2015 at 18:12, Simon Peyton Jones
I don’t think it would be difficult to recover the old behaviour, but it's not clear to me that it would be a Good Thing. A program that works today, and then does not work tomorrow because of some incidental change to the way type inference works, would not be a happy state of affairs.
In much the same way, programs that rely on the memory representation that GHC uses for objects can be written with the provided unsafe functions. In my view, if you make this danger clear, having those functions is much better than not having them. And it seems like the Haskell environment generally agree with this view. In any case, if I think of some reasonable but more permissive restriction, I'll write it up.
Meanwhile, if you would care to draft the bit of user-manual material that you wish had been there, I could review it and put it in.
I'll try to get some writing done regarding this and the FFI wiki page next week. Francesco

On Fri, Feb 13, 2015 at 12:43 PM, Francesco Mazzoli
Hi Simon,
I don’t think it would be difficult to recover the old behaviour, but it's not clear to me that it would be a Good Thing. A program that works today, and then does not work tomorrow because of some incidental change to
On 13 February 2015 at 18:12, Simon Peyton Jones
wrote: the way type inference works, would not be a happy state of affairs. In much the same way, programs that rely on the memory representation that GHC uses for objects can be written with the provided unsafe functions. In my view, if you make this danger clear, having those functions is much better than not having them. And it seems like the Haskell environment generally agree with this view.
Right, but the users of such features understand that their programs may break under future versions of GHC, and don't expect to have any particular recourse if this happens. And this is essentially what happened here. It doesn't make sense to ask about the type of a variable in a TH splice when the result of that splice might affect what type the variable has! Admittedly it was not documented that the behavior of reify was undefined in this case, but I imagine that's because nobody had considered this scenario (if they had, we'd have had the 7.8 design from the start). I don't like it more than anyone else when GHC breaks user programs, but when those programs were dependent on undefined behavior, I think it's incumbent on the user to find a way to rewrite their program so as to not depend on undefined behavior. This might include requesting a new GHC feature with well-defined semantics. Adding the old undefined behavior should be a last resort, and then in the future the undefined behavior might stop giving you the answer you want anyways.
In any case, if I think of some reasonable but more permissive restriction, I'll write it up.
Have you tried using Typed TH splices? Those interact differently with the type checker, because the type of the expression resulting from a splice is determined by the type of the splice action, and cannot depend upon its value. So, it seems to me that it would be fine to allow reify to ask about the type of a local variable from within a typed splice, and it may work that way already (I haven't tried it). Regards, Reid Barton
participants (3)
-
Francesco Mazzoli
-
Reid Barton
-
Simon Peyton Jones