Programming Language Technology 2005-6

Download Report

Transcript Programming Language Technology 2005-6

Refactoring
Functional Programs
Huiqing Li
Simon Thompson
Chris Brown
Claus Reinke
Computing Lab
University of Kent
WRT 2007
Overview
Refactoring tools.
Functional programming.
Haskell and Erlang.
Tools and tool building.
Tool design.
Experience.
WRT 2007
Introduction
WRT 2007
Refactoring tool support
Bureaucratic and
diffuse.
Tedious and error
prone.
Semantics: scopes,
types, modules, …
Undo/redo
Enhanced creativity
WRT 2007
Functional Programming
Values not variables.
Expressions not :=.
Functions as data.
Rich data and types.
Controlled side-effects.
Declarative descriptions
of refactorings.
WRT 2007
Haskell
Erlang
Strong, static types.
Lazy evaluation.
Weak, dynamic types.
Strict evaluation.
Hot code swap, apply etc.
Layout sensitive.
Concurrency library.
Haskell 98 standard.
GHC, NHC, Hugs, …
Academic, O/S apps.
WRT 2007
Concurrency built-in.
OTP, design patterns.
Single system.
Industrial applications.
Generalisation and renaming
-module (test).
-export([f/1]).
-module (test).
-export([f/1]).
add_one ([H|T]) ->
[H+1 | add_one(T)];
add_int (N, [H|T]) ->
add_one
[H+N | add_int(N,T)];
add_one(N,T)];
add_one ([]) -> [].
add_one (N,[]) -> [].
add_int
f(X) -> add_one(X).
f(X) -> add_int(1,
add_one(1, X).
WRT 2007
Generalisation
-export([printList/1]).
-export([printList/2]).
printList([H|T]) ->
io:format("~p\n",[H]),
printList(T);
printList([]) -> true.
printList(F,[H|T]) ->
F(H),
printList(F, T);
printList(F,[]) -> true.
printList([1,2,3])
printList(
fun(H) ->
io:format("~p\n", [H])
end,
[1,2,3]).
WRT 2007
Asynchronous to synchronous
pid! {self(),msg}
pid! {self(),msg},
receive {pid, ok}-> ok
{Parent,msg} ->
body
{Parent,msg} ->
Parent! {self(),ok},
body
WRT 2007
The tools
WRT 2007
HaRe: the Haskell Refactorer
Structural, data type,
and module-level.
In Haskell: embedded in
gvim and emacs.
Uses the Programatica
framework …
… + Strafunski program
transformation library.
WRT 2007
Wrangler: refactoring Erlang
Structural, data type and
module-level refactorings.
In Erlang plus emacs.
Uses the Erlang system
framework …
… + untyped Erlang
transformation library.
Respects aspects of the
macro system.
WRT 2007
Design to be usable
WRT 2007
Coverage and Standards
De jure standard, Haskell 98, …
vs de facto standard Glasgow Haskell.
Standard release pattern of Open Source
Erlang supervised by the OTP team at
Ericsson.
WRT 2007
Integration … with IDEs
Back to the future? Programmers'
preference for emacs and gvim …
… though some IDE interest:
Visual Studio, Eclipse, NetBeans.
Issue of integration with multiple IDEs:
HaRe interfaces with emacs and gvim.
WRT 2007
Integration … with tools
Test data sets and test generation.
Makefiles, etc.
Working with macros e.g. QuickCheck
uses Erlang macros …
… in a particular idiom.
WRT 2007
Preserving appearance
-- This is an example
-- This is an example
module Main where
module Main where
sumSquares x y = sq x + sq y
where sq :: Int->Int
sq x = x ^ pow
pow = 2 :: Int
sumSquares x y = sq pow x + sq pow y
where pow = 2 :: Int
main = sumSquares 10 20
sq :: Int->Int->Int
sq pow x = x ^ pow
main = sumSquares 10 20
module Main where
sumSquares x y
= sq pow x + sq pow y where pow
sq :: Int->Int->Int
sq pow x = x ^ pow
main = sumSquares 10 20
WRT 2007
= 2 :: Int
Experience
WRT 2007
Refactoring = Transformation + Condition
Transformation
Condition
Ensure change at all
those points needed.
Is the refactoring
applicable?
Ensure change at only
those points needed.
Will it preserve the
semantics of the
module? the program?
WRT 2007
Condition > Transformation
Renaming an identifier
"The existing binding structure should not be
affected. No binding for the new name may
intervene between the binding of the old name
and any of its uses, since the renamed identifier
would be captured by the renaming.
Conversely, the binding to be renamed must not
intervene between bindings and uses of the
new name."
WRT 2007
Which refactoring exactly?
Generalise f by making 23 a parameter of f:
f x = 23 + g x
where g x = x + 23 + con
con = 23
• This one occurrence?
• All occurrences (in the body)?
• Some of the occurrences … to be selected.
WRT 2007
Compensate or fail?
Lift g to a global definition in
f x = x + g x
where g x = x + con
con = 37
• Fail because con not defined globally?
• Add extra parameter to g, and pass in con?
• Lift con as well?
WRT 2007
Compensate or crash?
-export([oldFun/1,
newFun/1]).
oldFun(L) ->
newFun(L).
newFun(L) ->
…
… .
WRT 2007
-export([newFun/1]).
or
?
newFun(L) ->
…
… .
Infrastructure
Requirement for heavyweight infrastructure.
Best not to write your own!
Compiler APIs.
• Often non-existent.
• Can change with releases.
• Clearly system specific.
Tracking changes in systems and libraries.
WRT 2007
APIs … programmer / user
API in Haskell / Erlang to support userprogrammed refactorings:
• declarative, straightforward and complete
• but relatively low-level.
Higher-level combining forms?
• OK for transformations, but need a separate
condition language?
WRT 2007
Verification and validation
Possible to write formal proofs of correctness:
• check conditions and transformations
• different levels of abstraction
• possibly-name binding substitution for renaming etc.
• more abstract formulation for e.g. data type changes.
Use of QuickCheck to verify refactorings in both
Haskell and Erlang.
WRT 2007
Future work
Concurrency.
Refactoring within a design library: OTP.
Side-effects.
Working with Erlang Training and Consulting.
Data-type refactorings in Haskell.
Integration with other IDEs / compilers.
Test and property refactoring.
WRT 2007
Conclusion
WRT 2007