[Template-haskell] program transformation
Ganesh Sittampalam
Ganesh.Sittampalam at comlab.ox.ac.uk
Fri Nov 7 16:27:41 EST 2003
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"
<simonpj at microsoft.com> wrote:
>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 at haskell.org
>[mailto:template-haskell-bounces at haskell.org] On
>| Behalf Of Ganesh Sittampalam
>| Sent: 12 September 2003 17:10
>| To: template-haskell at 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 at haskell.org
>| http://www.haskell.org/mailman/listinfo/template-haskell
>
>
>_______________________________________________
>template-haskell mailing list
>template-haskell at haskell.org
>http://www.haskell.org/mailman/listinfo/template-haskell
More information about the template-haskell
mailing list