Aspectual Caml an AspectOriented Functional Language Hideaki Tatsuzawa

  • Slides: 56
Download presentation
Aspectual Caml an Aspect-Oriented Functional Language Hideaki Tatsuzawa Hidehiko Masuhara Akinori Yonezawa University of

Aspectual Caml an Aspect-Oriented Functional Language Hideaki Tatsuzawa Hidehiko Masuhara Akinori Yonezawa University of Tokyo 1

Background: Studies on AOPLs • Practical languages are mostly based on OOPLs – Java

Background: Studies on AOPLs • Practical languages are mostly based on OOPLs – Java [Kiczales et al. 2001] – C++ [Spinczyk et al. 2002] – etc. • AOPLs based on functional languages are designed for theoretical purposes – Mini. AML [Walker et al. 2003] – Tiny. Aspect [Aldrich 2004] – etc. 2

Motivation • Design and implement a functional AOPL Aspectual Caml by adopting advanced AOP

Motivation • Design and implement a functional AOPL Aspectual Caml by adopting advanced AOP features (e. g. inter-type declarations) for: – modularizing large functional programs • compilers, theorem provers, etc. – providing a foundation of further theoretical studies • under clear semantics of functional languages 3

Contributions of Aspectual Caml • Designed Aspect. J-like AOP features in a functional language

Contributions of Aspectual Caml • Designed Aspect. J-like AOP features in a functional language – pointcut-advice mechanism • curried pointcuts • type inference of aspects • polymorphic and monomorphic pointcuts – type extension mechanism (cf. inter-type declarations in Aspect. J) • Showed an implementation framework 4

Motivating Example Simple Interpreter Aspects aspect Sub. Extension type t = Add of t

Motivating Example Simple Interpreter Aspects aspect Sub. Extension type t = Add of t * t type+ t =. . . type | Sub of t * t advice eval_sub = | Num int extension type of declaration [around (call eval env t)] | Let of match t with ofstring terms* t Sub(t 1, t 2) -> | Var of string let e = eval env in extension of let rec eval env t = match t with e t 1 - e t 2 | _ -> proceed t function Add(t 1, t 2) -> end (eval env t 1) + (eval env t 2) function definition for behavior | Num(i) -> i aspect Log. Eval evaluation of terms logging evaluation of advice log_eval = | Let(s, t 1, t 2) -> [before (call eval _ _)] terms eval ((s, eval env t 1): : env) t 2 print_string “called evaln” end | Var(s) -> List. assoc s env 5

Motivating Example Aspects Simple Interpreter type t = Add of t * t |

Motivating Example Aspects Simple Interpreter type t = Add of t * t | Num of int | Let of string * t | Var of string of extension let rec eval env t = match t with the type declaration Add(t 1, t 2) -> (eval env t 1) + (eval env t 2) | Num(i) -> i | Let(s, t 1, t 2) -> eval ((s, eval env t 1): : env) t 2 | Var(s) -> List. assoc s env aspect Sub. Extension type+ t =. . . | Sub of t * t advice eval_sub = [around ( call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t applications end specifies 2 nd to function “eval” aspect Log. Eval advice log_eval = [before (call eval _ _)] print_string “called evaln” end 6

Required Features to Aspectual Caml • 2 kinds of AOP features – Pointcut-advice mechanism

Required Features to Aspectual Caml • 2 kinds of AOP features – Pointcut-advice mechanism – Type extension mechanism • Type inference of aspects without base code – writing aspects without type annotations – ensuring type safety of woven code – enabling separate compilation 7

Key Designs of Aspectual Caml • • Curried pointcuts Type extension mechanism Weaving with

Key Designs of Aspectual Caml • • Curried pointcuts Type extension mechanism Weaving with type inference 2 kinds of pointcuts – polymorphic and monomorphic 8

Key Designs of Aspectual Caml • • Curried pointcuts Type extension mechanism Weaving with

Key Designs of Aspectual Caml • • Curried pointcuts Type extension mechanism Weaving with type inference 2 kinds of pointcuts – polymorphic and monomorphic Today’s main topic 9

Curried Pointcuts • Specify applications to curried functions easily “call eval env t” specifies

Curried Pointcuts • Specify applications to curried functions easily “call eval env t” specifies 2 nd applications to “eval” – cover application to variables from the result of partial applications “call eval env t” covers the application “e t” in the context of “let e = eval env in e t” 10

Type Extension cf. inter-type declarations in Aspect. J • Constructor addition “type+ t =

Type Extension cf. inter-type declarations in Aspect. J • Constructor addition “type+ t = … | Sub t * t” adds the new constructor Sub that takes 2 arguments of the type t • Field addition “type+ t = Var of … * int{0}” adds the new integer field to the constructor Var and “ 0” is the default value for the extra field 11

Key Designs of Aspectual Caml • Curried pointcuts • Type extension mechanism • Weaving

Key Designs of Aspectual Caml • Curried pointcuts • Type extension mechanism • Weaving with type inference – ensures type safety of woven code – allows to define pointcuts and advices without type annotations – checks type of aspects without base code • cf. C++ templates • 2 kinds of pointcuts – polymorphic and monomorphic 12

Weaving of Type Inference: Background Possible 2 Approaches for Type Safety • Type checking

Weaving of Type Inference: Background Possible 2 Approaches for Type Safety • Type checking woven code after weaving – no need of aspect typing – impossible separate compilations • Type checking aspect code and base code before weaving – need of aspect typing – needed for separate compilations 13

Weaving of Type Inference: Background Possible 2 Approaches for Type Safety • Type checking

Weaving of Type Inference: Background Possible 2 Approaches for Type Safety • Type checking woven code after weaving – no need of aspect typing – impossible separate compilations • Type checking aspect code and base code before weaving – need of aspect typing – needed for separate compilations Our approach 14

Type System for Aspects • Should deal with all kinds of declarations in aspects

Type System for Aspects • Should deal with all kinds of declarations in aspects – pointcuts – advices – type extensions – local variables 15

Example of Aspect Type Inference aspect Sub. Extension type t =. . . |

Example of Aspect Type Inference aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end 16

Type System for Aspects • Should deal with all kinds of declarations in aspects

Type System for Aspects • Should deal with all kinds of declarations in aspects – pointcuts • infers types from explicitly specified types and kinds of pointcuts – advices – type extensions – local variables 17

Type Inference of Pointcuts eval : α -> β -> γ env : α

Type Inference of Pointcuts eval : α -> β -> γ env : α t: β aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in does not use type information e t 1 - e t 2 in base code | _ -> proceed t (eval: (string * int) list -> int) end 18

Type System for Aspects • Should deal with all kinds of declarations in aspects

Type System for Aspects • Should deal with all kinds of declarations in aspects – pointcuts – advices • infers types of an advice body using extended environment with top-level variables of base code, variables bound by pointcuts, and “proceed” • checks whether a type of an advice body match with one expected by contexts – type extensions – local variables 19

Type Inference of “proceed” eval : α -> β -> γ env : α

Type Inference of “proceed” eval : α -> β -> γ env : α t: β proceed : β -> γ aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in “proceed” the continuation e t 1 - e means t 2 that takes the 2 nd argument of “eval” | _ -> proceed t and returns the result end 20

Type Inference of Advice Body eval : α -> β -> γ env :

Type Inference of Advice Body eval : α -> β -> γ env : α t: β proceed : β -> γ aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with infer the type of the advice body Sub(t 1, t 2) -> let e = eval env in with the type environment extended with e t 1 - e t 2 variables and “proceed” | _ ->bound proceed t end 21

Type Inference of Advice Body eval : α -> t -> γ env :

Type Inference of Advice Body eval : α -> t -> γ env : α t: t proceed : t -> γ aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end 22

Type Inference of Advice Body eval : α -> t -> int env :

Type Inference of Advice Body eval : α -> t -> int env : α t: t proceed : t -> int aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end 23

Checks Whether Type of Advice Body Matches Expected Type aspect Sub. Extension type t

Checks Whether Type of Advice Body Matches Expected Type aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end the expected type is the return type of “proceed” 24

Checks Whether Type of Advice Body Matches Expected Type eval : α -> t

Checks Whether Type of Advice Body Matches Expected Type eval : α -> t -> int env : α aspect Sub. Extension t: t type t =. . . | Sub of t * t the type of advice body t -> int advice eval_sub = [around (callproceed eval env: t)] matches the expected type match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end the expected type is the return type of “proceed” 25

Type System for Aspects • Should deal with all kinds of declarations in aspects

Type System for Aspects • Should deal with all kinds of declarations in aspects – pointcuts – advices – type extensions • replaces corresponding information of type environment with the extended information – local variables 26

Type Extension type t = Num of int | Add of t * t

Type Extension type t = Num of int | Add of t * t aspect Sub. Extension | Let of string * t type t =. . . | Sub of t * t | Var of string advice eval_sub = [around (call eval env t)] | Sub of t * t match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 extends environment that is used in aspects | _ -> proceed t end 27

Type System for Aspects • Should deal with all kinds of declarations in aspects

Type System for Aspects • Should deal with all kinds of declarations in aspects – pointcuts – advices – type extensions – local variables • infers types using extended environment with toplevel variables of base code 28

Weaving with Type Information • Generates type safe woven code from typed base code

Weaving with Type Information • Generates type safe woven code from typed base code and typed aspect code – judges join points that advices are woven into • kinds of pointcut • specified names • type information of each code – reflects type extensions as changing corresponding type declarations 29

Example of Weaving aspect Sub. Extension type t =. . . | Sub of

Example of Weaving aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end type t = Add of t * t | Num of int | Let of string * t | Var of string let rec eval env t = match t with Add(t 1, t 2) -> (eval env t 1) + (eval env t 2) | Num(i) -> i | Let(s, t 1, t 2) -> eval ((s, eval env t 1): : env) t 2 | Var(s) -> List. assoc s env 30

Type Extension type t = Add of t * t aspect Sub. Extension |

Type Extension type t = Add of t * t aspect Sub. Extension | Num of int type t =. . . | Sub of t * t | Let of string * t advice eval_sub = | Var of string [around (call eval env t)] let rec eval env t = match t with Add(t 1, t 2) -> Sub(t 1, t 2) -> (eval env t 1) + (eval env t 2) let e = eval env in | Num(i) -> i e t 1 - e t 2 | Let(s, t 1, t 2) -> | _ -> proceed t eval ((s, eval env t 1): : env) t 2 end type declaraion in |woven includes Var(s) ->code List. assoc s env the constructor “Sub” 31

Woven Code type t = Add of t * t | Num of int

Woven Code type t = Add of t * t | Num of int | Let of string * t | Var of string | Sub of t * t 32

Weaving Judgment aspect Sub. Extension type t =. . . | Sub of t

Weaving Judgment aspect Sub. Extension type t =. . . | Sub of t * t advice eval_sub = [around (call eval env t)] match t with Sub(t 1, t 2) -> let e = eval env in e t 1 - e t 2 | _ -> proceed t end type t = Add of t * t | Num of int | Let of string * t | Var of string let rec eval env t = match t with Add(t 1, t 2) -> (eval env t 1) + (eval env t 2) | Num(i) -> i | Let(s, t 1, t 2) -> eval ((s, eval env t 1): : env) t 2 | Var(s) -> List. assoc s env specifies function calls to “eval” 33

Weaving Judgment eval : β-> t ->int env : β aspect Sub. Extension t

Weaving Judgment eval : β-> t ->int env : β aspect Sub. Extension t of t * t type t =. . . t |: Sub eval: (string*int)list->t-> int env: (string*int) type t = Add of t * t list | Num of t 1 int: t | Let of string * t advice eval_sub = | Var of string [around (call eval env t)] let rec eval env t = match t with type safe Sub(t 1, t 2) ->substitution Add(t 1, t 2) -> (eval env t 1) + (eval env t 2) let e =(string*int) eval env inlist β= | Num(i) -> i e t 1 - e t 2 | Let(s, t 1, matches t 2) -> types | _ -> proceed t of the pointcut eval ((s, eval env t 1): : env) t 2 end types of the applications | Var(s) -> List. assoc s env weaves the advice into the join point 34

Woven Code let rec eval_sub proceed type t = Add of t * t

Woven Code let rec eval_sub proceed type t = Add of t * t call eval env t = | Num of int match t with | Let of string * t Sub(t 1, t 2) -> | Var of string let e = eval env in | Sub of t * t e t 1 - e t 2 let rec eval env t = match t with | _ -> proceed t Add(t 1, t 2) -> end (eval_sub eval env t 1) + (eval_sub eval env t 2) | Num(i) -> i function definition | Let(s, t 1, t 2) -> for advice eval_sub eval ((s, eval_sub eval env t 1): : env) t 2 35 | Var(s) -> List. assoc s env

Example of Weaving eval : β-> t ->int env : β aspect Sub. Extension

Example of Weaving eval : β-> t ->int env : β aspect Sub. Extension t of t * t type t =. . . t |: Sub let eval t u = t + u in eval 2 3 advice eval_sub = [around (call eval env t)] eval : int -> match t with Sub(t 1, t 2) -> lettypes e = eval ofenv theinpointcut does not match e t 1 - e t 2 types of the application | _ -> proceed t end int do not weave the advice into the join point 36

Key Designs of Aspectual Caml • Curried pointcuts • Type extension mechanism • Weaving

Key Designs of Aspectual Caml • Curried pointcuts • Type extension mechanism • Weaving with type inference for aspects • 2 kinds of pointcuts – polymorphic pointcuts • writing pointcuts without explicit type annotations – monomorphic pointcuts • identifying join points specified by pointcuts only from their definitions 37

Why 2 Kinds of Pointcuts? • Writing pointcuts without type annotations – explicit type

Why 2 Kinds of Pointcuts? • Writing pointcuts without type annotations – explicit type annotations are tedious • “pointcut call_eval t = call eval t” is better rather than “pointcut call_eval t = call (eval: (string* int) list -> int) (t: t)” – automatic type inference is needed – familiar requirement for ML programmers 38

Why 2 Kinds of Pointcuts? • Identifying join points specified by pointcuts only from

Why 2 Kinds of Pointcuts? • Identifying join points specified by pointcuts only from their definitions – different advices using the same pointcuts should affect the same join points pointcut logpoint = … advice a = [after logpoint] … advice b = [before logpoint]. . . … ……… …. . …… ………………. ……. . 39

2 Conflicting Requirements • Automatic type inference can instantiate types of pointcut variables differently

2 Conflicting Requirements • Automatic type inference can instantiate types of pointcut variables differently – cf. types of polymorphic functions’ arguments 40

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x =

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x = expected result: call List. assoc x always paired advice before_trace = enter: 3 [before logpoint x] enter: 2 print_string (“enter: " leave ^(string_of_int x)) leave advice after_trace = enter: 0 [after logpoint x] leave print_string “leave” … 41

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x =

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x = call List. assoc x advice before_trace = [before logpoint x] Specifies applications to “assoc” print_string (“enter: " ^(string_of_int x)) advice after_trace = [after logpoint x] print_string “leave” 42

Advices with the Same Pointcuts May Affect Different Join Points 2 advice decls. using

Advices with the Same Pointcuts May Affect Different Join Points 2 advice decls. using the same pointcut “logpoint” pointcut logpoint x = call List. assoc x advice before_trace = [before logpoint x] print_string (“enter: " traces before calls ^(string_of_int x)) to “assoc” advice after_trace = [after logpoint x] print_string “leave” traces after calls to “assoc” 43

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x =

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x = call List. assoc x advice before_trace = [before logpoint x] print_string (“enter: " ^(string_of_int x)) advice after_trace = used as int [after logpoint x] print_string “leave” any type 44

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x =

Advices with the Same Pointcuts May Affect Different Join Points pointcut logpoint x = match different call List. assoc x join points advice before_trace = [before logpoint x] print_string (“enter: " ^(string_of_int x)) advice after_trace = used as int [after logpoint x] print_string “leave” any type 45

This output is not intended result base code assoc 2 int_env pointcut logpoint x

This output is not intended result base code assoc 2 int_env pointcut logpoint x = assoc 3 int_env call List. assoc x assoc “a” string_env advice before_trace = … [before logpoint x] output print_string (“enter: " enter: 2 ^(string_of_intleave x)) advice after_trace = enter: 3 [after logpoint x] leave print_string “leave” leave … “leave” without 46 “enter”!

Proposal: 2 Kinds of Pointcuts • Polymorphic pointcuts – variable types in pointcuts are

Proposal: 2 Kinds of Pointcuts • Polymorphic pointcuts – variable types in pointcuts are inferred from advice bodies – one pointcut used in different advice decls may match different join points • Monomorphic pointcuts – variable types must not be instantiated in advice bodies – one pointcut used in any advice decl matches the same join points • example: call (List. assoc: int -> (int * string) list -> string) x y 47

Current Implementation • Source to source translator • Extension of O’Caml compiler • Essential

Current Implementation • Source to source translator • Extension of O’Caml compiler • Essential AOP features are implemented – – – type extension around advice 2 kinds of pointcuts type inference of aspects weaving most primitive pointcuts except for wild card • call, exec, match, and, within 48

Related Work • Aspect. J [Kiczales et al. 2001] – a mature AOP language

Related Work • Aspect. J [Kiczales et al. 2001] – a mature AOP language – practical with various AOP features – AOP features of Aspectual Caml import from Aspect. J – too complicated for theoretical analysis 49

Related Work • Mini. AML [Walker et al. 2003] – proposes minimal typed functional

Related Work • Mini. AML [Walker et al. 2003] – proposes minimal typed functional AOP language core calculus – defines semantics of the calculus and proves its soundness – the semantics of Mini. AML are defined as a translation into the calculus • Tiny. Aspect [Aldrich 2004] – for studying interference between aspects and modules – proposes small typed functional AOP language including module system 50 – defines the semantics and proves its soundness

Related Work semantics polymor type pointcut extension definition -phism Mini. AML only call with

Related Work semantics polymor type pointcut extension definition -phism Mini. AML only call with 1 arg Tiny. Aspect only call with 1 arg Aspectual Caml many module soundness system proof 51

Conclusion • Designed and implemented a practical AOP language based on a typed functional

Conclusion • Designed and implemented a practical AOP language based on a typed functional language • Proposed solutions to problems in adaptations AOP to functional languages – curried pointcuts – weaving and type inference for aspects – 2 kinds of pointcuts – type extension mechanism 52

Future Work • • Define formal semantics Study well-typedness properties at aspects Implement βversion

Future Work • • Define formal semantics Study well-typedness properties at aspects Implement βversion Introduce more expressive AOP features 53

Fin 54

Fin 54

Problems of Constructor Addition • New constructor makes pattern matches in base code non-exhaustive

Problems of Constructor Addition • New constructor makes pattern matches in base code non-exhaustive – aspect programmers should supplement the lack case of pattern matches declaring proper advices – this non-exhaustiveness can be found using information in type check of woven code 55

Default Value of Field Addition • Aspect programmers should set proper initial values for

Default Value of Field Addition • Aspect programmers should set proper initial values for new fields using advices • Without proper advices default values preserve type safety of woven code 56