RE: [Template-haskell] program transformation
I'm returning to the question of reification in Template Haskell. Would it help here if one could say reify :: Var -> Q Decl and get the declaration for 'reverse'? (Var is as in the "notes" Postscript file I posted yesterday.) I can arrange that iff reverse is defined in the same module. Thus reverse = ... foo = $( do { rev_dec <- reify 'reverse; ... }) (The 'reverse is like a quote [|reverse|], but gets a Var not an Exp.) This is much harder if reverse is imported, because we simply don't have access to reverse's source code any more. (But type constructors and classes are fine. -- excluding the default-method bindings of the class.) Would this help? Simon | -----Original Message----- | From: template-haskell-bounces@haskell.org [mailto:template-haskell-bounces@haskell.org] On | Behalf Of Ganesh Sittampalam | Sent: 12 September 2003 17:10 | To: template-haskell@haskell.org | Subject: [Template-haskell] program transformation | | I'm currently investigating the possibility of redoing MAG in Template | Haskell. MAG is essentially (at least for the purposes of this email) a | system that takes a source program and a bunch of rewrite rules, and | applies the rewrite rules to the program. | | I'd like to be able to do this in TH with as little syntactic noise for | the user as possible. The general idea (at the moment) would be to put the | original program within [d| |] brackets, the set of rewrite rules within | [| |] brackets, run a function on the two and splice in the result. | | It's not the main purpose of this email, but I should mention that being | able to splice in code in the same module as it is defined would be very | useful for this application, since otherwise any module that makes use of | this will need to be split into two. | | There was a previous discussion about TH and Hydra at | http://www.haskell.org/pipermail/template-haskell/2003-January/000008.ht ml, | which ended up with the idea of using [d| |] brackets for code that was to | be transformed. The extra twist for me is that I have this set of rewrite | rules that I also want to use quasi-quotes for. | | A simplified example of a rewrite rule that uses the associativity of (++) | is as follows: | | \xs ys zs -> (xs ++ ys) ++ zs ==> xs ++ (ys ++ zs) | | ==> is an operator of type a -> a -> RewriteRule, so GHC will check for me | that the rewrite rule is type correct. The lambda binding for xs, ys and | zs specifies that the rewrite rule works for any value of them, and also | keeps the compiler happy that I haven't used undefined variables. Of | course, I'm never intending to actually run this code, I'll just use the | result of quasi-quoting it to apply transformations. | | Anyway, this all works fine. Now, let's suppose that my original program | defines the function reverse (hiding the Prelude reverse function), and I | want to write a rewrite rule mentioning reverse too. I end up with | something like this: | | reversecode = | [d| | reverse [] = [] | reverse (x:xs) = reverse xs ++ [x] | |] | | rules = [| [ reverse [] ==> [] ] |] | | The second definition won't compile, since reverse isn't in scope | anywhere. I'm trying to work out a good solution to this problem; so far | I've come up with the following ideas: | | (a) Merge the rewrite rules and the declarations. E.g: | [| | let reverse [] = [] | reverse (x:xs) = reverse xs ++ [x] | in [ reverse [] ==> [] | ... | ] | |] | Pros: - this should actually work for me right now (not actually tested | - though) | Cons: - it violates the nice separation between code and transformation, | - it doesn't read nicely for the user; in particular it'll be | unpleasant for them to take some existing code and decide to use | MAG on it | | (b) Use a lambda-abstraction or let-binding to make "reverse" appear to be | defined. | Pros: - again this ought to work right now | Cons: - unless I textually duplicate code, it won't be properly type-checked | - the renamer will rename "reverse" and I'll have to make some | nasty assumptions about how that works to get back to the | original form | | (c) Turn the rewrite rules into a separate [d| |] block, and splice in | $(reversecode) at the beginning | Pros: - Not nearly as inelegant/nasty as (a) or (b) | Cons: - I still have to search the declaration list for the rewrite | rules | - This will fall foul of the (second) bug I reported yesterday | | (d) Say something like let $(reversecode) in reverse [] ==> [] | Pros: - Seems even less nasty than the above options | Cons: - disallowed by design in TH, for good reasons; it destroys the | ability to see where things are bound statically | | I'd appreciate any comments or alternative suggestions. Ideally I think | I'm looking for some nice concise way to say that the rewrite rules | quasi-quotes should be parsed and type-checked in the context of the | declarations in original code quasi-quotes. | | Cheers, | | Ganesh | | | | _______________________________________________ | template-haskell mailing list | template-haskell@haskell.org | http://www.haskell.org/mailman/listinfo/template-haskell
The thing is that I need to be able to replace the original reverse
definition with a new one, so I really need to write the original definition
inside [d| ... |] brackets so that I can decide later what I actually want
to splice in - either the original definition if the user doesn't want to
apply the transformation or if it fails, or the transformed definition. I'm
not sure if what you're suggesting helps with that.
Cheers,
Ganesh
On Thu, 30 Oct 2003 15:28:39 -0000, "Simon Peyton-Jones"
I'm returning to the question of reification in Template Haskell.
Would it help here if one could say
reify :: Var -> Q Decl
and get the declaration for 'reverse'? (Var is as in the "notes" Postscript file I posted yesterday.)
I can arrange that iff reverse is defined in the same module. Thus
reverse = ... foo = $( do { rev_dec <- reify 'reverse; ... })
(The 'reverse is like a quote [|reverse|], but gets a Var not an Exp.)
This is much harder if reverse is imported, because we simply don't have access to reverse's source code any more. (But type constructors and classes are fine. -- excluding the default-method bindings of the class.)
Would this help?
Simon
| -----Original Message----- | From: template-haskell-bounces@haskell.org [mailto:template-haskell-bounces@haskell.org] On | Behalf Of Ganesh Sittampalam | Sent: 12 September 2003 17:10 | To: template-haskell@haskell.org | Subject: [Template-haskell] program transformation | | I'm currently investigating the possibility of redoing MAG in Template | Haskell. MAG is essentially (at least for the purposes of this email) a | system that takes a source program and a bunch of rewrite rules, and | applies the rewrite rules to the program. | | I'd like to be able to do this in TH with as little syntactic noise for | the user as possible. The general idea (at the moment) would be to put the | original program within [d| |] brackets, the set of rewrite rules within | [| |] brackets, run a function on the two and splice in the result. | | It's not the main purpose of this email, but I should mention that being | able to splice in code in the same module as it is defined would be very | useful for this application, since otherwise any module that makes use of | this will need to be split into two. | | There was a previous discussion about TH and Hydra at | http://www.haskell.org/pipermail/template-haskell/2003-January/000008.ht ml, | which ended up with the idea of using [d| |] brackets for code that was to | be transformed. The extra twist for me is that I have this set of rewrite | rules that I also want to use quasi-quotes for. | | A simplified example of a rewrite rule that uses the associativity of (++) | is as follows: | | \xs ys zs -> (xs ++ ys) ++ zs ==> xs ++ (ys ++ zs) | | ==> is an operator of type a -> a -> RewriteRule, so GHC will check for me | that the rewrite rule is type correct. The lambda binding for xs, ys and | zs specifies that the rewrite rule works for any value of them, and also | keeps the compiler happy that I haven't used undefined variables. Of | course, I'm never intending to actually run this code, I'll just use the | result of quasi-quoting it to apply transformations. | | Anyway, this all works fine. Now, let's suppose that my original program | defines the function reverse (hiding the Prelude reverse function), and I | want to write a rewrite rule mentioning reverse too. I end up with | something like this: | | reversecode = | [d| | reverse [] = [] | reverse (x:xs) = reverse xs ++ [x] | |] | | rules = [| [ reverse [] ==> [] ] |] | | The second definition won't compile, since reverse isn't in scope | anywhere. I'm trying to work out a good solution to this problem; so far | I've come up with the following ideas: | | (a) Merge the rewrite rules and the declarations. E.g: | [| | let reverse [] = [] | reverse (x:xs) = reverse xs ++ [x] | in [ reverse [] ==> [] | ... | ] | |] | Pros: - this should actually work for me right now (not actually tested | - though) | Cons: - it violates the nice separation between code and transformation, | - it doesn't read nicely for the user; in particular it'll be | unpleasant for them to take some existing code and decide to use | MAG on it | | (b) Use a lambda-abstraction or let-binding to make "reverse" appear to be | defined. | Pros: - again this ought to work right now | Cons: - unless I textually duplicate code, it won't be properly type-checked | - the renamer will rename "reverse" and I'll have to make some | nasty assumptions about how that works to get back to the | original form | | (c) Turn the rewrite rules into a separate [d| |] block, and splice in | $(reversecode) at the beginning | Pros: - Not nearly as inelegant/nasty as (a) or (b) | Cons: - I still have to search the declaration list for the rewrite | rules | - This will fall foul of the (second) bug I reported yesterday | | (d) Say something like let $(reversecode) in reverse [] ==> [] | Pros: - Seems even less nasty than the above options | Cons: - disallowed by design in TH, for good reasons; it destroys the | ability to see where things are bound statically | | I'd appreciate any comments or alternative suggestions. Ideally I think | I'm looking for some nice concise way to say that the rewrite rules | quasi-quotes should be parsed and type-checked in the context of the | declarations in original code quasi-quotes. | | Cheers, | | Ganesh | | | | _______________________________________________ | template-haskell mailing list | template-haskell@haskell.org | http://www.haskell.org/mailman/listinfo/template-haskell
_______________________________________________ template-haskell mailing list template-haskell@haskell.org http://www.haskell.org/mailman/listinfo/template-haskell
participants (2)
-
Ganesh Sittampalam -
Simon Peyton-Jones