
Furthermore, when I need to perform refactoring, a rename is just *one* change to the entire system, no matter how many other files use the name; no more merging for stupid renames. I'm a little confused as to what you mean here. A renaming renames all (and only those) uses of an identifier within a particular definition, and not every use of a particular name. The binding structure of the program
Suppose we have a file Foo.hs, with the content: foo ::Int foo = 42 Translated into a syntax tree, this might look like (majorly simplified) <Definition id="68684" name="foo"> <Constant value="42" type="Int"/> </Definition> and a file Bar.hs, with bar :: Int bar = foo + 27 or translated <Definition id="577647" name="bar"> <Add> <Reference id="68684"/> <Constant value="27" type="Int"/> </Add> </Definition> If you rename foo, using textual representation, both Foo.hs and Bar.hs will be touched / checked-out. However, if you work directly on the structure, then only the Foo XML file is changed, Bar is not changed at all. Of course this might only be the case with renames, more complex refactorings usually require modifying other files :) Anyway, I hate merges caused by renames by others. And many developers tend to leave names as they are, because you get used to strange names anyway... A good example is Microsoft's Windows Presentation Foundation code: what do you think the method FindName on an element tree does? It searches for an element with a particular name, and returns that element ;)
There is also (preliminary at the moment) duplicate code detection built into HaRe. This is based on the principle of looking at the shape of functions and expressions, concentrating on where variables are bound and whether one term is an intance of another. Duplicate expressions can be converted into a more general abstraction, transforming the duplicate expressions into function calls (parameterised by their differences).
Impressive! Cheers, Peter