DOC PREVIEW
UW CSE 341 - Programming Languages

This preview shows page 1-2-3-4 out of 12 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 12 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 12 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 12 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 12 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 12 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

'&$%CSE 341:Programming LanguagesDan GrossmanSpring 2004Lecture 25— Static Overloading; Subtype vs. ParametricPolymorphism; Bounded QuantificationDan Grossman CSE341 Spring 2004, Lecture 25 1'&$%Static OverloadingMany OO languages allow methods in the same class to have the same“name” but different argument types. E.g.:void show(Window w) ...void show(DancingBear db) ...float distTo(Point p) ...float distTo(3DPoint p) ...This complicates slightly the semantics of message send. As before,we:• Use the class (“run-time type”) of the receiver to pick a method.• Call the method with the receiver bound to self.But now there are multiple methods with the same name, so we:• Use the (compile-time) types of the arguments to pick the “bestmatch”.Dan Grossman CSE341 Spring 2004, Lecture 25 2'&$%A lower-level viewHere’s an equivalent way to think about it:• A method’s name includes the types of its “formal” arguments(e.g., show$Window)• A message send is rewritten with the types of its “actual”arguments after typechecking (e.g., show(e) becaomesshow$Window(e) if e has type Window.This seems like an “ugly” view, but:• It’s exactly how static overloading is implemented.• It suggests static overloading is not very “interesting”, justconvenient.But... It interacts poorly with contravariant subtyping on methodargument-types, which (I believe) is why Java and C++ use invariantsubtyping there.Dan Grossman CSE341 Spring 2004, Lecture 25 3'&$%Static Overloading vs. Multimethod sA very simple difference: Multimethods choose the method atrun-time using the class of the actuals.Example: e.distTo((Point)(new 3DPoint(3.0,4.0,2.0)))The same “no best match” errors arise, but with overloading they ariseat compile-time (and can be resolved with explicit subsumption).Dan Grossman CSE341 Spring 2004, Lecture 25 4'&$%Static Typing and Code ReuseKey idea: Scheme and Smalltalk are different but not that different:• Scheme has arbitrarily nested lexical scope (so does Smalltalk, butonly within a method)• Smalltalk has subclassing and dynamic dispatch (but easy to codeup what you need in Scheme)Java and ML are a bit more different:• ML has datatypes; Java has classes• The ML default is immutable• Java does not have first-class functions (but does have anonymousinner classes)But the key difference is the type system: Java has subtyping; ML hasparametric polymorphism (e.g., (’a * (’a -> ’b)) -> ’b).Dan Grossman CSE341 Spring 2004, Lecture 25 5'&$%What are “forall” types good for?Some good uses for forall types:• Combining functions:(* ((’a->’b)*(’b->’c)) -> (’a->’c) *)let compose (f,g) x = g (f x)• Operating on generic container types:isempty : (’a list) -> boolmap : ((’a list) * (’a -> ’b)) -> ’b list• Passing private data (unnecessary with closures):(* (’a * ((’a * string) -> int)) -> int *)let f (env, g) =let val s1 = getString(37)val s2 = getString(49)in g(env,s1) + g(env,s2) endDan Grossman CSE341 Spring 2004, Lecture 25 6'&$%More on private data(* (’a * ((’a * string) -> int)) -> int *)let f (env, g) =let val s1 = getString(37)val s2 = getString(49)in g(env,s1) + g(env,s2) endThe last point is important in safe, lower-level languages (related tomy research), but is unnecessary in ML or Java:• In ML, just use (string->int) -> int and have the caller “passthe ’a” via a closure (a free variable in the function passed in.– This works because the types of free variables do not appear ina function type• In Java, just “pass the ’a” as a field in the object thatimplements the interface.– This works because subtyping lets us “forget” we have fields.Dan Grossman CSE341 Spring 2004, Lecture 25 7'&$%What is subtyping good for?• Passing in values with “extra” or “more useful” stuffbool isXPos(Pt p) { p.x > 0; } // works fine for a Pt3DBut in ML, we end up encoding coercive subtyping using regular MLfunctions that build new values:type pt = { x : real, y : real}type pt3D = { x : real, y : real, z : real }fun isXPos (p:pt) = (#x p) > 0.0val p3:pt3D = { x=4.0, y=3.0, z=5.0}fun pt (p:pt3D) = { x=(#x p), y=(#y p)}val _ = isXPos ((pt) p3)Dan Grossman CSE341 Spring 2004, Lecture 25 8'&$%What else is subtyping good for?In addition to adding “public” fields, we can use it for private state:interface I { int f(int); }class MaxEver implements I {int m = 0;int f(int i) {if(i > m)i = m;return m;}}In ML, we encode private state using closures.Dan Grossman CSE341 Spring 2004, Lecture 25 9'&$%Wanting bothCould one language support subtype polymorphism and parametricpolymorphism?• Sure; and the next generation of OO languages will• C++ templates are sort of like parametric polymorphism, but theyduplicate code, so they’re a bit like macrosMore interestingly, you may want both at once!Pt withXZero(Pt p) { return new P(0,p.y); }How could we make a version that worked for subtype s too?Dan Grossman CSE341 Spring 2004, Lecture 25 10'&$%Bounded QuantificationHere’s an excellent start:interface I { Pt copy(Pt p); }Pt withXZero(Pt p, I i) {Pt ans = i.copy(p); ans.x = 0; return ans;}But consider using it for a Pt3D:• copy method will have to downcast argument.• user of withXZero will have to downcast result.Enter bounded quantification:interface I<’a> { ’a copy(’a p); }’a withXZero(’a p, I<’a> i) where ’a <: Pt {’a ans = i.copy(p); ans.x = 0; return ans;}Dan Grossman CSE341 Spring 2004, Lecture 25 11'&$%How did that work?• No downcasts.• Without the bound, ans.x would not typecheck.• At call-sites of withXZero, just check the instantiation for ’a is asubtype of PtIn general, in a language with subtyping (t1<:t2) and parametricpolymorphism, a useful generalization of forall ’a. t is forall’a<:t1 . t2. This allows fewer instantiations for ’a.Advanced point: When is forall ’a<:t1. t2 a subtype of forall’a<:t3. t4.• Sound answer: contravariant bounds; covariant body.• But that answer makes the subtyping question (for any two types,is one a subtype of the other) undecidable! (1992 result)• A common restriction in practice is invariant bounds.Dan Grossman CSE341 Spring 2004, Lecture 25


View Full Document

UW CSE 341 - Programming Languages

Documents in this Course
Macros

Macros

6 pages

Macros

Macros

6 pages

Macros

Macros

3 pages

Mutation

Mutation

10 pages

Macros

Macros

17 pages

Racket

Racket

25 pages

Scheme

Scheme

9 pages

Macros

Macros

6 pages

Load more
Download Programming Languages
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Programming Languages and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Programming Languages 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?