CS152: Programming Languages. Lecture 23 Advanced Concepts in Object-Oriented Programming. Dan Grossman Spring 2011

Similar documents
CS-XXX: Graduate Programming Languages. Lecture 23 Types for OOP; Static Overloading and Multimethods. Dan Grossman 2012

Don t Believe the Hype. CS152: Programming Languages. Lecture 21 Object-Oriented Programming. Class-based OOP. So what is OOP?

CS152: Programming Languages. Lecture 24 Bounded Polymorphism; Classless OOP. Dan Grossman Spring 2011

CS-XXX: Graduate Programming Languages. Lecture 22 Class-Based Object-Oriented Programming. Dan Grossman 2012

Tradeoffs. CSE 505: Programming Languages. Lecture 15 Subtyping. Where shall we add useful completeness? Where shall we add completeness?

Subtyping. Lecture 13 CS 565 3/27/06

Today. CSE341: Programming Languages. Late Binding in Ruby Multiple Inheritance, Interfaces, Mixins. Ruby instance variables and methods

Late Binding; OOP as a Racket Pattern

CSE341, Fall 2011, Lecture 26 Summary

Featherweight Java (FJ)

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

Week 7. Statically-typed OO languages: C++ Closer look at subtyping

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 17: Types and Type-Checking 25 Feb 08

Object typing and subtypes

CS153: Compilers Lecture 11: Compiling Objects

History C++ Design Goals. How successful? Significant constraints. Overview of C++

Lecture 13: Subtyping

Java Inheritance. Written by John Bell for CS 342, Spring Based on chapter 6 of Learning Java by Niemeyer & Leuck, and other sources.

Interfaces, Mixins, & Multiple Inheritance

Type Hierarchy. Lecture 6: OOP, autumn 2003

CS558 Programming Languages

Subtyping (Dynamic Polymorphism)

CS107 Handout 37 Spring 2007 May 25, 2007 Introduction to Inheritance

CS558 Programming Languages Winter 2013 Lecture 8

Inheritance and object compatibility

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

Polymorphism. Miri Ben-Nissan (Kopel) Miri Kopel, Bar-Ilan University

CSE341: Programming Languages Lecture 23 Multiple Inheritance, Mixins, Interfaces, Abstract Methods. Dan Grossman Autumn 2018

Lecture Notes on Programming Languages

Part III. Chapter 15: Subtyping

CSE 431S Type Checking. Washington University Spring 2013

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

C++ Yanyan SHEN. slide 1

Lecture 13: Object orientation. Object oriented programming. Introduction. Object oriented programming. OO and ADT:s. Introduction

VIRTUAL FUNCTIONS Chapter 10

Making Inheritance Work: C++ Issues

Making Inheritance Work: C++ Issues

8 Understanding Subtyping

CS558 Programming Languages

Types for References, Exceptions and Continuations. Review of Subtyping. Γ e:τ τ <:σ Γ e:σ. Annoucements. How s the midterm going?

Virtual functions concepts

Some instance messages and methods

Type Checking in COOL (II) Lecture 10

Derived and abstract data types. TDT4205 Lecture 15

INF 212/CS 253 Type Systems. Instructors: Harry Xu Crista Lopes

Subtyping (cont) Lecture 15 CS 565 4/3/08

Recursive Types and Subtyping

Object Oriented Issues in VDM++

301AA - Advanced Programming [AP-2017]

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

CSE 505, Fall 2008, Final Examination 11 December Please do not turn the page until everyone is ready.

CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping. Dan Grossman Winter 2013

Part III Chapter 15: Subtyping

CSE 505, Fall 2007, Final Examination 10 December Please do not turn the page until everyone is ready.

QUIZ. How could we disable the automatic creation of copyconstructors

C++ Inheritance and Encapsulation

CS558 Programming Languages

QUIZ. How could we disable the automatic creation of copyconstructors

Rules and syntax for inheritance. The boring stuff

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

Software Paradigms (Lesson 3) Object-Oriented Paradigm (2)

Inheritance, Polymorphism and the Object Memory Model

INF 212 ANALYSIS OF PROG. LANGS Type Systems. Instructors: Crista Lopes Copyright Instructors.

QUIZ. Write the following for the class Bar: Default constructor Constructor Copy-constructor Overloaded assignment oper. Is a destructor needed?

Method Resolution Approaches. Dynamic Dispatch

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

Java Object Oriented Design. CSC207 Fall 2014

Introduction to Object-Oriented Programming

Subtyping (cont) Formalization of Subtyping. Lecture 15 CS 565. Inversion of the subtype relation:

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CSE 401/M501 Compilers

CMSC 330: Organization of Programming Languages

More Static Semantics. Static. One-Slide Summary. Lecture Outline. Typing Rules. Dispatch Rules SELF_TYPE

ITI Introduction to Computing II

Design issues for objectoriented. languages. Objects-only "pure" language vs mixed. Are subclasses subtypes of the superclass?

Concepts of Programming Languages

Recursive Types and Subtyping

Strict Inheritance. Object-Oriented Programming Spring 2008

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Administrivia. CMSC433, Fall 2001 Programming Language Technology and Paradigms. Administrivia (cont.) Project 1. Copy constructor.

Records. ADTs. Objects as Records. Objects as ADTs. Objects CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 15: Objects 25 Feb 05

Lecture Outline. Type systems and their expressiveness. Type Checking in COOL (II) Type checking with SELF_TYPE in COOL

Increases Program Structure which results in greater reliability. Polymorphism

Programming Language Concepts Object-Oriented Programming. Janyl Jumadinova 28 February, 2017

COMP322 - Introduction to C++ Lecture 09 - Inheritance continued

Programming Languages and Techniques (CIS120e)

Featherweight Java. Lecture 12 CS 565 3/18/08

CPS 506 Comparative Programming Languages. Programming Language

HAS-A Relationship. If A uses B, then it is an aggregation, stating that B exists independently from A.

ITI Introduction to Computing II

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Conformance. Object-Oriented Programming Spring 2015

Object Oriented Paradigm

Introduction to Object-Oriented Programming

Rushikesh K Joshi. Department of Computer Science and Engineering Indian Institute of Technology Bombay

Chapter 2: Java OO II X I A N G Z H A N G

Project 6 Due 11:59:59pm Thu, Dec 10, 2015

Transcription:

CS152: Programming Languages Lecture 23 Advanced Concepts in Object-Oriented Programming Dan Grossman Spring 2011

So far... The difference between OOP and records of functions with shared private state is dynamic-dispatch (a.k.a. late-binding) of self (Informally) defined method-lookup to implement dynamic-dispatch correctly: use run-time tags or code-pointers Now: Subclassing vs. subtyping Then fancy stuff: multiple-inheritance, interfaces, static overloading, multiple dispatch Next lecture: Bounded polymorphism and classless OOP Dan Grossman CS152 Spring 2011, Lecture 23 2

Type-Safety in OOP Should be clearer about what type-safety means... Not getting stuck has meant don t apply numbers, don t add functions, don t read non-existent record fields, etc. Pure OO has only method calls (and maybe field access) Stuck if method-lookup fails (no method matches) Stuck if method-lookup is ambiguous (no best match) So far only failure is receiver has no method with right name/arity Dan Grossman CS152 Spring 2011, Lecture 23 3

Revisiting Subclassing is Subtyping Recall we have been confusing classes and types: C is a class and a type and if C extends D then C is a subtype of D Therefore, if C overrides m, the type of m in C must be a subtype of the type of m in D Just like functions, method-subtyping is contravariant arguments and covariant results If code knows it has a C, it can call methods with more arguments and know there are fewer results Dan Grossman CS152 Spring 2011, Lecture 23 4

Subtyping and Dynamic Dispatch We defined dynamic dispatch in terms of functions taking self as an argument But unlike other arguments, self is covariant!! Else overriding method couldn t access new fields/methods Sound because self must be passed, not another value with the supertype This is the key reason encoding OO in a typed λ-calculus requires ingenuity, fancy types, and/or run-time cost We won t attempt it Dan Grossman CS152 Spring 2011, Lecture 23 5

More subtyping With single-inheritance and the class/type confusion, we don t get all the subtyping we want Example: Taking any object that has an m method from int to int Interfaces help somewhat, but class declarations must still say they implement an interface Object-types bring the flexibility of structural subtyping to OOP With object-types, subclassing implies subtyping Dan Grossman CS152 Spring 2011, Lecture 23 6

More subclassing Breaking one direction of subclassing = subtyping allowed more subtyping (so more code reuse) Breaking the other direction ( subclassing does not imply subtyping ) allows more inheritance (so more code reuse) Simple idea: If C extends D and overrides a method in a way that makes C D unsound, then C D. This is useful: class P1 {... Int get_x(); Bool compare(p1);... } class P2 extends P1 {... Bool compare(p2);... } But this is not always correct... Dan Grossman CS152 Spring 2011, Lecture 23 7

Subclass not a subtype class P1 { Int x; Int get_x() { x } Bool compare(p1 p) { self.get_x() == p.get_x() } } class P2 extends P1 { Int y; Int get_y() { y } Bool compare(p2 p) { self.get_x() == p.get_x() && self.get_y() == p.get_y() } } As expected, P2 P1 is unsound (assuming compare in P2 is overriding unlike in Java or C++) Dan Grossman CS152 Spring 2011, Lecture 23 8

Subclass not a subtype Can still inherit implementation (need not reimplement get_x) We cannot always do this: what if get_x called self.compare? Possible solutions: Re-typecheck get_x in subclass Use a Really Fancy Type System I see little use in allowing subclassing that is not subtyping But I see much use in understanding that typing is about interfaces and inheritance is about code-sharing Dan Grossman CS152 Spring 2011, Lecture 23 9

Where we are Summary of last few slides: Separating types and classes expands the language, but clarifies the concepts: Typing is about interfaces, subtyping about broader interfaces Inheritance (a.k.a. subclassing) is about code-sharing Combining typing and inheritance restricts both Most OO languages purposely confuse subtyping (about type-checking) and inheritance (about code-sharing), which is reasonble in practice Dan Grossman CS152 Spring 2011, Lecture 23 10

Multiple Inheritance Why not allow class C extends C1,C2,...{...} (and C C1 and C C2)? What everyone agrees: C++ has it and Java doesn t All we ll do: Understand some basic problems it introduces and how interfaces get most of the benefits and some of the problems Problem sources: Class hierarchy is a dag, not a tree (not true with interfaces) Subtype hierarchy is a dag, not a tree (true with interfaces) Dan Grossman CS152 Spring 2011, Lecture 23 11

Diamond Issues If C extends C1 and C2 and C1,C2 have a common superclass D (perhaps transitively), our class hierarchy has a diamond If D has a field f, should C have one field f or two? If D has a method m, C1 and C2 will have a clash If subsumption is coercive (changing method-lookup), how we subsume from C to D affects run-time behavior (incoherent) Diamonds are common, largely because of types like Object with methods like equals Dan Grossman CS152 Spring 2011, Lecture 23 12

Multiple Inheritance, Method-Name Clash If C extends C1 and C2, which both define a method m, what does C mean? Possibilities: 1. Reject declaration of C (Too restrictive with diamonds) 2. Require C to override m (Possibly with directed resends) 3. Left-side (C1) wins (Must decide if upcast to right-side (C2) coerces to use C2 s m or not) 4. C gets both methods (Now upcasts definitely coercive and with diamonds we lose coherence) 5. Other? (I m just brainstorming based on sound principles) Dan Grossman CS152 Spring 2011, Lecture 23 13

Implementation Issues This isn t an implementation course, but many semantic issues regarding multiple inheritance have been heavily influenced by clever implementations In particular, accessing members of self via compile-time offsets...... which won t work with multiple inheritance unless upcasts adjust the self pointer That s one reason C++ has different kinds of casts Better to think semantically first (how should subsumption affect the behavior of method-lookup) and implementation-wise second (what can I optimize based on the class/type hierarchy) Dan Grossman CS152 Spring 2011, Lecture 23 14

Digression: Casts A cast can mean many things (cf. C++). At the language level: upcast: no run-time effect until we get to static overloading downcast: run-time failure or no-effect conversion: key question is round-tripping reinterpret bits : not well-defined At the implementation level: upcast: usually no run-time effect but see last slide downcast: usually only run-time effect is failure, but... conversion: same as at language level reinterpret bits : no effect (by definition) Dan Grossman CS152 Spring 2011, Lecture 23 15

Least Supertypes Consider if e 1 then e 2 else e 3 (or in C++/Java, e 1? e 2 : e 3 ) We know e 2 and e 3 must have the same type With subtyping, they just need a common supertype Should pick the least (most-specific) type Single inheritance: the closest common ancestor in the class-hierarchy tree Multiple inheritance: there may be no least common supertype Example: C1 extends D1, D2 and C2 extends D1, D2 Solutions: Reject (i.e., programmer must insert explicit casts to pick a common supertype) Dan Grossman CS152 Spring 2011, Lecture 23 16

Multiple Inheritance Summary Method clashes (what does inheriting m mean) Diamond issues (coherence issues, shared (?) fields) Implementation issues (slower method-lookup) Least supertypes (may be ambiguous) Complicated constructs lead to difficult language design Doesn t necessarily mean they are bad ideas Now discuss interfaces and see how (and how not) multiple interfaces are simpler than multiple inheritance... Dan Grossman CS152 Spring 2011, Lecture 23 17

Interfaces An interface is just a (named) (object) type. Example: interface I { Int get_x(); Bool compare(i); } A class can implement an interface. Example: class C implements I { Int x; Int get_x() {x} Bool compare(i i) {...} // note argument type } If C implements I, then C I Requiring explicit implements hinders extensibility, but simplifies type-checking (a little) Basically, C implements I if C could extend a class with all abstract methods from I Dan Grossman CS152 Spring 2011, Lecture 23 18

Interfaces, continued Subinterfaces (interface J extends I {...}) work exactly as subtyping suggests they should An unnecessary addition to a language with abstract classes and multiple inheritance, but what about single inheritance and multiple interfaces: class C extends D implements I1,I2,...,In Method clashes (no problem, inherit from D) Diamond issues (no problem, no implementation diamond) Implementation issues (still a problem, different object of type I will have different layouts) Least supertypes (still a problem, this is a typing issue) Dan Grossman CS152 Spring 2011, Lecture 23 19

Using Interfaces Although it requires more keystrokes and makes efficient implementation harder, it may make sense (be more extensible) to: Use interface types for all fields and variables Don t use constructors directly: For class C implementing I, write: I makei(...) { new C(...) } This is related to factory patterns ; constructors are behind a level of indirection It is using named object-types instead of class-based types Dan Grossman CS152 Spring 2011, Lecture 23 20

Static Overloading So far, we have assumed every method had a different name Same name implied overriding and required a subtype Many OO languages allow the same name for methods with different argument types: A f(b x) {... } C f(d x, E y) {... } F f(g x, H z) {... } Complicates definition of method-lookup for e1.m(e2,...,en) Previously, we had dynamic-dispatch on e1: method-lookup a function of the class of the object e1 evaluates to (at run-time) We now have static overloading: Method-lookup is also a function of the types of e2,...,en (at compile-time) Dan Grossman CS152 Spring 2011, Lecture 23 21

Static Overloading Continued Because of subtyping, multiple methods can match! Best-match can be roughly Subsume fewest arguments. For a tie, allow subsumption to immediate supertypes and recur Ambiguities remain (no best match): A f(b) vs. C f(b) (usually rejected) A f(i) vs. A f(j) for f(e) where e has type T, T I, T J and I,J are incomparable (We saw this before) A f(b,c) vs. A f(c,b) for f(e1,e2) where B C, and e1 and e2 have type B Type systems often reject ambiguous calls or use ad hoc rules to give a best match (e.g., left-argument precedence ) Dan Grossman CS152 Spring 2011, Lecture 23 22

Multiple Dispatch Static overloading saves keystrokes from shorter method-names We know the compile-time types of arguments at each call-site, so we could call methods with different names Multiple (dynamic) dispatch (a.k.a. multimethods) is much more interesting: Method-lookup a function of the run-time types of arguments It s a natural generalization: the receiver argument is no longer treated differently! So e1.m(e2,...,en) is just sugar for m(e1,e2,...,en) It wasn t before, e.g., when e1 is self and may be a subtype Dan Grossman CS152 Spring 2011, Lecture 23 23

Example class A { int f; } class B extends A { int g; } Bool compare(a x, A y) { x.f == y.f } Bool compare(b x, B y) { x.f == y.f && x.g == y.g } Bool f(a x, A y, A z) { compare(x,y) && compare(y,z) } Neat: late-binding for both arguments to compare (choose second method if both arguments are subtypes of B, else first method) With power comes danger. Tricky question: Can we add && compare(x,z) to body of f and have an equivalent function? With static overloading? With multiple dispatch? Dan Grossman CS152 Spring 2011, Lecture 23 24

Pragmatics Not clear where multimethods should be defined No longer belong to a class because receiver isn t special Multimethods are more OO because dynamic dispatch is the essence of OO Multimethods are less OO because without a distinguished receiver the analogy to physical objects is reduced Nice paper in OOPSLA08: Multiple Dispatch in Practice Dan Grossman CS152 Spring 2011, Lecture 23 25

Revenge of Ambiguity The no best match issues with static overloading exist with multimethods and ambiguities arise at run-time It s undecidable if no best match will happen: // B <= C A f(b,c) {...} A f(c,b) {...} unit g(c a, C b) { f(a,b); /* may be ambiguous */ } Possible solutions: Raise exception when no best match Define best match such that it always exists A conservative type system to reject programs that might have a no best match error when run Dan Grossman CS152 Spring 2011, Lecture 23 26

Summary so far Sketched several advanced issues in class-based OOP: multiple inheritance thorny semantics interfaces less thorny, but no least supertypes static overloading reuse method names, get ambiguities multimethods generalizes late-binding, ambiguities at run-time But there s still no good way to define a container type such as homogeneous lists Add back in parametric polymorphism Dan Grossman CS152 Spring 2011, Lecture 23 27