cs 251 fall 2019 cs 251 fall 2019 oo essence principles
play

CS 251 Fall 2019 CS 251 Fall 2019 OO essence: Principles of - PowerPoint PPT Presentation

CS 251 Fall 2019 CS 251 Fall 2019 OO essence: Principles of Programming Languages Principles of Programming Languages Ben Wood Ben Wood Program design principles? Subtyping Objects model state/behavior of real-world


  1. λ λ CS 251 Fall 2019 CS 251 Fall 2019 OO essence: Principles of Programming Languages Principles of Programming Languages Ben Wood Ben Wood • Program design principles? Subtyping – Objects model state/behavior of real-world entities/concepts? Kinda – Organization by classification and encapsulation and Substitutivity – Reuse via implicit extensibility • Key semantics: – Late binding / dynamic dispatch – Su Substitutability and subtyping – Inheritance or delegation Will contrast function-oriented principles/semantics later. https://cs.wellesley.edu/~cs251/f19/ 1 Subtyping 2 Subtyping Subtyping and substitutability Subtyping and substitutability class Rectangle { void f() { void f() { private int x,y,w,h; Rectangle r = Rectangle r = void moveTo(int x, int y); new Rectangle (); new FilledRectangle (); void setSize(int width, int height); r.moveTo(100,100); r.moveTo(100,100); void show(); void hide(); r.hide(); r.hide(); } } } Which are Wh e safe? e? class FilledRectangle { private int x,y,w,h; void g() { void g() { private Color c; void moveTo(int x, int y); FilledRectangle r = FilledRectangle r = void setSize(int width, int height); new FilledRectangle (); new Rectangle (); void show(); r.moveTo(100,100); r.moveTo(100,100); void hide(); r.setFillColor(Color.red); r.setFillColor(Color.red); void setFillColor(Color color); r.hide(); r.hide(); Color getFillColor(); } } } Subtyping 3 Subtyping 4

  2. Subtyping: broad definitions Type variable instantiation is NO NOT subtyping. Parametric polymorphism ≠ subtype polymorphism Job of type system: Jo If a program type-checks, th then evaluation of the program never If applies an operation to an incompatible value. map : ('a -> 'b) -> 'a list -> 'b list Ne New type relation: T <: U "Type T is a subtype of type U." f : int -> int Sound on only if all operations that are valid on values of type U are also valid on values of type T. xs : int list New type-ch Ne checki cking rule le: If e : T and T <: U th If then e : U . ß type-check (map f xs) : int list Principle: substitutability. type variable instantiation: 'a = int, 'b = int ML ML has no su subtyping Subtyping 5 Subtyping 6 Mutable Records (made-up lang.) A made-up language for subtyping data (half like ML, half like Java) ation (field names and contents): Record cr creat {f1=e1, f2=e2, …, fn=en} • Can cover most core subtyping ideas by Evaluate all ei , make a record considering re records wi with mutable fields Record field acce access : e.f Evaluate e to record v with an f field, get contents of f field • Make up our own syntax e1.f = e2 Record field up update – ML records, no subtyping or field-mutation Evaluate e1 to a record v1 and e2 to a value v2 ; – Racket and Smalltalk: no static type system Change v1 's f field (which must exist) to v2 ; Return v2 – Java is verbose Subtyping 7 Subtyping 8

  3. A Basic Type System Type system is so sound (safe). Record ty Re types : fields a record has, type for each field Does this program type check? Can it ever try to access a non-existent field? {f1:t1, f2:t2, …, fn:tn} Ty Type-ch check ecking expressions: fun distToOrigin (p:{x:real,y:real}) = • If e1 : t1 , … , en : tn Math.sqrt(p.x*p.x + p.y*p.y) then {f1=e1,…,fn=en} : {f1:t1,…,fn:tn} val p : {x:real,y:real} = • If e : {…,f:t,…} {x=3.0, y=4.0} then e.f : t • If e1 : {…,f:t,…} and e2 : t , val five : real = distToOrigin( p ) then e1.f = e2 : t Subtyping 9 Subtyping 10 Type system is so sound (safe) . Why not allow extra fields? Natural idea of related types: if expression has type Na Does this program type check? Can it ever try to access a non-existent field? {f1 : t1, f2 : t2, ..., fn : tn} Then it also can have a type with a subset of those fields. fun distToOrigin (p:{x:real,y:real}) = Math.sqrt(p.x*p.x + p.y*p.y) fun distToOrigin (p:{x:real,y:real}) = … val c : {x:real,y:real,color:string} = fun makePurple (p:{color:string}) = {x=3.0, y=4.0, color="green"} p.color = "purple" val c :{x:real,y:real,color:string} = val five : real = distToOrigin( c ) {x=3.0, y=4.0, color="green"} val _ = distToOrigin(c) But type system is (too?) conservative. val _ = makePurple(c) Subtyping 11 Subtyping 12

  4. Changing the type system 4 reasonable subtyping rules Princ Pr nciple: su substitutability So Soluti ution: n: 2 additions, no changes If t1 <: t2 , then values of type t1 must be usable in every way values of type t2 are. – su subtypi ping rel relation : t1 <: t2 " t1 is a subtype of t2 " 1. 1. “Wi Width” subtyping: A supertype can have a subset of fields with the same types. – ne new ty typing ng ru rule: 2. 2. “P “Permutation” ” su subtyping: If e : t1 and t1 <: t2 , A supertype can have the same set of fields with the same types in a different order. then (also) e : t2 3. 3. Transitivity: Tr If t1 <: t2 and t2 <: t3 , then t1 <: t3 . 4. 4. Reflex Re exivity: No Now def efine e t1 <: t2 Every type is a subtype of itself: t <: t May seem unnecessary, but simplifies other rules in large languages Subtyping 13 Subtyping 14 Depth subtyping? Depth subtyping? fun circleY (c:{center:{x:real,y:real}, r:real}) = fun circleY (c:{center:{x:real,y:real}, r:real}) = c.center.y c.center.y val sphere:{center:{x:real,y:real,z:real}, r:real} = val sphere:{center:{x:real,y:real,z:real}, r:real} = {center={x=3.0,y=4.0,z=0.0}, r=1.0} {center={x=3.0,y=4.0,z=0.0}, r=1.0} val _ = circleY(sphere) val _ = circleY(sphere) Does this currently type-check? Does it ever try to use non-existent fields? Ty Type checks only if: How could we change the type system to allow it? {center:{x:real,y:real,z:real}, r:real} <: Should we? {center:{x:real,y:real}, r:real} Subtyping 15 Subtyping 16

  5. Adding depth subtyping St Stop! Ne New subt btyping ru rule: We added a new subtyping rule If ta <: tb , to make type system more flexible. then {f1:t1, …, f: ta , …, fn:tn} <: {f1:t1, …, f: tb , …, fn:tn} But is it sound? Bu Does it allow any program that accesses non- fun circleY (c:{center:{x:real,y:real}, r:real}) = c.center.y existent fields? val sphere:{center:{x:real,y:real,z:real}, r:real} = {center={x=3.0,y=4.0,z=0.0}, r=1.0} val _ = circleY(sphere) Does it type-check now? Subtyping 17 Subtyping 18 Mutation strikes again Moral of the story In a language with records/objects with mu mutable fields , dept de pth subtypi ping is uns unsound und. Subtyping ca Su canno nnot t allow ch changi nging ng th the typ type of mu mutable fields. fun setToOrigin (c:{center:{x:real,y:real}, r:real})= c.center = {x=0.0, y=0.0} If fields are im immutable , then de dept pth subtypi ping is sound ! val sphere:{center:{x:real,y:real,z:real}, r:real} = {center={x=3.0, y=4.0, z=0.0}, r=1.0} Choose at most two of three: val _ = setToOrigin(sphere) – mutability val _ = sphere.center.z (* kaboom! (no z field) *) – depth subtyping – soundness Subtyping 19 Subtyping 20

  6. !!! !!! !!! !!! Subtyping mistakes: Java (really) What??? if t1 <: t2 , then t1[] <: t2[] Wh Why allow it? "Covariant array subtyping" Object[] System.arrayCopy(Object[] src) {…} Seemed especially important before generics class Point { … } What goes wrong? Wh class ColorPoint extends Point { … } … void replaceFirst(Point[] pts) { pts[0] = new Point(3,4); } String m2(int x) { ColorPoint[] cpts = new ColorPoint[x]; for(int i=0; i < x; i++) "F "Fix:" :" dynamic checking on every non-primitive array store. cpts[i] = new ColorPoint(0,0,"green"); replaceFirst(cpts); ArrayStoreException return cpts[0].color; } Subtyping 21 Subtyping 22 !!! !!! !!! !!! From Bill Joy (Sun Cofounder) Hypothetical: Allow subclass C to change type of field from Date: Fri, 09 Oct 1998 09:41:05 -0600 From: bill joy superclass in scope of C Subject: …[discussion about java genericity] – To unrelated type actually, java array covariance was done for less noble reasons …: it – To supertype of field's original type made some generic "bcopy" (memory copy) and like operations much – To subtype of field's original type easier to write... I proposed to take this out in 95, but it was too late (...). i think it is unfortunate that it wasn't taken out... Which ones go wrong? it would have made adding genericity later much cleaner, and [array covariance] doesn't pay for its complexity today. wnj Subtyping 23 Subtyping 24

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend