Top Banner
The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent www.cs.kent.ac.uk/projects/refactor-fp/
32

The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

Dec 20, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

The Formalisation of Haskell Refactorings

Huiqing LiSimon Thompson

Computing Lab, University of Kent www.cs.kent.ac.uk/projects/refactor-fp/

Page 2: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 2

Outline

Refactoring HaRe: The Haskell Refactorer Formalisation of Haskell Refactorings Formalisation of Generalise a Definition Conclusion and Future Work

Page 3: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 3

Refactoring What? Changing the structure of existing code

without changing its meaning. Where and why? Development, maintenance, …

To make the code easier to understand and modify

To improve code reuse, quality and productivity

Essential part of the programming process.

Page 4: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 4

HaRe – The Haskell Refactorer A tool for refactoring Haskell 98 programs. Full Haskell 98 coverage. Driving concerns: usability and extensibility. Implemented in Haskell, using Programatica’s

frontends and Strafunski’s generic traversals. Integrated with the two program editors:

(X)Emacs and Vim. Preserves both comments and layout style of

the source.

Page 5: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 5

Refactorings Implemented in HaRe

Structural Refactorings

Module Refactorings

Data-Oriented Refactorings

Page 6: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 6

Refactorings Implemented in HaRe Structural Refactorings

Generalise a definition

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

module Main (main) where

f z y = y : f z (y + z)

main y = print $ f 1 10

Page 7: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 7

Refactorings Implemented in HaRe Structural Refactorings (cont.)

Rename an identifier Promote/demote a definition to widen/narrow its scope Delete an unused function Duplicate a definition Unfold a definition Introduce a definition to name an identified expression Add an argument to a function Remove an unused argument from a function

Page 8: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 8

Refactorings Implemented in HaRe Module Refactorings

Move a definition from one module to another module

module Test (f) where

f y = y : f (y + 1) module Main where import Test

main = print $ f 10

module Test ( ) where

module Main whereimport Test

f y = y : f (y + 1) main = print $ f 10

Page 9: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 9

Refactorings Implemented in HaRe Module Refactorings (cont.)

Clean the imports Make the used entities explicitly imported Add an item to the export list Remove an item from the export list

Page 10: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 10

Refactorings Implemented in HaRe Data-oriented Refactorings

From concrete to abstract data-type (ADT), which is a composite refactoring built from a sequence of primitive refactorings. Add field labels Add discriminators Add constructors Remove (nested) patterns Create ADT interface

Page 11: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 11

Formalisation of Refactorings Advantages:

Clarify the definition of refactorings in terms of side-conditions and transformations.

Improve our confidence in the behaviour-preservation of refactorings.

Guide the implementation of refactorings. Reduce the need for testing.

Challenges: Haskell is a non-trivial language. Haskell does not have an officially defined semantics.

Page 12: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 12

Formalisation of Refactorings

Our Strategy: Start from a simple language (letrec). Extend the language gradually to formalise

more complex refactorings.

Page 13: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 13

Formalisation of Refactorings

The specification of a refactoring contains four parts: The representation of the program before the

refactorings, say P1

The side-conditions for the refactoring. The representation of the program after the

refactorings, say P2.

A proof showing that P1 and P2 have the same

functionality under the side-conditions.

Page 14: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 14

Formalisation of Refactorings

The -calculus with letrec (letrec) Syntax of letrec terms.

E ::= x | x.E | E1 E2 | letrec D in E D ::= | xi=Ei | D, D

Use the call-by-name semantics developed by Zena M. Ariola and Stefan Blom in the paper Lambda Calculi plus letrec.

Page 15: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 15

Formalisation of Generalisation Recall the example

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

module Main (main) where

f z y = y : f z (y + z)

main = print $ f 1 10

Page 16: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 16

Formalisation of Generalisation Formal definition of Generalisation using letrec

Given the expression:

Assume E is a sub-expression of Ei, and Ei= C[E].

letrec x1=E1, ..., xi =Ei , ..., xn =En in E0

Page 17: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 17

Formalisation of Generalisation

Formal definition of Generalisation using letrec

The condition for generalising the definition xi=Ei on E is:

xiFV(E ) Æ 8x, e: (x 2FV(E ) Æ e 2 sub(Ei,C) ) x 2FV(e))

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

Page 18: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 18

Formalisation of Generalisation

Formal definition of Generalisation using letrec

The condition for generalising the definition xi=Ei on E is:

xiFV(E ) Æ 8x, e: (x 2FV(E ) Æ e 2 sub(Ei,C) ) x 2FV(e))

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

Page 19: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 19

Formalisation of Generalisation

Formal definition of Generalisation using letrec

The condition for generalising the definition xi=Ei on E is:

xiFV(E ) Æ 8x, e: (x 2FV(E ) Æ e 2 sub(Ei,C) ) x 2FV(e))

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

Page 20: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 20

Formalisation of Generalisation

Formal definition of Generalisation using letrec

The condition for generalising the definition xi=Ei on E is:

xiFV(E ) Æ 8x, e: (x 2FV(E ) Æ e 2 sub(Ei,C) ) x 2FV(e))

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

Page 21: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 21

Formalisation of Generalisation

Formal definition of Generalisation using letrec

After generalisation, the original expression becomes:

letrec x1= E1 [xi := xiE],

..., xi = z.C[z][xi:=xi z],

..., xn = En [xi:= xi E]

in E0 [xi:= xi E],

where z is a fresh variable.

module Main (main) where

f z y = y : f z (y + z)

main = print $ f 1 10

module Main (main) where

f y = y : f (y + 1)

main = print $ f 10

Page 22: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 22

Formalisation of Generalisation Formal definition of Generalisation using letrec

Proof. Decompose the transformation into a number of sub steps, if each sub step is behaviour-preserving, then the transformation is behaviour-preserving.

Page 23: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 23

Formalisation of Generalisation

Step1: add definition x = z.C[z] , where x and z are

fresh variables, and C[E]=Ei.

module Main (main) where

f y = y : f (y +1)

x z y = y : f ( y + z)

main = print $ f 10

letrec x1=E1, ..., xi =Ei, x = z.C[z], ..., xn =En in E0

Step 2: Replace Ei with x E. (Note: Ei = x E)

Page 24: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 24

Formalisation of Generalisation

Step 2: Replace Ei with x E. (Note: Ei = x E)

module Main (main) where

f y = x 1 y

x z y = y : f ( y + z)

main = print $ f 10

letrec x1=E1, ..., xi = x E, x = z.C[z], ..., xn =En in E0

Step 3: Unfolding xi in the right-hand side of x.

Page 25: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 25

Formalisation of Generalisation

Step 3: Unfolding xi in the right-hand side of x.

module Main (main) where

f y = x 1 y

x z y = y : x 1 ( y + z)

main = print $ f 10

letrec x1=E1, ..., xi = x E, x = z.C[z] [x_i:= x E], ..., xn =En in E0

Step 4: In the definition of x, replace E with z, and prove this does not change the semantics of x E.

Page 26: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 26

Formalisation of Generalisation

Step 4: In the definition of x, replace E with z. and prove this does not change the semantics of x E.

module Main (main) where

f y = x 1 y

x z y = y : x z ( y + z)

main = print $ f 10

letrec x1=E1, ..., xi = x E, x = z.C[z] [x_i:= x z], ..., xn =En in E0

Step 5: Unfolding the occurrences of xi.

Page 27: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 27

Formalisation of Generalisation

Step 5: Unfolding the occurrences of xi.

module Main (main) where

f y = x 1 y

x z y = y : x z ( y + z)

main = print $ x 1 10

letrec x1=E1 [xi:= x E] , ..., xi = x E, x = z.C[z] [xi:= x z], ..., xn =En [xi:= x E] in E0 [xi:= x E]

Step 6: Remove the definition of xi.

Page 28: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 28

Formalisation of Generalisation

Step 6: Remove the definition of xi.

module Main (main) where

x z y = y : x z ( y + z)

main = print $ x 1 10

letrec x1=E1 [xi:= x E] , ..., x = z.C[z] [xi:= x z], ..., xn =En [xi:= x E] in E0 [xi:= x E]

Step 7: Rename x to xi and simplify the substitution.

Page 29: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 29

Formalisation of Generalisation

module Main (main) where

f z y = y : f z ( y + z)

main = print $ f 1 10

letrec x1=E1 [xi:= x E] [x:=xi] , ..., x = z.C[z] [xi:= x z] [x:=xi], ..., xn =En [xi:= x E] [x:=xi] in E0 [xi:= x E] [x:=xi]

letrec x1= E1 [xi := xiE], ..., xi = z.C[z][xi:=xi z], ..., xn = En [xi:= xi E] in E0 [xi:= xi E]

Page 30: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 30

Formalisation of Refactorings

letrec has been extended to model the Haskell module system (M).

The move a definition from one module to another refactoring has also been formalised

using M.

Page 31: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 31

Conclusion and Future Work

Formalisation helps to clarify the side-conditions and transformation rules.

Improves our confidence about the behaviour-preservation of refactorings.

Future: Extend the calculus to formalise more complex

refactorings. Formalise the composition of refactorings.

Page 32: The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent

04/18/23 TFP 2005 32

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

Thank You