• Keine Ergebnisse gefunden

2 A Model of Classes

N/A
N/A
Protected

Academic year: 2022

Aktie "2 A Model of Classes"

Copied!
37
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

for Classes and Mixins

TR 97-293: Corrected Version, June 8, 1999

Original inFormal Syntax and Semantics of Java, LNCS volume 1523 (1999)

Matthew Flatt, Shriram Krishnamurthi, Matthias Felleisen Rice University

Abstract. While class-based object-oriented programming languages provide a flexible mechanism for re-using and managing related pieces of code, they typically lack linguistic facilities for specifying a uniform extension of many classes with one set of fields and methods. As a result, programmers are unable to express certain abstractions over classes. In this paper we develop a model of class-to-class functions that we refer to asmixins. A mixin function maps a class to an extended class by adding or overriding fields and methods. Programming with mixins is similar to programming with single inheritance classes, but mixins more directly encourage programming to interfaces. The paper develops these ideas within the context of Java. The results are

1. an intuitive model of an essential Java subset;

2. an extension that explains and models mixins; and 3. type soundness theorems for these languages.

1 Organizing Programs with Functions and Classes

Object-oriented programming languages offer classes, inheritance, and overrid- ing to parameterize over program pieces for management purposes and re-use.

Functional programming languages provide various flavors of functional abstrac- tions for the same purpose. The latter model was developed from a well-known, highly developed mathematical theory. The former grew in response to the need to manage large programs and to re-use as many components as possible.

Each form of parameterization is useful for certain situations. With higher- order functions, a programmer can easily define many functions that share a similar core but differ in a few details. As many language designers and program- mers readily acknowledge, however, the functional approach to parameterization is best used in situations with a relatively small number of parameters. When a function must consume a large number of arguments, the approach quickly

0 This research was partially supported by a Lodieska Stockbridge Vaughan Fellowship, NSF Graduate Research Fellowship, NSF grants CCR-9619756, CDA-9713032, and CCR-9708957, and a Texas ATP grant.

(2)

becomes unwieldy, especially if many of the arguments are the same for most of the function’s uses.1

Class systems provide a simple and flexible mechanism for managing col- lections of highly parameterized program pieces. Using class extension (inheri- tance) and overriding, a programmer derives a new class by specifying only the elements that change in the derived class. Nevertheless, a pure class-based ap- proach suffers from a lack of abstractions that specify uniform extensions and modifications of classes. For example, the construction of a programming envi- ronment may require many kinds of text editor frames, including frames that can contain multiple text buffers and frames that support searching. In Java, for ex- ample, we cannot implement all combinations of multiple-buffer and searchable frames using derived classes. If we choose to define a class for all multiple-buffer frames, there can be no class that includes only searchable frames. Hence, we must repeat the code that connects a frame to the search engine in at least two branches of the class hierarchy: once for single-buffer searchable frames and again for multiple-buffer searchable frames. If we could instead specify a mapping from editor frame classes to searchable editor frame classes, then the code connecting a frame to the search engine could be abstracted and maintained separately.

Some class-based object-oriented programming languages provide multiple inheritance, which permits a programmer to create a class by extending more than one class at once. A programmer who also follows a particular protocol for such extensions can mimic the use of class-to-class functions. Common Lisp programmers refer to this protocol as mixin programming [21, 22], because it roughly corresponds to mixing in additional ingredients during class creation.

Bracha and Cook [7] designed a language of class manipulators that promote mixin thinking in this style and permit programmers to build mixin-like classes.

Unfortunately, multiple inheritance and its cousins are semantically complex and difficult to understand for programmers.2As a result, implementing a mixin protocol with these approaches is error-prone and typically avoided.

For the design of MzScheme’s class and interface system [16], we experi- mented with a different approach. In MzScheme, classes form a single inheri- tance hierarchy, but are also first-class values that can be created and extended at run-time. Once this capability was available, the programmers of our team used it extensively for the construction of DrScheme [15], a Scheme programming environment. A thorough analysis, however, reveals that the code only contains first-order functions on classes.

In this paper, we present a typed model of such “class functors” for Java [18].

We refer to the functors as mixins due to their similarity to Common Lisp’s multiple inheritance mechanism and Bracha’s class operators. Our proposal is superior in that it isolates the useful aspects of multiple inheritance yet retains the simple, intuitive nature of class-oriented, single-inheritance Java program-

1 Function entry points`a laFortran or keyword arguments`a laCommon Lisp are a symptom of this problem, not a remedy.

2 Dan Friedman determined in an informal poll in 1996 that almost nobody who teaches C++ teaches multiple inheritance [pers. com.].

(3)

ming. In the following section, we develop a calculus of Java classes. In the third section, we motivate mixins as an extension of classes using a small but illumi- nating example. The fourth section extends the type-theoretic model of Java to mixins. The last section considers implementation strategies for mixins and puts our work in perspective.

interfacePlacei. . . interfaceBarrieri. . . interfaceDoori

extendsPlacei,Barrieri. . . . . .

classDoorcextendsObject implementsDoori{ . . .

RoomcEnter(Personcp){. . .} . . .

}

classLockedDoorcextendsDoorc. . . classShortDoorcextendsDoorc. . .

Placei . . .

s

Barrieri . . .

Doori . . .

. . .). . .?

Interfaces

JJ JJ JJ JJ JJ JJ JJ

Object . . .

. . . ?HHj. . .

Doorc Enter . . .

HHj

LockedDoorc . . .

. . .) . . .?

ShortDoorc . . .

PPq. . .

. . .?

Classes

QQ QQs

Fig. 1.A program determines a static directed acyclic graph of types

JJ

J

`

h

player:

Personc

room:

Roomc

door:

LockedDoorc

. . .

. . .

Q s) '

&

$

%

,door.Enter(player)i

, h player:

Personc

room:

Roomc

door:

LockedDoorc

. . .

. . .

? ) '

&

$

%

,roomi

Fig. 2.Given a type graph, reductions map a store-expression pair to a new pair

2 A Model of Classes

ClassicJava is a small but essential subset of sequential Java. To model its type structure and semantics, we use well-known type elaboration and rewriting techniques for Scheme and ML [14, 19, 30]. Figures 1 and 2 illustrate the essence

(4)

of our strategy. Type elaboration verifies that a program defines a static tree of classes and a directed acyclic graph (dag) of interfaces. A type is simply a node in the combined graph. Each type is annotated with its collection of fields and methods, including those inherited from its ancestors.

Evaluation is modeled as a reduction on expression-store pairs in the context of a static type graph. Figure 2 demonstrates reduction using a pictorial repre- sentation of the store as a graph of objects. Each object in the store is a tagged record of field values, where the tag indicates the class of the object and its field values are references to other objects. A single reduction step may extend the store with a new object, or it may modify a field for an existing object in the store. Dynamic method dispatch is accomplished by matching the class tag of an object in the store with a node in the static class tree; a simple relation on this tree selects an appropriate method for the dispatch.

The class model relies on as few implementation details as possible. For example, the model defines a mathematical relation, rather than a selection algorithm, to associate fields with classes for the purpose of type-checking and evaluation. Similarly, the reduction semantics only assumes that an expression can be partitioned into a proper redex and an (evaluation) context; it does not provide a partitioning algorithm. The model can easily be refined to expose more implementation details [13, 19].

P = defn*e

defn = classcextendscimplementsi*{field*meth*}

|interfaceiextendsi*{meth*} field = tfd

meth = tmd(arg* ){body} arg = tvar

body = e|abstract

e = newc|var|null|e:c.fd|e:c.fd=e

|e.md(e* )|superthis:c.md(e* )

|viewt e|letvar=eine var = a variable name orthis

c = a class name orObject i = interface name orEmpty fd = a field name

md = a method name t = c|i

Fig. 3.ClassicJavasyntax; underlined phrases are inserted by elaboration and are not part of the surface syntax

2.1 ClassicJava Programs

The syntax for ClassicJavais shown in Figure 3. A programP is a sequence of class and interface definitions followed by an expression. Each class definition consists of a sequence of field declarations and a sequence of method declarations, while an interface consists of methods only. A method body in a class can be abstract, indicating that the method must be overridden in a subclass before

(5)

the class is instantiated. A method body in an interface must beabstract. As in Java, classes are instantiated with the newoperator, but there are no class constructors in ClassicJava; instance variables are always initialized to null.

Finally, the view and let forms represent Java’s casting expressions and local variable bindings, respectively.

The evaluation rules for ClassicJava are defined in terms of individual expressions, but certain rules require information about the context of the ex- pression in the original program. For example, the evaluation rule for a field use depends on the syntactic type of the object position, which is determined by the expression’s type environment in the original program. To remove such context dependencies before evaluation, the type-checker annotates field uses andsuper invocations with extra source-context information (see the underlined parts of the syntax).

A validClassicJavaprogram satisfies a number of simple predicates and re- lations; these are described in Figures 4 and 5. For example, theClassesOnce(P) predicate states that each class name is defined at most once in the programP. The relationcP associates each class name inP to the class it extends, and the (overloaded)∈∈cP relations capture the field and method declarations ofP.

The syntax-summarizing relations induce a second set of relations and pred- icates that summarize the class structure of a program. The first of these is the subclass relation cP, which is a partial order if the CompleteClasses(P) and WellFoundedClasses(P) predicates hold. In this case, the classes declared in P form a tree that hasObjectat its root.

If the program describes a tree of classes, we can “decorate” each class in the tree with the collection of fields and methods that it accumulates from local declarations and inheritance. The source declaration of any field or method in a class can be computed by finding theminimum (i.e., farthest from the root) superclass that declares the field or method. This algorithm is described precisely by thecP relations. ThecP relation retains information about the source class of each field, but it does not retain the source class for a method. This reflects the property of Java classes that fields cannot be overridden (so instances of a subclass always contain the field), while methods can be overridden (and may become inaccessible).

Interfaces have a similar set of relations. The superinterface declaration re- lation Pi induces a subinterface relation Pi . Unlike classes, a single interface can have multiple proper superinterfaces, so the subinterface order forms adag instead of a tree. The set methods of an interface, as described by Pi , is the union of the interface’s declared methods and the methods of its superinterfaces.

Finally, classes and interfaces are related by implements declarations, as captured in the≺≺cP relation. This relation is a set of edges joining the class tree and the interface graph, completing the subtypepicture of a program. A type in the full graph is a subtype of all of its ancestors.

(6)

The sets of names for variables, classes, interfaces, fields, and methods are assumed to be mutually distinct. The meta-variableT is used for method signatures (t . . .−→t),V for variable lists (var. . .), andΓ for environments mapping variables to types. Ellipses on the baseline (. . .) indicate a repeated pattern or continued sequence, while centered ellipses (· · ·) indicate arbitrary missing program text (not spanning a class or interface definition).

ClassesOnce(P) Each class name is declared only once

classc· · ·classc0· · · is inP =c6=c0 FieldOncePerClass(P) Field names in each class declaration are unique

class· · · { · · ·fd· · ·fd0· · · }is inP =fd6=fd0 MethodOncePerClass(P)Method names in each class declaration are unique

class· · · { · · ·md(· · ·){ · · · } · · ·md0(· · ·){ · · · } · · · }is inP =md6=md0 InterfacesOnce(P) Each interface name is declared only once

interfacei· · ·interfacei0· · · is inP =i6=i0 InterfacesAbstract(P) Method declarations in an interface areabstract

interface· · · { · · ·md(· · ·){e} · · · } is inP =⇒eisabstract

cP Class is declared as an immediate subclass

ccP c0 classcextendsc0· · · { · · · } is inP

∈∈cP Field is declared in a class

hc.fd,ti ∈∈cP c classc· · · { · · ·t fd· · · }is inP

∈∈cP Method is declared in class

hmd, (t1. . . tn−→t), (var1. . .varn),ei ∈∈cPc

classc· · · { · · ·t md(t1var1. . .tnvarn){e} · · · }is inP

iP Interface is declared as an immediate subinterface

iPi i0interfaceiextends· · ·i0· · · { · · · } is inP

∈∈Pi Method is declared in an interface

hmd, (t1. . . tn−→t), (var1. . .varn),ei ∈∈iPi

interfacei· · · { · · ·t md(t1var1. . .tnvarn){e} · · · } is inP

≺≺cP Class declares implementation of an interface

c≺≺cP iclassc· · ·implements· · ·i· · · { · · · } is inP

cP Class is a subclass

cP the transitive, reflexive closure ofcP

CompleteClasses(P) Classes that are extended are defined

rng(cP)dom(cP)∪{Object} WellFoundedClasses(P) Class hierarchy is an order

cPis antisymmetric ClassMethodsOK(P) Method overriding preserves the type

(hmd,T,V,ei ∈∈cPcandhmd,T0,V0,e0i ∈∈cP c0) =(T=T0orc6≤cP c0)

cP Field is contained in a class

hc0.fd,ti ∈cPc

⇔ hc0.fd,ti ∈∈cP c0andc0= min{c00|ccP c00and∃t0s.t.hc00.fd,t0i ∈∈cP c00}

cP Method is contained in a class

hmd,T,V,ei ∈cPc

(hmd,T,V,ei ∈∈cP c0andc0= min{c00|ccP c00ande0, V0s.t.hmd,T,V0,e0i ∈∈cPc00})

Fig. 4.Predicates and relations in the model ofClassicJava(Part I)

2.2 ClassicJava Type Elaboration

The type elaboration rules forClassicJavaare defined by the following judge- ments:

`pP ⇒P0 :t P elaborates toP0 with typet P `ddefn⇒defn0 defnelaborates todefn0 P, t`mmeth⇒meth0 methintelaborates tometh0 P, Γ `e e⇒e0 :t eelaborates toe0with typetinΓ P, Γ `se⇒e0 :t ehas typetusing subsumption inΓ

P `t t texists

(7)

Pi Interface is a subinterface

Pi the transitive, reflexive closure ofiP

CompleteInterfaces(P) Extended/implemented interfaces are defined

rng(≺Pi )rng(≺≺cP)dom(≺iP)∪{Empty}

WellFoundedInterfaces(P)Interface hierarchy is an order

Pi is antisymmetric

¿cP Class implements an interface

c¿cP i⇔ ∃c0,i0s.t.ccP c0andi0Pi iandc0≺≺cPi0 InterfaceMethodsOK(P) Interface inheritance or redeclaration of methods is consistent hmd,T,V,abstracti ∈∈Pi iandhmd,T0,V0,abstracti ∈∈iPi0

=⇒(T =T0or∀i00(i006≤iP iori006≤iPi0))

iP Method is contained in an interface

hmd,T,V,abstracti ∈iP i⇔ ∃i0s.t.iPi i0andhmd,T,V,abstracti ∈∈iPi0 ClassesImplementAll(P) Classes supply methods to implement interfaces

c≺≺cP i=(∀md, T, V hmd,T,V,abstracti ∈Pi i=⇒ ∃e, V0s.t.hmd,T,V0,ei ∈cPc) NoAbstractMethods(P, c) Class has noabstractmethods (can be instantiated)

hmd,T,V,ei ∈cPc =e6=abstract

P Type is a subtype

P ≡ ≤cP∪ ≤iP∪ ¿cP

P Field or method is in a type

P ≡ ∈cP∪ ∈iP

Fig. 5.Predicates and relations in the model ofClassicJava(Part II)

`p

ClassesOnce(P) InterfacesOnce(P) MethodOncePerClass(P)FieldOncePerClass(P) CompleteClasses(P)

WellFoundedClasses(P) CompleteInterfaces(P) WellFoundedInterfaces(P) InterfaceMethodsOK(P)

InterfacesAbstract(P) ClassesImplementAll(P) P`ddefnj defn0j forj[1, n]

P,[ ]`eee0:t whereP=defn1. . .defnne

`pdefn1. . .defnnedefn01. . .defn0ne0:t [progc]

`d

P`ttj for eachj[1, n] P, c`m methkmeth0kfor eachk[1, p]

P`dclassc· · · {t1 fd1. . .tnfdn

meth1 . . .methp}classc· · · {t1fd1 . . .tnfdn meth01. . .meth0p}

[defnc]

P, i`mmethjmethj for eachj[1, p]

P `dinterfacei· · · {meth1 . . .methp} ⇒interfacei· · · {meth1. . .methp}[defni]

`m

P`tt P`ttj forj[1, n] P,[this:to,var1:t1,. . .varn:tn]`see0:t P, to`mt md(t1var1. . .tnvarn){e} ⇒t md(t1var1. . .tnvarn){e0} [meth]

`e

P`tc NoAbstractMethods(P, c)

P, Γ`enewcnewc:c [newc] vardom(Γ)

P, Γ `evarvar:Γ(var)[var]

P`tt

P, Γ `enullnull:t[null] P, Γ `eee0:t0 hc.fd,ti ∈P t0 P, Γ`ee.fde0:c.fd:t [getc] P, Γ `eee0:t0 hc.fd,ti ∈P t0 P, Γ `seve0v:t

P, Γ`ee.fd=eve0:c.fd=e0v:t [setc] Fig. 6.Context-sensitive checks and type elaboration rules forClassicJava(Part I)

(8)

P, Γ `eee0:t0hmd, (t1. . . tn−→t), (var1. . .varn),ebi ∈P t0 P, Γ `sej e0j:tj forj[1, n]

P, Γ`ee.md(e1. . .en)e0.md(e01. . .e0n) :t [callc] P, Γ`ethisthis:c0 c0cP c hmd, (t1. . . tn−→t), (var1. . .varn),ebi ∈P c P, Γ`seje0j :tjforj[1, n] eb6=abstract

P, Γ`esuper.md(e1. . .en)superthis:c.md(e01. . .e0n) :t [superc] P, Γ `see0:t

P, Γ `eviewt ee0:t[wcastc] P`tt

P, Γ`eabstractabstract:t[abs]

P, Γ`eee0:t0 tP t0ortdom(Pi ) ort0dom(Pi ) P, Γ`eviewt eviewt e0 :t [ncastc] P, Γ `ee1e01:t1 P, Γ[var:t1]`ee2e02:t

P, Γ`eletvar=e1ine2letvar=e01ine02:t [let]

`s,`t

P, Γ`eee0:t0 t0Pt

P, Γ`see0:t [subc] tdom(cP)dom(Pi )∪{Object,Empty}

P `tt [typec]

Fig. 7.Context-sensitive checks and type elaboration rules forClassicJava(Part II)

The type elaboration rules translate expressions that access a field or call a supermethod into annotated expressions (see the underlined parts of Figure 3).

For field uses, the annotated expression contains the compile-time type of the instance expression, which determines the class containing the declaration of the accessed field. Forsupermethod invocations, the annotated expression contains the compile-time type of this, which determines the class that contains the declaration of the method to be invoked.

The complete typing rules are shown in Figures 6 and 7. A program is well- typed if its class definitions and final expression are well-typed. A definition, in turn, is well-typed when its field and method declarations use legal types and the method body expressions are well-typed. Finally, expressions are typed and elaborated in the context of an environment that binds free variables to types.

For example, the getc and setc rules for fields first determine the type of the instance expression, and then calculate a class-tagged field name usingP; this yields both the type of the field and the class for the installed annotation. In thesetc rule, the right-hand side of the assignment must match the type of the field, but this match may exploit subsumption to coerce the type of the value to a supertype. The other expression typing rules are similarly intuitive.

2.3 ClassicJava Evaluation

The operational semantics forClassicJavais defined as a contextual rewriting system on pairs of expressions and stores. A store S is a mapping from objects to class-tagged field records. A field recordF is a mapping from elaborated field

(9)

e=. . .|object v=object|null

E=[ ]|E:c.fd|E:c.fd=e|v:c.fd=E

| E.md(e. . .)|v.md(v. . .Ee. . .)

| superv:c.md(v. . .Ee. . .)

| viewtE|letvar=Eine

P ` hE[newc],Si,→ hE[object],S[object7→hc,Fi]i [new]

whereobject6∈dom(S) andF= {c0.fd7→null|ccP c0and∃ts.t.hc0.fd,ti ∈∈cP c0}

P ` hE[object:c0 .fd],Si,→ hE[v],Si [get]

whereS(object) =hc,FiandF(c0.fd) =v

P ` hE[object:c0 .fd=v],Si,→ hE[v],S[object7→hc,F[c0.fd7→v]i]i [set]

whereS(object) =hc,Fi

P ` hE[object.md(v1,. . .vn)],Si,→ hE[e[object/this,v1/var1,. . .vn/varn]],Si [call]

whereS(object) =hc,Fiandhmd, (t1. . . tn−→t), (var1. . .varn),ei ∈cPc P ` hE[superobject:c0.md(v1,. . .vn)],Si

,→ hE[e[object/this,v1/var1,. . .vn/varn]],Si

[super]

wherehmd, (t1. . . tn−→t), (var1. . .varn),ei ∈cPc0

P ` hE[viewt0 object],Si,→ hE[object],Si [cast]

whereS(object) =hc,FiandcP t0

P ` hE[letvar=vine],Si,→ hE[e[v/var]],Si [let]

P ` hE[viewt0 object],Si,→ herror: bad cast,Si [xcast]

whereS(object) =hc,Fiandc6≤P t0

P ` hE[viewt0 null],Si,→ herror: bad cast,Si [ncast]

P ` hE[null:c.fd],Si,→ herror: dereferenced null,Si [nget]

P ` hE[null:c.fd=v],Si,→ herror: dereferenced null,Si [nset]

P ` hE[null.md(v1,. . .vn)],Si,→ herror: dereferenced null,Si [ncall]

Fig. 8.Operational semantics forClassicJava

names to values. The evaluation rules are a straightforward modification of those for imperative Scheme [14].

The complete evaluation rules are in Figure 8. For example, the call rule invokes a method by rewriting the method call expression to the body of the invoked method, syntactically replacing argument variables in this expression with the supplied argument values. The dynamic aspect of method calls is im- plemented by selecting the method based on the run-time type of the object (in the store). In contrast, the super reduction performs super method selection using the class annotation that is statically determined by the type-checker.

2.4 ClassicJava Soundness

For a program of typet, the evaluation rules forClassicJavaproduce either a value that has a subtype oft, or one of two errors. Put differently, an evaluation cannot go wrong, which our model model means getting stuck. This property can be formulated as a type soundness theorem.

Theorem 1 (Type Soundness). If `p P ⇒P0 :t and P0 =defn1 . . . defnn e, then either

P0 ` he, ∅i,→ hobject, SiandS(object) =ht0,Fiandt0 P t; or P0 ` he, ∅i,→ hnull,Si; or

(10)

P0 ` he, ∅i,→ herror: bad cast,Si; or P0 ` he, ∅i,→ herror: dereferenced null,Si.

The main lemma in support of this theorem states that each step taken in the evaluation preserves the type correctness of the expression-store pair (relative to the program) [30]. Specifically, for a configuration on the left-hand side of an evaluation step, there exists a type environment that establishes the expression’s type as some t. This environment must be consistent with the store.

Definition 2 (Environment-Store Consistency).

P,Γ `σ S

(S(object) = hc,Fi Σ1: ⇒Γ(object) = c

Σ2: and dom(F) ={c1.fd | hc1.fd,c2i ∈cP c}

Σ3: and rng(F)dom(S)∪ {null}

Σ4: and (F(c1.fd) = object0 andhc1.fd,c2i ∈cP c)

((S(object0) =hc0,F0i)⇒c0 P c2)) Σ5: andobject dom(Γ)⇒object dom(S)3 Σ6: and dom(S)dom(Γ)

Since the rewriting rules reduceannotated terms, we derive new type judge- ments `s and `e that relate annotated terms to show that reductions preserve type correctness. Each of the new rules performs the same checks as the rule it is derived from without removing or adding annotation. Thus,`sis derived from

`s, and so forth.

The judgement onview expressions is altered slightly; we retain the view operation in all cases, and we collapse the [wcastc] and [ncastc] relations to a new [castc] relation that permits any casting operation:

P,Γ `e e:t0

P,Γ `e viewt e:t[castc]

The new [castc] relation lets us prove that every intermediate expresion in a reduction is well-typed, whereas [wcastc] and [ncastc] more closely approximate Java, which rejects certain expressions because they would certainly produce error: bad cast. For example, assuming thatLockedDoorcandShortDoorcextend Doorc separately, a legal source program

let x = o.GetDoor() in (view LockedDoorc x) might reduce to

view LockedDoorc shortDoorObject

where shortDoorObject is an instance of ShortDoorc. Unlike the [wcastc] and [ncastc] rules in`e, the [castc] rule in`eassigns a type to the reduced expression.

3 InΣ5, it would be wrong to write dom(Γ)dom(S) becauseΓ may contain bindings for lexical variables.

(11)

The `e relation also generalizes the [superc] judgement to allow an arbi- trary expression within asuperexpression’s annotation (in place ofthis). The generalized judgement permits replacement and substitution lemmas that treat super annotations in the same manner as other expression. Nevertheless, at each reduction step, everysuperexpression’s annotation contains eitherthisor an object. This fact is crucial to proving the soundness ofClassicJava, so we formalize it as aSuperOkpredicate.

Definition 3 (Well-Formed Super Calls).

SuperOk(e)For allsuper≡e0 :c.md(e1, . . . en) ine, eithere0 =thisor∃object s.t.e0=object.

Although `e types more expressions than `e, we are only concerned with source expressions typed by `e. The following lemma establishes that the new typing judgements conserve the result of the original typing judgements.

Lemma 4 (Conserve). If `p P P0 : t and P0 =defn1 . . . defnn e, then P0,∅ `e e0 :t .

Proof. The claim follows from a copy-and-patch argument. 2

Lemma 5 (Subject Reduction). If P,Γ `e e : t , P,Γ `σ S, SuperOk(e), andP ` he,Si,→ he0,S0i, then e0 is an errorconfiguration or∃ Γ0 such that

1. P,Γ0 `s e0 : t , 2. P,Γ0 `σ S0, and 3. SuperOk(e0).

Proof. The proof examines reduction steps. For each case, if execution has not halted with an error configuration, we construct the new environment Γ0 and show that the two consequents of the theorem are satisfied relative to the new expression, store, and environment. See Appendix A for the complete proof. 2 Lemma 6 (Progress). IfP,Γ `ee:t ,P,Γ `σS, andSuperOk(e), then either e is a value or there exists an he0,S0isuch thatP ` he,Si,→ he0,S0i.

Proof. The proof is by analysis of the possible cases for the current redex ine (in the case thateis not a value). See Appendix A for the complete proof. 2 By combinining the Subject Reduction and Progress lemmas, we can prove that every non-value ClassicJava program reduces while preserving its type, thus estrablishing the soundness ofClassicJava.

Referenzen

ÄHNLICHE DOKUMENTE

In this paper, we have shown how to compute the period lattice of loosely periodic func- tions, and applied the technique to the computation of the unit group of a finite extension K

In an effort to prevent human rights violations at an early stage, the Mission advises and supports local actors who review laws and secondary legislation for compliance with

In the present thesis, we consider the possibility of a reconstruction of the coronal magnetic field by tomographic technique based on possible coronagraph observations of the Hanle

Moreover, by (4.9) one of the last two inequalities must be proper.. We briefly say k-set for a set of cardinality k. Its number of vertices |V | is called the order of H. We say that

If you can influence intensity, then you have a choice of strategies: whether to try to build intensive mass support for a distributive outcome, or to exploit the running room of

Because the Mecp2 -/y mice showed a significant increase in Trh compared to wt mice in almost all brain areas analyzed and the TRH function depends on the

Four Points on Secondary Analysis 2.1 Sociology as a source for social history 2.2 The value of original fieldwork materials5. 2.3 Secondary analysis reveals insights into the

The descrioed indicators would be prepared at the national level as per capita values for models on the basis of specific national population structures. The dietary allowances