aspectual caml an aspect-oriented functional language
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 PresentationTRANSCRIPT
1
Aspectual Camlan Aspect-Oriented Functional Language
Hideaki TatsuzawaHidehiko MasuharaAkinori Yonezawa
University of Tokyo
2
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– MiniAML [Walker et al. 2003]
– TinyAspect [Aldrich2004]
– etc.
3
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
4
Contributions of Aspectual Caml
• Designed AspectJ-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 AspectJ)
• Showed an implementation framework
5
aspect 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 tend
aspect LogEval advice log_eval = [before (call eval _ _)] print_string “called eval\n”end
type 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 env
Motivating ExampleSimple Interpreter Aspects
type declaration type declaration of termsof terms
function definition for evaluation of terms
type type extensionextension
extension of extension of function function behaviorbehavior
logging evaluation of logging evaluation of termsterms
6
Motivating Example
type 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 env
aspect 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 tend
Simple Interpreter Aspects
aspect LogEval advice log_eval = [before (call eval _ _)] print_string “called eval\n”end
extension ofthe type declaration
specifies 2nd applicationsto function “eval”
7
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
8
Key Designs of Aspectual Caml
• Curried pointcuts
• Type extension mechanism
• Weaving with type inference
• 2 kinds of pointcuts – polymorphic and monomorphic
9
Key Designs of Aspectual Caml
• Curried pointcuts
• Type extension mechanism
• Weaving with type inference
• 2 kinds of pointcuts – polymorphic and monomorphic
Today’smaintopic
10
Curried Pointcuts
• Specify applications to curried functions easily
– cover application to variables from the result of partial applications
“call eval env t” specifies 2nd applications to “eval”
“call eval env t” covers the application “e t”in the context of “let e = eval env in e t”
11
Type Extensioncf. inter-type declarations in AspectJ
• Constructor addition
• Field addition
“type+ t = … | Sub t * t” adds the new constructor Subthat takes 2 arguments of the type t
“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
12
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 typ
e annotations– checks type of aspects without base code
• cf. C++ templates• 2 kinds of pointcuts
– polymorphic and monomorphic
13
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
Weaving of Type Inference: Background
14
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
Weaving of Type Inference: Background
15
Type System for Aspects
• Should deal with all kinds of declarations in aspects– pointcuts– advices– type extensions– local variables
16
Example of Aspect Type Inference
aspect 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 tend
17
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
18
Type Inference of Pointcuts
aspect 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 tend
eval :α β γenv : α
t : β
does not use type information in base code
(eval: (string * int) list t int)
19
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
20
Type Inference of “proceed”
aspect 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 tend
“proceed” means the continuationthat takes the 2nd argument of “eval”
and returns the result
eval :α β γenv : α
t : βproceed : β γ
21
Type Inference of Advice Body
aspect 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 tend
infer the type of the advice bodywith the type environment extended with
bound variables and “proceed”
eval :α β γenv : α
t : βproceed : β γ
22
Type Inference of Advice Body
aspect 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 tend
eval :α t γenv : α
t : tproceed : t γ
23
Type Inference of Advice Body
aspect 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 tend
eval :α t intenv : α
t : tproceed : t int
24
Checks Whether Type of Advice Body Matches Expected Type
aspect 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 tend
the expected type is the return type of “proceed”
25
Checks Whether Type of Advice Body Matches Expected Type
aspect 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 tend
the expected type is the return type of “proceed”
the type of advice body matches the expected type
eval :α t intenv : α
t : tproceed : t int
26
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
27
Type Extension
aspect 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 tend
type t = Num of int | Add of t * t | Let of string * t * t | Var of string | Sub of t * t
extends environment that is used in aspects
28
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 top-level variables of base code
29
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
30
Example of Weaving
type 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 env
aspect 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 tend
31
Type Extension
type 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 env
aspect 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 tend
type declaraion in woven code includesthe constructor “Sub”
32
Woven Code
type t = Add of t * t | Num of int | Let of string * t * t | Var of string | Sub of t * t
33
aspect 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 tend
type 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 env
Weaving Judgment
specifies function calls to “eval”
34
type 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 env
aspect 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 tend
Weaving Judgmenteval : β t int
env : βt : t
eval:(string*int)listt intenv:(string*int) list
t1 : t
weaves the advice into the join point
types of the pointcut matchestypes of the applications
type safe substitutionβ = (string*int) list
35
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 env
let rec eval_sub proceed call eval env t = match t with Sub(t1, t2) let e = eval env in e t1 - e t2 | _ proceed tend
function definition for advice
36
aspect 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 tend
Example of Weaving
let eval t u = t + u in eval 2 3
eval : int int int
types of the pointcut does not matchtypes of the application
do not weave the advice into the join point
eval : β t intenv : β
t : t
37
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 th
eir definitions
38
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 t int) (t: t)”
– automatic type inference is needed– familiar requirement for ML programmers
39
Why 2 Kinds of Pointcuts?
• Identifying join points specified by pointcuts only from their definitions– different advices using the same pointcuts shou
ld affect the same join points
…………
…..……
……………….………….
……..
pointcut logpoint = …advice a = [after logpoint] …advice b = [before logpoint] ...
40
2 Conflicting Requirements
• Automatic type inference can instantiate types of pointcut variables differently– cf. types of polymorphic functions’ arguments
41
Advices with the Same PointcutsMay Affect Different Join Points
pointcut 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”
enter:3enter:2leaveleaveenter:0leave…
expected result:always paired
42
pointcut 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”
Specifies applications to “assoc”
Advices with the Same PointcutsMay Affect Different Join Points
43
Advices with the Same PointcutsMay Affect Different Join Points
pointcut 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”
2 advice decls. using the same pointcut “logpoint”
traces before callsto “assoc”
traces after calls to “assoc”
44
Advices with the Same PointcutsMay Affect Different Join Points
pointcut 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”
used as int
any type
45
Advices with the Same PointcutsMay Affect Different Join Points
pointcut 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”
used as int
any type
match differentjoin points
46
This output is not intended result
pointcut 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”
outputenter:2leaveenter:3leaveleave…
base codeassoc 2 int_envassoc 3 int_envassoc “a” string_env…
“leave” without “enter”!
47
Proposal: 2 Kinds of Pointcuts
• Polymorphic pointcuts– variable types in pointcuts are inferred from advice bo
dies– 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 sa
me join points• example:
call (List.assoc:int (int * string) list string) x y
48
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
49
Related Work
• AspectJ [Kiczales et al. 2001]
– a mature AOP language– practical with various AOP features– AOP features of Aspectual Caml import from
AspectJ– too complicated for theoretical analysis
50
Related Work
• MiniAML [Walker et al. 2003]– proposes minimal typed functional AOP language core
calculus– defines semantics of the calculus and proves its sound
ness– the semantics of MiniAML are defined as a translation i
nto the calculus
• TinyAspect [Aldrich 2004]– for studying interference between aspects and modules– proposes small typed functional AOP language includin
g module system– defines the semantics and proves its soundness
51
Related Work
polymor-phism
pointcuttypeextension
semanticsdefinition
modulesystem
soundnessproof
MiniAMLonly callwith 1 arg
TinyAspectonly callwith 1 arg
AspectualCaml many
52
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
53
Future Work
• Define formal semantics
• Study well-typedness properties at aspects
• Implement βversion
• Introduce more expressive AOP features
54
Fin
55
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
56
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