The Haskell Refactorer, HaRe, and its API Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent www.cs.kent.ac.uk/projects/refactor-fp/

Slides:



Advertisements
Similar presentations
Sml2java a source to source translator Justin Koser, Haakon Larsen, Jeffrey Vaughan PLI 2003 DP-COOL.
Advertisements

HaRe The Haskell Refactorer Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent
Tool Support for Refactoring Functional Programs Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent
Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent Refactoring Functional Programs.
Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent Refactoring Functional Programs.
Progress on ‘HaRe: The Haskell Refactorer’ Huiqing Li, Claus Reinke, Simon Thompson Computing Laboratory, University of Kent Refactoring is the process.
Programming Languages
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Refactoring Functional Programs Claus Reinke Simon Thompson TCS Seminar, 1 October 2001.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Chapter 7 User-Defined Methods. Chapter Objectives  Understand how methods are used in Java programming  Learn about standard (predefined) methods and.
9/27/2006Prof. Hilfinger, Lecture 141 Syntax-Directed Translation Lecture 14 (adapted from slides by R. Bodik)
Denotational Semantics Syntax-directed approach, generalization of attribute grammars: –Define context-free abstract syntax –Specify syntactic categories.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
The Formalisation of Haskell Refactorings Huiqing Li Simon Thompson Computing Lab, University of Kent
Cse321, Programming Languages and Compilers 1 6/19/2015 Lecture #18, March 14, 2007 Syntax directed translations, Meanings of programs, Rules for writing.
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.
Refactoring Haskell Programs Huiqing Li Computing Lab, University of Kent
WRT 2007 Refactoring Functional Programs Huiqing Li Simon Thompson Computing Lab Chris Brown Claus Reinke University of Kent.
Abstract Data Types and Encapsulation Concepts
Refactoring Functional Programs Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent.
CSC 8310 Programming Languages Meeting 2 September 2/3, 2014.
CSE 331 Software Design & Implementation Hal Perkins Winter 2013 Design Patterns Part 3 (Slides by Mike Ernst and David Notkin) 1.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
DIY Refactorings in Wrangler Huiqing Li Simon Thompson School of Computing University of Kent.
Data Abstraction UW CSE 140 Winter What is a program? – A sequence of instructions to achieve some particular purpose What is a library? – A collection.
Haskell. 2 GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
Reviewing Recent ICSE Proceedings For:.  Defining and Continuous Checking of Structural Program Dependencies  Automatic Inference of Structural Changes.
Supported by ELTE IKKK, Ericsson Hungary, in cooperation with University of Kent Erlang refactoring with relational database Anikó Víg and Tamás Nagy Supervisors:
Supported by ELTE IKKK, Ericsson Hungary, in cooperation with University of Kent Erlang refactoring with relational database Anikó Víg and Tamás Nagy Supervisors:
Refactoring Erlang Programs Huiqing Li Simon Thompson University of Kent Zoltán Horváth Eötvös Loránd Univ.
1 JTransformer Framework Tobias Windeln Institut für Informatik III Rheinische Friedrich-Wilhelms-Universität Bonn.
Chapter 3 Collections. Objectives  Define the concepts and terminology related to collections  Explore the basic structures of the Java Collections.
Scalable Clone Detection and Elimination for Erlang Programs Huiqing Li, Simon Thompson University of Kent Canterbury, UK.
GROUPING OBJECTS CITS1001. Lecture outline The ArrayList collection Process all items: the for-each loop 2.
(1) ICS 313: Programming Language Theory Chapter 11: Abstract Data Types (Data Abstraction)
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
Refactoring. 2 Process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal.
72 4/11/98 CSE 143 Abstract Data Types [Sections , ]
CMSC 330: Organization of Programming Languages Operational Semantics.
Haskell. GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
Data Abstraction UW CSE 160 Spring What is a program? – A sequence of instructions to achieve some particular purpose What is a library? – A collection.
Defining Classes Modules and ADTs CSCE 314 Spring 2016.
1 Objective Caml (Ocaml) Aaron Bloomfield CS 415 Fall 2005.
XuanTung Hoang 1 Something to discuss Feedbacks on Midterm Exam Final exam and term project  Final exam requires solid knowledge/skills in Java  Be more.
Prof. I. J. Chung Data Structure #1 Professor I. J. Chung.
6-Jul-16 Haskell II Functions and patterns. Data Types Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr isSpace isUpper … Bool.
Lecture 9 Symbol Table and Attributed Grammars
Chapter 0: Introduction
Principles of programming languages 12: Functional programming
Module Road Map Refactoring Why Refactoring? Examples
ML: a quasi-functional language with strong typing
Introduction to Parsing (adapted from CS 164 at Berkeley)
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2013.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Zach Tatlock Winter 2018.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2017.
Stack ADT & Modularity 2 implementations of the Stack abstract data type: Array Linked List Program design: modularity, abstraction and information hiding.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2018.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Autumn 2017.
Combining Compile-Time and Run-Time Components
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2016.
Java IDE Dwight Deugo Nesa Matic Portions of the notes for this lecture include excerpts from.
Functions and patterns
CSCE 314: Programming Languages Dr. Dylan Shell
Corresponds with Chapter 5
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Spring 2019.
Presentation transcript:

The Haskell Refactorer, HaRe, and its API Huiqing Li Claus Reinke Simon Thompson Computing Lab, University of Kent

29/06/2015LDTA Outline  Refactoring  HaRe: The Haskell Refactorer  HaRe Demo  The HaRe API  API Demo  Conclusion and Future Work

29/06/2015LDTA Refactoring  What? Changing the structure of existing code without changing its meaning. Source-to-source Functionality-preserving Diffuse and bureaucratic Bi-directional  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.

29/06/2015LDTA 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.

29/06/2015LDTA Refactorings Implemented in HaRe  Structural Refactorings Generalise a definition e.g. module Test1 where g x = x : (g (x + 1)) g m x = x : ((g m) (x + m)) module Test2 where  module Test2 where import Test1 h y = g y h y = g 1 y

29/06/2015LDTA 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

29/06/2015LDTA Refactorings Implemented in HaRe  Module Refactorings Move a definition from one module to another module e.g. module Test1(g) where module Test1 where g x = x : (g (x + 1)) module Test2 where  module Test2 where import Test1 h y = g y g x = x : ( g ( x + 1)) h y = g y

29/06/2015LDTA 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

29/06/2015LDTA 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) pattern  Create ADT interface.

29/06/2015LDTA Demonstration of HaRe, hosted in Emacs HaRe Demo

29/06/2015LDTA module Tree where data Tree a = Leaf a | Node a (Tree a) (Tree a) flatten :: Tree a -> [a] flatten (Leaf x ) = [x] flatten (Node x l r ) = x : (flatten l ++ flatten r) From concrete data type to ADT

29/06/2015LDTA module Tree where data Tree a = Leaf {leaf1 :: a} | Node {node1 :: a, node2 :: Tree a, node3 :: Tree a} flatten :: Tree a -> [a] flatten (Leaf x ) = [x] flatten (Node x l r ) = x : (flatten l ++ flatten r) From concrete data type to ADT

29/06/2015LDTA module Tree where data Tree a = Leaf {leaf1 :: a} | Node {node1 :: a, node2 :: Tree a, node3 :: Tree a} isLeaf :: (Tree a) -> Bool isLeaf (Leaf _) = True isLeaf _ = False isNode :: (Tree a) -> Bool isNode (Node _ _ _) = True isNode _ = False flatten :: Tree a -> [a] flatten (Leaf x ) = [x] flatten (Node x l r ) = x : (flatten l ++ flatten r) From concrete data type to ADT

29/06/2015LDTA module Tree where data Tree a = Leaf {leaf1 :: a} | Node {node1 :: a, node2 :: Tree a, node3 :: Tree a} mkLeaf :: a -> Tree a mkLeaf = Leaf mkNode :: a -> (Tree a) -> (Tree a) -> Tree a mkNode = Node isLeaf :: (Tree a) -> Bool isLeaf (Leaf _) = True isLeaf _ = False isNode :: (Tree a) -> Bool isNode (Node _ _ _) = True isNode _ = False flatten :: Tree a -> [a] flatten (Leaf x ) = [x] flatten (Node x l r ) = x : (flatten l ++ flatten r) From concrete data type to ADT

29/06/2015LDTA module Tree where data Tree a = Leaf {leaf1 :: a} | Node {node1 :: a, node2 :: Tree a, node3 :: Tree a} mkLeaf :: a -> Tree a mkLeaf = Leaf mkNode :: a -> (Tree a) -> (Tree a) -> Tree a mkNode = Node isLeaf :: (Tree a) -> Bool isLeaf (Leaf _) = True isLeaf _ = False isNode :: (Tree a) -> Bool isNode (Node _ _ _) = True isNode _ = False flatten :: Tree a -> [a] flatten p |isLeaf p = [(leaf1 p)] flatten p |isNode p = (node1 p) : (flatten (node2 p) ++ flatten (node3 p)) From concrete data type to ADT

29/06/2015LDTA module Tree (Tree,flatten,isLeaf,isNode,leaf1,mkLeaf,mkNode,node1,node2,node3) where data Tree a = Leaf {leaf1 :: a} | Node {node1 :: a, node2 :: Tree a, node3 :: Tree a} mkLeaf :: a -> Tree a mkLeaf = Leaf mkNode :: a -> (Tree a) -> (Tree a) -> Tree a mkNode = Node isLeaf :: (Tree a) -> Bool isLeaf (Leaf _) = True isLeaf _ = False isNode :: (Tree a) -> Bool isNode (Node _ _ _) = True isNode _ = False flatten :: Tree a -> [a] flatten p |isLeaf p = [(leaf1 p)] flatten p |isNode p = (node1 p) : (flatten (node2 p) ++ flatten (node3 p)) From concrete data type to ADT

29/06/2015LDTA Test1.hs module Test1(g) where -- a generator g x = x: (g (x +1)) -- Test2.hs module Test2 where import Test1 h y = g y Generalise a definition

29/06/2015LDTA Test1.hs module Test1(g) where -- a generator g m x = x: ((g m) (x +m)) -- Test2.hs module Test2 where import Test1 h y = g 1 y Generalise a definition

29/06/2015LDTA Test1.hs module Test1() where -- Test2.hs module Test2 where import Test1 -- a generator g m x = x: ((g m) (x +m)) h y = g 1 y Move a definition to another module

29/06/2015LDTA Test1.hs module Test1() where -- Test2.hs module Test2 where -- a generator g m x = x: ((g m) (x +m)) h y = g 1 y Clean imports

29/06/2015LDTA The HaRe API  A collection of functions for program analysis and transformation extracted from the HaRe.  Hidden layout and comment preservation in program transformation functions.  Programatica’s abstract syntax for Haskell 98 + Strafunski’s library for AST traversals + HaRe’s API make implementing primitive refactorings or general program transformations much easier.

29/06/2015LDTA The HaRe API  Program analysis API Variable analysis Property checking Module interface (import and exports) analysis Module and files  Program transformation API Add/remove/update/swap program entities (e.g. declarations, expressions, parameters, identifiers, etc.)  Others Parsing/writing Name generators, from textual to AST syntax phrase, …

29/06/2015LDTA API Demo  Example refactoring: Swap the first two arguments of a function, say foo. This affects: The formal parameters of foo. The arguments at the use-sites of foo throughout the program (could be a multi-module program). The type signature.

29/06/2015LDTA API Demo -- swap the first two arguments of a function swapArgs fileName row col = do (inscps, exps, mod, ts)<-parseSourceFile fileName -- from text to program let pnt =locToPNT fileName row col mod if isFunPNT pnt mod then -- deal with the current module do r<-applyRefac (doSwap pnt) (Just (mod, ts)) fileName if isExported pnt exps then -- deal with the client modules. do rs <- applyRefacToClientMods (doSwap pnt) fileName writeRefactoredFiles False (r:rs) else writeRefactoredFiles False [r] else error "\nInvalid cursor position!" -- more code to follow

29/06/2015LDTA API Demo --- Inside a module doSwap pnt = applyTP (full_buTP (idTP `adhocTP` inMatch `adhocTP` inExp `adhocTP` inDecl)) where inMatch ((HsMatch loc fun pats rhs ds)::HsMatchP) | fun == pnt = case pats of (p1:p2:ps) -> do pats'<-swap p1 p2 pats return (HsMatch loc fun pats' rhs ds) _ -> error "Insufficient arguments to swap." inMatch m = return m inExp (HsApp (Exp (HsApp e e1)) e2))::HsExpP) | expToPNT e == pnt = swap e1 e2 exp inExp e = return e

29/06/2015LDTA API Demo inDecl (HsTypeSig loc is c tp))::HsDeclP) |isTypeSigOf pnt decl = if length is ==1 then do let ts = tyFunToList tp swap (ts!!0) (ts!!1) ts -- assume no type synonym is used. else error "This type signature defines the type of more than one identifiers." inDecl d = return d tyFunToList (Typ (HsTyFun t1 t2)) = t1:(tyFunToList t2) tyFunToList t = [t]

29/06/2015LDTA Demonstration of the swap refactoring API Demo

29/06/2015LDTA Test3.hs module Test3 where sumLength:: String -> [Int]-> Int sumLength x y = length x + length y -- Test4.hs module Test4 where import Test3 test3 = sumLength "abc" [1,2,3] Swap arguments

29/06/2015LDTA Test3.hs module Test3 where sumLength:: [Int] -> String-> Int sumLength y x = length x + length y -- Test4.hs module Test4 where import Test3 test3 = sumLength [1,2,3] "abc“ Swap arguments

29/06/2015LDTA Conclusion and Future Work  The API is relatively low-level, but essential for implementing program transformations.  Program appearance preservation hidden in the API.  Together with Strafunski, the API allows to write concise source-to-source program transformations and their side- conditions.  A framework for exploring your program transformation ideas. In the future:  Complete and improve the current API.  Look for some higher-level API.

29/06/2015LDTA