aspectual caml an aspect-oriented functional language

of 56 /56
1 Aspectual Caml an Aspect-Oriented Functional L anguage Hideaki Tatsuzawa Hidehiko Masuhara Akinori Yonezawa University of Tokyo

Author: elisha

Post on 22-Jan-2016

24 views

Category:

Documents


0 download

Embed Size (px)

DESCRIPTION

Aspectual Caml an Aspect-Oriented Functional Language. Hideaki Tatsuzawa Hidehiko Masuhara Akinori Yonezawa University of Tokyo. Background: Studies on AOPLs. Practical languages are mostly based on OOPLs Java [Kiczales et al. 2001] C++ [Spinczyk et al. 2002] etc. - PowerPoint PPT Presentation

TRANSCRIPT

  • Aspectual Camlan Aspect-Oriented Functional LanguageHideaki Tatsuzawa Hidehiko Masuhara Akinori YonezawaUniversity of Tokyo

  • Background: Studies on AOPLsPractical languages are mostly based on OOPLsJava [Kiczales et al. 2001]C++ [Spinczyk et al. 2002]etc.AOPLs based on functional languages are designed for theoretical purposesMiniAML [Walker et al. 2003]TinyAspect [Aldrich2004]etc.

  • MotivationDesign and implement a functional AOPL Aspectual Caml by adopting advanced AOP features (e.g. inter-type declarations) for:modularizing large functional programscompilers, theorem provers, etc.providing a foundation of further theoretical studiesunder clear semantics of functional languages

  • Contributions of Aspectual CamlDesigned AspectJ-like AOP features in a functional languagepointcut-advice mechanismcurried pointcutstype inference of aspectspolymorphic and monomorphic pointcutstype extension mechanism (cf. inter-type declarations in AspectJ)Showed an implementation framework

  • Motivating Exampleaspect SubExtension type+ t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endaspect LogEval advice log_eval = [before (call eval _ _)] print_string called eval\n endtype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envSimple InterpreterAspectstype declaration of termsfunction definition for evaluation of termstype extensionextension of function behaviorlogging evaluation of terms

  • Motivating Exampletype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envaspect SubExtension type+ t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endSimple InterpreterAspectsaspect LogEval advice log_eval = [before (call eval _ _)] print_string called eval\n endextension of the type declarationspecifies 2nd applications to function eval

  • Required Features to Aspectual Caml2 kinds of AOP featuresPointcut-advice mechanismType extension mechanismType inference of aspects without base codewriting aspects without type annotationsensuring type safety of woven codeenabling separate compilation

  • Key Designs of Aspectual CamlCurried pointcutsType extension mechanism Weaving with type inference 2 kinds of pointcuts polymorphic and monomorphic

  • Key Designs of Aspectual CamlCurried pointcutsType extension mechanismWeaving with type inference 2 kinds of pointcuts polymorphic and monomorphicTodays main topic

  • Curried PointcutsSpecify applications to curried functions easily cover application to variables from the result of partial applicationscall eval env t specifies 2nd applications to evalcall eval env t covers the application e t in the context of let e = eval env in e t

  • Type Extensioncf. inter-type declarations in AspectJConstructor addition

    Field additiontype+ t = | Sub t * t adds the new constructor Sub that takes 2 arguments of the type ttype+ t = Var of * int{0} adds the new integer field to the constructor Var and 0 is the default value for the extra field

  • Key Designs of Aspectual CamlCurried pointcutsType extension mechanismWeaving with type inferenceensures type safety of woven code allows to define pointcuts and advices without type annotationschecks type of aspects without base codecf. C++ templates2 kinds of pointcuts polymorphic and monomorphic

  • Possible 2 Approaches for Type SafetyType checking woven code after weavingno need of aspect typingimpossible separate compilationsType checking aspect code and base code before weavingneed of aspect typingneeded for separate compilationsWeaving of Type Inference: Background

  • Possible 2 Approaches for Type SafetyType checking woven code after weavingno need of aspect typingimpossible separate compilationsType checking aspect code and base code before weavingneed of aspect typingneeded for separate compilationsOur approachWeaving of Type Inference: Background

  • Type System for AspectsShould deal with all kinds of declarations in aspectspointcutsadvicestype extensionslocal variables

  • Example of Aspect Type Inferenceaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t end

  • Type System for AspectsShould deal with all kinds of declarations in aspectspointcutsinfers types from explicitly specified types and kinds of pointcutsadvicestype extensionslocal variables

  • Type Inference of Pointcutsaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endeval : -> -> env : t : does not use type information in base code(eval: (string * int) list -> t -> int)

  • Type System for AspectsShould deal with all kinds of declarations in aspectspointcutsadvicesinfers types of an advice body using extended environment with top-level variables of base code, variables bound by pointcuts, and proceedchecks whether a type of an advice body match with one expected by contextstype extensionslocal variables

  • Type Inference of proceedaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endproceed means the continuationthat takes the 2nd argument of eval and returns the resulteval : -> -> env : t : proceed : ->

  • Type Inference of Advice Bodyaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endinfer the type of the advice body with the type environment extended with bound variables and proceedeval : -> -> env : t : proceed : ->

  • Type Inference of Advice Bodyaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endeval : -> t -> env : t : t proceed : t ->

  • Type Inference of Advice Bodyaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endeval : -> t -> int env : t : t proceed : t -> int

  • Checks Whether Type of Advice Body Matches Expected Typeaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endthe expected type is the return type of proceed

  • Checks Whether Type of Advice Body Matches Expected Typeaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endthe expected type is the return type of proceed the type of advice body matches the expected typeeval : -> t -> int env : t : t proceed : t -> int

  • Type System for AspectsShould deal with all kinds of declarations in aspectspointcutsadvicestype extensionsreplaces corresponding information of type environment with the extended informationlocal variables

  • Type Extensionaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endtype t = Num of int | Add of t * t | Let of string * t * t | Var of string | Sub of t * textends environment that is used in aspects

  • Type System for AspectsShould deal with all kinds of declarations in aspectspointcutsadvicestype extensionslocal variablesinfers types using extended environment with top-level variables of base code

  • Weaving with Type InformationGenerates type safe woven code from typed base code and typed aspect codejudges join points that advices are woven intokinds of pointcutspecified namestype information of each codereflects type extensions as changing corresponding type declarations

  • Example of Weavingtype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t end

  • Type Extensiontype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endtype declaraion in woven code includes the constructor Sub

  • Woven Codetype t = Add of t * t | Num of int | Let of string * t * t | Var of string | Sub of t * t

  • Weaving Judgmentaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endtype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envspecifies function calls to eval

  • Weaving Judgmenttype t = Add of t * t | Num of int | Let of string * t * t | Var of stringlet rec eval env t = match t with Add(t1, t2) -> (eval env t1) + (eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval ((s, eval env t1)::env) t2| Var(s) -> List.assoc s envaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endeval : -> t ->intenv : t : teval:(string*int)list->t-> intenv:(string*int) listt1 : tweaves the advice into the join pointtypes of the pointcut matches types of the applicationstype safe substitution = (string*int) list

  • Woven Codetype t = Add of t * t | Num of int | Let of string * t * t | Var of string | Sub of t * tlet rec eval env t = match t with Add(t1, t2) -> (eval_sub eval env t1) + (eval_sub eval env t2)| Num(i) -> i| Let(s, t1, t2) -> eval_sub eval ((s, eval_sub eval env t1)::env) t2| Var(s) -> List.assoc s envlet rec eval_sub proceed call eval env t = match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endfunction definition for advice

  • Example of Weavingaspect SubExtension type t = ... | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t1, t2) -> let e = eval env in e t1 - e t2 | _ -> proceed t endlet eval t u = t + u in eval 2 3eval : int -> int -> int

    types of the pointcut does not match types of the applicationdo not weave the advice into the join pointeval : -> t ->intenv : t : t

  • Key Designs of Aspectual CamlCurried pointcutsType extension mechanismWeaving with type inference for aspects2 kinds of pointcutspolymorphic pointcutswriting pointcuts without explicit type annotationsmonomorphic pointcutsidentifying join points specified by pointcuts only from their definitions

  • Why 2 Kinds of Pointcuts?Writing pointcuts without type annotationsexplicit type annotations are tediouspointcut call_eval t = call eval t is better rather than pointcut call_eval t = call (eval: (string* int) list -> t -> int) (t: t) automatic type inference is neededfamiliar requirement for ML programmers

  • Why 2 Kinds of Pointcuts?Identifying join points specified by pointcuts only from their definitionsdifferent advices using the same pointcuts should affect the same join points

    ......pointcut logpoint = advice a = [after logpoint] advice b = [before logpoint] ...

  • 2 Conflicting RequirementsAutomatic type inference can instantiate types of pointcut variables differentlycf. types of polymorphic functions arguments

  • Advices with the Same PointcutsMay Affect Different Join Pointspointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter:" ^(string_of_int x))advice after_trace = [after logpoint x] print_string leave

  • Advices with the Same PointcutsMay Affect Different Join Pointspointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter: " ^(string_of_int x))advice after_trace = [after logpoint x] print_string leaveSpecifies applications to assoc

  • Advices with the Same PointcutsMay Affect Different Join Pointspointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter:" ^(string_of_int x))advice after_trace = [after logpoint x] print_string leave2 advicedecls. using the same pointcut logpointtraces before callsto assoctraces after calls to assoc

  • Advices with the Same PointcutsMay Affect Different Join Pointspointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter:" ^(string_of_int x))advice after_trace = [after logpoint x] print_string leaveused as intany type

  • Advices with the Same PointcutsMay Affect Different Join Pointspointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter:" ^(string_of_int x))advice after_trace = [after logpoint x] print_string leaveused as intany typematch different join points

  • This output is not intended resultpointcut logpoint x = call List.assoc xadvice before_trace = [before logpoint x] print_string (enter:" ^(string_of_int x))advice after_trace = [after logpoint x] print_string leaveoutput enter:2leaveenter:3leaveleavebase code assoc 2 int_env assoc 3 int_env assoc a string_env leave without enter!

  • Proposal: 2 Kinds of PointcutsPolymorphic pointcutsvariable types in pointcuts are inferred from advice bodiesone pointcut used in different advice decls may match different join pointsMonomorphic pointcutsvariable types must not be instantiated in advice bodiesone pointcut used in any advice decl matches the same join pointsexample: call (List.assoc:int -> (int * string) list -> string) x y

  • Current ImplementationSource to source translatorExtension of OCaml compilerEssential AOP features are implementedtype extensionaround advice2 kinds of pointcutstype inference of aspectsweavingmost primitive pointcuts except for wild cardcall, exec, match, and, within

  • Related WorkAspectJ [Kiczales et al. 2001]a mature AOP languagepractical with various AOP featuresAOP features of Aspectual Caml import from AspectJtoo complicated for theoretical analysis

  • Related WorkMiniAML [Walker et al. 2003]proposes minimal typed functional AOP language core calculusdefines semantics of the calculus and proves its soundnessthe semantics of MiniAML are defined as a translation into the calculusTinyAspect [Aldrich 2004]for studying interference between aspects and modulesproposes small typed functional AOP language including module systemdefines the semantics and proves its soundness

  • Related Work

  • ConclusionDesigned and implemented a practical AOP language based on a typed functional languageProposed solutions to problems in adaptations AOP to functional languagescurried pointcutsweaving and type inference for aspects2 kinds of pointcutstype extension mechanism

  • Future WorkDefine formal semantics Study well-typedness properties at aspectsImplement versionIntroduce more expressive AOP features

  • Fin

  • Problems of Constructor AdditionNew constructor makes pattern matches in base code non-exhaustiveaspect programmers should supplement the lack case of pattern matches declaring proper advicesthis non-exhaustiveness can be found using information in type check of woven code

  • Default Value of Field AdditionAspect programmers should set proper initial values for new fields using advicesWithout proper advices default values preserve type safety of woven code

  • Judgment of Weaving or NotTypes and names are used to judge whether weave or notaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendlet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

  • Judgment of Weaving or NotTypes and names are used to judge whether weave or notaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendlet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

    assoc:string -> (string * ) list -> assoc:string -> -> type safe substitution: = (string * ) list, = the advice body can be evaluated preserving type safety of target code

  • Judgment of Weaving or NotTypes and names are used to judge whether weave or notaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendlet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

    assoc:int -> (int * ) list -> assoc:string -> -> no substitutions preserve type safetyevaluation of the advice body destroys type safety of target code at the join point

  • Flow of CompileOcamlSourceAspectSourcetype inferencetype inference for aspectstypedOcamlASTtypedAspectweave withtypestype extensionWoven program

  • Example of Aspect Type Inferenceaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendassoc: -> -> elem:env:type inference of pointcuts does not usetype information of target code(assoc: -> (*) list -> )

  • Example of Aspect Type Inferenceaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendassoc: -> -> elem:env:proceed: -> proceed means the continuationthat takes the 2nd argument of assoc and returns the result

  • Example of Aspect Type Inferenceaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n);proceed envendinfer the type of the advice body with the type environment extended with bound variables and proceedassoc: -> -> elem:env:proceed: ->

  • Example of Aspect Type Inferenceaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendassoc:string -> -> elem:stringenv:proceed: ->

  • Example of Aspect Type Inferenceaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendthe expected type is the return type of proceed the type of this expression matches the expected type

  • Limitation of Simple Call Pointcutsaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendImpossible to specify applications to partially applied functionslet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

    specifies applications to assoc

  • Limitation of Simple Call Pointcutsaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendImpossible to specify applications to partially applied functionslet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

    defines advice code

  • Limitation of Simple Call Pointcutsaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendImpossible to specify applications to partially applied functionslet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

    impossible to specify 2nd applications to functions assoc since it takes 2 arguments

  • Proposal: Curried PointcutsCurried pointcuts allow to easily specify applications to curried functionscall/exec pointcuts in AspectJ can specify only 1st applications call assoc elem env specifies2nd applications to functions assoc

  • Design for Curried PointcutsSpecify applications to variables bound to partially applied closuresaspect LogAssoc advice log_assoc [around call assoc elem env] print_string (assoc with:^elem^\n); proceed envendlet assoc1 = assoc strassoc1 envassoc1 env2assoc 20 env3

  • Aspect-Oriented Programming (AOP)modularizing program units over multiple modulesBetter readability and flexibility of programsindustrial benefitsrefactoring a huge product with AspectJ [Adrian et.al 2004]crosscutting concerns

  • An Example of an Aspect Definitionaspect LogAssoc advice log_assoc=[around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendLogging function calls to assoc

  • An Example of an Aspect Definitionaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendspecifies function calls to assocLogging function calls to assoc

  • An Example of an Aspect Definitionaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendexecution points of applications to a function named assocprints a messageLogging function calls to assoc

  • An Example of an Aspect DefinitionLogging function calls to assocaspect LogAssoc advice log_assoc [around call assoc elem] print_string (assoc with:^elem^\n); proceed elemendexecution points of applications to a function named assocprint the messagepointcutadvice body