1 / 33

David Evans http://www.cs.virginia.edu/~evans

Lecture 18: Behavioral Subtyping and Eiffel . Must it be assumed that because we are engineers beauty is not our concern, and that while we make our constructions robust and durable we do not also strive to make them elegant?

dacian
Download Presentation

David Evans http://www.cs.virginia.edu/~evans

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 18: Behavioral Subtyping and Eiffel Must it be assumed that because we are engineers beauty is not our concern, and that while we make our constructions robust and durable we do not also strive to make them elegant? Is it not true that the genuine conditions of strength always comply with the secret conditions of harmony? Gustav Eiffel David Evans http://www.cs.virginia.edu/~evans CS655: Programming Languages University of Virginia Computer Science

  2. Menu • Behavioral Subtyping Recap and Example • Eiffel’s Type System • Method overriding in C++ CS 655: Lecture 18

  3. Subtype Definition (ST) • Subtype methods preserve the supertype methods’ behavior: • Signatures have contravariant arguments, covariant results • Pre-conditions of T imply preconditions of S; post-conditions of S imply post-conditions of T. • Subtypes preserve supertype properties • Invariant of S implies invariant of T. • Constraint of S implies constraint of T. CS 655: Lecture 18

  4. Subtype Relation 2: Preserves supertype Properties • Subtypes preserve supertype properties For all states p and q such that p precedes q, for all x: S: Invariant Rule ISIT [ A (xp) / xp] Constraint Rule CSCT [A (xp) / xp, A (xq) / xq ] “covariance – subtype is stronger” CS 655: Lecture 18

  5. Example • Liskov & Wing showed stack  bag • Is bset  bag? • bset specification on the Manifest • bag in Liskov & Wing, Figure 1 CS 655: Lecture 18

  6. bset = type uses BSet (set for S) for all s: bset invariant max(sp.elements) <= sp.limit, min (sp.elements) >= 0. constraintsp.limit = sq.limit insert = proc (i: int) requires i <= sp.limit  i >= 0. modifies s ensures spost.limit = spre.limit  spost.elements = spre.elements  {i} CS 655: Lecture 18

  7. contains = proc (el: int) returns (bool) ensures result = el  s choose = proc () returns (int) requires spre.elements  {} modifies s ensures spost.elements = spre.elements – { result }  result  spre.elements  spost.limit = spre.limit size = proc() returns (int) ensures result = | s.elements | equal = proc (t: set) returns (bool) ensures result = (s = t) CS 655: Lecture 18

  8. Subtype Definition (ST) • Subtype methods preserve the supertype methods’ behavior: • Signatures have contravariant arguments, covariant results • Pre-conditions of T imply preconditions of S; post-conditions of S imply post-conditions of T. • Subtypes preserve supertype properties • Invariant of S implies invariant of T. • Constraint of S implies constraint of T. CS 655: Lecture 18

  9. Subtype Condition 1: Methods Rule • Methods rule: • Pre-condition  x : s mT.pre [ A (xpre) / xpre ]  mS.pre Replace every xpre in mT.pre with A(xpre). Abstraction function, A : s  t. • Post-condition mS.post  mT.post [A (xpre) / xpre, A (xpost) / xpost] “contravariance – subtype is weaker” “covariance – subtype is stronger” CS 655: Lecture 18

  10. We need an Abstraction Function A type is: < set of objects, set of values, set of methods > bset = <Oset, BSet, { insert, contains, choose, size, equal } > bag = <Obag, BBag, { put, get, card, equal } > • We need an abstraction function that maps both to the same abstract type: A : BSet BBag BSet: < s.elems, s.limit > BBag: < s.elems, s.bound > • s : BSetA (s) = < s.elems, s.limit > • Renaming: R(insert) = put, R(choose) = get, R(size) = card, R(equal) = equal CS 655: Lecture 18

  11. Check method choose  get1. Preserves method behavior. • Signatures: get =proc () returns (int); choose = proc () returns (int) • Pre-condition of get pre-condition of choose x : BSet get.pre [ A(xpre) / xpre ]  choose.pre bpre.elems  {} [A(bpre) / bpre ]  spre.elems  {} • s : BSet; A (s) = < s.elements, s.limit > so we can replace bpre.elems with spre.elems and the implication holds. • Post-condition of choose post-condition of get • Can prove with similar renaming CS 655: Lecture 18

  12. Check method insert  put • Signatures: put =proc (i: int); insert = proc (i: int) • Pre-condition of put pre-condition of insert • x : BSet put.pre [ A(xpre) / xpre ]  insert.pre | A(spre).elems | < A(spre).bound  i <= sp.limit  i >= 0 • NO! The subtype method has a stronger pre-condition, so it is not a subtype. CS 655: Lecture 18

  13. Does this make sense? • Intuition: subtype is unsafe, if there is some program written for the supertype that can tell the difference • Here’s one: put (999235);  insert (999235); CS 655: Lecture 18

  14. uset  bag? • A : S  T • A : Set  BBag • s : Set; A (s) = < s, > • Renaming: • R(insert) = put R(choose) = get • R(size) = card R(equal) = equal • Check method choose  get (same as bset) 8 CS 655: Lecture 18

  15. Check method insert  put • Pre-condition of put pre-condition of insert • x : BSet put.pre [ A(xpre) / xpre ]  insert.pre = true • Post-condition of insert post-condition of put insert.post put.post [ A(xpre) / xpre, A(xpost) / xpost] (spost.elements = spre.elements  { i }) • (bpost.elems = bpre.elems  { i }  bpost.bound = bpre.bound) [ A(bpre) / bpre, A(bpost) / bpost] recall: A (s) = < s, infinity> so (spost.elems = spre.elems  { i }  infinity = infinity CS 655: Lecture 18

  16. Check Invariant • Need to show: IS IT [ A(xp) / xp] true  (| bp.elems | <= bp.bound) [ A(bp) / bp] true  (| <s.elements, infinity>.elems | <= <s.elements, infinity>.bound true  true • Similar for constraint • uset is a subtype of bag! Yippee! (Except: signature of equal should take a bag!) CS 655: Lecture 18

  17. Summary Questions • uset  bset?, bset  uset? • Does the Liskov/Wing subtype relation definition match intuition? • Is it useful? CS 655: Lecture 18

  18. Eiffel and I Can’t Get Up Eiffel’s Type System

  19. Normal Procedure Type Rule f = proc(p1: P1, ..., pn: Pn) returns (X) g = proc(p1: Q1, ..., pn: Qn) returns (Y) Qi Pi forall i in 1..n X  Y f g Procedures are contravariant on parameters, covariant on results. CS 655: Lecture 18

  20. Eiffelling Athlete How can Girl override set_roomate? Covariance: set_roommate (Girl) set_roommate (Boy) Contravariance: set_roommate (Athlete) Novariance: set_roommate (Skier) (Eiffel) Skier set_roommate (Skier) (Sather) (C++ (complicated), Java) Boy Girl CS 655: Lecture 18

  21. Can’t Get Up? Athlete s: skier; g: girl; b: boy; s := g; ... s.set_roommate (b); Skier set_roommate (Skier) Girl set_roomate (Girl) Boy CS 655: Lecture 18

  22. Meyer’s Excuse Strangely enough, some workers in the field have been advocating a contravariant policy. Here it would mean that if we go for example to class RANKED_GIRL, where the result of roommate is naturally redefined to be of type RANKED_GIRL, we may for the argument of routine share use type GIRL, or rather scaringly, SKIER of the most general kind. One type that is never permitted in this case is RANKED_GIRL! Here is what, under various mathematical excuses, some professors have been promoting. No wonder teenage pregnancies are on the rise. CS 655: Lecture 18

  23. What’s wrong with Meyer’s Rule? • Disallow polymorphic catcalls: s.f (t) where some subtype of type of s hides f or changes covariantly type of parameters of f. • Violates useful notion of subtyping: adding a new subtype breaks existing programs! • Eiffel compiler will complain for redefinition CS 655: Lecture 18

  24. What does C++ really do? • Can add covariant methods in subtype, but they overload the original method, instead of overriding it! • Does this make sense? CS 655: Lecture 18

  25. class skier { public: virtual void set_roommate (class skier *s) { fprintf (stderr, "skier roomate!"); } } ; class girl : public skier { void set_roommate (class girl *g) { fprintf (stderr, "girl roomate!"); } } ; class boy : public skier { void set_roommate (class boy *b) { fprintf (stderr, "boy roomate!"); } } ; int main (void) { girl *g = new girl (); boy *b = new boy (); skier *s; s = g; s->set_roommate (b); g->set_roommate (b); } CS 655: Lecture 18

  26. Result • Both g++ and MSVC++ produce compile-time errors for g->set_roommate (b) skiers.C:27: no matching function for call to `girl::set_roommate (boy *&)' skiers.C:9: candidates are: void girl::set_roommate(girl *) • After removing this line, compiles okay, produces: “skier roomate!” (calls the superclass method) • If girl::set_roommate (girl *) overloads, but doesn’t override skier::set_roommate why does this happen? CS 655: Lecture 18

  27. Some C++ Facts • 1996 Draft Standard is 680 pages long • 50x more complex than Algol60! Is this progress? • Current open issues list of Core Language Issues contains 223 issues • Compare to Knuth’s 9 ambiguities in Algol 60 • Current open issues list for standard library (Revision 12) is 59 pages • Good luck! CS 655: Lecture 18

  28. Date: Fri, 03 Mar 2000 18:09:53 -0500 From: Avneesh Saxena <avneesh@cs.virginia.edu> To: bs@research.att.com Subject: C++: overriding problems! Sir, I am Avneesh, a graduate student in the CS Dept, Univ of Virginia. I am currently taking a course on Programming languages in which we are doing a detailed study of subclassing mechanisms in computer languages. I have learned C++ from your book "The C++ Pgm'ing Language" which is written in a very clear and concise manner. Especially, the concepts are made clear and ambiguties about language features have been discussed and resolved in an appreciable manner. However, I have run in a problem while trying to figure out what this code would do: CS 655: Lecture 18

  29. ... (example same as ours but less of a social statement) I have tried to run this code both through GCC v2.8.1 and MS-VC++, which give the same results. It appears that while we would accept other() to be accessible through the derived classes, the compiler doesn't find it. The second (more serious)problem is when other(bPtr) is called, we expect it to execute the function which has been defined in class B as it overrides the function defines in class A as the type of the actual argument matches this more closely; however, it executes the base classes function (circumvents polymorphism!). I tried to check if this behavior was consistent with the language definition but I failed to find anything which would clarify things. So, I am left wondering whether this is a case of the compiler not understanding the language and doing something wrong or is it what the language desires? I hope you will be able to clarify things for me, Thanks, Avs CS 655: Lecture 18

  30. Subject: Re: C++: overriding problems! Date: Sat, 4 Mar 2000 20:19:34 -0500 (EST) From: Bjarne Stroustrup <bs@research.att.com> To: avneesh@cs.virginia.edu > ... (copy of Avneesh’s message elided) Your problem is that you think that the two other() function overloads. They don’t functions in different scope do not overload, so when you look at scope C::other(). If you want overloading you'll have to explicitly do so in C. One simple way of doing so is to say: using B::other; in C, but that's a relatively new feature > I have tried to run this code both through GCC v2.8.1 and MS-VC++, which give the same > results. It appear that while we would accept other() to be > accessible through the derived classes, the compiler doesn't find it. I think you mean "expect", but you expect wrongly. > ... So, I am left wondering whether this is a case of the compiler not understanding the > language and doing something wrong or is it what the language desires? The compilers are wrong I suggest a re-read of the sections about deriving classes in your textbook. CS 655: Lecture 18

  31. Emailing Experts • All of you should (soon if not already) have email exchanges with experts relevant to your projects • One good email can save you reading thousands of pages! • Good to build your research contacts CS 655: Lecture 18

  32. Be polite Introduce Yourself (be brief) Flattery is always a good idea! (okay to lie a little if necessary) Do your homework first Concisely ask a clear and specific question. Date: Fri, 03 Mar 2000 18:09:53 -0500 From: Avneesh Saxena <avneesh@cs.virginia.edu> To: bs@research.att.com Subject: C++: overriding problems! Sir, I am Avneesh, a graduate student in the CS Dept, Univ of Virginia. I am currently taking a course on Programming languages in which we are doing a detailed study of subclassing mechanisms in computer languages. I have learned C++ from your book "The C++ Pgm'ing Language" which is written in a very clear and concise manner. Especially, the concepts are made clear and ambiguties about language features have been discussed and resolved in an appreciable manner. However, I have run in a problem while trying to figure out what this code would do: CS 655: Lecture 18

  33. Charge • Be ready for elevator speeches next week: • Convince the class your project is interesting and worthwhile in 90 seconds • Next time: pragmatic aspects of OO languages - comparison of Sather, Eiffel, Java and C++ CS 655: Lecture 18

More Related