Commit d5db4843 authored by Julien COHEN's avatar Julien COHEN
Browse files

opie du code et des exemples de la version 0.3 d'avril 2011, qui étaient...

opie du code et des exemples de la version 0.3 d'avril 2011, qui étaient publiés sur le Wiki d'Ascola.
parents
Julien Cohen 2011.
This example illustrates a scenario of evolution based on the Expression Problem [Wadler 1998]. See the report [Cohen/Douence 2011] for a description of the implemented evolutions.
STATE_0:
The files of the program in its initial state (function oriented).
transfo_1_fun_data.el :
The Haskell View Switcher script to transform the initial program in a data oriented view. (Dont' forget to create the HaRe project before running the script, and to add the empty modules AddMod and ConstMod to the project. See the instructions on the web page of Haskell View Switcher.)
STATE_1:
The program after the transformation, data oriented.
STATE_2:
The first evolution is implemented: we add a case Mult in the data-type Expr. A module MultMod is created on the model of AddMod (business code). The code for fold, eval and toString are updated to take the new business functions into account (administrative change). Don't forget to add MultMod into the project.
transfo_2_data_fun.el:
The script to pass from the data oriented view from the function oriented view. Here, that script does not depend on the type Expr (the corresponding business functions and modules are extracted from the program).
STATE_3:
The program after the transformation, function oriented.
STATE_4: The second evolution is implemented: we add a function 'pos' to check that all the integers are positive. We add a module PosMod (and add it into the project). The function follow the model of eval for the pattern matching.
transfo_3_fun_data.el:
The script to pass from the function oriented view from the data oriented view. To take the new function into account, a part of the script has been duplicated by copy/paste and updated with 'pos' and 'PosMod'. Of course, for people mastering LISP, you would prefer to parametrize the script by the name of the function and the corresponding module instead of duplicating code.
STATE_5:
The program after the transformation, data oriented.
STATE 6:
The third evolution is implemented: we add a constructor Div for division. As for the first evolution, all the business code is in a single module DivMod.
transfo_4_data_fun.el:
The script transfo_2_data_fun.el is adapted to take the function pos into account. No change is needed to take the contructo Div into account.
STATE_7:
The program after the transformation, function oriented.
STATE_8:
The fourth evolution is implemented: we add a function 'check' to check divisions by 0. The code is in the module CheckMod can follow the model of any other function. Note that the function check contains a local declaration and that the recursion scheme is not the same as for the other functions.
STATE_9:
A maintenance task on a function has been performed: the toString function returns expressions in prefixed form instead of infix. As the program was in function oriented view, the maintenance is modular.
transfo_5_fun_data.el:
This script is adapted from transfo_3_fun_data.el to take the function 'check' into account. Note that two additional operations are necessary to handle the specificities of 'check'. Also, as the recursion scheme is not the same as for the other function, fold cannot be reused and a specific iterator will be extracted. Here the script bis not uniform with respect to functions anymore but the transformation remains possible.
STATE_10:
The program after the transformation, data oriented. The view is convenient for a change in the behavior of a data constructor.
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))
module EvalMod where
import Expr
eval (Const i) = i
eval (Add (e1,e2)) = eval e1 + eval e2
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)
\ No newline at end of file
module ToStringMod where
import Expr
toString (Const i) = show i
toString (Add (e1,e2)) = toString e1 ++ "+" ++ toString e2
module AddMod (eval,toString) where
eval x0 x1 = (x0) + (x1)
toString x0 x1
= (x0) ++ ("+" ++ (x1))
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))
module ConstMod (eval,toString) where
eval i = i
toString i = show i
module EvalMod where
import Expr
\ No newline at end of file
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)
\ No newline at end of file
module AddMod (eval,toString,pos,check) where
eval x0 x1 = ((x0) + (x1))
toString x0 x1
= "+" ++ ((x0) ++ (x1))
pos x0 x1 = ((x0) && (x1))
check x0 x1 = ((x0) && (x1))
module CheckMod where
import Expr
\ No newline at end of file
module Client where
import Expr
import ConstMod (check,pos,toString,eval)
import AddMod (check,pos,toString,eval)
import MultMod (check,pos,toString,eval)
import DivMod (check,pos,toString,eval)
r1 = print (if Client.pos e1 && Client.check e1 then Client.toString e1 else "invalid expression")
check x
=
Expr.checkskeleton ConstMod.check AddMod.check
MultMod.check
DivMod.check
x
pos x
= fold ConstMod.pos AddMod.pos MultMod.pos DivMod.pos x
toString x
=
fold ConstMod.toString AddMod.toString
MultMod.toString
DivMod.toString
x
r2 = print (show (Client.eval e1))
eval x
=
Expr.fold ConstMod.eval AddMod.eval MultMod.eval DivMod.eval
x
r3 = print (Client.toString e2)
r4 = print (show (Client.eval e2))
module ConstMod (eval,toString,pos,check) where
eval i = i
toString i = (show i)
pos i = (i >= 0)
check = True
module DivMod where
import Expr
eval x0 x1 = (div (x0) (x1))
toString x0 x1
= "/" ++ ((x0) ++ (x1))
pos x0 x1 = ((x0) && (x1))
check e2 x0 x1
= (x0) && ((x1) && (nonzero e2))
where
nonzero (Const 0) = False
nonzero _ = True
module Expr where
data Expr =
Const Int
| Add (Expr,Expr)
| Mult (Expr,Expr)
| Div (Expr,Expr)
checkskeleton f0 f1 f2 f3 ((Const i)) = f0
checkskeleton f0 f1 f2 f3 ((Add (e1, e2))) = f1 (((((checkskeleton f0) f1) f2) f3) e1) (((((checkskeleton f0) f1) f2) f3) e2)
checkskeleton f0 f1 f2 f3 ((Mult (e1, e2)))
= f2 (((((checkskeleton f0) f1) f2) f3) e1) (((((checkskeleton f0) f1) f2) f3) e2)
checkskeleton f0 f1 f2 f3 ((Div (e1, e2))) = f3 e2 (((((checkskeleton f0) f1) f2) f3) e1) (((((checkskeleton f0) f1) f2) f3) e2)
fold f0 f1 f2 f3 ((Const i)) = f0 i
fold f0 f1 f2 f3 ((Add (e1, e2)))
= f1 (((((fold f0) f1) f2) f3) e1) (((((fold f0) f1) f2) f3) e2)
fold f0 f1 f2 f3 ((Mult (e1, e2)))
= f2 (((((fold f0) f1) f2) f3) e1) (((((fold f0) f1) f2) f3) e2)
fold f0 f1 f2 f3 ((Div (e1, e2)))
= f3 (((((fold f0) f1) f2) f3) e1) (((((fold f0) f1) f2) f3) e2)
e1 = Add (Mult (Const 1,Const 2),Const 3)
e2 = Add (Div (Const 0,Const 1),Const 2)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment