+ All Categories
Home > Documents > Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

Date post: 31-Mar-2015
Category:
Upload: allan-coveny
View: 213 times
Download: 1 times
Share this document with a friend
Popular Tags:
47
Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke www.cs.kent.ac.uk/projects/ refactor-fp
Transcript
Page 1: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

Refactoring Functional Programs

Simon Thompson

with

Huiqing Li

Claus Reinke

www.cs.kent.ac.uk/projects/refactor-fp

Page 2: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 2

Session 1

Page 3: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 3

Refactoring

Refactoring means changing the design or structure of a program … without changing its behaviour.

RefactorModify

Page 4: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 4

Splitting a function in two

Page 5: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 5

Splitting a function in two

Page 6: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 6

Splitting a function in two

Page 7: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 7

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = foldr (++) [] [ y++"\n" | y <- ys ]

Page 8: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 8

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = foldr (++) [] [ y++"\n" | y <- ys ]

Page 9: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 9

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join [y ++ "\n" | y <- ys] where join = foldr (++) []

Page 10: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 10

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join [y ++ "\n" | y <- ys] where join = foldr (++) []

Page 11: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 11

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join addNL where join zs = foldr (++) [] zs addNL = [y ++ "\n" | y <- ys]

Page 12: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 12

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join addNL where join zs = foldr (++) [] zs addNL = [y ++ "\n" | y <- ys]

Page 13: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 13

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join (addNL ys) where join zs = foldr (++) [] zs addNL ys = [y ++ "\n" | y <- ys]

Page 14: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 14

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join (addNL ys) where join zs = foldr (++) [] zs addNL ys = [y ++ "\n" | y <- ys]

Page 15: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 15

Splitting a functionmodule Split where

f :: [String] -> [String] -> String

f ys = join (addNL ys) join zs = foldr (++) [] zs

addNL ys = [y ++ "\n" | y <- ys]

Page 16: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 16

Generalisation

ff 9 + 37

h x = … f 9 + 37 …

e = h 37 + 12

Page 17: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 17

Generalisation

f 9 + 37

h y x = … y …

e = h (f 9 + 37) 37 + 12

Page 18: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 18

Session 1

Potted history of refactoring.

Refactoring and design.

Example refactorings … what do we learn?

Demonstration of the HaRe tool for Haskell.

A practical exercise.

Page 19: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 19

A little bit of history …

Floyd, 1978 Turing Award Lecture: encourages reflective revision.

Griswold: Automated assistance for (LISP) program restructuring.

Opdyke: Refactoring OO Frameworks.

Fowler et al: Refactoring: Improving the Design of Existing Code.

Page 20: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 20

Refactoring in OO

Smalltalk refactoring browser … relies heavily on reflection.

Built into a number of IDEs: Eclipse, …

Refactor and test … major way of ensuring correctness of refactorings …

… others require heavyweight static analysis.

Link with design …

Page 21: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 21

Design

Structure of the program?• Modules, types, interfaces …

Artefact?• UML diagrams of various kinds …• … with accompanying constraints.• Model Driven Architecture

Design patterns?

The problem of consistency: design vs code.

Page 22: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 22

Designing functional programs

No evidence of an appetite for separate modelling languages …

No established terminology of patterns …

… it’s all in the code.

Page 23: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 23

Development

Development of functional programs

is spiral …

… from a working base, extend, refactor and elaborate.

Design emerges.

Page 24: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 24

Soft Ware

There’s no single correct design …

… different options for different situations.

Maintain flexibility as the system evolves.

Page 25: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 25

Modify and refactor

Page 26: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 26

Refactoring functional programs

Semantics: can articulate preconditions and verify transformations.

Absence of side effects makes big changes predictable and verifiable … unlike OO.

Language support: expressive type system; abstraction mechanisms: higher order functions, classes, …

Page 27: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 27

Rename f x y = …

Name may be too specific, if the function is a candidate for reuse.

findMaxVolume x y = …

Make the specific purpose of the function clearer.

Scope: just change occurrences of this f.

Modules: change f (and M.f) everywhere.

Page 28: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 28

Lift / demotef x y = … h … where h = …

Hide a function which is clearly subsidiary to f; clear up the namespace.

f x y = … (h y) … h y = …

Makes h accessible to the other functions in the module and beyond.

Free variables: which parameters of f are used in h?

Need h not to be defined at the top level, … ,

Type of h will generally change … DMR.

Page 29: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 29

Lessons from these examples

Ensuring correctness requires knowledge of:

Lexical structure of programs Abstract syntax Binding structure Type system Module system

Page 30: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 30

Lessons from these examples

Changes are not limited to a single point or even a single module: diffuse and bureaucratic …

Most refactorings bidirectional …

… unlike traditional program transformation.

Page 31: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 31

Visualising the effect

Estimating the effect of a refactoring.

Work by

Chris Ryder

Page 32: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 32

Program transformations

Operational semantics reduction to normal form

Program optimisation source-to-source transformations to get more efficient code

Program derivation calculating efficient code from obviously correct specifications

Refactoring transforming code structure

Related themes, with substantial overlap, and common theory, but with different intentions.

Page 33: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 33

Conditions: renaming f to g

“No change to the binding structure”

1. No two definitions of g at the same level.

2. No capture of g.

3. No capture by g.

Page 34: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 34

Capture of renamed identifier h x = … h … f … g … where g y = …

f x = …

h x = … h … g … g … where g y = …

g x = …

Page 35: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 35

Capture by renamed identifier h x = … h … f … g … where f y = … f … g …

g x = …

h x = … h … g … g … where g y = … g … g …

g x = …

Page 36: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 36

Refactoring by hand?

By hand = in a text editor

Tedious

Error-prone• Implementing the transformation …• … and the conditions.

Depends on compiler for type checking, …

… plus extensive testing.

Page 37: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 37

Machine support invaluable

Reliable

Low cost of do / undo, even for large refactorings.

Increased effectiveness … and creativity.

Page 38: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 38

Demonstration of HaRe, hosted in vim.

Page 39: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 39

The refactorings in HaRe

Rename

Delete

Lift / Demote

Introduce definition

Remove definition

Unfold

Generalise

Add/remove parameters

Move def between modules

Delete/add to exports

Clean imports

Make imports explicit

data type to ADT

Short-cut, warm fusion

All module aware

Page 40: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 40

Practical exercise

A practical exercise in reflective programming and design.

Work together in groups, preferably pairs.

Page 41: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 41

Two roles

The writer writes design or types the program.

The logger keeps a log of the process:• Rationale for design decisions.• Refactorings in the design or the coding• Purpose, effect, extent.

Regularly swap roles.

Better understand refactoring in practice.

Page 42: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 42

Context

ASCII log files plus program(s) … conclusions to go on the web.

Mail to [email protected]

To reach a consensus on which refactorings are most useful and commonly used.

• Document.• Implement.• Evaluate API.

Page 43: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 43

What?

Any project of your own choice, perhaps building on other courses at AFP04.

Alternatively, a minesweeper program.

Page 44: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 44

Minesweeper

Page 45: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 45

Minesweeper

Mines distributed in a grid: find and mark all the mines.

On revealing a square, lose if it’s occupied, if not see # adjacent.

If # is zero, clear connected region.

Can also unmark.

Page 46: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 46

Minesweeper extensions

Add deduction: play all the guaranteed moves …

… or probability: reveal the square which is least likely to explode.

Show the deductions: how large support set for each deduction?

Page 47: Refactoring Functional Programs Simon Thompson with Huiqing Li Claus Reinke .

AFP04 47

Minesweeper extensions

Add a GUI …

… or animation.

Allow backtracking?


Recommended