aspectual collaborations

40
Aspectual Collaborations Flexible Modules for Generic Object Oriented Programming

Upload: azura

Post on 05-Jan-2016

23 views

Category:

Documents


0 download

DESCRIPTION

Aspectual Collaborations. Flexible Modules for Generic Object Oriented Programming. Host Class Graph. Consists of Classes written by programmer connected by interrelationships Has-A parts Is-A edges Just plain ol’ java. Collaboration. Like a class graph, but Roles instead of Classes - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Aspectual Collaborations

Aspectual Collaborations

Flexible Modules for

Generic Object Oriented

Programming

Page 2: Aspectual Collaborations

Host Class Graph

• Consists of Classes written by programmer connected by interrelationships

• Has-A parts

• Is-A edges

• Just plain ol’ java.

Page 3: Aspectual Collaborations

Collaboration

• Like a class graph, but– Roles instead of Classes– Roles may have missing behavior (methods or

fields)– Closed

• No new roles can be added to the collaboration

Page 4: Aspectual Collaborations

Roles

• Differ from classes in that they may have missing methods or fields

• Different from abstract– Abstract behavior must be method– Abstract classes can never be instantiated– Roles will be completed in-situ at a later date.

Page 5: Aspectual Collaborations

Adapter

• Connects host class graph and collaboration– Classes and Roles equated pointwise– Subject to semantic constraints

• Collaboration is stretched to fit• Provides expected parts by exports from

host• Exports some parts of collaboration to

outside world, encapsulates rest

Page 6: Aspectual Collaborations

Example: Sort Hostpackage host; class HasUsers { User[] users; void initUsers() { ... } void addUser(User u) { ... } void sortusers() { System.err.println("No sorting. Yet."); } User firstuser() { sortusers(); return users[0]; }}class User { String name; int uid; boolean alphabeticallybefore(User that) { return this.name.lexicographicallybefore(that.name); } boolean uidbefore(User u) { return this.uid < that.uid; }}

Page 7: Aspectual Collaborations

Example: Sort Collaborationcollaboration sort;role ArrayHolder { expected Item[] arr; void insertionsort() { for (int i=0; i<arr.length; i++) for (int j=i; j<arr.length; j++) if (arr[j].before(arr[i])) swap(i,j); int m=0.0; for (int i=0; i<arr.length; i++) m += arr[i].moved*arr[i].moved; System.out.println("geom. average number of moves: "+(m/arr.length)); } private void swap(int i, int j) { arr[i].moved++; arr[j].moved++; Item o = arr[i]; arr[i]=arr[j]; arr[j]=o; }}role Item { expect boolean before(Item other); int moved = 0; }

Page 8: Aspectual Collaborations

Example: Sort Adapteradapter sortedhost;combine {sort,host} { host.HasUsers += sort.ArrayHolder { sort::Item[] arr provided-by host::User[] users; host::void sortusers() provided-by sort::void insertionsort(); } host.User += sort.Item { sort::boolean before(Item) provided-by host::boolean uidbefore(User); }}

Page 9: Aspectual Collaborations

Discussion

• Expected parts are what give a collaboration a tight yet generic coupling to the host application.

• Allow generic behavior to have complex interactions with host behavior.

Page 10: Aspectual Collaborations

Different class graphs

• How much may the collaboration’s role graph and host class graph differ?– Must maintain sub/super class links– Expected types after mapping must match types

provided by host: Item must be User since arr is users

Page 11: Aspectual Collaborations

Composition

• Why does the host need to be a complete class graph? Why not a collaboration too?

• Provide behavior needed by one from the other.

• Some behavior remains expected.• But, What is the return type?

– come back next week for exciting conclusion! Same bat time, same bat channel

Page 12: Aspectual Collaborations

A Tale of Two Implementations

Page 13: Aspectual Collaborations

Dynamic / Proxy

• Layering behavior like a cake• Host remains unchanged• Two simultaneous different types, but no object

equality between them.• Behavior can be removed• No permanent memory overhead• Hard to compose• Object mapping hard (vectors are nigh impossible)• Unclear whether we can be type safe and pre-compiled

at the same time

Page 14: Aspectual Collaborations

‘tis a far far better thing

• Combine bytecode to make new class– Already front-end processed– Type checked, easily parsable– More SOP than layering

• Determine types by adapter• Permanent• Can be precompiled type safely (each

object has only one type)

Page 15: Aspectual Collaborations

Format of Class Files

• The secret to working with class files are their convenient layout

• All references are stored in one local pool, the class pool. Parts are stored in area, and class attributes in the last.

ClassPool

Attributes

Info

Fields

Methods

Page 16: Aspectual Collaborations

The Constant Pool

• All identifiers and references stored there– MethodRef, FieldRef, InterfaceMethodRef– External Method and Type Refs

• same for fields and methods!

– Constant: Strings, Ints, Doubles, Classes, …– Raw Strings

Page 17: Aspectual Collaborations

No need to inspect method body

• To move into a new class, we just do a recursive copy into new class, chasing all index pointers into constant pool.

Page 18: Aspectual Collaborations

Dealing with Expected Parts

• Preprocessor adds stub body to all expected method.

• Postprocessor annotates expected parts as such, so that stub may be thrown away.

• For unit testing purposes, bodies may not be stubs, but user-written test stubs that simulate expected behavior. – Allows collaborations to be tested without application.– Can be simulated by linking to simplistic app.

Page 19: Aspectual Collaborations

How to store annotations

• Expected methods need to be marked as such, so that our implementation knows it’s ok to remove their existing body.

• Class files allow additional attributes to be stored on fields and methods. Byte code is one

Void foo()

ATTR_expectedATTR_deprecated

Info_index

OtherClass::int bar

ATTR_Code

1234.6

Method entry in class

Constant pool

Page 20: Aspectual Collaborations

Alpha Conversion vs Export

• Of course, we don’t want to pollute name space of resulting class file, so we systematically rename all intra-collaboration references.

• Names exported are renamed to resulting name, while non-exported names are renamed to unpronouncable names ($).

Page 21: Aspectual Collaborations

Implementation Subconclusion

• Class files are easy and flexible to work with• Pre-parsed semantics make our life easier, while

compiled status means we can take well-formedness for granted.

• This implementation is statically linked (we build up new collaborations from old statically). Dynamic linking is an option, but hard.

Page 22: Aspectual Collaborations

Composition, Cont

• Under insertive approach, the types are completely decided by adapter: we are creating new classes

• Must make sure no expected parts are unexported – they become unprovidable

Page 23: Aspectual Collaborations

Aspects

• We’ve been promising aspectual programming. Now we get some.

• Aspects are defined as systematic behaviors that are localised to issue, but distributed over multiple classes

• Additionally, the rest of the program can be oblivious to aspects’ existence (Filman&Friedman).

Page 24: Aspectual Collaborations

Precise Aspects

• Precise aspects we almost have already. All we require is to not throw away old method body when replacing a method stub. (memo to self- what happens when we wrap an expected method?)

• Allows us to play with arguments of wrapped method

Page 25: Aspectual Collaborations

Example: No Duplicates, pleasecollaboration nodups;role ElemHolder { expected Elem[] elems; expected void addElem(Elem e); void insertMaybe(Elem e) { for (int i=0; i<elems.length; i++) if (elems[i].equals(e)) return; addElem(e); } }role Elem { expect int id; public equals(Object o) { return ((Elem)o).id == id; }}

Page 26: Aspectual Collaborations

Example: No Duplicates, cont

adapter sortednoduphost;combine {nodups,sortedhost} { sortedhost.HasUsers += nudups.ElemHolder { nodups::Elem[] elems provided-by sortedhost::User[] users; sortedhost::void addUser(User) replaced-by nodups::void insertMaybe(Elem) provides nodups::void addElem(Elem); } sortedhost.User += nodups.Elem { export nodups::boolean equals(Object); }}

Page 27: Aspectual Collaborations

What happens

• When the addUser method is invoked, the collaboration addElem is invoked instead, and eventually invokes the expected old method.

• Notice that the aspect magic is from the adapter, the collaboration sees it as a normal method.

Page 28: Aspectual Collaborations

Generic Aspects

• Precise aspects are nice, but very limited– How often can do we know the interface

precisely

• Approach:– Precompile method to known simple signature– Wrap with generated code at adaptation time to

convert arguments and return values of wrapped host method to the known signature

Page 29: Aspectual Collaborations

Example: Keep it Sortedcollaboration keepsorted;role Thing { expected void sort(); aspectual ReturnVal sortafter(ExpectedMethod e) { ReturnVal r = e.invoke(); sort(); return r; } }

adapter keepsortedhost;combine {keepsorted,sortedhost} { sortedhost.HasUsers += keepsorted.Thing { keepsorted::void sort() provided-by sortedhost::sortusers(); keepsorted::sortafter wraps sortedhost::void initUsers(); } } and { sortedhost.HasUsers += keepsorted.Thing { keepsorted::void sort() provided-by sortedhost::sortusers(); keepsorted::sortafter wraps sortedhost::void addUser(User); }}

Page 30: Aspectual Collaborations

Discussion: Generated CodeFrom Collaboration

package keepsorted;class Thing { void sort() { /*expected*/ }; ReturnVal$A sortafter(ExpectedMethod$A e) { /*aspectual*/ ReturnVal$A r = e.invoke(); sort(); return r; } }abstract class ReturnVal$A { }abstract class ExpectedMethod$A { abstract ReturnVal$A invoke(); }

Page 31: Aspectual Collaborations

Discussion: Generated CodeFrom Adapterpackage keepsortedhost;

class HasUsers { ... void sortusers() { ... }; ReturnVal$A sortafter$addUser(ExpectedMethod$A e) { /*aspectual*/ ReturnVal$A r = e.invoke(); sortusers(); return r; } void addUser$A(Elem e) { /* original method body, untouched */ } void addUser(Elem e) { } ExpectedMethod$A ex = new ExpectedMethod$A$addUser(this,e); ReturnVal$A$addUser r = (ReturnVal$A$addUser) sortafter$addUser(ex); return; }}class ReturnVal$A$addUser extends ReturnVal$A { }class ExpectedMethod$A$addUser extends ExpectedMethod$A { User arg1; HasUsers self; ExpectedMethod$A$addUser(HasUsers s, User u) { self=s; arg1=u; } ReturnVal$A invoke() { ReturnVal$A$addUser r = new ReturnVal$A$addUser(); self.addUser$A(arg1); }}

Page 32: Aspectual Collaborations

The wrapping approach

• Handles return values of any type• Exceptions in a similar manner• Since each signature will generate different

extracting code (exceptions must be rethrown, for example) we have to have subclasses of ReturnVal for each signature. We then downcast to the known type to extract info

Page 33: Aspectual Collaborations

The dollar signs

• The needed downcast is in the generated body for addUser. We must make sure this cast succeeds, as it is not in user code, and they will not know what caused it.

Page 34: Aspectual Collaborations

Causing a casting errorcollaboration fail; role Foo { RV old; aspectual RV meth(EM e) { ReturnVal r = e.invoke(); ReturnVal o = old; old = r; return (o!=null):o?r; }}

package host;class A { A get_a() { return new A(); }}class B { void print() { System.err.println("hi"); }}

adapter whatever;combine {fail,host} { host.A += fail.Foo { export fail::RV old fail::meth wraps host::A get_a(); }} and { host.B += fail.Foo { export fail::RV old fail::meth wraps host::void print(); }} void failit() {

A anA = new A(); B aB = new B(); aB.print(); // now aB.old has void ReturnVal aB.old = anA.old; // so does anA! A otherA = anA.get_a(); // tries to unwrap void to A}

Page 35: Aspectual Collaborations

Existential Types

• ReturnVal and ExpectedMethod are local to an attachment of the collaboration; we cannot export them.

• We assure this by adding the unpronounceable $ to their types; thus they cannot be mentioned in an adapter, and cannot be exported.

• Casting is still an issue, but that’s java.

Page 36: Aspectual Collaborations

Aspectual Subconclusion

• Small addition to collaborations make them intuitive fits for aspectual programming.

• We are able to offer type-safe separate compilation of aspects that can be used with a wide variety of class graphs.

Page 37: Aspectual Collaborations

Scoping Collaborations

• Objects have variables scoped per instance and per class.

• Collaborations have another dimension:– Per Attachment

• A counter for method invocation is per method. The default.

– Per Host• A counter for method invocation is shared for methods of

class. Expected parts have this property.

– Per Application• All the methods of the application share the same counter. Can

be simulated a-la object oriented globals.

Page 38: Aspectual Collaborations

A Scoping examplecollaboration c_attachment; role Counter { int att=0; static int st_att=0; expected int sha; expected int st_sha; aspectual ReturnVal meth(ExpectedMethod exmeth) { att++; st_att++; sh++; st_sh++; System.err.println("this wrapped method on this object: "+att+ " and for all objects of this class: "+st_att); System.err.println("all wrapped methods of this object: "+sha+ " and for all objects of this class: "+st_sha); return exmeth.invoke(); }}

adapter counting;combine {c_shared,c_attachment} { Counted = {c_shared.CountHolder,c_attachment.Counter} { c_attachment::int sha provided-by c_shared::int shared; c_attachment::static int st_sha provided-by c_shared::static int st_shared; export c_attachment::aspectual meth; }}

collaboration c_shared;role CountHolder { int shared=0; static int st_shared=0;}

Page 39: Aspectual Collaborations

Discussion: Scoping

• Composition is used to add the expected parts to the host.

• It is still unclear how we specify that one sub-collaboration is only added once, the other possibly multiple times.

Page 40: Aspectual Collaborations

Conclusion

• Very flexible system

• Our mechanisms expressive enough to express many kinds of aspectual behavior

• Few unclear issues– What is added once from composed collabs,

what is duplicated.– Wrapping expected methods with ascpectual

methods.