370 likes | 510 Views
Designing Aspects for Side-Effect Localization. Joint work with Kung Chen, Jia-Yin Lin , and Siau-Cheng Khoo National Chengchi University National University of Singapore. Shu-Chun Weng National Taiwan University. Outline. Introduction AspectFun Side-effecting aspects Transformations
E N D
Designing Aspects forSide-Effect Localization Joint work with Kung Chen, Jia-Yin Lin, and Siau-Cheng KhooNational Chengchi UniversityNational University of Singapore Shu-Chun WengNational Taiwan University
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
} Base program ExecutionPointcut Advice name } Aspect { Advice body Introduction (aspects) fib 0=1fib 1=1fib n = fib (n-1) + fib (n-2) cache@advice around{fib} (arg) =if cacheContains(arg)then getCachedValue(arg)else setCache(arg, proceed(arg))
Introduction (weaving) fib 0=1fib 1=1fib n = (cache fib) (n-1)+ (cache fib) (n-2) cache proceed arg =if cacheContains(arg)then getCachedValue(arg)else setCache(arg, proceed(arg))
Advice Advice Introduction (side-effecting aspects) Aspects requiring state monad Base Program State State pointcut pointcut Monad Introduction Global rewrite
Related works (monadification) • Manual monadification • Automatic monadification has been explored • CPS conversion by Flanagan and Hatcliff • Monad transformation by Lämmel • Selective transformation by Erwig and Ren
Motivation • Advice give us a systematical way to add monad-specific actions in a purely functional language • getCachedValue, setCache • Issues involved • Language support • Preserving evaluation order • Monadic base programs
Contributions • Language constructs for developing side-effecting aspects • user-defined variables • outputting function. • A monadification scheme to transform purely functional programs to monadic; retaining lazy-evaluation semantics via cache-enabled monads. • Extension for monadic programs.
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
AspectFun (base program) • Purely functional • Polymorphic • Lazy fib n =if n <=1then1else fib (n-1) + fib (n-2) fac n acc =if n ==0then accelse fac (n-1) (n*acc)
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
User-defined variable & side-effecting advice Declaration d ::= … | var id :: t = eExpression e ::= … | e1 ; e2 var profileMap :: Map.Map String Int = Map.empty getProfileMap :: Map.Map String Int setProfileMap :: Map.Map String Int -> () profiler@advice around {fib} (arg) = incProfile "fib"; proceed arg
let! Expression e ::= … | let! x = e1 in e2 var memoMap :: Map.Map Int Int memoFib@advice around {fib} (arg) =case lookupCache arg of Just v -> v Nothing ->let! v = proceed arg in insertCache arg v; v
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
Transformation for monad introduction • A-normalization • Type directed monadification • Lifting values and functions to monadic space • The monadification operator M :Type→ Type • The monad to be introduced: M • M(t1→t2) ⇒ M(t1) → M(t2) • M(a) ⇒M a
The Monadification Operator • Previous worksM(t1→t2) ⇒ t1→ M(t2) • Ours M(a→a) ⇒ M a→ M a • (M a) is an action as well as a thunk
Monadification • [e]Γ lifts expressions to monadic space
Monadified code (fac) fac n acc =if n ==0then accelse fac (n-1) (n*acc) facM :: M Int -> M Int -> M IntfacM n acc =dolet n_eq_0 = (liftM2 (==)) n (return 0) neq0 <- n_eq_0if neq0 then accelsedolet nmacc = (tracedMulM) n acclet nm1 = (liftM2 (-)) n (return 1) (tracerFacM facM) nm1 nmacc
Monadification (correctness) • Proposition 1 (Type Lifting)If Γ├e : t, then M(Γ)├ [e]Γ : M(t) • Proposition 2 (Semantics Preserving)If Γ├e : t and e→∗βv, thenrunIdentity([e]Γ)= v,where the underlying monad, M, is set to the Identity monad
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
The State Monad • Concrete monad to support memoization and profiling aspects • data State s a = State { runState :: s -> (a, s) } • type M a = State (UserVar, OutBuf) a
This Join Point: name of advised function Interference in the order of evaluation(Tracer example) • Adapted from Kishon ‘92 var indent :: String = "" tracer@advice around{fac, (*)} (arg) = \arg2 ->let! ind = getIndent in setIndent ("| "++ ind); putMsg "tracer" (ind ++tjp++" receives ["++ show arg ++", "++ show arg2 ++"]"); let! result = proceed arg arg2 in setIndent ind; putMsg "tracer" (ind ++ tjp ++ " returns "++ show result); result
Expecting result fac receives [3, 1] | fac receives [2, 3] | | fac receives [1, 6] | | | fac receives [0, 6] | | | | (*) receives [1, 6] | | | | | (*) receives [2, 3] | | | | | | (*) receives [3, 1] | | | | | | (*) returns 3 | | | | | (*) returns 6 | | | | (*) returns 6 | | | fac returns 6 | | fac returns 6 | fac returns 6 fac returns 6 } (*) are all called at the end according to lazy semantics
Wrong result fac receives [3, 1] | | (*) receives [3, 1] | | (*) returns 3 | fac receives [2, 3] | | | | (*) receives [3, 1] | | | | (*) returns 3 | | | (*) receives [2, 3] | | | | (*) receives [3, 1] | | | | (*) returns 3 | | | (*) returns 6 | | fac receives [1, 6] : : | | | | | | (*) receives [3, 1] | | | | | | (*) returns 3 | | | | | (*) returns 6 | | | | (*) returns 6 | | | fac returns 6 | | fac returns 6 | fac returns 6 fac returns 6 Displaying argument forces the multiplication being called(Premature evaluation) } } It is called every time whenever (3 * 1) is read(Duplicated evaluation)
Monadified code (tracer) tracer@advice around{fac, (*)} (arg) = \arg2 ->let! ind = getIndent in setIndent ("| "++ ind); putMsg "tracer" (ind++tjp++" receives ["++show arg++", "++show arg2++"]"); let! result = proceed arg arg2 in setIndent ind; putMsg "tracer" (ind ++ tjp ++" returns "++ show result); result tracerFacM proceed arg arg2 =do getIndentResult <- getIndentMlet ind = return getIndentResultlet show_arg = (liftM show) arg putMsgM (return "tracerFacM") ind…show_arg… proceedResult <- proceed arg arg2let result = return proceedResult setIndent indlet s_result = (liftM show) result putMsgM (return "tracerFacM") …s_result… result
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
The CState monad • We introduce a Cached State monad that extends the standard state monad with cache facility • Implemented by the CState monad • Insert add2Cache when necessary • Create thunks for argument expressions • Provide showM to replace ordinary show • Stringify the thunk, not the value • Post-process the output
Monadified code (correct tracer) tracerFacM proceed arg arg2 =do getIndentResult <- getIndentMlet ind = return getIndentResult s_arg <-add2cache (showM arg) putMsgM (return "tracerFacM") (add2cache …s_arg…) proceedResult <- proceed arg arg2let result = return proceedResult setIndent ind s_res <-add2cache (showM result) putMsgM (return "tracerFacM") (add2cache …s_res…) result
Tracer result fac receives [3, 1] | fac receives [2, 3] | | fac receives [1, 6] | | | fac receives [0, 6] | | | | (*) receives [1, 6] | | | | | (*) receives [2, 3] | | | | | | (*) receives [3, 1] | | | | | | (*) returns 3 | | | | | (*) returns 6 | | | | (*) returns 6 | | | fac returns 6 | | fac returns 6 | fac returns 6 fac returns 6
Outline • Introduction • AspectFun • Side-effecting aspects • Transformations • The state monad • The CState monad • Extension
Extension: Monadic base programs • M(t1→t2) ⇒ M(t1) → M(t2) • M(a) ⇒ MT N a • M(N (t1 → t2)) ⇒ MTN (M(t1) →M(t2)) • M(N a) ⇒ MT N a • type CStateT s m a = CacheT (StateT s m) a
StateT s m a CState s a CacheT (StateT s m) a Unified Monadification Scheme State s a
Conclusion • We presents an approach to provide side-effecting aspects for purely lazy functional languages in a user transparent fashion. • We propose a simple yet direct state manipulation construct for developing side-effecting aspects and devise a systematic monadification scheme to translate the woven code to a monadic style functional code. • All these can be extended to monadic base programs.