RE: [Template-haskell] RE: Template Haskell...
| I have one meta-function that generates declarations; and I have | another meta function that needs to know what definitions generated by | the first meta function there are (accross module boundaries). I'm not sure what you're asking for here. Some kind of monadic function that stores persistent state, that persists across multiple compilations? Presumably held in the file system? Some kind of database? I suppose you could write a library using strings only that would support write :: FileName -> String -> String -> IO () read :: FileName -> String -> IO String So (write f key val) writes the (key,value) pair into the file f; and read gets it back. Now you could use those in Q (because Q supports IO). Alastair wants per-module persistence. I'm sceptical about that because TH makes absolutely no guarantees about which order things will be evaluated in. So how would you know which effect occurs first? In both cases I feel I'm missing the point. | reifyImportedModules :: [String] -- or Q [String] | reifyCurrentModuleName :: String -- or Q String The latter seems sensible; but what should the former return? Just the *direct* imports? Do-able anyway. Simon
On Thursday 30 October 2003 9:32 am, Simon Peyton-Jones wrote:
| I have one meta-function that generates declarations; and I have | another meta function that needs to know what definitions generated by | the first meta function there are (accross module boundaries).
I'm not sure what you're asking for here. Some kind of monadic function that stores persistent state, that persists across multiple compilations? Presumably held in the file system? Some kind of database?
A simple approach would be to allow us to write things into the .hi file. For example, the function: write :: String -> Q () would write some data into the .hi file. The concrete representation in the .hi file could be something as simple as: <START_TH>your data here<END_TH> GHC would be responsible for using an escape mechanism on the offchance that the string happened to contain the string "<END_TH>". Since several things could be written into the .hi file, read should return all of them: read :: Q [String] This would return all strings in all .hi files for all directly imported modules. In some cases, we want the strings for all _indirectly_ imported modules too. (That is, to give behaviour like that seem for typeclass instances.) This would require that these strings get propagated from one module to another. Since this isn't always wanted, maybe there should be two kinds of 'write': one to write strings which are propagated and one to write strings which are not. Also, for convenience, we might want a slightly more complex interface which lets users specify a 'tag' (which would often be the name of the splice library being used - e.g., "TemplateGreencard") and in which GHC automatically adds the module name too: write :: Tag -> String -> Q () read :: Q [(ModuleId,Tag,String)]
Alastair wants per-module persistence. I'm sceptical about that because TH makes absolutely no guarantees about which order things will be evaluated in. So how would you know which effect occurs first?
I guess all the TH code I write uses top-level splices so I hadn't thought about this issue. Two solutions suggest themselves: 1) Restrict writes to top-level splices. 2) Allow writes anywhere and warn users about potential non-determinism. -- Alastair Reid www.haskell-consulting.com
participants (2)
-
Alastair Reid -
Simon Peyton-Jones