Simon Peyton-Jones wrote:
Here's your program boiled down a bit foo = 3 baz = $(varE ("fo" ++ "o"))
Like any Haskell compiler, GHC does dependency analysis, and type-checks in that order. There no way for it to see that 'baz' depends on 'foo', so it may well typecheck the definition of baz before that of foo. I haven't actually run your example, but I bet that's what's happening. "-ddump-rn" would tell you, because it shows the code after dependency analysis.
Ah, thanks, that makes a lot of sense. In fact, -ddump-rn reveals that's exactly what's happening.
I wonder if others have tripped over this. There is a tension between dynamic scope and dependency analysis (which is required for type checking) that's hard to resolve. For example, you probably want the example to work even if the definition of 'foo' is after that of 'baz'; at least that's the standard Haskell story.
I suppose a workaround is to put 'foo' in another module, but it's not nice.
I just rephrased the code in such a way that I didn't need that dynamic scoping anymore. I don't think using modules to constrain dependency analysis for TH is such a bad idea, though. Particularly if there were some syntax for creating said modules in the same file... That's a discussion for another day, though. Thanks for the help! Bryn