Nantes Université

cohen-j created page: expression_problem_chains_0_3 rédigé par Julien COHEN's avatar Julien COHEN
Go to: [[internet:view_switcher|Tool Homepage]] - [[internet:view_switcher:download|Downloads]] - [[internet:view_switcher:user_guide|User Guide]] - [[internet:view_switcher:examples|Examples]]
(This page is based on version 0.3, dowload the code from the [[internet:view_switcher:examples | example page]])
===== Function-oriented view =====
|<code haskell>
module Expr where
data Expr =
Const Int
| Add (Expr,Expr)
e1 = Add (Add (Const 1,Const 2),Const 3)
e2 = Add (Add (Const 0,Const 1),Const 2)
</code>|<code haskell>
module Client where
import Expr
import ToStringMod
import EvalMod
r1 = print (toString e1)
r2 = print (show (eval e1))
r3 = print (toString e2)
r4 = print (show (eval e2))
</code>|
|<code haskell>
module EvalMod where
import Expr
eval (Const i) = i
eval (Add (e1,e2)) = eval e1 + eval e2
</code>|<code haskell>
module ToStringMod where
import Expr
toString (Const i) = show i
toString (Add (e1,e2)) = toString e1 ++ "+" ++ toString e2
</code>|
===== Data-oriented view =====
|<code haskell>
module Expr where
data Expr =
Const Int
| Add (Expr,Expr)
fold f0 f1 (Const i) = f0 i
fold f0 f1 (Add (e1,e2)) = f1 (((fold f0) f1) e1) (((fold f0) f1) e2)
e1 = Add (Add (Const 1,Const 2),Const 3)
e2 = Add (Add (Const 0,Const 1),Const 2)
</code>|<code haskell>
module Client where
import Expr
import ConstMod (toString,eval)
import AddMod (toString,eval)
r1 = print (Client.toString e1)
toString x = fold ConstMod.toString AddMod.toString x
r2 = print (show (Client.eval e1))
eval x = fold ConstMod.eval AddMod.eval x
r3 = print (Client.toString e2)
r4 = print (show (Client.eval e2))
</code>|
|<code haskell>
module ConstMod (eval,toString) where
eval i = i
toString i = show i
</code>|<code haskell>
module AddMod (eval,toString) where
eval x0 x1 = (x0) + (x1)
toString x0 x1
= (x0) ++ ("+" ++ (x1))
</code>|
===== The Transformation Scripts =====
Function-centered architecture -> Data-centered architecture
<code lisp>
(defvar f1 "eval" )
(defvar f2 "toString" )
(defvar f1mod "EvalMod" )
(defvar f2mod "ToStringMod" )
(defvar f1reducer "fold" )
(defvar f2reducer "fold2" )
(defvar clientmod "Client" )
(defvar f1prefix (concat f1 "_") )
(defvar f2prefix (concat f2 "_") )
; 1) Introduce definitions for equations ------------------------------------------------------
(haskell-refac-newDefAllEqBodiesIn f1 f1mod)
(haskell-refac-newDefAllEqBodiesIn f2 f2mod)
; 2) abstract pattern variables or rec calls on pattern variables -----------------------------
(haskell-refac-generaliseAllRecAppToPatternVariablesInAllLocalDefsIn f1 f1prefix f1mod)
(haskell-refac-generaliseAllPatternVariablesInAllLocalDefsIn f1 f1prefix f1mod)
(haskell-refac-generaliseAllRecAppToPatternVariablesInAllLocalDefsIn f2 f2prefix f2mod)
(haskell-refac-generaliseAllPatternVariablesInAllLocalDefsIn f2 f2prefix f2mod)
; 3) lift the business functions to the top level ---------------------------------------------
(haskell-refac-liftAllLocalDefsToTopLevelIn f1 f1prefix f1mod)
(haskell-refac-liftAllLocalDefsToTopLevelIn f2 f2prefix f2mod)
; 4) abstract the business functions in the functions of interest -----------------------------
(haskell-refac-generaliseAllIdentsTopLevel f1 f1prefix "f" f1mod)
(haskell-refac-forgetTopLevelPrefixed (concat f1 "_gen") f1mod)
(haskell-refac-generaliseAllIdentsTopLevel f2 f2prefix "f" f2mod)
(haskell-refac-forgetTopLevelPrefixed (concat f2 "_gen") f2mod)
; 5) rename the functions of interest (they have become traversal iterators) ------------------
(haskell-refac-renameTopLevelIdent f1 f1mod f1reducer)
(haskell-refac-renameTopLevelIdent f2 f2mod f2reducer)
; 6) reconstruct the functions of interest as calls to the traversal functions ----------------
(haskell-refac-newDefIdentApp f1reducer f1 clientmod)
(haskell-refac-newDefIdentApp f2reducer f2 clientmod)
(haskell-refac-generaliseIdentIn "r1" clientmod "e1" "x")
(haskell-refac-generaliseIdentIn "r2" clientmod "e1" "x")
(haskell-refac-liftDefToTopLevel f1 clientmod)
(haskell-refac-liftDefToTopLevel f2 clientmod)
; 7) make calls to function of interest appear and move fold operators-------------------------
(haskell-refac-foldToplevelDefinition f1 clientmod)
(haskell-refac-foldToplevelDefinition f2 clientmod)
(haskell-refac-moveDefBetweenModules f1reducer f1mod "Expr")
(haskell-refac-moveDefBetweenModules f2reducer f2mod "Expr")
(haskell-refac-replaceIdentIn f2reducer f2 clientmod f1reducer)
(haskell-refac-removeTopLevelDef f2reducer "Expr")
; 8) move business functions to the data-centered modules and rename them ---------------------
(haskell-refac-moveAllDefsOnSuffix f2prefix f2mod)
(haskell-refac-moveAllDefsOnSuffix f1prefix f1mod)
(haskell-refac-renameAllIdentsIn f1 f1prefix clientmod)
(haskell-refac-renameAllIdentsIn f2 f2prefix clientmod)
; 9) clean useless import ---------------------------------------------------------------------
(haskell-refac-cleanImportsMod clientmod)
</code>
Data-centered architecture -> Function-centered architecture
<code lisp>
(defvar f1 "eval" )
(defvar f2 "toString" )
(defvar f1mod "EvalMod" )
(defvar f2mod "ToStringMod" )
(defvar f1reducer "fold" )
(defvar clientmod "Client" )
(defvar f1prefix (concat f1 "_") )
(defvar f2prefix (concat f2 "_") )
;; use specific names for business functions
(haskell-refac-renameAllIdentsIn2 f1 f1 f1prefix clientmod)
(haskell-refac-renameAllIdentsIn2 f2 f2 f2prefix clientmod)
;; prepare the generative fold operations :
;; the equations for functions of interest are saved into comments
(haskell-refac-duplicateTopLevelDefIntoComment f1 clientmod)
(haskell-refac-duplicateTopLevelDefIntoComment f2 clientmod)
;; unfold the use of the traversal function
;; in the definition of functions of interest
(haskell-refac-unfoldIn f1reducer f1 clientmod)
(haskell-refac-unfoldIn f1reducer f2 clientmod)
;; fold the use of the traversal function in the body of the
;; functions of interest in order to find a recursive definition of them
;; (without a call to the traversal function)
(haskell-refac-generativeFoldAllIdentAppIn f1 f1reducer clientmod)
(haskell-refac-generativeFoldAllIdentAppIn f2 f1reducer clientmod)
;; comments introduced for the generative fold can be deleted
(haskell-refac-rmCommentBeforeTopLevelDef f1 clientmod)
(haskell-refac-rmCommentBeforeTopLevelDef f2 clientmod)
;; generative fold has produced case expressions that have to be simplified
(haskell-refac-repeatSimplifyCasePatternIn f1 clientmod)
(haskell-refac-repeatSimplifyCasePatternIn f2 clientmod)
;; the case expressions introduced by the generative fold
;; have to be transformed into equations
(haskell-refac-caseToEqIn f1 clientmod)
(haskell-refac-caseToEqIn f2 clientmod)
;; replace calls to the business functions by their bodies (unfold)
(haskell-refac-forgetAllTopLevelIdentWithOccurenceIn f1 f1prefix clientmod)
(haskell-refac-forgetAllTopLevelIdentWithOccurenceIn f2 f2prefix clientmod)
;; the traversal functions can be deleted
(haskell-refac-removeTopLevelDef f1reducer "Expr")
(haskell-refac-addImplicitImportUnsafe clientmod f2mod);; the order is important for the order of the imports directives
(haskell-refac-addImplicitImportUnsafe clientmod f1mod)
(haskell-refac-moveDefBetweenModules f2 clientmod f2mod)
(haskell-refac-moveDefBetweenModules f1 clientmod f1mod)
;; business functions are not used an can be deleted
;; (imports, exports and declarations)
(haskell-refac-cleanImportsMod clientmod)
</code>
\ No newline at end of file