A Definition, Overview and Taxonomy of Generic Aspect Languages Günter Kniesel — Tobias Rho Institut für Informatik III Universität Bonn Römerstr. 164 D-53117 Bonn, Germany [email protected] [email protected] ABSTRACT. Aspect-orientation promises better modularity than pure object-oriented decomposition. A typical benefit of increased modularity is ease of maintenance, evolution and reuse. However, it has been noted by various researchers that many of the first generation aspect languages do not provide the degree of reusability initially hoped for. In this paper, we argue that the problem of insufficient reusability is due to a lack of support for aspect genericity. We analyze various problems of traditional aspect languages and define aspect genericity to be the ability to concisely express aspect effects that vary depending on the context of a join point known at weave-time, without falling back to runtime reflection. We identify the ability to parameterize aspect effects with meta-variables ranging over base language elements as the technical prerequisite for achieving genericity and describe the design space for generic aspect languages in terms of five basic questions that a language designer should consider. Within this space we review the different proposals for generic aspect languages made so far and compare them by showing which part of the possible design space is explored within these languages. Among the reviewed design options we identify predicate-based binding of logic metavariables, uniform genericity and fine-grained genericity as optimal answers to three of the discussed questions. Last but not least, we identify open research problems that are specific to aspect genericity or aggravated in the presence of genericity. We expect that genericity will be a key ingredient of a second generation of aspect languages. It will significantly reduce the dependency of aspects on base programs and will automatically select behavior depending on the weave-time context of a join point in the same way as dynamic binding does depending on the type of a message receiver. KEYWORDS: aspect-oriented programming, generic aspect language, uniform genericity, finegrained genericity. 2 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 1. Introduction Aspect-oriented software development (AOSD) is a powerful new paradigm for separation of concerns. Functionality that would otherwise be scattered throughout a program because it cannot be modularized in the dominant decomposition (Ossher et al., 2001a) of a particular language can be encapsulated into an aspect. Filman and Friedman (Filman et al., 2000) characterize AOSD as a modularization concept with two desirable properties: quantification, which is the ability to declare actions to be applied consistently to many places in a program, and obliviousness, which means that the modified program entities do not need to be aware of being subject to aspect activity and do not need to provide special hooks for enabling such activity. Obliviousness of base code greatly eases evolution, since changes in aspects do not require corresponding changes in base code. However, while base code is oblivious to aspects (or should at least be as oblivious as possible), aspects are not at all oblivious of base programs. Obviously, aspects must know about the base entities that they want to influence. It is the degree of knowledge and implied coupling that has turned out to be a problem in first generation aspect languages – AspectJ (Kiczales et al., 2001), HyperJ (Ossher et al., 2001a), Composition Filters (Aksit et al., 1992), DemeterJ (Demeter) – and later approaches that adopted and evolved one of these archetypes, e.g. AspectC++ (Spinczyk et al., 2002). These languages introduce strong dependencies of aspects on base code by requiring aspects to use concrete names of types, classes, methods, and other entities from base programs. In these languages, the only mechanism to alleviate the dependence of aspects from base entities is the provision of wildcards1 in the pointcut language.2 However, as noted by various researchers (De Volder, Hassoun et al., 2003, Hanenberg et al., 2003a, Gybels et al., 2003, ) the lexical dependencies introduced by wildcard-based pointcut languages negatively influence aspect applicability, conciseness, reuse and evolution. This paper makes the following contributions to the state of the art of aspectoriented language design: − an analysis of the problems with aspect languages based exclusively on wildcard-matching (Section 2 and 3), − a definition of generic aspect languages (Section 4), − a thorough discussion of the design dimensions of generic aspect languages and a classification of current work in this area (Section 5), − a discussion of research challenges imposed by generic aspects (Section 6), 1 In AspectJ, for instance, ‘*’ matches type, method and field names (or parts of them), ‘..’ matches a parameter list, and ‘**’, matches portions of a fully qualified Java type name. 2 The terms crosscut language and pointcut language are used to denote the aspect sublanguage that specifies where and when aspect actions should be executed. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 3 − a classification of existing generic aspect languages with respect to the discussed design options and challenges (Section 7), − a discussion of work related to aspect genericity in aspect languages and other domains (Section 8). The current paper is a significantly extended version of (Kniesel et al. 2005). Besides various improvements of the structure and presentation of the material we have refined our definitions and our taxonomy (Section 4 and 5), added the summary section 7 and extended our discussion to include related work in the area of non-generic aspect languages, logic meta-programming, program transformations, and predicate dispatch for object-oriented languages (Section 8). 1.1. Terminology Before we delve into the sketched topics we first define a few terms that we need to make the following discussion language-independent. Aspect effect. The term aspect effect denotes the changes that an aspect performs on a program or a program execution. Effect specifications are static declarations of such effects. They correspond, for instance, to inter-type declarations in AspectJ (Kiczales et al., 2001), filter types in Composition Filters (Aksit et al., 1992), and composition specifications in HyperJ (Ossher et al., 2001a). An AspectJ advice without the associated pointcut is also an effect specification. Aspect predicate. An aspect predicate is a predicate that selects places in the program or events in the program execution where aspect effects should be applied. Predicates correspond, for instance, to the pointcuts of AspectJ and filter conditions of Composition Filters. Crosscut specification. A crosscut specification is a pair consisting of an aspect predicate and an aspect effect specification. It expresses the crosscutting nature of aspect effects by connecting them to all the places / events where they should occur. Examples of crosscut specifications are filter declarations in Composition Filters, introductions in Sally (Hanenberg et al., 2003a) and advice in AspectJ. Some languages provide a single crosscut specification syntax that can express crosscutting introduction and advice in a unified way (e.g. Josh (Chiba et al., 2004), LogicAJ (Rho et al., 2004, Windeln 2003), and recent versions of Sally). Aspect. An aspect is a module that contains crosscut specifications. In many aspect languages, aspects can also contain base language elements (fields, methods). Base language. A base language is a conventional programming language that has no notion of aspects, crosscut specifications, aspect effects or aspect predicates. For instance, the base language of HyperJ and AspectJ, is Java. AspectC++ has C++ as its base language. The Composition Filter model and its incarnation in the aspect language Compose* has many different base languages. 4 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages Base module. A base module is a module containing only base language elements. The set of all base modules in a program is called the base program. 2. Limitations of Non-Generic Aspect Languages A large class of current aspect languages allows references to base language entities (types, classes, methods, etc.) only via names or via patterns consisting of names and wildcards. We call them wildcard-matching-based languages. This class includes various derivates of AspectJ (e.g. AspectC++, AspectC#) but also different instantiations of the Composition Filters model and HyperJ. The following discussion of the problems arising from the sole reliance on wildcard matching is applicable to all the languages in this category. 2.1. Expressiveness Languages based on wildcard matching cannot express that certain wildcards must match the same value, which limits their applicability. As an illustration of the problem, consider the Eclipse framework. It is organized into public packages that provide stable APIs for a major Eclipse version and internal packages, whose implementation may change in every minor release. Each public package provides an API to a set of internal packages. The Eclipse Internal Package Convention states that an internal package may only be accessed from its public superpackage or from another internal subpackage of its public superpackage (EPNC01). For instance, ‘org.eclipse.platform’ is the public superpackage for all the packages named ‘org.eclipse.platform.internal.*’. Although this is a simple lexical convention, AspectJ cannot express it because it cannot express that different wildcards matching a package prefix must share the same value. This is illustrated in Figure 1. 1 aspect EclipsePackageAccessContract { 2 declare warning : 3 call(* **.internal.**.*.*(..)) 4 && !( within(**.internal.**) || within(**) ) 5 : 6 "The call violates the Eclipse package access contract."; 7 } Figure 1 In order to check the Eclipse Internal Package Convention it would be necessary to express that the underlined wildcards must match the same value. This is not possible with AspectJ. 2.2. Evolvability It has been often pointed out that lexical dependencies make aspects highly sensitive to changes in base programs – see, for instance, (Tourwé et al., 2003) and (Hanenberg et al., 2003b). If names in base programs are changed, the aspects that rely on those names must be changed too. For instance, this is the case if setter methods are described as methods whose name starts with the string ‘set’ and the A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 5 naming convention is changed or abandoned entirely. Therefore, independent evolution of aspects and base programs is not possible in languages based on wildcard matching, except in trivial cases. Tourwé, Brichau and Gybels (Tourwé et al., 2003) call this the aspect evolution paradox because one would generally assume that improved modularity goes together with improved evolvability. 2.3. Conciseness In order to implement a concern that has heterogeneous (that is, similar but not entirely equal) effects on different base code entities, crosscut specifications that are similar up to the used base entity names must be written for every relevant base entity. This makes aspects highly redundant, which is inconvenient for programmers and a source of errors and maintenance problems. We illustrate the conciseness problem of wildcard-matching-based aspect languages by considering ‘class posing’ as an example of a crosscutting concern that requires heterogeneous effects. A class posing statement in Objective C (Pinston et al., 1991) guarantees that henceforth all statements of the program that specify creation of S instances automatically create C instances instead, provided S is a superclass of C. This is very useful for unanticipated object-oriented extension by inheritance.3 A frequent scenario is the use of mock objects (Mackinnon et al., 2002), a common technique for narrowing down the potential sources of a failure during testing. Its essence is the replacement of some of the tested classes by mock classes that provide a fixed, expected behavior. In a language that does not support class posing, the common way to use mocks of a class S is to implement a subclass of S, say C, that provides mock behavior and then replace all instantiations of S with instantiations of C.4 This must be done for all the pairs of original classes and mock classes to be used in a test run. For each pair, it must be done consistently throughout the entire program, not just in the test classes – otherwise the inconsistent simultaneous use of mocks and original objects might itself be a source of errors. An aspect implementing class posing must replace the creation of S instances by the creation of C instances throughout the program. This can be done in AspectJ by an around advice that replaces invocations5 of constructors of S by invocations of constructors of C. However, if S has multiple constructors, we need to repeat the same advice for every constructor, as illustrated in Figure 2. The problem is that there is no way to intercept the values of an unknown number of arguments in the 3 Note that programmers cannot foresee every possible case where ‘class posing’ might be useful in the future. Therefore one cannot assume that the entire program is written following some of the object creation patterns (Gamma). 4 In the related work section we discuss the advantages of this implementation scheme over an alternative one, known as “virtual mock objects”. 5 Replacing the execution of a constructor by an invocation of a subclass constructor would lead to infinite recursion. Therefore, we can only replace constructor calls. 6 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages pointcut and to pass them to the body of the advice. This leads to redundant code that is tedious to write, opens the door for editing errors, and hampers reuse (see Section 2.4). aspect AJ_Replace_S_by_C { // Replace new S(String) Æ new C(String) S around(String arg1) : call(S.new(..)) && args(arg1) { return new C(arg1); } // Replace new S(String,int) Æ new C(String,int) S around(String arg1, int arg2) : call(S.new(..))&& args(arg1,arg2) { return new C(arg1,arg2); } // Continue like this for all other constructors of S... } Figure 2: Heterogeneous aspect effects via redundant code: Replacement of constructor invocations by repeating largely similar advice. 2.4. Reusability A further problem that stems from being dependent on concrete names of base entities is the lack of reusability of aspects (De Volder 2001, Hassoun et al., 2003, Hanenberg et al., 2003a, Gybels et al., 2003). For instance, the aspect from Figure 2 is specific to the classes S and C. It does not implement the class posing concern, it just implements a specific instance of it. It is clearly not reusable, not even for another pair of classes, say X and Y, within the same application. This problem is amplified when trying to write an aspect that is reusable across multiple applications. Then, reliance on base entity names is not possible, unless the aspect programmer knows all of the applications well enough to specify relevant entities by name. 2.5. Safety A more reusable implementation of class posing could be achieved in AspectJ by an around advice using runtime reflection, as illustrated in Figure 3. The advice intercepts all constructor invocations (line 6). For every intercepted invocation it checks whether the constructor belongs to the ‘old’ class and whether the ‘new’ class exists (line 7-21). If both are true, it accesses the dynamic join point context to get the arguments of the intercepted constructor call (line 24-28). Then the auxiliary resolveConstructor method determines via reflection the constructor with the right signature from the new class (line 29-30). Finally, it uses reflection to invoke the A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 7 new constructor with the intercepted arguments (line 31). The primary drawback of this solution compared to the first one is that it cannot detect errors at weave-time. Use of non-existing classes, for instance, will result in unforeseen ClassNotFoundExceptions at run-time. Apart from that, the solution is lengthy, hard to read and error-prone.6 Last but not least, it is also inefficient, since it requires run-time reflection instead of exploiting static information at weave-time, as discussed next. 1 aspect AJClassPosingWithReflection { 2 3 abstract String getOldClassName(); 4 abstract String getNewClassName(); 5 6 Object around() : call(*.new(..)) { 7 Class class = thisJoin point. 8 getSignature().getDeclaringType(); 9 Class newClass; 10 11 // Is this the class to replace? 12 if (!class.getName().equals(getOldClassName()){ 13 return proceed(); 14 } 15 16 // Does new class exist? 17 try { 18 newClass = Class.forName(getNewClassName()); 19 } catch (Exception ex) { 20 return proceed(); 21 } 22 23 // Try replacement 24 Object() args = thisJoin point.getArgs(); 25 try { 26 Class() types = 27 ((CodeSignature)thisJoin point(). 28 getSignature()).getParamtypes(); 29 Constructor constr = 6 30 resolveConstructor (newClass, types); 31 return constr.newInstance(args); 32 } catch (Exception ex) { 33 throw new RuntimeException(“AspectJ:”+ 34 “Instance creation failed“); 35 } 36 } 37 } Figure 3 Heterogeneous effects using runtime reflection in an advice. Constructor invocations are replaced after lengthy, unsafe and inefficient run-time checking of purely static information. The implementation of the method resolveConstructor is not shown here, since it consumes additional 30 lines of reflective code. The complete code of the example can be found at http://roots.iai.uni-bonn.de/research/logicaj/examples. 6 8 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 3. Problem Analysis: Statically Expressing Variation The examples from Figure 2 and Figure 3 illustrate that writing reusable and non-redundant aspect code with AspectJ requires falling back on plain Java reflection, with all the implied drawbacks. Looking at the reflection-based implementation in Figure 3, it is noteworthy that all the reflective advice code, except line 31, is concerned only with determining at run-time information that is entirely static (classes, argument lists, and method signatures). Obviously, wildcardmatching based languages are not expressive enough to capture all the static context of a join point and to parameterize the aspect effects by this context. The need to parameterize aspect effects by the static context of a join point stems from the fact that the effect of an aspect needs to vary depending on this context, as illustrated by the class posing example. The important point here is that the choice of which particular variant of an effect applies at a particular join point should be done at weave-time by the aspect weaver, whenever the variation is completely determined by information available at weave-time. This frees programmers from having to hand-code the different aspect effect variants, in the same way as dynamic binding frees object-oriented programmers from having to manually encode message dispatch to different receiver types. Both cases are about a higher level abstraction that allows to concisely express variant behavior. Dynamic binding expresses dependency of behavior on the message receiver’s type whereas aspect genericity expresses dependency of behavior on the context of a join point. A join point can be seen as the receiver of the aspect’s advice and the join point context can be seen as the advice receiver’s type. Continuing the analogy, the repetitive advice from Figure 2 corresponds to an encoding of message dispatch by type tags and switch statements – each copy of the advice is like a branch of a switch statement that discriminates over the static join point context. The reflective advice from Figure 3 corresponds to a reflective implementation of message dispatch in a non-object-oriented language. What we want instead is to reduce the code from Figure 2 to a single advice that is parametric with respect to the name, arity and parameter list of the intercepted constructor call. Depending on the parameter values, the advice should perform different effects at different join points. For instance, it should perform a C(arg1) constructor call at a join point that matches a S(arg1) invocation and a C(arg1,arg2) constructor call at a join point that matches a S(arg1,arg2) invocation. An example of a generic advice that achieves this is given in Section 5.1.2, Figure 6. Similar observations where made by (De Volder et al., 2000) and (De Volder). They argue that a good aspect-oriented language should provide mechanisms of genericity, polymorphism and parameterization that would allow code to be reusable and to adapt to different contexts. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 9 4. Aspect Genericity In this section we give two definitions of aspect genericity. The first definition says what must be expressible in a generic aspect language. The second one says how it can be expressed. The problem analysis from the previous section identified a desirable property that is lacking in aspect languages based on wildcard-matching: the ability to express variability concisely and safely. This leads us to our first, declarative definition of generic aspect languages: Definition 1 “Generic Aspect Language” (Declarative): An aspect language is generic if its aspects can specify multiple variants of an aspect effect in one single crosscut specification, without falling back on reflection. Meta-variables. In order to express the desired variability we need to be able to parameterize aspect effects by meta-variables. A meta-variable is a variable that ranges over syntactic entities of the base language. For instance, an aspect language based on Java could provide meta-variables that range over packages, types, classes, fields, methods, modifiers, statements, and expressions. In the remainder we will denote meta-variables by identifiers starting with a question mark, e.g. ?class or ?methodBody. Based on meta-variables we can rephrase aspect genericity from a more technical point of view: Definition 2 “Generic Aspect Language” (Technical): An aspect language is generic if it enables the use of meta-variables in aspect effect specifications. This redefinition fulfils the requirement of the initial definition of aspect genericity because meta-variables contained in the aspect effects let the effects vary depending on the meta-variables values. Such aspects provide a concise specification of many different effects. Meta-variables play the role of generic parameters of the aspect and every tuple of values for the meta-variables of an aspect represents one instantiation of the generic effects. We claim that the use of meta-variables in aspect effect specifications is the only way to achieve genericity according to our first definition. Therefore, we consider the two definitions to be equivalent. Our claim cannot be proved formally. However, it is supported by the approaches reviewed in this paper, which are all based on meta-variables in aspect effects. To the best of our knowledge, this is a complete overview of all existing work on aspect genericity. 5. Design Space for Generic Aspect Languages The technical definition of aspect genericity in Section 4 encompasses an entire family of aspect languages that can differ depending on the answers that their designers choose for each of the following questions: 10 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages How values for meta-variables are provided (meta-variable binding)? 2. Where can meta-variables be used (meta-variable scope)? 3. What kind of meta-variables are supported (meta-variable kind)? 4. Over which base entities can meta-variables range (meta-variable domain)? 5. What actions can be performed on the base language entities referred to by meta-variables (effect granularity)? In this section we present these language design dimensions, explain their impact on the expressiveness of a language, and discuss where existing systems fit in these dimensions. Note that this is not meant to be an introduction to the different languages. Please see the referenced papers for details of the discussed languages. 1. 5.1. Meta-Variable Binding Regarding meta-variable binding there are two categories of generic aspect languages: ones that use external parameterization and ones that use predicate based binding. 5.1.1. External Parameterization The simplest way of providing values for meta-variables is to promote the metavariables contained in the aspect effect to parameters of the aspect definition. Then the values can be supplied “from the outside”. This external parameterization is analogous to the way generic types are defined in object-oriented languages where type variables get values when the generic type definition is instantiated by a client. Figure 4 shows an example illustrating the syntax of SuperJ (Sihman et al., 2003), a generic aspect language based on external parameterization. The SuperJ preprocessor creates concrete AspectJ aspects from generic SuperJ aspects by replacing formal parameters by basic variables, locations, and classes. For this it uses a binding file, whose lines each contain a set of bindings between elements of a particular base class and parameters of a particular generic aspect. Similarly, the Lancaster Frame Processor (LFP) (Loughran et al., 2004) provides external parameters for aspect constructs and uses a macro expansion approach that replaces parameter markers in AspectJ code by values provided in an external binding file. LFP supports fine-grained external parameterization (see Section 5.3). Meta-AspectJ (Zook et al., 2004) additionally supports syntactically typed meta-variables that guarantee at compilation time syntactic correctness of generated code (see Section 6). External parameterization decouples the aspect code from concrete names of entities in the base program. Thus, aspects become more reusable, in principle. However, base entity names must still be provided statically in a binding file. In order to provide the suitable bindings of meta-variables to base entities, the creator of the binding file must have intimate knowledge of the generic aspect and of the base classes to which the aspect is applied. This seriously limits the reusability of externally parameterized aspects in practice. In addition, the binding file might A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 11 become very large since its size depends on the number of matches in the base program, which can grow combinatorially with the size of the base program. Manually editing large numbers of matches can be the source of omissions, typos and other input errors that will lead to hard to locate errors at run-time. Figure 5 sketches the start of a binding file7 necessary to express class posing via external parameterization. Its purpose is to enumerate all combinations of values for the required meta-variables (?className, ?subName and ??args). Compare this to the solution using predicate-based binding shown below in figures 6 and 7.. aspect Constant_DPP_Heavy(?EAT_METHOD, ...) extends Common { ... void around(?BOUND_CLASS C) : execution(?EAT_METHOD) ... { ... forks = 0; nAssigns++; logRecord(); } ... } Figure 4 Excerpt of externally parameterized generic SuperJ aspect adapted from (Sihman et al., 2003, Figure 6). For consistency with the notation used in our paper, prepended question marks denote generic parameters whose values can be provided when the aspect is instantiated. bindings_for(?className, ?subName, ??args): // All combinations for C and S: ( “C”, “S”, “arg1:String”) ( “C”, “S”, “arg1:String,arg2:int”) ( “C”, “S”, “arg1:String,arg2:int,arg3:T”) ( “C”, “S”, “arg1:String,arg2:int,arg3:T,arg4:T4”) // All combinations for C1 and S1: ( “C1”,“S1”,“arg1:T1”) ( “C1”,“S1”,“arg1:T1,arg2:T2,arg3:int”) ( “C1”,“S1”,“arg1:T1,arg2:T2,arg3:int,arg4:T4,arg5:T5”) // All other combinations: ... ; || || || || || || || Figure 5 External parameterization: Start of the listing of all tuples of relevant values for the meta-variables required to express the class posing concern for one particular base program (see Sections 2.3 and 5.1.2 for comparison). 7 Since the original literature does not describe the binding file contents in detail, we invented our own ad-hoc syntax. Arguments are described by their name and type. 12 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 5.1.2. Predicate-based binding A much more powerful alternative to external parameterization is provided by predicate-based meta-variable binding. The idea is to replace manual enumeration of statically known values by weave-time evaluation of predicates that bind metavariables to statically unknown values from the base program. In this approach the aspect predicates (or pointcuts) play a double role: they select join points where aspect effects are to be applied and they bind meta-variables to values from the static context of the selected join points. Andrew / Carma (Gybels 2001) is an aspect-oriented extension of Smalltalk that lets meta-variables ranging over arbitrary values be used in pointcuts and advices. OReA, (D’Hondt 2004, D’Hondt et al., 2004) extends this to hybrid aspect languages, based on the integration of aspects with rules. AspectC++ (Lohmann et al., 2004) enables the use of type variables in pointcuts and advice bodies. Silaghi and Strohmeier (Silaghi et al., 2003) propose the same for AspectJ. Sally is an aspect-oriented extension of Java. Its design described in (Hanenberg et al., 2003a) supports meta-variables in pointcuts and introductions. Since its November 2005 release Sally also supports meta-variables in advice. LogicAJ (Rho et al., 2004) is an aspect-oriented extension of Java that has supported meta-variables in pointcuts, introductions and advice from its first release (Windeln 2003). Logic variables. In order to enable predicate based binding, meta-variables must be used in the entire scope of a crosscut declaration, that is, in aspect effect specifications and in aspect predicates. Like wildcards, meta-variables in aspect predicates are used as placeholders for statically unknown parts of a logic expression. They can match arbitrary structures when the predicate is evaluated. However, they are strictly more powerful than unnamed wildcards. Meta-variables provide the ability (1) to express that different occurrences of the same placeholder must agree on the matched value and (2) to use the matched values as a building block of associated effect specifications. Both abilities depend on the guarantee that different occurrences of a metavariable in the scope of a crosscut declaration represent the same matched value. Variables that have this property are called logic variables. A logic variable can only be bound to a value by the evaluation of predicates that take the variable as an argument. Logic variables cannot be manipulated in other ways (by assignments / side-effects). Upon evaluation of an aspect predicate the tuple of logic variables that it contains is bound to the tuple of values for which the predicate is true. Such a tuple is said to be a successful substitution of the logic variables. A predicate that has multiple solutions successively yields multiple substitutions. For instance, assume an aspect language whose predicate field(?F,?C) expresses that the field represented by ?F is a member of the class represented by ?C. For a program that contains the field c1 and c2 in class C, and b1 in class B the evaluation of the query class(?F,?C) will successively bind the tuple <?F,?C> to <c1, C>, <c2, C> and <b, B>. Every suc- A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 13 cessful substitution triggers an execution of the associated aspect effect specification during which the logic variables are replaced by the corresponding substitution values. Logic meta-variables. A logic meta-variable is a logic variable and a metavariable. The variables ?F and ?C in the above example are logic meta-variables because are logic variables that ranges over syntactic entities of the base language. Note that logic meta-variables are not specific to systems based on logic programming. They are commonly used, albeit in restricted forms, in object oriented and aspect-oriented languages. For instance, generic type parameters in Java, Eiffel or C++ are just strongly restricted logic meta-variables. They are logic variables because they always represent the same value within a scope (cannot be explicitly assigned to). They are meta-variables because they range over base language entities. However they are subject to two restrictions: they only range over types and their values are provided manually by specifying constants at instantiation time, instead of being bound by the evaluation of predicates. Indeed, even wildcards in aspect predicates (‘pointcuts’, ‘filter conditions’, etc.) can be seen as a very restricted form of logic metavariable. The restriction is that, strictly speaking, wildcards are not proper meta-variables. They range not over base language entities but just over strings that are the names of base languages entities. They are additionally restricted because they are unnamed – two occurrences are always treated as being different. De Volder (de Volder1999) points out that this leads to a set-oriented semantics of aspects and shows why a more powerful relational semantics is needed. The fact that the evaluation of a pointcut is side-effect free and yields all matching values for contained wildcards is familiar to every aspect programmer. Filman and Friedman (Filman et al., 2000) call this ‘quantification’ and regard it as a basic characteristic of aspect languages. Acknowledging that wildcards are restricted logic meta-variables we could say that the use of logic meta-variables is a basic characteristic of aspect languages. In the following we will explore the added expressiveness that can be achieved by removing the restrictions imposed by wildcards and supporting the full power of logic meta-variables. Example. We illustrate the power of predicate-based binding of logic metavariables by the generic implementation of the concept of class posing introduced in Section 2. The implementation in Figure 6 uses the syntax of LogicAJ (Rho et al., 2004, Windeln 2003): Logic meta-variables are denoted by names starting with a question mark, e.g. “?class”. Identifiers starting with a double question mark, e.g. “??args”, denote list meta-variables. They can match an arbitrary number of elements, e.g. any number of call arguments or method parameters (see Section 5.4). The pointcut of the advice in Figure 6 (line 7-14) binds the meta-variables ?sub and ??args to values that conform to all the constraints checked in the pointcut. These values are passed to the advice body. Every pair of values produced by the 14 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages pointcut evaluation instantiates the body in a different way. The instantiated body is then executed. Let us see how this works in the scenario from Figure 2, with the original superclass S and its subclass C having each four constructors. If the replace pointcut returns the bindings ?class = S and ?sub = C, then the check in line 11 succeeds and the call pointcut in line 13 successively selects all join points where constructors of S are called. For each intercepted join point the args pointcut in line 15 binds ??args to the list of constructor argument values at that join point. Thus the advice body will be executed multiple times, with ?sub always bound to C and ??args bound differently each time. As a result, it will perform a C(arg1) constructor call at a join point that matches a S(arg1) invocation and a C(arg1,arg2) constructor call at a join point that matches a S(arg1,arg2) invocation. 1 abstract aspect ClassPosing { 2 3 // To be defined in a subaspect (See Figure 7): 4 // Who poses for whom? May return multiple pairs of values. 5 abstract pointcut replace(?class,/*by*/?sub); 6 7 Object around(?sub, ??args) : 8 // Determine replaced class and replacing class: 9 replace(?class, /*by*/?sub) && 10 // Check if ?sub is a subclass of ?super: 11 subtype8(?sub,?class) && 12 // Intercept ?super constructor invocations 13 call(?class.new(..)) && 14 // Bind ??args to the argument list of the invocation: 15 args(??args) 16 { // Return instance of posing subclass ?sub (includes 17 // weave time check that the constructor exists): 18 return new ?sub(??args); 19 } 20 } Figure 6: Implementation of class posing in LogicAJ. The aspect replaces each call of a constructor from ?class with a call to the respective constructor of the posing subclass, if the subclass exists. Comparison. It is instructive to compare the reflective example from Figure 3 to the generic one from Figure 6. Most of the code in Figure 3 is concerned with determining whether the intercepted join point was relevant at all, determining its arguments, finding the constructor with the right signature from the new class, and invoking it with the intercepted arguments. In the variant from Figure 6 only the relevant join points are intercepted, their specific context information is captured in meta-variables and used at the appropriate places of the aspect effect. The generic 8 The subtype predicate expresses the (reflexive, transitive) subtype relation. If called as above – with all meta-variables bound to values by a previous predicate – it will just check that the values are in a subtype relation. Otherwise it will successively bind the free variables to suitable pairs of values. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 15 aspect from Figure 6 has the same effect as the redundant code from Figure 2 and the reflective one from Figure 3. However, it is − precise (only the relevant join points are processed), − efficient (no run-time weaving is required), − safe (it provides weave-time type checking), − concise (just 7 lines of non-redundant code), and − reusable (applying it to other classes or entirely different base programs requires just another implementation of the replace pointcut in a concrete subaspect). The last two benefits don’t apply for externally parameterized aspects because of the need to provide a manually generated binding file for every base program to which the aspect is applied. For instance, the abstract replace pointcut in Figure 6 subsumes an explicit parameterization of the entire aspect with the meta-variables ?className, ?subName and ??args. With predicate-based binding there is no need for an explicit enumeration of all possible bindings because these can be expressed concisely by stating the properties of base entities to be bound to the meta-variables. Figure 7 shows a concrete subaspect of the class posing aspect from Figure 6. Its definition of replace selects all the classes that have mock subclasses in any base program (Rho et al., 2004). See for comparison the binding file from Figure 5, which enumerates all the values for ?className, ?subName, and ??args for one particular base program. 1 2 3 4 5 6 7 8 9 10 aspect MockObjectConcern extends ClassPosing { // The mock replaces the orginal class. pointcut replace(?class, /*by*/ ?mock): // Pick a class: class9(?class, _10, ?className,_) && // Its mock class must have the suffix “Mock”: concat11(?className, "Mock", ?mockName) && class(?mock, _, ?mockName,_) ; } Figure 7 Predicate-based meta-variable binding: An aspect concisely defining class posing for mock classes, assuming that every class to be tested has a single mock class that defines all its mock behavior. 5.1.3. Other Alvarez (Alvarez 2004) proposes to extend AspectJ by string-valued parameters for the names of types, methods or fields. This proposal is called parametric This use of the class predicate says that ?class is a class with simple name ?className. Underscores are anonymous meta-variables. 11 The third argument of concat is the concatenation of the first and second one. 9 10 16 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages aspects. Parameter values must be provided by enumeration or by parametric expressions. These are functions on the class hierarchy that are evaluated at weave time and may yield a set of program element names. The proposal is not implemented. Parametric aspects look like a mix of explicit external parameterization and predicate-based binding. However, they do not achieve the full functionality of predicate-based binding. In particular, it is not possible to relate different parametric expressions. Instead, the entire cartesian product of different parametric expressions is created as a result. For instance, one can create a parametric expression that selects fields and one that selects classes, but one cannot express that one wants only those pairs of fields and classes for which the field is an element of the class. In the example given in the explanation of logic variables (Section 5.1.2) the result would also contain the wrong tuples <c1, B>, <c2, B> and <b, C>. We consider this a flawed design. Therefore, it is not included in the overview of generic aspect languages in Table 1 and Table 3. 5.2. Meta-Variable Scope Different languages use meta-variables in different ways and for different purposes, depending on the scope in which meta-variables can be used. In this section we discuss the available options and their implications. The definition of generic aspect languages requires meta-variables to be used in aspect effects in order to enable effect variability. It is up to aspect language designers to decide (1) whether meta-variables are confined to effects or are additionally supported in aspect predicates and (2) whether meta-variables can be used in all kinds of aspect effects or just in some of them. Use of meta-variables in aspect effects and in their associated pointcuts enables predicate-based binding (see 5.1.2). However, some languages do not take full advantage of this option. For instance, SuperJ (Sihman et al., 2003) and LFP (Loughran et al., 2004) only support external parameterization, although metavariables may be contained in their predicates. Their predicates can only check externally provided values but cannot bind meta-variables to values. Other languages support predicate-based binding but limit the use of meta-variables to a subset of the aspect effects expressible in the respective language. Some support only advice containing predicate-bound meta-variables – we call this generic advice. Others only support introductions containing predicate-bound metavariables – we call these generic introductions. For instance, Andrew12 (Gybels 2001) and OReA, (D’Hondt 2004, D’Hondt et al., 2004) only support generic advice, whereas the initial design of Sally (Hanenberg et al., 2003a) supported only generic introductions. 12 Andrew has since been renamed to "Carma", see prog.vub.ac.be/~kgybels/Research/. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 17 Such restrictions limit the expressiveness of a language, since most non-trivial applications require the joined power of introductions and advice. For instance, Kniesel, Rho and Hanenberg (Kniesel et al., 2004) analyze design patterns as a typical use case for generic aspect languages. They show that a language without generic advice (1) cannot express instantiation of the decorator pattern for multiple Component classes, (2) cannot enforce that all clients use the decorator instead of the original component, and (3) cannot implement object based inheritance as a generalization of simple decorators. Furthermore, they show that a language without generic introductions cannot create decorators at all, since it cannot fill them with the required forwarding methods. External Parameters Meta-variable values bound by Introductions only Externally parameterized introductions: — Generic Introductions: Predicates (Hanenberg et al., 2003a) Meta-variables used in … Advice only All effects Externally Uniform external parameterized advice: parameterization: (Sihman et al., 2003) — (Zook et al., 2004) (Loughran et al., 2004) Uniform Genericity: Generic Advice: (Gybels 2001) (Windeln 2003) (Silaghi et al., 2003) (Rho et al., 2004) (D’Hondt et al., 2004) (Lohmann et al., 2004) (Hanenberg et al., 2003a)13 Table 1 Design subspace for generic aspect languages defined by the options for meta-variable binding and meta-variable scope. The table shows where known languages fit within this space. The symbol “—” indicates an empty category. Uniform Genericity. Summarizing the considerations of Sections 5.1 and 5.2 we can conclude that for maximum expressiveness a language should (1) support predicate based binding of logic meta-variable values and additionally (2) enable use of logic meta-variables in all aspect predicates and all aspect effects. A language that does this is said to provide uniform genericity. Uniform genericity is clearly the most powerful option in the design space discussed so far and summarized in Table 1. Currently, we know of only two uniformly generic aspect languages: LogicAJ (Rho et al., 2004, Windeln 2003) and Sally (Hanenberg et al., 2003a).13 It appears that the Andrew / Carma (Gybels 2001) prototype, which extends SOUL (Wuyts 2001, SOUL 2003) by generic advice, could be extended to support also generic introductions, taking advantage of the reflective facilities of Smalltalk and of the 13 The version of Sally described in (Hanenberg et al., 2003a) only supports generic introductions. However, as of its November 2004 release, Sally also provides uniform genericity – see http://dawis.informatik.uni-essen.de/site/site/research/aosd/sally/. 18 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages logic inference engine of SOUL. However, Gybels decided not to do so, considering introductions to be just a by-product of the lack of support for explicit aspect instances in more static aspect languages (Gybels 2001, Section 5.1.5). Similar considerations apply for the second SOUL-based aspect language, OReA, (D’Hondt 2004, D’Hondt et al., 2004). It implements the concept of hybrid aspect languages based on the integration of aspects with rules. Its concept of hybrid advice is a hybrid language’s instance of generic advice. Like Andrew, OReA does not support introductions but could be extended accordingly. Suitable extensions of these two languages would qualify as uniformly generic. 5.3. Meta-Variable Domain Table 1 does not yet provide a sufficiently fair comparison of existing generic aspect languages since it does not reflect their significant differences with respect to the domain of meta-variables. The variants of generic advice proposed by Silaghi and Strohmeier (Silaghi et al., 2003) for AspectJ and by Lohmann, Blaschke and Spinczyk (Lohmann et al., 2004) for AspectC++ let meta-variables range over types only. They mimic type genericity of object-oriented languages in a generic aspect language but do not achieve context-dependent variability of behavior14. The other approaches in Table 1 are more expressive, letting meta-variables additionally range over behavioral base language elements. Carma, Sally and SuperJ support meta-variables for (the names of) types, fields, and methods. LogicAJ 1.x additionally provides meta-variables ranging over code blocks but only supports their use for matching entire method bodies. Fine-grained genericity. Various researchers have pointed out that this is still insufficient for modularizing certain cross-cutting concerns. For instance, program optimization (Harbulot et al., 2004, Harbulot et al., 2005) and code-coverage (Rajan et al., 2005), can only be modularized if aspects are able to address base language entities at the finest level of granularity: individual statements and expressions. Extension of this idea to generic aspect languages leads to the notion of fine-grained meta-variables. We say that a language supports fine-grained meta-variables if its meta-variables can range over all syntactic entities of the respective base language. In Java, this would cover the entire spectrum from packages, types, methods and fields, down to annotations, statements and expressions. A language supports finegrained genericity (fine-grained external parameterization) if it supports finegrained meta-variables and predicate-based binding (external parameterization). 14 In C++ one could use template meta-programming but this fallback to reflection by the application programmer is not to be confused with functionality supported by the language itself (see Definition 1 in Section 4). A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 19 The Lancaster Frame Processor (Loughran et al., 2004) and Meta-AspectJ (Zook et al., 2004) support fine-grained external parameterization. LogicAJ 2 (Rho et al., 2006) is the first proposal for fine-grained genericity. 5.4. Meta-Variable Kind The example from Figure 6 illustrates the distinction between two kinds of metavariables: singular meta-variables and list meta-variables. Singular meta-variables match only one base language element at a time, e.g. a type, field, etc. With singular meta-variables only, we are still forced to write sometimes redundant code that differs only in the length or depth of a nested structure, e.g. in the number of arguments of a method. This is clearly undesirable and limits the expressive power, since it is practically infeasible to enumerate an infinite number of arbitrary length structures. Therefore, Josh (Chiba et al., 2004) and LogicAJ (Rho et al., 2004, Windeln 2003) and additionally provide list meta-variables that match a sequence of elements from the base language. Josh supports the $$ list meta-variable that can be used in a proceed call to match an arbitrary list of arguments. LogicAJ supports list meta-variables wherever structures of statically unknown length or depth must be matched in aspect predicates or generated in aspect effects. Examples are argument and parameter lists and the statements in a block. The concise implementation of class posing from Figure 6 would not be possible without the list meta-variable ??args. Some languages, for instance Sally (Hanenberg et al., 2003a), only support one kind of meta-variables but allow them to match indiscriminately singular values and list values. We call these hybrid meta-variables. Hybrid meta-variables do not allow to distinguish syntactically conditions where exactly one value is required (?x) from those where a (possibly empty) sequence of values is required (??x). However, this distinction can alternatively be expressed by additional predicates for checking that a meta-variable is a list and for accessing the different elements of the list. Another sensible design alternative is to subsume the distinction of metavariable domains and meta-variable kinds in the concept of syntactic types for metavariables (see Section 6). The syntactic type of a meta-variable would indicate the number and domain of base language elements that may be matched by a particular meta-variable. Currently, syntactic typing is supported only by the externally parameterized aspect language Meta-AspectJ. 5.5. Effect Granularity Within a class of languages that have the same meta-variable domains it is interesting to compare whether all possible effects (e.g. variants of introductions and advice) can indeed be performed on all supported meta-variable domains. For 20 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages instance, Sally allows meta-variables for types, methods and fields but only allows introduction of methods and fields. LogicAJ does not restrict the effect granularity in any way. In particular, it also supports generic type introductions – that is the generic creation of a set of types, whose names are not statically fixed in the aspect code (Rho et al., 2004). This is very useful in many scenarios that require generative capabilities. An example is the generic creation of abstract decorator classes that are specific for a particular type of decorated objects. The following code from (Kniesel et al., 2004, Figure 5) creates a decorator for a specific component type, declares it to be a subtype of ?component and provides it with an instance variable parent of type ?component to which messages can be forwarded. 1 2 3 4 5 6 7 introduce abstractDecorator(?component, ?decorator) : component(?component) && decorator(?decorator) { abstract class ?decorator implements ?component { protected ?component parent; } } Figure 9 Generic type introduction The concept of generic type introductions falls out from the uniform granularity of pointcuts and effects supported by LogicAJ. The above example demonstrates that uniform granularity increases the expressiveness of a language. In addition it simplifies its specification, implementation and learning since it frees designers, implementers and users from having to deal with special cases. 6. Challenges for Generic Aspect Languages The previous section has identified design dimensions for aspect genericity and has discussed the options reflected in existing languages. Now we turn to open problems of generic aspect languages, focusing on those that are typical of aspect genericity or harder to address in conjunction with generic aspects. Fine-grained genericity. Within the discussed design dimensions the combination of uniform and fine-grained genericity is addressed by a single approach (Rho et al., 2006). Lacking alternative proposals and experience reports it is still unclear whether this proposal is indeed a good design for a language that integrates uniform and fine-grained genericity. In addition, fine grained genericity might impose new challenges for the implementation of aspect languages. Modular, static analysis versus global, weave-time analysis. One of the advantages of generic aspect languages over run-time reflection is their ability to perform weave-time type checking. During weaving, all meta-variables get concrete values (either via external parameterization or by evaluation of pointcut decalrations). As soon as the value of the meta-variables are known all expressions in the A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 21 body of an advice can be type-checked. For instance, if we know that the value of ?metaVar is the class C, we know that the expression ?metaVar.m() is a class method invocation and can check whether C contains a class method m with empty parameter list. However, weaving is a global process that requires a complete program as its input, rather than a partial one. Various researchers have pointed out that more modular analysis of aspect code would be desirable. In a modular approach, it would be possible to analyze aspect definitions in isolation, before weaving. Therefore we also call it static analysis (in contrast to weave-time analysis). Modular, static analysis is a largely unsolved challenge, even for non-generic aspects. In the presence of meta-variables static analysis is even more difficult because we need to verify program properties at a time when concrete meta-variable values are not yet known. In such a case, an expression like ?metaVar.m() cannot be checked with traditional techniques because we cannot even determine its syntactic category. If the meta-variable value is a class, the expression is the invocation of a class method. However, if the meta-variable value is a field, the expression is the invocation of an instance method of that field’s type. Modular static verification of aspects in such a setting involves, at least, three challenges: syntactic typing, semantic typing and interference detection. Syntactic typing. Static verification of uniformly generic aspects should ensure, at least, that code using meta-variables is syntactically correct. For instance, one would like to prevent substitution of classes where fields are expected and viceversa. This means that meta-variables need to be syntactically typed, that is every meta-variable must have a type that determines the kind of syntactic entity from the base language that may be substituted. Syntactic types can either be declared or inferred from the definition of the predicates that are used to bind the respective meta-variable values. Syntactic typing enables modular, static checking whether values substituted for meta-variables in aspect effects will always produce legal base language programs. Meta-AspectJ (Zook et al., 2004) is the first external parameterization approach that supports syntactically typed meta-variables, guaranteeing syntactic correctness of generated code at compilation time. The type check is based on type inference. Meta-AspectJ is fine-grained, its meta-variables range over all syntactic elements of AspectJ. We know of no published generic aspect language with predicate-based binding that supports syntactic typing. Semantic typing. In addition, we need a second level of typing, in order to determine also the base language type that a meta-variable will take on. We call this the semantic type of the meta-variable because it refers to the type notion defined in the static semantics of the base language. For instance, for our above invocation of m() we need to know whether ?metaVar is guaranteed to be bound only to base language elements whose base language type contains the method m(). 22 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages Interference detection. Last but not least, as long as we know neither the semantic nor the syntactic type of a meta-variable, let alone the precise entity to which it will be bound at weave-time, aspect interference checking becomes much harder than it already is in non-generic aspect languages. Performing modular interference analysis for generic aspects is a challenge that has not yet been addressed by any published paper that we know of. 7. Generic Aspect Languages – A Quick Overview In this section we categorize the generic aspect languages introduced in the previous sections according to their position in the design space discussed so far. Table 2 recalls the design dimensions for meta-variable binding (Section 5.1), scope (Section 5.2) and domain (Section 5.3) and illustrates the design space corresponding to the identified ‘optimal’ choices assuming an aspect language that supports pointcuts, advice and introductions and a base language that has types, methods, fields, statements and expressions. Every entry in the table names the respective part of the design space. Because predicate-based binding is the optimal choice in the binding dimension (see Section 5.1), uniform, fine-grained genericity is the cumulated optimum in all three dimensions. Currently, the only proposal in this category is (Rho et al., 2006). The meta-variable kind dimension is not included in the table because we could not identify a clear optimum. The effect granularity dimension has an optimum but is not included since it is hard to visualize in a two dimensional space. pointcut Binding External parameterization Predicate-based binding Scope advice introduction Uniform external parameterization Uniform genericity Domain method / statement / field expression Fine-grained external parameterization type Fine-grained genericity Table 2 Design space for meta-variable binding, scope and domain. Table 3 categorizes existing generic aspect languages according to their position in the design space discussed so far. The languages are grouped by their approach to meta-variable binding (Section 5.1). The columns reflect the choices for scope (Section 5.2), domain (Section 5.3) and typing (6). Only one approach supports syntactic typing. Static semantic typing is not yet supported by any of the surveyed languages. Interference detection and resolution is not included in the table since we found no related information in any of the reviewed papers. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 23 8. Related Work Our overview shows that there have been many, partly similar and partly highly differing proposals for generic aspect languages. However, to the best of our knowledge, there has been no comprehensive overview of the various proposals so far. In particular, we know of no previous attempt to provide a definition of aspect genericity that unifies all these approaches while still drawing a clear distinction to non-generic aspect languages. While there is no immediately related work in this sense, there are a number of interesting parallels of generic aspects in general to work in the area of logic meta-programming, non-generic aspect systems, program transformations, and dispatch in object-oriented programming. Although AspectJ 5 uses the term “generic aspects” it is not a generic aspect language according to any of the definitions given in Section 4. Without using reflection it does not achieve effect variability and does not allow the use of type variables in pointcut expressions and type patterns (AspectJ 2005). The “generic aspects” of AspectJ 5 just enable use of the Java 5 genericity syntax within aspect code. The problem of hard couplings and dependencies between aspects is also analysed in (Hassoun et al., 2003). In order to increase aspect reusability, Hassoun and Constantinides propose a language framework based on run-time reflection. This does not comply with our definition of genericity. Various proposals in the context of aspect-oriented logic meta-programming (AOLMP) have shown that some of the dependencies of aspects on base programs discussed in Section 2 can be alleviated by the use of a logic-based pointcut language, e.g. (De Volder), (Gybels 2001), (Gybels et al., 2003). However, most AOLMP research confines the scope of meta-variables to aspect predicates. The resulting logic-based pointcut languages let aspect predicates implement powerful analyses of base programs but do not achieve genericity. Aspect genericity requires meta-variables to be used in aspect effects in order to enable effect variability. Meta-variable pointcut External parameterization SuperJ 9 LFP 9 Meta-AspectJ 9 Predicate-based binding Better Generative 9 Programming AspectC++ 9 15 Scope advice Domain Typing method / statement / syntactic / field expression semantic introduction type 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9/ – 9 – 9 – – 915 9 – 9 – – 915 – Trivial, because meta-variables can only be bound to types in this approach. – – 24 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages Carma OReA Sally LogicAJ 1.x LogicAJ 2 9 9 9 9 9 9 9 – – – 16 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 – – – – – – – – 917 –16 / – Table 3 Classification of existing generic aspect languages. De Volder, Tourwé and Brichau (De Volder et al., 2000) and DeVolder (De Volder) argue that a good aspect-oriented language provides mechanisms of genericity, polymorphism and parameterization that would allow code to be reusable and to adapt to different contexts. This is fully in line with our problem analysis. There has been much work on program transformation systems and on their relation to aspect-oriented programming. The following systems fall into this category. On one hand, they cannot be considered generic aspect languages because they don’t provide certain language features that are typical of aspects. On the other hand, they are more expressive than aspect languages and are typically used to build an aspect layer on top of them. TyRuBa, de Volder’s Typed Rule Base language (De Volder 1998) introduces logic meta-programming for Java programs. All block elements of the base program are represented as quoted Java code within the TyRuBa rules. The quoted code logic may contain meta-variables for types and identifiers. Both kinds of variables are explicitly typed. Quoted code terms allow for easy manipulation of source code templates. Using the logic inference-engine, it is possible to generate complete programs by composing such templates. Quoted code terms can only be used as a template for generating Java code but not in the query language. SOUL, the Smalltalk Open Unification Language (Wuyts 2001, SOUL 2003), is a reflective logic meta-programming system based on Smalltalk that incorporates and extends the concept of quoted code terms of TyRuBa. Compared to TyRuBa, SOUL achieves a much tighter and more dynamic integration of the logic inference engine with the execution of quoted code terms, blurring the distinction between code generation and code execution. Both can be seamlessly done ‘on the fly’, in the typical style of dynamic languages. SOUL is the basis for the two generic aspect languages Andrew / Carma (Gybels 2001) and OReA, (D’Hondt 2004, D’Hondt et al., 2004), reviewed in Section 5 and 7. Both languages support generic advice (see concluding discussion in 5.2). Stratego/XT (Visser 2004, Visser 2002) is a framework for the development of software transformations systems. It enables arbitrary transformations of source 16 17 Supported but yet unpublished. Proposal in (Rho et al., 2006). A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 25 code, based on rewriting strategies. Transformations are described as conditional term rewrite rules. The XT tools provide generators for parsers and source code pretty printers. The rewrite rules transform the AST of the parsed source code, supporting source patterns and meta variables. This is not quite the same as an aspect language, although interesting analogies to aspects exist. A thorough comparison of strategic and adaptive programming is presented in (Lämmel et al., 2003). (Kalleberg et al., 2005) shows how to achieve aspect behaviour with Stratego. Castor and Borba (Castor et al., 2001) introduce JaTS, the Java Transformation System, which allows pattern based program transformations. The structure of target programs is described by base language code enriched by logic meta-variables that act as placeholders. The transformation specification is described with another code pattern containing meta-variables. The obvious advantage of code patterns is the avoidance of the need to design and learn an artificial predicate language. The disadvantage is the inability to specify conditions without implicitly specifying also a certain textual order of elements. This makes it impossible to express recursive conditions and very hard to express non-recursive ones that span multiple classes. Spoon (Spoon 2006) is a program transformation tool based on the annotation processing facilities and the type genericity of Java 5. Meta-variables that range over types are translated to Java generic types, ensuring proper type-checking by the Java compiler. This basic functionality is used to provide an annotation-based AOP layer, Spoon / AOP (Pawlak 2005). It requires no language extension to Java,18 which is often an advantage in practice. A restriction that Spoon / AOP shares with all approaches based on Java’s annotation facility is the inability to support finegrained aspects and fine-grained genericity.20 Since Spoon and Spoon AOP have been released only recently21 and information about many details is still lacking, we cannot precisely assess where this system fits in our taxonomy. In Section 3 we have explained the analogy of generic aspects to dynamic binding. That discussion implicitly assumed predicate-based meta-variable binding. Achieving varying behavior via predicate based binding is strongly reminiscent of the concept of predicate dispatching proposed for object-oriented languages by Ernst, Kaplan and Chambers (Ernst et al. 1988). Doug Orleans (Orleans 2001) shows that a simple extension to predicate dispatching can support separation of cross-cutting concerns, which is one of the goals of aspect-oriented programming. However, he notes that “another goal is the modularization of cross-cutting 18 Therefore it is not listed in our overview of generic aspect languages in Section 5 and 7. The documentation at http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html specifies that annotation types “are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types”. 20 Annotations can only be added to declarations, not to statements or expressions (see http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html). 21 First public announcement and release in February 2006. 19 26 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages concerns, which is more than just separation; modularizing predicate dispatch methods is an active area of research”. We claim that predicate-based meta-variable binding in generic aspects is modularized predicate dispatch. We see it as the next level of a unified theory of dispatch, stepping from locally inlined dispatch predicates to extracted and modularized ones. 9. Conclusions In this paper we have reviewed the needs, design options and technical challenges related to generic aspect languages. This includes a comprehensive overview of the various proposals for generic aspect languages and a first definition of aspect genericity that unifies all these approaches while still drawing a clear distinction to non-generic languages. We started from an analysis of the limitations of non-generic aspect languages regarding, evolvability, expressiveness, conciseness, reusability and type safety. The common cause of the identified problems is the reliance of aspects on concrete names of base program entities and wildcards. This makes aspects highly susceptible to changes of base code and prevents statically expressing contextdependent variation of aspect effects. We defined generic languages as those that are able to express the desired variation and identified the ability to use meta-variables in aspect effects as their common technical essence. Our review of existing and proposed generic languages revealed five basic questions that language designers must consider when extending their aspect language towards genericity: − How are the values of meta-variables provided (meta-variable binding)? − Where can meta-variables be used (meta-variable scope)? − Over which base entities can meta-variables range (meta-variable domain)? − What kind of meta-variables are supported (meta-variable kind)? − What actions can be performed on the base language entities referred to by meta-variables (effect granularity)? With respect to the first three design dimensions we were able to identify predicate-based binding, uniform genericity and fine grained genericity as the most expressive design options. Predicate-based binding frees programmers from having to hand-code different aspect effect variants, in the same way as dynamic binding frees object-oriented programmers from having to manually encode message dispatch to different receiver types. Reaching beyond the current state of the art we have discussed two main challenges for future generic aspect languages: the development of modular static analysis techniques for generic aspects and a combination of uniform and fine grained genericity that goes beyond the first approach in (Rho et al., 2006). A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 27 10. Acknowledgements We want to thank the anonymous referees of JFDLPA 2005 for thorough proofreading of an early version of this paper and many encouraging but also critical remarks that showed us how it could be improved. Stimulating discussions with the participants and the excellent organization by Lionel Senturier made JFDLPA a rewarding event. We are indebted to Laurence Duchien, Renaud Pawlak, and Mireille Blay-Fornarino for an interesting day of mutual exchange of experience at LIFL. Discussions with Maja d’Hondt, Kris Gybels and Johann Brichau helped us understand better how SOUL, Carma and OreA relate to uniform genericity. Our numerous meetings and sometimes deeply philosophical discussions with Stefan Hanenberg about the very essence of aspects and the relation of Sally to LogicAJ have been challenging, enlightening and fun. Our work benefited from its embedding in the ideal environment of senior guidance by Prof. Armin B. Cremers and enthusiastic help by our colleagues and students in the ROOTS group – Daniel Speicher, Malte Appeltauer, Mark Schmatz, Lukas Degener are just the tip of the iceberg. Last but not least, we are grateful to Julia Lawall for her knowledgeable and thoughtful shepherding. Her numerous up-to-the-point comments and constructive suggestions have considerably shaped this paper. 11. References Aksit M., Bergmans L., Vural S.: “An Object-Oriented Language-Database Integration Model: The Composition Filters Approach”, ECOOP 1992 proceedings, SpringerVerlag, 1992. Alvarez J.: “Parametric Aspects: A Proposal”. Proc. of ECOOP'2004 Workshop on Reflection, AOP and Meta-Data for Software Evolution, March 2004. The AspectJ Team: The AspectJ 5 Development Kit Developer's Notebook, http://www.eclipse.org/aspectj/doc/released/adk15notebook/generics-inAspectJ5.html, Feb. 2005. Castor F., Borba P., “A Language for Specifying Java Transformations” V Brazilian Symposium on Programming Languages, Curitiba, Brazil, 23rd-25th May 2001, pages 236-251. Chiba S., “Load-time structural reflection in Java”, in ECOOP 2000 proceedings, LNCS 1850, pp. 313–336, Springer-Verlag, 2000. Chiba S., Nakagawa K.: “Josh: An Open AspectJ-like Language”, in AOSD 2004 Conference Proceedings, pp. 102-111, ACM Press, 2004. Compose* Homepage: http://composestar.sf.net/ Demeter/Java Homepage: http://www.ccs.neu.edu/research/demeter/releases de Volder K., Type-Oriented Logic Meta Programming, Ph.D thesis, Vrije Universiteit Brussel, 1998, Brussels. de Volder K.: Type-Oriented Logical Meta Programming, PhD thesis, Vrije Universiteit Brussel, Belgium, 1998. 28 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages de Volder K.: “Code Reuse, an Essential Concern in the Design of Aspect Languages?”, Workshop on Advanced Separation of Concerns, Budapest, 2001. de Volder K., Tourwé T., Brichau J.: “Logic meta-programming as a Tool for Separation of Concerns”. In ECOOP 2000 International Workshop on Aspects and Dimensions of Concerns", 2000. D’Hondt M., “Hybrid Aspects for Integrating Rule-based Knowledge and Object-oriented Functionality”, PhD Thesis, Vrije Universiteit Brussel, May 2004. D’Hondt M., Jonckers V., “Hybrid Aspects for Weaving Object-Oriented Functionality and Rule-Based Knowledge”, in AOSD '04: Proceedings of the 3rd international conference on Aspect-oriented software development, Lancaster, UK, ISBN 1-58113842-3, http://doi.acm.org/10.1145/976270.976287, p. 132-140, ACM Press, New York, NY, USA, 2004. Eclipse Platform Naming Conventions, http://www.eclipse.org/documentation/ html/plugins/org.eclipse.platform.doc.isv/doc/reference/misc/naming.html, June 2001. Ernst M., Kaplan C., Chambers C.: “Predicate Dispatching: A Unified Theory of Dispatch.” In: E. Jul (ed.): ECOOP'98 - -Object-Oriented Programming (12th European Conference; Brussels, Belgium, July 1998, Springer-Verlag, LNCS 1445, p. 186-211, 1988. Filman R. E., Friedman D. P.: “Aspect-Oriented Programming is Quantification and Obliviousness”, Workshop on Advanced Separation of Concerns, OOPSLA 2000, October 2000, Minneapolis. Gamma E, Helm R, Johnson R, Vlissides J.: Design Patterns: Elements of Reusable ObjectOriented Software, Addison-Wesley, 1995. Gybels K., “Aspect-Oriented Programming using a Logic Meta Programming Language to express cross-cutting through a dynamic join point structure”, Licentiate's Thesis Dissertation, Aug 2001 Gybels K, Brichau J, “Arranging Language Features for More Robust Pattern-based Crosscuts”, Proceedings of the 2nd International Conference on Aspect-Oriented Software Development (AOSD), Boston, MA, March 17-21, ACM Press, 2003 Hassoun Y., Constantinides C., “Considerations on component visibility and code reusability in AspectJ”. In Proceedings of third German Workshop on Aspect-oriented Software Development of the German Informatics Society (AOSD-GI 2003), http://dawis.informatik.uni-essen.de/site/events/GI_AOSD_2003/index.html, p. 33-38. Hannemann J., Kiczales G., “Design Pattern Implementations in Java and AspectJ”, Conference on Object-Oriented Programming Systems, Languages and Applications, OOPSLA 2002, November 4-8, 2002, Seattle, Washington, USA. SIGPLAN Notices 37(11), November 2002, ACM Press, pp. 161-173. Hanenberg, S.; Unland, R.: Parametric Introductions, 2nd International Conference of Aspect-Oriented Software Development (AOSD), Boston, MA, March 17-21, ACM Press, 2003, pp. 80-89. Hanenberg S, Unland R., Oberschulte C., “Refactoring of Aspect-Oriented Software”, Net ObjectDays 2003, Erfurt, Germany, September 2003. Harbulot B, Gurd J. R., “Using AspectJ to Separate Concerns in Parallel Scientific Java Code”, Proceedings of 3rd International Conference on Aspect-Oriented Software Development (AOSD), March 2004. A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages 29 Harbulot B, Gurd J. R., “A Join Point for Loops in AspectJ”, Proceedings of FOAL 2005 – Workshop on Foundations of Aspect Languages, collocated with 4th International Conference on Aspect-Oriented Software Development (AOSD.05), March 2005. Hassoun Y., Constantinides C, “Considerations on Component Visibility and Code Reusability in AspectJ”, Proceedings of third German Workshop on Aspect-Oriented Software Development, March 4-5, 2003, Essen, Germany, p. 33-36,, University of Duisburg-Essen. Rajan H., Sullivan K., "Generalizing AOP for Aspect-Oriented Testing", In the proceedings of the Fourth International Conference on Aspect-Oriented Software Development (AOSD 2005), 14-18 March, 2005, Chicago, IL, USA, ACM Press, 2005. Kalleberg K. T. and Visser E.. Combining Aspect-Oriented and Strategic Programming. In H. Cirstea and N. Marti-Oliet, editors, Workshop on Rule-Based Programming (RULE'05), Electronic Notes in Theoretical Computer Science, Nara, Japan, April 2005. Elsevier Science Publishers. http://archive.cs.uu.nl/pub/RUU/CS/techreps/CS2005/2005-030.pdf Kiczales G., Hilsdale E., Hugunin J., Kersten M., Palm J., Griswold W., “An Overview of AspectJ”, Proceedings of ECOOP 2001 Kniesel G., Rho T., “Generic Aspect Languages – Needs, Options and Challenges”, Proceedings of JFDLPA 2005, 2ème Journée Francophone sur le Développement de Logiciels Par Aspects, Lille, Sept. 15, 2005, http://www.lifl.fr/jfdlpa05/kniesel.pdf Kniesel G., Rho T., Hanenberg S., “Evolvable Pattern Implementations need Generic Aspects”, ECOOP 2004 Workshop on Reflection, Aspects and Meta-Data for Software Evolution, Oslo, June 2004, http://roots.iai.uni-bonn.de/research/logicaj/ publications Lämmel R., Visser, E., Visser J., “Strategic Programming Meets Adaptive Programming”, Proceedings of Aspect-Oriented Software Development (AOSD'03), March 2003, Boston, USA, pp. 168-177, ACM Press, 2003.Loughran N, Rashid A., “Framed Aspects : Supporting Variability and Configurability for AOP”, International Conference on Software Reuse 2004 (ICSR-8), Madrid, Spain, July 2004 Mackinnon T., Freeman S., Craig P., “Endo-Testing: Unit Testing with Mock Objects”, Proceedings of eXtreme Programming and Flexible Processes in Software Engineering - XP2000, May 2000. Orleans, D., “Separating Behavioral Concerns With Predicate Dispatch, or, If Statement Considered Harmful”, position paper at OOPSLA 2001 Workshop on Advanced Separation of Concerns in Object-Oriented Systems, http://www.cs.ubc.ca/ ~kdvolder/Workshops/ OOPSLA2001/submissions.html Ossher H., Tarr P., “Using multidimensional separation of concerns to (re)shape evolving software”, Communication of the ACM, 44 (10), 2001, pp. 43-50. Ossher H., Tarr P., “Hyper/J: Multi-dimensional separation of concerns for Java”, Proceedings of ICSE 2001, IEEE Computer Society. Pawlak R. “Spoon: Annotation-Driven Program Transformation - The AOP Case”. First Workshop on Aspect-Orientation for Middleware Development at Middleware 2005, Grenoble, France. http://www.lifl.fr/~pawlak/papers/Pawlak_AOMD05.pdf Pinson L., Wiener R., “Objective-C: object-oriented programming techniques”. ISBN: 0201508281, Addison-Wesley, 1991. 30 A Definition, State of the Art Overview and Taxonomy of Generic Aspect Languages Rho T., Kniesel G., Appeltauer M., “Fine-Grained Generic Aspects”, Proceedings of FOAL 2006 – Workshop on Foundations of Aspect-Oriented Languages in conjunction with 5th International Conference on Aspect Oriented Software Development (AOSD.06), March 20-24, 2006, Bonn, Germany. Rho T., Kniesel G., “Uniform Genericity for Aspect Languages”, Technical Report IAI-TR2004-4, Computer Science Department III, University of Bonn, December 2004. Silaghi R., Strohmeier A., “Better Generative Programming with Generic Aspects”. 2nd OOPSLA 2003 Workshop on Generative Techniques in the context of Model-DrivenArchitecture. Technical Report IC/2003/80, Swiss Federal Institute of Technology in Lausanne, Switzerland. Sihman M., Katz S., “Superimpositions and Aspect-oriented Programming”, The Computer Journal, 46 (5), pp. 529-541, doi:10.1093/comjnl/ 46.5.529, British Computer Society, 2003. SOUL homepage, http://prog.vub.ac.be/research/DMP/soul/soul2.html, accessed Feb. 2006 (last update October 22, 2003) Homepage of Spoon and Spoon/AOP http://spoon.gforge.inria.fr/ (Accessed Feb. 2006). Spinczyk O., Gal A., Schröder-Preikschat W., “AspectC++: An Aspect-Oriented Extension to C++”, Proceedings of the TOOLS Conference Pacific 2002, Sydney, Australia, February 18-21, 2002 Lohmann D., Blaschke G., and Spinczyk O., “Generic Advice: On the Combination of AOP with Generative Programming in AspectC++”. In Proceedings of GPCE'04, October 24th-28th, 2004, Vancouver, Canada, LNCS 3286, p. 55-74, Springer Verlag 2004. Tourwé T., Brichau J., Gybels K., “On the Existence of the AOSD Evolution Paradox”, SPLAT Workshop, Boston, AOSD 2003. StrategoXT homepage, http://www.stratego-language.org/Stratego/StrategoXT, accessed Feb. 2006 (last update Nov. 17, 2002) E. Visser. Program Transformation with Stratego/XT: Rules, Strategies, Tools, and Systems in StrategoXT-0.9. In C. Lengauer et al., editors, Domain-Specific Program Generation, volume 3016 of Lecture Notes in Computer Science, pages 216-238. Spinger-Verlag, June 2004. See also http://www.cs.uu.nl/research/techreps/UU-CS2004-011.html and http://www.stratego-language.org/Stratego/StrategoXT. Wampler D., “The Challenges of Writing Reusable and Portable Aspects in AspectJ: Lessons from Contract4J”. In Chapman M., Vasseur A., Kniesel G. (Eds): International Conference on Aspect Oriented Software Development (AOSD 2006) – Industry Track Proceedings, March 20-24, 2006, Technical Report IAI-TR-2006-3, ISSN 0944-8535, Institut für Informatik III, Universität Bonn, Germany, 2006. Windeln T., „LogicAJ – eine Erweiterung von AspectJ um logische Meta-Programmierung“ (in German), Diploma thesis, CS Dept. III, University of Bonn, Germany, August 2003. Wuyts, R., “A Logic Meta-Programming Approach to Support the Co-Evolution of ObjectOriented Design and Implementation”, Ph.D. Thesis, Vrije Universiteit Brussel, 2001. Zook, D., Huang, S. S., and Smaragdakis, Y., Generating AspectJ Programs with MetaAspectJ. In Proceedings of GPCE'04, LNCS 3286, pages 1-19. Springer-Verlag, 2004.
© Copyright 2026 Paperzz