[Haskell-cafe] [GSoC] Porting HaRe to use the GHC API

Claus Reinke claus.reinke at talk21.com
Thu Apr 3 20:00:44 EDT 2008

|Another notion I was interested in was to be able to reproduce a
|sequence of multi-module refactorings even in the absence of the
|initial module. It would allow to present a kind of "interface diff"
|for a distribution which would allow the developer of a module which
|depends on the distribution to update the call to this library. Of
|course it wouldn't be perfect and wouldn't convey the semantic
|modifications of the interface but it would help for all the renaming
|and usual modifications of external interfaces.

refactorings crossing external APIs are a very real problem,
and when i last checked (several years ago..), published solutions 
went little further than establishing informal work-patterns ("if you
do it like this, you'll save yourself and us some trouble. if you want
to stay on our project, you'd better do it like this") or boundaries
to limit the spread of refactoring effects over distributed projects.

my own favourite approach expresses the process as a "buffered
refactoring", with an adapter module serving as the buffer and 
formal spec of your "interface diff" (with apologies for ascii art;-):

    L: some library code
    I: L's external API
    C: some external client of L

    0. C uses L, via I: L |I| C

    1. introduce internal proxy/adapter A: { L |I| A } |I| C

    2. refactor internally, leaving external API I unchanged
        while creating new internal API I': { L' |I'| A' } |I| C

    3. publish L's new interface I', together with refactored 
        adapter A', and deprecate old interface I:   L' |I'| { A' |I| C }

    4. clients can refactor to new interface, eliminating adapter A':
        L' |I1'| C'

when it works, this approach has the advantage of formalizing
every part of the process as a sequence of refactorings, and
clients have the choice either to continue using the adaptor,
ignoring the new interface in favour of the old one, or to 
get rid of the indirection and to use the new interface directly,
by pushing the refactoring that started in the library code
into their own code base.

you could combine that with giving clients the sequence of
refactorings that turned A (just re-export) into A'
(implement old API in terms of new one), as it might help
them to proceed.

|But all of that should wait after we get HaRe working with the GHC API. :-)

good to hear that - it is all too easy to get side-tracked when
there are so many interesting problems!-) i just wanted to
point out that soon after you get it working, there might be
some disappointments due to GHC's source-less distribution
installation model, use of cpp, etc. .. which just means that 
there'll be more work left after this necessary first step.


More information about the Haskell-Cafe mailing list