reifyDecl: syntax and semantics
Hi there "Reification is a language construct, not a function", as said in the paper. I would like to discuss this choice a bit, focusing on reifyDecl. First, I don't really see any justification for this restriction. As far as I can see, if we say, for instance: reifyDecl :: String -> Decl as long as the result is in the quotation monad, it should be okay, or shoudln't it ? Maybe there are some implementation considerations that I can't see behind that choice. I think at least constructs of the form reifyDecl $(con "Tree") should be allowed. At present, the parser rejects that. My second point is that the syntax is inconsistent with the intended semantics: for example, the documentation says that it should be possible to reify a function definition and a prototype. But if I ask reifyDecl length, what do I expect ? The def or the proto ? Same thing with reification of instance declarations. As a matter of fact, the present implementation does not seem to handle the cases of prototypes and instances, and I don't think it is an urgent matter. However, I think the syntax should not already forbid that. My last point, is that it is really impractical. I think it is a pity that such a powerful construct is in fact almost unusable because of poor syntactic restrictions. For example, I want to reify a datatype declaration and then generate a declaration, say for a function, depending on the structure of the datatype. I can do that, but I can't abstract from the original datatype, which I am not happy with. If you're not convinced yet, I can be a bit more specific about what I want to do. So, what do you think about that ? -fr-
On 02 May 2003 16:51:46 +0200
François-Régis Sinot
My second point is that the syntax is inconsistent with the intended semantics: for example, the documentation says that it should be possible to reify a function definition and a prototype. But if I ask reifyDecl length, what do I expect ? The def or the proto ? Same thing with reification of instance declarations. As a matter of fact, the present implementation does not seem to handle the cases of prototypes and instances, and I don't think it is an urgent matter. However, I think the syntax should not already forbid that. [...]
I can't comment on the other parts, I would imagine it's an implementation restriction that could be lifted, but with quite a bit of effort. However, which documntation says reifyDecl reifies the type? I don't remember reading that anywhere (though I may have just forgotten). I've always thought of reifyDecl and it has always worked that way for me as providing the definition and only the definition. There is a seperate construct (reifyType) for type information (I think last time I checked it wasn't implemented or maybe I'm thinking of something else). My solution for abstracting away which datatype to process, is simply to have the generation function be f :: Decl -> Decl, actually in my case it was genAlgebra :: String -> [Decl] -> Q [Dec]. Then, one would use it as: $(genAlgebra "Lang" [reifyDecl Type,reifyDecl Expr]) not the prettiest solution, but not much worse than what it would be anyways. However, I can think of other problems where this limitation may be an issue, your problem may be in that category.
I can't comment on the other parts, I would imagine it's an implementation restriction that could be lifted, but with quite a bit of effort. However, which documntation says reifyDecl reifies the type? I don't remember reading that anywhere (though I may have just forgotten). I've always thought of reifyDecl and it has always worked that way for me as providing the definition and only the definition. There is a seperate construct (reifyType) for type information (I think last time I checked it wasn't implemented or maybe I'm thinking of something else).
Ok, so maybe it is a bit unclear what reifyDecl should do. I was refering to the paper, where something like "for example datatype declarations, etc." is said, and I assumed it should work the same way for every case in Decl. And actually, one may very well want to reify an instance declaration. The case of prototypes is less clear, because there is an access to (almost ?) the same information with reifyType. It may however be more convenient for some applications, I suppose.
My solution for abstracting away which datatype to process, is simply to have the generation function be f :: Decl -> Decl, actually in my case it was genAlgebra :: String -> [Decl] -> Q [Dec]. Then, one would use it as: $(genAlgebra "Lang" [reifyDecl Type,reifyDecl Expr]) not the prettiest solution, but not much worse than what it would be anyways. However, I can think of other problems where this limitation may be an issue, your problem may be in that category.
Sure, there is a solution, thanks. However it is not really convenient. In particular, suppose you want to write a library that performs that kind of things (reify a declaration, and generate another one), then your line above has to be written by the user ! This is clearly too much to ask. You'll tell me I just have to write a preprocessor, sure, but again this is not really satisfactory. If TH is intended to be widely distributed and used at middle-term, I still think my "request" makes sense. Now, I understand this represents some work, and that there are other priorities. -fr-
On 02 May 2003 19:06:09 +0200
François-Régis Sinot
Sure, there is a solution, thanks. However it is not really convenient. In particular, suppose you want to write a library that performs that kind of things (reify a declaration, and generate another one), then your line above has to be written by the user ! This is clearly too much to ask. You'll tell me I just have to write a preprocessor, sure, but again this is not really satisfactory. If TH is intended to be widely distributed and used at middle-term, I still think my "request" makes sense. Now, I understand this represents some work, and that there are other priorities.
I'm sure the TH implementors won't mind if you want to try to implement this (or something similar) yourself ;), such is the bounty of open-source.
participants (2)
-
Derek Elkins -
François-Régis Sinot