470 likes | 622 Views
Object-Oriented Software Construction Bertrand Meyer Lesson 21. Type issues, covariance and catcalls. Last update: 25 May 2004. What’s special about this lecture. Mix of: Fundamental concepts Unsolved issues Recent proposal. Flexibility vs. safety.
E N D
Object-Oriented Software ConstructionBertrand MeyerLesson 21 Type issues, covariance and catcalls Last update: 25 May 2004
What’s special about this lecture • Mix of: • Fundamental concepts • Unsolved issues • Recent proposal Programming in the Large, 2004
Flexibility vs. safety • Expressive power (no “bondage and discipline” language) • Protection against crashes and attacks Programming in the Large, 2004
Typing approaches • Pascalx := y Only if types of xandy are identical! • Smalltalk • x.f always permitted, not static type check! • At execution time: “Message not understood” Programming in the Large, 2004
Typed O-O languages • Like Pascal in basic forms • But polymorphism allows more flexible assignment rule: x := y permitted if type of y“conforms to” typeof x Programming in the Large, 2004
Basic type rules in typed O-O languages • Eiffel, Java, .NET... • In every assignment x := y (or argument passing), type of y conforms to type ofx. • In every feature call x.f(…)(qualified), f is an exported feature of the class of x. • C++: “A little bit typed” (Casts) Programming in the Large, 2004
Terminology • Typed vs untyped languages • More accurate: • Statically typed, vs • Dynamically typed Programming in the Large, 2004
Typing is always pessimistic • Invalid in Pascal: • var n: INTEGER • n := 0.0 • if 0 > 1 then • begin • n := 0.0 • end Programming in the Large, 2004
The basic goal • A programming language is statically typedif its definition includes a set of type rules, guaranteeing that no execution of a valid program will ever produce a run-time type failure. • A type rule is a validity constraint involving the types associated with program elements. • A validity constraint for a programming language is a boolean condition applicable to any syntactically legal program text in the language. Programming in the Large, 2004
Precise definitions • An object-oriented programis class-level-valid if it satisfies the following properties: • In every assignment x := y(or argument passing), type of y conforms to type ofx. • In every feature call x.f(…)(qualified), f is an exported feature of the class of x. • Without catcalls, any class-level-valid program would be type-safe! Programming in the Large, 2004
The issue: flexibility vs safety • Find a type system that: • Supports covariance and genericity • Permits full static type checking • Stated differently: • Disprove the “Pierre America conjecture” that one can have at most two of polymorphic substitution, covariance, and static type checking • Fix the “holes” in Eiffel’s type system Programming in the Large, 2004
A typical covariance situation Programming in the Large, 2004
Original class • class BOAT feature • captain: SKIPPER • -- Skipper assigned to this boat • sail(c: SKIPPER)is • -- Appoint c as captain of this boat. • require • c /= Void • do • captain:=c • ensure • captain = c • end • end Programming in the Large, 2004
Original class (simplified) captain • classBOATfeature • captain:SKIPPER • sail(c: SKIPPER)is • do • captain:=c • end • end SKIPPER BOAT sail (...) captain CAT_ ARRAYED_ ARRAYED_ CAT SKIPPER STACK STACK sail (...) Programming in the Large, 2004
Heir class • classCATinherit • BOATredefine • captain, sail • end • feature • captain:CAT_SKIPPER • sail (c:CAT_SKIPPER)is • do • captain:= c • end • end Programming in the Large, 2004
Original class, using anchored type • classBOATfeature • captain: SKIPPER • sail (c:like captain)is • do • captain:= c • end • end • No explicit redefinition necessaryforsailinCAT(see next) Programming in the Large, 2004
Heir class • class • CAT • inherit • BOAT • redefine • captain • end • feature • captain: CAT_SKIPPER • end Programming in the Large, 2004
Static typing vs. dynamic binding • x.f • Static typing: ensures that there is AT LEAST ONE FEATURE • Dynamic binding: ensures that it is THE RIGHT FEATURE Programming in the Large, 2004
captain “Ticking bomb” (CAT) (SKIPPER) Catcalls • boat1: BOAT; cat1: CAT • skipper1: SKIPPER; cat_skipper1: CAT_SKIPPER • ... • boat1 :=cat1 • ... • boat1.sail (skipper1) • Thecaptainof this catamaran is now a plainSKIPPER! • Might try to do captain.repair_second_hull(see next) Programming in the Large, 2004
feature do_maintenanceis do captain.repair_second_hull end end Catcalls • classBOAT • feature • do_maintenance is • do • -- Something here. • end • end classCATinherit BOAT redefine do_maintenance end Programming in the Large, 2004
Catcall situation captain SKIPPER BOAT sail (...) captain CAT_ ARRAYED_ ARRAYED_ CAT SKIPPER STACK STACK sail (...) repair_second_hull Programming in the Large, 2004
Consequences of a catcall • Crash? • Security attack? Programming in the Large, 2004
Catcalls: source #2 — Genericity • skipper_list: LIST [SKIPPER] • cat_skipper_list: LIST [CAT_SKIPPER] • ... • skipper_list :=cat_skipper_list • skipper_list.extend (skipper1) • cat_skipper1 := cat_skipper_list.last Programming in the Large, 2004
Catcalls: source #3 — Descendant hiding • classRECTANGLEinherit • POLYGON export {NONE} add_vertexend • ... • end poly1 := rect1 ... poly1.add_vertex (...) Programming in the Large, 2004
CAT • Changed Availability or Type Programming in the Large, 2004
Pierre America, 1990 • At most two of: • Polymorphic substitution • Covariance • Static type checking Programming in the Large, 2004
Previous solutions: novariance • C++, Java, .NET... • Eliminates the problem (obviously) • Forces programmers to do the conversions themselves • May result in brittle code Programming in the Large, 2004
Previous solutions: contravariance • Results specialized, arguments generalized • Solves the problem • Only problem: doesn’t match practical needs • The world seems to be covariant. Programming in the Large, 2004
Previous solutions: catch catcalls • Generate code to check arguments • Cause exception if wrong type • Avoids the security issue • Disadvantages: • Performance penalty in all cases • Forces issue on client! • No easy way to force client to handle exception • Exception too drastic Programming in the Large, 2004
Previous solutions: Overloading • Consider that redefinition creates a new variant of the routine but doesn’t obliterate the previous one. • Name resolution combines dynamic binding and overloading. Semantic rules can be devised (Giuseppe Castagna, ENS Paris) • Doesn’t seem compatible with goals of O-O programming Programming in the Large, 2004
Previous solutions: system-level validity • Considering all assignments, compute dynamic type set (DTS) of any variable x. • If there is an assignment x := y, or a corresponding argument passing, all elements of DTS of y are also in the DTS of x. • No attempt at control flow analysis • Fixpoint algorithm • Helps with optimization • Disadvantages: • Pessimistic • Not incremental • Difficulty of giving precise diagnostics Programming in the Large, 2004
Previous solutions: class-level validity • If there is an assignment x := y and y is of a different type from x, or (recursively) y is polymorphic, consider x polymorphic. • Any formal routine argument is polymorphic • Disallow x. r (...) if x is polymorphic and r is a CAT routine. • Local information, all incremental • Disadvantages: • Pessimistic • Difficulty of giving precise diagnostics Programming in the Large, 2004
Recent Eiffel developments • Tuples • Expanded inheritance Programming in the Large, 2004
Tuple types and tuples • TUPLE [X, Y, Z] • Denotes sequences of at least three elements, first of type X, second of type Y, third of type Z • Individual tuple: [x1, y1, z1] • Conformance relations • TUPLE [X, Y, Z] TUPLE [X, Y] Programming in the Large, 2004
Expanded inheritance • classC inherit • A • expanded B • feature • ... • end • No polymorphism permitted: • a1 := c1 -- OK • b1 := c1-- Not permitted Programming in the Large, 2004
The new solution (1) • Covariance etc. OK with expanded inheritance • Covariance also OK with non-exported features • x.f(a) -- Qualified • f(a) -- Unqualified Programming in the Large, 2004
The new solution (2) • Allow covariant redefinition even with polymorphism! • Replacement (“recast”) must be provided • Also applies to generic case Programming in the Large, 2004
Covariant cats • classCATinherit • BOATredefine • captain, sail • end • feature • captain: CAT_SKIPPER • sail (c: CAT_SKIPPER)is • recast • trained_as_cat_skipper • do • captain:= c • end • end Programming in the Large, 2004
A recast function • trained_as_cat_skipper (s: SKIPPER): CAT_SKIPPER is • -- Version of skipper s reborn as cat skipper • require • exists: s /= Void • do • create Result.train_skipper (s) • end Programming in the Large, 2004
In CAT_SKIPPER • classCAT_SKIPPERinherit • SKIPPER • create • make_from_skipper • feature-- Initialization • train_skipper (s: SKIPPER)is • require • s /=Void • s.trained_as_cat_skipper • do • … • end • end Programming in the Large, 2004
The latest… • No more recast function • Use exceptions instead • sail (c: CAT_SKIPPER)is • do • captain:= c • rescue • … Can use c … • end Programming in the Large, 2004
The multi-argument case • r (x: TYPE1 ; y: TYPE2; z: TYPE3)is • recast • transform • do • ... • end • with • transform(x: OLD1 ; y: OLD2; z: OLD3): • TUPLE [TYPE1, TYPE2, TYPE3] is • do • ... • end Programming in the Large, 2004
The generic case • In C [G], if there is a routine r (x: G) • it must have a recast clause! Programming in the Large, 2004
Possible criticism • Creates a copy • What if LIST of catamarans Programming in the Large, 2004
The descendant hiding case • Expanded inheritance works, of course • More flexibility: still under discussion Programming in the Large, 2004
More work • Implement • Analyze benefits and disadvantages further • Study real software • Formalize through a mathematical model, prove • Solve descendant hiding issue Programming in the Large, 2004
Some tentative conclusions • Flexibility can be reconciled with safety No need to choose between anarchy and “bondage and discipline” • Static typing is practical • Language design is needed • Language design is fun • Committees work! • Don’t sail a catamaran unless you know how to Programming in the Large, 2004