2015-6-28PADL041 A Typeful Approach to Object- Oriented Programming with Multiple Inheritance Chiyan...
-
date post
21-Dec-2015 -
Category
Documents
-
view
214 -
download
2
Transcript of 2015-6-28PADL041 A Typeful Approach to Object- Oriented Programming with Multiple Inheritance Chiyan...
23/4/18 PADL04 1
A Typeful Approach to Object-Oriented Programming with
Multiple Inheritance
Chiyan Chen, Rui Shi, Hongwei Xi
Computer Science Dept.
Boston University
23/4/18 PADL04 2
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.
23/4/18 PADL04 3
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.
23/4/18 PADL04 4
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,) →
23/4/18 PADL04 5
Typed OOP Model
An improved typed OOP model based on the previous work (POPL’03, Xi, Chen and Chen)Takes the “objects as functions” viewModels 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
23/4/18 PADL04 6
Single Inheritance vs. Multiple Inheritance
Single Inheritance:Examples: Smalltalk, JavaEasy to reason and implement.
Multiple Inheritance:Examples: Eiffel, C++Complicated modelInteraction with other OO features
23/4/18 PADL04 7
Subtlety with MI in C++
A
B1 B2
C
A :: foo() = 0
B2 :: foo() = 2B2 :: bar2() = foo()
B1 :: foo() = 1B1 :: bar1() = foo()
C :: foo() = 3
C* pc = new C();pc->bar1() returns 3
23/4/18 PADL04 8
Subtlety with MI in C++
A
B1 B2
C
A :: foo() = 0
B2 :: foo() = 2B2 :: bar2() = foo()
B1 :: foo() = 1B1 :: bar1() = foo()
foo() is not overridden.C* pc = new C();
pc->bar1() returns 1
23/4/18 PADL04 9
Subtlety with MI in C++
A
B1 B2
C
A :: foo() = 0
B2 :: foo() = 2B2 :: bar2() = foo()
B1 :: foo() = 1B1 :: bar1() = foo()
C :: bar3 () = B1 :: foo()D* pd = new D();
pd->bar3() returns 1
D D :: foo() = 4
23/4/18 PADL04 10
Subtlety with MI in C++
A
B1 B2
C
A :: foo() = 0
B2 :: foo() = 2B2 :: bar2() = foo()
B1 :: foo() = 1B1 :: bar1() = foo()
C :: foo () = B1 :: foo()D* pd = new D();
pd->bar2() returns 1
D foo() is not overridden.
23/4/18 PADL04 11
Our Solution
Using explicit inheritance paths to direct method lookup.
A
B1 B2
C
A :: foo() = 0
B2 :: foo() = 2B2 :: bar2() = A ::
B2 :: foo()
B1 :: foo() = 1B1 :: bar1() = A ::
B1 :: foo()
C :: bar3 () = A :: B1 :: C :: foo()
D* pd = new D();pd->C :: D :: bar3() returns 4
D D :: foo() = 4
23/4/18 PADL04 12
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
23/4/18 PADL04 13
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 C1 and C2 to form a type PTH(C1, C2) for paths from C1 to C2
E.g. Abbreviate a path from class obj to cip as [CLSobj, CLSip, CLScip]
23/4/18 PADL04 14
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:
c0:cls.:type.PTH(c0,C) → MSG(c0,C,) → There is another form of objects that are only
constructed during run-time called temporary objects. Given a static class tag C, OBJ0(C) stands for the type:
c0:cls. :type.MSG(c0,C,) → Note that a temporary object is not constructed by
applying a regular object to a given path.
23/4/18 PADL04 15
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) → OBJ0(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.
23/4/18 PADL04 16
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 C0, the super function associated with C0 is assigned the type SUPER(C0), which is the shorthand for the following type:
c:cls.PTH(C0,c) → WRP (c) → WRP (c)
23/4/18 PADL04 17
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)
23/4/18 PADL04 18
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))
23/4/18 PADL04 19
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)
23/4/18 PADL04 20
Example for Method Lookup
Given two integer pair objects o1 and o2, let us consider
O1(MSGneq(o2))
[CLSeq, CLSip]No message handler for MSGneq(o2)
path2wrapper [CLSeq, CLSip] o1 (MSGneq(o2))
SUPERip [CLSip] (SUPEReq [CLSeq, CLSip] nullWrapper) o1 (MSGneq(o2))
No message handler for MSGneq(o2)
(SUPEReq [CLSeq, CLSip] nullWrapper) o1 (MSGneq(o2))
Has message handler for MSGneq(o2)
O1(MSGeq(o2))
[CLSeq, CLSip]not
MSGeq(o2) finally be handled by SUPERip
23/4/18 PADL04 21
Conclusion
We have developed a general approach to multiple inheritance in a typed settingRepresenting inheritance paths as (typed) run-ti
me proof-terms.Different strategies to resolve dispatching ambi
guityInteraction between multiple inheritance and par
ametric polymorphismA clear model which can be implemented efficie
ntly (e.g. by following C++ implementation)