WRT 2007 Refactoring Functional Programs Huiqing Li Simon Thompson Computing Lab Chris Brown Claus...

Post on 21-Dec-2015

215 views 2 download

transcript

WRT 2007

RefactoringFunctional Programs

Huiqing LiSimon Thompson

Computing Lab

Chris BrownClaus Reinke

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 supportBureaucratic 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

ErlangStrong, static types.Lazy evaluation.

Layout sensitive.Concurrency library.

Haskell 98 standard.GHC, NHC, Hugs, …Academic, O/S apps.

Weak, dynamic types.Strict evaluation.Hot code swap, apply etc.

Concurrency built-in.OTP, design patterns.

Single system.Industrial applications.

WRT 2007

Generalisation

-module (test).-export([f/1]). add_one ([H|T]) -> [H+1 | add_one(T)];

add_one ([]) -> [].

f(X) -> add_one(X).

-module (test).-export([f/1]). add_one (N, [H|T]) -> [H+N | add_one(N,T)];

add_one (N,[]) -> [].

f(X) -> add_one(1, X).

-module (test).-export([f/1]). add_int (N, [H|T]) -> [H+N | add_int(N,T)];

add_int (N,[]) -> [].

f(X) -> add_int(1, X).

Generalisation and renaming

WRT 2007

Generalisation

-export([printList/1]).

printList([H|T]) -> io:format("~p\n",[H]), printList(T);printList([]) -> true.

printList([1,2,3])

-export([printList/2]).

printList(F,[H|T]) -> F(H), printList(F, T);printList(F,[]) -> true.

printList( fun(H) -> io:format("~p\n", [H]) end, [1,2,3]).

WRT 2007

Asynchronous to synchronous

pid! {self(),msg}

{Parent,msg} -> body

pid! {self(),msg}, receive {pid, ok}-> ok

{Parent,msg} -> Parent! {self(),ok}, body

WRT 2007

The tools

WRT 2007

HaRe: the Haskell RefactorerStructural, data type, and module-level.

In Haskell: embedded in gvim and emacs.

Uses the Programatica framework …

… + Strafunski program

transformation library.

WRT 2007

Wrangler: refactoring ErlangStructural, 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 IDEsBack 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 toolsTest 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

module Main where

sumSquares x y = sq x + sq y where sq :: Int->Int sq x = x ^ pow pow = 2 :: Int

main = sumSquares 10 20

module Main where

sumSquares x y = sq pow x + sq pow y where pow = 2 :: Int

sq :: Int->Int->Int sq pow x = x ^ pow

main = sumSquares 10 20

-- This is an example

module Main where

sumSquares x y = sq pow x + sq pow y where pow = 2 :: Int

sq :: Int->Int->Int sq pow x = x ^ pow

main = sumSquares 10 20

WRT 2007

Experience

WRT 2007

Refactoring = Transformation + Condition

Transformation

Ensure change at all those points needed.

Ensure change at only those points needed.

Condition

Is the refactoring applicable?

Will it preserve the semantics of the module? the program?

WRT 2007

Condition > TransformationRenaming 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) -> … … .

-export([newFun/1]).

newFun(L) -> … … .

or ?

WRT 2007

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 / userAPI in Haskell / Erlang to support user-programmed 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 validationPossible 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