Download presentation
Presentation is loading. Please wait.
1
2015-6-28PADL041 A Typeful Approach to Object- Oriented Programming with Multiple Inheritance Chiyan Chen, Rui Shi, Hongwei Xi Computer Science Dept. Boston University
2
2015-6-28PADL042 Motivation Through translating high-level OOP syntax to a typed -calculus, the soundness of the typing rules for the OOP features follows from the soundness of the target system. Within the Applied Type System (ATS) framework, we want to support OOP as an additional package without complicating the existing system.
3
2015-6-28PADL043 Objects as Functions Examples: Smalltalk Interpretation: An object is represented as a message interpreter, that is, a function which takes messages dispatched to it as arguments and then selects the appropriate behavior according to the messages. Message passing: function application.
4
2015-6-28PADL044 Constructing an Integer Pair Object fun newIntPair x y = let val xref = ref x and yref = ref y fun dispatch msg = case msg of | MSGgetfst => !xref | MSGgetsnd => !yref | MSGsetfst x' => (xref := x') | MSGsetsnd y' => (yref := y') | _ => raise UnknownMessage in dispatch end withtype int -> int -> OBJ(ip) Given a class C, OBJ(C) is a shorthand for the following type: : type.MSG(C, ) →
5
2015-6-28PADL045 Typed OOP Model An improved typed OOP model based on the previous work (POPL ’ 03, Xi, Chen and Chen) Takes the “ objects as functions ” view Models the basic features: message passing, single inheritance. Provides a natural solution to the notion of “ self type ”. Subclassing is modeled with explicit proof terms. Supports multiple inheritance
6
2015-6-28PADL046 Single Inheritance vs. Multiple Inheritance Single Inheritance: Examples: Smalltalk, Java Easy to reason and implement. Multiple Inheritance: Examples: Eiffel, C++ Complicated model Interaction with other OO features
7
2015-6-28PADL047 Subtlety with MI in C++ A B1B2 C A :: foo() = 0 B2 :: foo() = 2 B2 :: bar2() = foo() B1 :: foo() = 1 B1 :: bar1() = foo() C :: foo() = 3 C* pc = new C(); pc->bar1() returns 3
8
2015-6-28PADL048 Subtlety with MI in C++ A B1B2 C A :: foo() = 0 B2 :: foo() = 2 B2 :: bar2() = foo() B1 :: foo() = 1 B1 :: bar1() = foo() foo() is not overridden. C* pc = new C(); pc->bar1() returns 1
9
2015-6-28PADL049 Subtlety with MI in C++ A B1B2 C A :: foo() = 0 B2 :: foo() = 2 B2 :: bar2() = foo() B1 :: foo() = 1 B1 :: bar1() = foo() C :: bar3 () = B1 :: foo() D* pd = new D(); pd->bar3() returns 1 D D :: foo() = 4
10
2015-6-28PADL0410 Subtlety with MI in C++ A B1B2 C A :: foo() = 0 B2 :: foo() = 2 B2 :: bar2() = foo() B1 :: foo() = 1 B1 :: bar1() = foo() C :: foo () = B1 :: foo() D* pd = new D(); pd->bar2() returns 1 D foo() is not overridden.
11
2015-6-28PADL0411 Our Solution Using explicit inheritance paths to direct method lookup. A B1B2 C A :: foo() = 0 B2 :: foo() = 2 B2 :: bar2() = A :: B2 :: foo() B1 :: foo() = 1 B1 :: bar1() = A :: B1 :: foo() C :: bar3 () = A :: B1 :: C :: foo() D* pd = new D(); pd->C :: D :: bar3() returns 4 D D :: foo() = 4
12
2015-6-28PADL0412 Run-Time Class Tags datasort cls = obj | eq | ip | cip | … datatype ClS (cls) = | CLSobj (obj) | CLSeq (eq) | CLSip (ip) | CLScip (cip) |... obj eq Ip cip
13
2015-6-28PADL0413 Inheritance Paths Paths from (super)classes to (sub)classes are treated as run-time proof terms (of subclass relation) Declare PTH as a guarded datatype, which takes two static class tags C 1 and C 2 to form a type PTH(C 1, C 2 ) for paths from C 1 to C 2 E.g. Abbreviate a path from class obj to cip as [CLSobj, CLSip, CLScip]
14
2015-6-28PADL0414 Regular/Temporary Objects Given a static class tag C, OBJ(C) is the type for regular objects in class C, which is the shorthand for the following type: c 0 :cls. :type.PTH(c 0,C) → MSG(c 0,C, ) → There is another form of objects that are only constructed during run-time called temporary objects. Given a static class tag C, OBJ 0 (C) stands for the type: c 0 :cls. :type.MSG(c 0,C, ) → Note that a temporary object is not constructed by applying a regular object to a given path.
15
2015-6-28PADL0415 Wrapper Functions A wrapper function for a class C is assigned the type WRP(C), where WRP(C) stands for the following type: OBJ(C) → OBJ 0 (C) Intuitively, a wrapper function turns a regular object in class C into a temporary object in class C. A wrapper function is mainly used to “hard-wire” a method lookup strategy into a regular object.
16
2015-6-28PADL0416 Super Functions For each class C, there is a super function associated with it, which plays a key role in implementing (multiple) inheritance. Given a static class tag C 0, the super function associated with C 0 is assigned the type SUPER(C 0 ), which is the shorthand for the following type: c:cls.PTH(C 0,c) → WRP (c) → WRP (c)
17
2015-6-28PADL0417 An Example of Super Function fun SUPEReq pth wrp obj = let fun dispatch msg = case msg of | MSGeq (obj') => not (obj pth (MSGneq (obj'))) | MSGneq (obj') => not (obj pth (MSGeq (obj'))) | _ => wrp obj msg in dispatch end withtype {c:cls} PTH (eq,c) → WRP(c) → WRP (c)
18
2015-6-28PADL0418 Chaining Super Functions Together Given an object o, nullwrapper(o) constructs a temporary object, which raises the UnknownMessage exception for any message received. Given a run-time inheritance path p, path2wrapper(p) turns the path to a wrapper. e.g. path2wrapper [CLSobj, CLSip, CLScip] = SUPERcip [CLScip] (SUPERip [CLSip, CLScip] (SUPERobj [CLSobj, CLSip, CLScip] nullWrapper))
19
2015-6-28PADL0419 Constructing Objects newintPair is an object constructor function, which takes two integers to create an integer pair object. fun newIntPair x y = let val xref = ref x and yref = ref y fun dispatch pth msg = case msg of | MSGcopy => newIntPair (!xref) (!yref) | MSGgetfst => !xref | MSGsetfst x' => (xref := x') | … | _ => path2wrapper pth dispatch msg in dispatch end withtype int -> int -> OBJ (ip)
20
2015-6-28PADL0420 Example for Method Lookup Given two integer pair objects o 1 and o 2, let us consider O1O1 (MSGneq(o 2 )) [CLSeq, CLSip] No message handler for MSGneq(o 2 ) path2wrapper [CLSeq, CLSip] o 1 (MSGneq(o 2 )) SUPERip [CLSip] (SUPEReq [CLSeq, CLSip] nullWrapper) o 1 (MSGneq(o 2 )) No message handler for MSGneq(o 2 ) (SUPEReq [CLSeq, CLSip] nullWrapper) o 1 (MSGneq(o 2 )) Has message handler for MSGneq(o 2 ) O1O1 (MSGeq(o 2 )) [CLSeq, CLSip] not MSGeq(o 2 ) finally be handled by SUPERip
21
2015-6-28PADL0421 Conclusion We have developed a general approach to multiple inheritance in a typed setting Representing inheritance paths as (typed) run- time proof-terms. Different strategies to resolve dispatching ambiguity Interaction between multiple inheritance and parametric polymorphism A clear model which can be implemented efficiently (e.g. by following C++ implementation)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.