Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Multi-Methods in Cecil Objects and Aspects (Fall 2004) September 20, 2004 Kevin Bierhoff Agenda Generic functions Cecil Object model Method dispatch Encapsulation Open questions Discussion any time September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 2 Generic functions allow dynamic dispatch on multiple arguments Define the generic function add(a, b) with add(Integer a, Integer b) add(Integer a, Double b) add(Double a, Integer b) add(Double a, Double b) Which method receives add(x, y) ? Depends on runtime type of x and y Java’s September 20, 2004 x.add(y) would only look at x! Objects and Aspects: Multi-Methods in Cecil 3 Generic functions can be simulated in object-oriented languages … class Object boolean return other.equalsOther(this) boolean equals(Object other) equalsOriginal(Object original) return this == original class Point extends Object protected “Double Dispatch” int x, y; boolean equalsOriginal(Point original) return x == original.x && y == original.y; September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 4 … but it’s a real pain class Point [cont.] boolean equals(Object other) return other.equalsOther(this) class ShadowPoint extends Point boolean equals(Object other) return other.equalsOther(this) boolean equalsOriginal(Point original) return x == (original.x – 5) && y == (original.y – 5) return x == original.x && y == original.y class Point [cont.] Consistent behavior boolean equalsOriginal(ShadowPoint original) Static binding Code both sides boolean equalsOriginal(ShadowPoint original) return x == (original.x + 5) && y == (original.y + 5) Behavior for new classes cannot be added later September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 5 Generic functions as in CLOS foster functional programming Generic functions are external to objects Leave only data fields within the objects Implicit generic functions for accessor methods Prohibit data encapsulation Objects are really structs Incredibly complex inheritance rules To resolve dispatch ambiguities (cf.) Really not transparent to programmer Cecil addresses both problems mentioned here September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 6 Cecil builds its object model on Self Object model based on prototypes Supports multiple inheritance Root object called “any” Adds or modifies several ideas Inheritance vs. subtyping of objects Abstract, template, and unique objects Local vs. shared fields and their accessors September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 7 Cecil distinguishes inheritance and subtyping of objects Adopt behavior through inheritance int = object inherits number Override methods to adapt behavior Get new concrete object at runtime var ::= object inherits int Adopt interface through subtyping type collection type list subtypes collection set = object inherits array subtypes collection Inheritance crucial for method dispatch September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 8 Cecil can enforce special roles of objects at runtime abstract objects are not completely defined Can contain abstract methods Similar to abstract classes in Java template objects for concrete incarnations Cannot be manipulated at runtime int = template object inherits number var ::= object inherits int int.set_value(5) -- is invalid unique objects exist exactly once zero = unique object inherits number var ::= object inherits zero -- is invalid September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 9 Objects can have state Define data fields for objects value(n@number) { field } By default fields are local to an object Can also be shared between objects Each field implicitly defines pair of accessors Get with value(num), set it with set_value(num, 5) Fields can be declared read-only / init-only var ::= object inherits int [value := 5] -- for initialization Note: Self shares fields on inheritance Thus usually need a “traits” object with behavior and an inheriting “template” that holds fields and is cloned This separation is not necessary in Cecil September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 10 Cecil associates multi-methods with all objects involved Constrained arguments for multi-methods Dynamic dispatch on all constrained arguments OOP as special case No constrained argument static function One constrained argument ~ OOP (Single-Dispatch) Two or more constrained arguments Multi-Dispatch Multi-methods belong to all constrained args Code is now best viewed as a graph int + int int int + double double + int double double + double September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 11 Constrain arguments with @ Template objects int = template object inherits number double = template object inherits number Methods a@int + b@int { … } a@int + b@double { … } a@double + b@int { … } a@double + b@double { … } September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 12 Multi-methods provoke ambiguities similar to multiple inheritance … “Diamond” relationships collection contains(c@collection, elem) unsorted_list sorted_list contains(c@unsorted_list, elem) contains(c@sorted_list, elem) set Now what happens if you call “contains” with a set? September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 13 … as well as new ambiguities related to multiple dispatch collection merge(c1@collection, c2@collection) sorted_list merge(s1@sorted_list, c2@collection) merge(c1@collection, s2@sorted_list) Now what happens if you call “merge” with two sorted_list objects? September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 14 Cecil leaves these ambiguities to the programmer Cecil’s dispatch mechanism Find syntactically fitting methods Ignore those with a too specialized argument Find the most specialized under the remaining Ambiguity runtime exception Programmer must resolve manually Note: CLOS avoids ambiguities By totally ordering all methods September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 15 Cecil allows information hiding … Fields and methods can be private Really means protected Access based on caller privileges Analyze signature of calling method Match calling to requested objects Grant access to all super- and sub-objects visible draw(v@visible) draw(s@shape) shape private draw_shape(s@shape) x rectange September 20, 2004 y size_x size_y private draw_shape(s@shape) draw(s@shape) { if(has_changed(s), { draw_shape(s) }, {} What is ) the difference to } OO? draw(v@visible) { draw_shape(v) } Objects and Aspects: Multi-Methods in Cecil 16 … but tolerates serious encapsulation breaches Want to break into an object? Just define a new method that takes this object as a constrained argument breach(a@rectangle) { access private fields now } breach(a@any) { access whatever you want } Is that good or evil? September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 17 Cecil solves issues in CLOS … CLOS Generic functions Cecil Multi-methods External to object hierarchy Foster functional programming approach Fails to address object encapsulation September 20, 2004 Belong to all dynamic arguments Graph-based objectoriented programming Offers (some) encapsulation Objects and Aspects: Multi-Methods in Cecil 18 … but raises new questions Do you like the object model better than Self’s? how Cecil (does not re)solve ambiguities? that methods belong to multiple objects? Hey, where is the code hierarchy? Is this really better than double dispatch? Does this really feel like (multi-) object-oriented programming? September 20, 2004 Objects and Aspects: Multi-Methods in Cecil 19