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

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

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

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

CSci 4223 Lecture 18 April 3, 2013 Topics: OOP vs. FP

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

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

CSE341: Programming Languages Lecture 22 OOP vs. Functional Decomposition; Adding Operators & Variants; Double-Dispatch. Dan Grossman Autumn 2018

Concepts of Programming Languages

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

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

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

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

CS558 Programming Languages Winter 2013 Lecture 8

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

Late Binding; OOP as a Racket Pattern

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CPS 506 Comparative Programming Languages. Programming Language

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

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

CSE 505: Concepts of Programming Languages

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

Featherweight Java (FJ)

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

Subtyping. Lecture 13 CS 565 3/27/06

Lecture Notes on Programming Languages

What s Conformance? Conformance. Conformance and Class Invariants Question: Conformance and Overriding

Type Hierarchy. Lecture 6: OOP, autumn 2003

CSEP505 Programming Languages, Autumn 2016, Final Exam December, Programming Languages for a World of Change

Lecture 13: Subtyping

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

CS152: Programming Languages. Lecture 7 Lambda Calculus. Dan Grossman Spring 2011

Inheritance. Inheritance Reserved word protected Reserved word super Overriding methods Class Hierarchies Reading for this lecture: L&L

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

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

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

Object typing and subtypes

CSE341: Programming Languages Lecture 19 Introduction to Ruby and OOP. Dan Grossman Winter 2013

Java Object Oriented Design. CSC207 Fall 2014

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Ruby logistics. CSE341: Programming Languages Lecture 19 Introduction to Ruby and OOP. Ruby: Not our focus. Ruby: Our focus. A note on the homework

1B1b Inheritance. Inheritance. Agenda. Subclass and Superclass. Superclass. Generalisation & Specialisation. Shapes and Squares. 1B1b Lecture Slides

On to Objects. CIS 500 Software Foundations Fall November 20. A Change of Pace. Case study: object-oriented programming

Object Oriented Issues in VDM++

Semantic Analysis. How to Ensure Type-Safety. What Are Types? Static vs. Dynamic Typing. Type Checking. Last time: CS412/CS413

CSE 341: Programming Languages

CSE 413 Spring Introduction to Ruby. Credit: Dan Grossman, CSE341

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Lecture Contents CS313D: ADVANCED PROGRAMMING LANGUAGE. What is Inheritance?

CSE341 Spring 2017, Final Examination June 8, 2017

Inheritance, Polymorphism and the Object Memory Model

CMSC330. Objects, Functional Programming, and lambda calculus

CS313D: ADVANCED PROGRAMMING LANGUAGE

CSE-505: Programming Languages. Lecture 18 Existential Types. Zach Tatlock 2016

CS153: Compilers Lecture 11: Compiling Objects

Part III. Chapter 15: Subtyping

CSE Lecture 3: Objects 2 September Nate Nystrom University of Texas at Arlington

Chapter 4 Defining Classes I

CS-202 Introduction to Object Oriented Programming

Inheritance and object compatibility

CS558 Programming Languages

Chapter 5 Object-Oriented Programming

Part III Chapter 15: Subtyping

Cunning Plan. One-Slide Summary. Functional Programming. Functional Programming. Introduction to COOL #1. Classroom Object-Oriented Language

Programming II (CS300)

CS558 Programming Languages

Exceptions and Continuations. Lecture #19: More Special Effects Exceptions and OOP. Approach II: Non-Standard Return. Approach I: Do Nothing

Rules and syntax for inheritance. The boring stuff

CSE 341, Autumn 2015, Ruby Introduction Summary

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

Java: introduction to object-oriented features

CompuScholar, Inc. 9th - 12th grades

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

Interfaces, Mixins, & Multiple Inheritance

CSE 431S Type Checking. Washington University Spring 2013

Functional Programming. Introduction To Cool

ITI Introduction to Computing II

CSE341 Spring 2017, Final Examination June 8, 2017

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

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

PROGRAMMING LANGUAGE 2

Type Hierarchy. Comp-303 : Programming Techniques Lecture 9. Alexandre Denault Computer Science McGill University Winter 2004

CS111: PROGRAMMING LANGUAGE II

Project 2 Due 11:59:59pm Wed, Mar 7, 2012

Atelier Java - J1. Marwan Burelle. EPITA Première Année Cycle Ingénieur.

COMP 401 INHERITANCE: IS-A. Instructor: Prasun Dewan

Chapter 5: Procedural abstraction. Function procedures. Function procedures. Proper procedures and function procedures

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

Lecture 3: Recursion; Structural Induction

CS111: PROGRAMMING LANGUAGE II

Object Oriented Paradigm

Big Bang. Designing a Statically Typed Scripting Language. Pottayil Harisanker Menon, Zachary Palmer, Scott F. Smith, Alexander Rozenshteyn

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

ITI Introduction to Computing II

CSE 341: Programming Languages

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

A Short Summary of Javali

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

Data Structures and Algorithms Design Goals Implementation Goals Design Principles Design Techniques. Version 03.s 2-1

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

CS/ENGRD 2110 FALL Lecture 6: Consequence of type, casting; function equals

Transcription:

Don t Believe the Hype CS152: Programming Languages Lecture 21 Object-Oriented Programming Dan Grossman Spring 2011 OOP lets you: 1. Build some extensible software concisely 2. Exploit an intuitive analogy between interaction of physical entities and interaction of software pieces It also: Raises tricky semantic and style issues that deserve careful PL study Is more complicated than functions Not necessarily worse, but I m skeptical that all those accessor methods are productive Dan Grossman CS152 Spring 2011, Lecture 21 2 So what is OOP? OOP looks like this, but what s the essence? class Point1 extends Object { int x; int get_x() { x unit set_x(int y) { self.x = y int distance(point1 p) { p.get_x() - self.get_x() constructor() { x = 0 class Point2 extends Point1 { int y; int get_y() { y int get_x() { 34+super.get_x() constructor() { super(); y=0; Class-based OOP In (pure) class-based OOP: 1. Everything is an object 2. Objects communicate via messages (handled by methods) 3. Objects have their own state 4. Every object is an instance of a class 5. A class describes its instances behavior Why is this approach such a popular way to structure software?... Dan Grossman CS152 Spring 2011, Lecture 21 3 Dan Grossman CS152 Spring 2011, Lecture 21 4 OOP can mean many things An ADT (private fields) Inheritance, method/field extension, method override Implicit this / self Dynamic dispatch Subtyping All the above (plus constructor(s)) with 1 class declaration Design question: Better to have small orthogonal features or one do it all feature? Anyway, let s consider how unique to OO each is... Dan Grossman CS152 Spring 2011, Lecture 21 5 OO as ADT-focused Fields, methods, constructors often have visibilities What code can invoke a method / access a field? Other methods in same object, other methods in same class, a subclass, within some other boundary (e.g., a package), any code,... With just classes, the only other way to hide a member is cast to supertype. With interfaces (which are more like record types), we can hide members more selectively: interface I { int distance(point1 p); class Point1 implements I {... I f() { self... (This all assumes no downcasts, reflection, etc.) Previously: objects are a bad match for strong binary methods distance takes a Point1, notani Dan Grossman CS152 Spring 2011, Lecture 21 6

Records with private fields If OOP = functions + private fields, we already have it But it s more (e.g., inheritance) type t = { get_x : unit -> int; set_x : int -> unit; distance : t -> int let point1_constructor () = let x = ref 0 in { get_x = (fun () ->!x); set_x = (fun y -> x := y); distance = (fun p -> p.get_x() - self.get_x() ) in self Subtyping Most class-based OO languages confuse classes and types: If C is a class, then C is a type If C extends D (via declaration), then C D Subtyping is (only) the reflexive, transitive closure of this Is this novel? If C adds members, that s width subtyping This is by name subtyping: If classes C1 and C2 are incomparable in the class hierarchy they are incomparable types, even if they have the same members Dan Grossman CS152 Spring 2011, Lecture 21 7 Dan Grossman CS152 Spring 2011, Lecture 21 8 Subtyping, continued Inheritance and Override If C extends D and overrides a method of D, what restrictions should we have? Argument types contravariant (assume less about arguments) Result type covariant (provide more about result) Many real languages are even more restrictive Often in favor of static overloading Some bend over backward to be more flexible At expense of run-time checks/casts/failures Subclasses: 1. inherit fields and methods of superclass 2. can override methods 3. can use super calls (a.k.a. resends) CanwecodethisupinCaml? No because of field-name reuse and lack of subtyping, but ignoring that and trying is illuminating... It s good we studied this in a simpler setting Dan Grossman CS152 Spring 2011, Lecture 21 9 Dan Grossman CS152 Spring 2011, Lecture 21 10 Attempting Inheritance let point1_constructor () = let x = ref 0 in { get_x = (fun () ->!x); set_x = (fun y -> x := y); distance = (fun p -> p.get_x() - self.get_x() ) in self (* note: adding get_y prevents type-checking in Caml *) let point2_constructor () = let r = point1_constructor () in let y = ref 0 in { get_x = (fun () -> 34 + r.get_x()); set_x = r.set_x; distance = r.distance; get_y = (fun () ->!y) in self Dan Grossman CS152 Spring 2011, Lecture 21 11 Problems Small problems: Have to change point2 code when point1 changes. But OOPs have tons of fragile base class issues too No direct access to private fields of super-class Big problem: Distance method in point2 code doesn t behave how it does in OOP!!! We do not have late-binding of self (i.e., dynamic dispatch) Dan Grossman CS152 Spring 2011, Lecture 21 12

The essence Claim: Class-based object are: So-so ADTs Same-old record and function subtyping Some syntactic sugar for extension and override And: A fundamentally different rule for what self maps to in the environment Dan Grossman CS152 Spring 2011, Lecture 21 13 More on late binding Late-binding, dynamic dispatch, and open recursion are all essentially synonyms. The simplest example I know: Functional (even still O(n)) let c1() = let rec r = { even i = if i > 0 then r.odd (i-1) else true; odd i = if i > 0 then r.even (i-1) else false in r let c2() = let r1 = c1() in let rec r = {even = r1.even; odd i = i % 2 == 1 in r OO (even now O(1)): class C1 { int even(int i) {if i>0 then odd(i-1) else true int odd(int i) {if i>0 then even(i-1) else false class C2 extends C1 { int odd(int i) {i % 2 == 1 Dan Grossman CS152 Spring 2011, Lecture 21 14 The big debate Open recursion: Code reuse: improve even by just changing odd Superclass has to do less extensibility planning Closed recursion: Code abuse: break even by just breaking odd Superclass has to do more abstraction planning Reality: Both have proved very useful; should probably just argue over the right default Where We re Going Now we know overriding and dynamic dispatch is the interesting part of the expression language. Next: How exactly do we define method dispatch? How do we use overriding for extensible software? Revisiting subtyping is subclassing Usually convenient Not necessary Not always desirable Dan Grossman CS152 Spring 2011, Lecture 21 15 Dan Grossman CS152 Spring 2011, Lecture 21 16 Defining Dispatch Focus on correct definitions, not super-efficient compilation techniques Methods take self as an argument (Compile down to functions taking an extra argument) So just need self bound to the right thing Approach 1: Each object has 1 code pointer per method For new C() where C extends D: Start with code pointers for D (inductive definition!) If C adds m, add code pointer for m If C overrides m, change code pointer for m self bound to the (whole) object in method body Dispatch continued Approach 2: Each object has 1 run-time tag For new C() where C extends D, tagisc self bound to the (whole) object in method body Method call to m reads tag, looks up (tag,m) in a global table Both approaches model dynamic-dispatch and are routinely formalized in PL papers. Real implementations a bit more clever. Difference in approaches only observable in languages with run-time adding/removing/changing of methods. Informal claim: This is hard to explain to freshmen, but in the presence of overriding, no simpler definition is correct. Else it s not OOP and overriding leads to faulty reasoning Dan Grossman CS152 Spring 2011, Lecture 21 17 Dan Grossman CS152 Spring 2011, Lecture 21 18

Overriding and Hierarchy Design Subclass writer decides what to override to modify behavior Often-claimed unchecked style issue: overriding should specialize behavior But superclass writer often has ideas on what will be overridden Leads to abstract methods (must override) and abstract classes: An abstract class has > 0 abstract methods Overriding an abstract method makes it non-abstract Cannot call constructor of an abstract class Adds no expressiveness (superclass could implement method to raise an exception or loop forever), but uses static checking to enforce an idiom and saves you a handful of keystrokes Dan Grossman CS152 Spring 2011, Lecture 21 19 Overriding for Extensibility APLexample: class Exp { abstract Exp eval(env); abstract Typ typecheck(ctxt); abstract Int toint(); class IntExp extends class Exp { Int i; Exp eval(env e) { self Typ typecheck(ctxt c) { new IntTyp() Int toint() { i constructor(int _i) { i=_i Dan Grossman CS152 Spring 2011, Lecture 21 20 Example Continued class AddExp extends class Exp { Exp e1; Exp e2; Exp eval(env e) { new IntExp(e1.eval(e).toInt().add( e2.eval(e).toint())); Typ typecheck(ctxt c) { if(e1.typecheck(c).equals(new IntTyp()) && e2.typecheck(c).equals(new IntTyp())) new IntTyp() else throw new TypeError() Int toint() { throw new BadCall() Impure OO may have a plus primitive (not a method call) Pure OO continued Can make everything an object and all primitives method calls (cf. Smalltalk, Ruby,...) Example: true and false are objects with ifthenelse methods e1.typecheck(c).equals(new IntTyp()).ifThenElse( e2.typecheck(c).equals(new IntTyp()).ifThenElse( (fun () -> new IntTyp()), (fun () -> throw new TypeError())), (fun () -> throw new TypeError())) Essentially identical to the lambda-calculus encoding of booleans Closures are just objects with one method, perhaps called apply Dan Grossman CS152 Spring 2011, Lecture 21 21 Dan Grossman CS152 Spring 2011, Lecture 21 22 Extending the example Now suppose we want MultExp No change to existing code, unlike ML In ML, we would have to prepare with an Else of a variant and make Exp a type-constructor In general, requires very fancy acrobatics Now suppose we want a tostring method Must change all existing classes, unlike ML In OOP, we would have to prepare with a Visitor pattern In general, requires very fancy acrobatics Extensibility has many dimensions most require forethought! See picture... Variants and Operations Given a type with several variants/subtypes and several functions/methods, there s a 2D-grid of code you need: Int Negate Add Mult eval tostring haszero OO and FP just lay out the code differently! Which is more convenient depends on what you re doing and how the variants/operations fit together Often, tools let you view the other dimension Opinion: Dimensional structure of code is greater than 2 3, so we ll never have exactly what we want in text Dan Grossman CS152 Spring 2011, Lecture 21 23 Dan Grossman CS152 Spring 2011, Lecture 21 24

Yet more example Now consider actually adding MultExp If you have MultExp extend Exp, you will copy typecheck from AddExp If you have MultExp extend AddExp, you don t copy. The AddExp implementer was not expecting that. May be brittle; generally considered bad style. Best (?) of both worlds by refactoring with an abstract BinIntExp class implementing typecheck. Sowechoose to change AddExp when we add MultExp. This intermediate class is a fairly heavyweight way to use a helper function Dan Grossman CS152 Spring 2011, Lecture 21 25