Title: Progress on HaRe: The Haskell Refactorer
1Progress on HaRe The Haskell Refactorer
Huiqing Li, Claus Reinke, Simon Thompson
Computing Laboratory, University of Kent
- Tool support is considered invaluable as it is
more reliable and allows refactorings to be done
(and undone) easily.
The Project Refactoring Functional Programs
- Explore the prospects of refactoring functional
programs taking Haskell as a case-study. - Build the HaRe tool to explore the practicalities
of refactoring, and to support refactoring
Haskell programs.
A Simple Example
generalisation
sum 0 sum (ht) () h (sum t) main
print sum 1..4
What is Refactoring?
- Refactoring is the process of improving the
design of existing code without changing their
functionality. Its key characteristic is the
focus on the structural change, strictly
separated from changes in functionality. If
applied properly, refactoring can make a program
easier to understand or modify. - Refactorings are diffuse and bureaucratic in
the sense that they have an effect not only at
the point where they are initiated, but also at
the places where the refactored component is
used. - An elementary refactoring is a refactoring that
can not be decomposed into simpler refactorings,
whereas a composite refactoring can be decomposed
into a number of elementary refactorings.
sum n n sum n (ht) () h (sum n
t) main print sum 0 1..4
generalisation
sum c n n sum c n (ht) c h (sum c n
t) main print sum () 0 1..4
renaming
fold c n n fold c n (ht) c h (fold c n
t) main print fold () 0 1..4
. . .
2 HaRe the Haskell Refactorer
Refactorings Implemented in HaRe
- A system designed to support refactoring Haskell
programs. - Full Haskell 98 coverage.
- Integrated into two program editors (X)Emacs and
Vim. - Preserves both comments and layout of refactored
program. - Implemented in Haskell using Programaticas
frontends and Strafunskis generic programming
technique. - Driving concerns usability and solid basis for
extensions. - The first version of HaRe was released in October
2003. The current version is available online at - http//www.cs.kent.ac.uk/projec
ts/refactor-fp
- Structural Refactorings
- Rename an identifier
- Delete an unused function
- Duplicate a definition.
- Promote a definition to a wider scope
- Demote a definition to narrow its scope
- Unfold a definition
- Introduce a definition to name an identified
expression - Generalise a definition
- Add an argument to a function
- Remove an unused argument from a function
- Module Refactorings
- Clean the import list
- Make the used entities explicitly imported
- Add an item to the export list
- Remove an item from the export list
- Move a definition from one module to another
module - Data-oriented Refactorings
- From concrete to abstract data-type (ADT), which
is a composite refactoring built from a set of
primitive refactorings
Whats New in HaRe?
- All the implemented refactorings are now
module-aware. - Added new refactorings for the module system.
- Added data-oriented refactorings.
- Evolved architecture to allow the end users to
define their own refactorings.
3 Implementing a Refactoring
Snapshots of HaRe Embedded in Emacs
program source
Information gathering using the Programatica
front-end for Haskell (lexer,parser, type checker
and module analysis)
Program analysis and transformation using
Strafunski's generic traversal library
After applying the From concrete to abstract
data type refactoring to the data type Tree
Program rendering by extracting program source
from token stream
refactored program source
- HaRe preserves the comments and layout of
refactored programs by making use of the white
space and comment information in the token
stream, as well as the location information in
both the token stream and the abstract syntax
tree(AST). Both the AST and the token stream are
modified during the program transformation
process.
4 The Architecture of HaRe
Evaluation of HaRe
Composite Refactorings
- Testing by applying HaRe to medium/large-size
Haskell 98 programs. - Clarify and prove concepts by formalization.
Elementary Refactorings
RefacUtils
Future Directions
- Populate more refactorings into HaRe, such as
removing duplicated code, monadification and
further data-centred refactorings. - Finalise the API for user-defined refactorings
and further investigate the composition of
refactorings. - Extend HaRe to handle no-source files.
- Develop proofs of correctness for a variety of
the refactorings implemented in HaRe. - Extend HaRe to support Haskell 98 extensions.
RefacLocUtils
Programatica
Strafunski
- Hidden token stream manipulation. RefacLocUtils
is a library for token stream manipulation. Its
core is a layout adjustment algorithm which keeps
the programs layout correct after a modification
to the token stream. - An API for program analysis and transformation.
This API forms the basis for implementing
primitive refactorings. - Open architecture. Design your own refactorings.
Contact Information
-- Example Swapping the first two arguments to
the function pn in the AST mod doSwap pn mod
applyTP (full_buTP (idTP adhocTP swapInMatch
adhocTP swapInExp)) mod where
swapInMatch ((HsMatch loc fun pats rhs
ds)HsMatchP) pNTtoPN fun pn
case pats of (p1p2ps) -gt do swapInToks p1 p2
return (HsMatch loc fun (p2p1ps) rhs
ds) _
-gt error "Insufficient arguments to swap."
swapInExp ((Exp (HsApp (Exp (HsApp e e1))
e2))HsExpP) expToPN e pn do
swapInToks e1 e2 return (Exp
(HsApp (Exp (HsApp e e2)) e1)) swapInExp
e return e
The refactoring group at UKC refactor-fp_at_kent.ac.
uk Huiqing Li hl_at_kent.ac.uk Claus
Reinke cr3_at_kent.ac.uk Simon Thompson
sjt_at_kent.ac.uk
The project is funded by EPSRC. We are grateful
to Programatica (http//www.cse.ogi.edu/PacSoft
/projects/programatica/) and Strafunski
(http//www.cs.vu.nl/Strafunski/) development
teams.