510 likes | 527 Views
Explore the implementation of a semantic model for Java wildcards and existential types to ensure soundness and completeness in Java's type system. Learn about how wildcard types in Java work, and how existential types can hide type information. Discover the significance of using existential types and the syntactic type assignment framework in Java programming.
E N D
Towards a Semantic Model for Java Wildcards Sophia Drossopoulou Nicholas Cameron Alexander J. Summers ETH Zurich Zürich Victoria Univ. of Wellington New Zealand Mariangiola Dezani-Ciancaglini Università di Torino Italy Imperial College London
Outline • Java Wildcards & Existential Types • Semantic Model for Existential Types • Soundness & (In-)Completeness • Weak Independence & Completeness • Conclusions
Outline • Java Wildcards & Existential Types • Semantic Model for Existential Types • Soundness & (In-)Completeness • Weak Independence & Completeness • Conclusions
Wildcards in Java • Based on Java Generics (since Java 5.0) • Parameterised types : List<X>, List<List<String>>, etc. • Generic types are subtype invariant • List<String> and List<Object> are incomparable • Wildcards introduce “hiding” of type parameters • List<?> is a type (a List of “something”) • List<Object> subtype of List<?> • List<String> subtype of List<?> • Bounded wildcards allow subtype variance • List<? extends String> subtype of List<? extends Object> • List<? super Object> subtype of List<? super String>
Existential Types • Existential types allow type information to be hidden • Bounded existentials expose some information about hidden type, e.g., X:[String Object].C<X> • Standard representation of wildcard types • C<?> represented by X:[ Object].C<X> • C<? super B>represented byX:[B Object].C<X> • For Java, introduction and elimination of existential types is handled implicitly (by subtyping). • Java has f-bounded types (type variables may occur in each other’s bounds, mutually)
Why use Existential Types? • Not all types that can occur during type checking of Java programs can be written using the Java syntax • i.e., there are types that are expressible but not denotable in Java • Not true for existential types • All Java types can be denoted using existential types • e.g., X.Pair<X, X> can arise during type-checking (but Pair<?,?>corresponds to X,Y.Pair<X, Y>)
Syntactic Type Assignment • Types and type environments are defined by:Class types N ::= C < T >types T ::= X | ∃Δ.Ntype bounds B ::= T | ⊥type environments Δ ::= X : [B B] • We use σfor type substitutions, and use a judgement Δ ⊢ σ to express that σ maps the type variables in Δ to types within their declared bounds • Syntactic subtypingΔ⊢ T1≤ T2 handles subclassing, existential types and their bounds • e.g.,Δ, Δ1 ⊢ σ ⇒Δ ⊢ σ(N) ≤ ∃Δ1.N
Outline • Java Wildcards & Existential Types • Semantic Model for Existential Types • Soundness & (In-)Completeness • Weak Independence & Completeness • Conclusions
Our semantics for types • Idea: interpret existential types as unions • all the possible concrete types the existential might “hide” • What are “concrete types”? • One idea: use structural types to describe fields and methods guaranteed to exist in the runtime object • but Java uses a nominal type system • allows use of fields and methods based only on class type • Each runtime object has an associated closed class type • We use these as the “concrete types” of our model
Our semantics for types • Semantic types S are sets of closed class types • all the possible runtime types the type might permit • We give a semantic interpretation of closed types • open types will be dealt with later • We map closed types to semantic types as follows: [[ N ]] = { N’| N’⊑ N } [[ ⊥ ]] = ∅ [[ ∃Δ.N ]] = Uσ with Δ ⊢ σ[[ σ(N) ]]
Our semantics for types [[ N ]] = { N’| N’⊑ N } [[ ⊥ ]] = ∅ [[ ∃Δ.N ]] = Uσ with Δ ⊢ σ[[ σ(N) ]] • For example... • [[ Object ]] = { Object, String, List<Object>, … } • [[∃X : [String Object], ∃Y : [X Object].Pair<X,Y> ]] = • { Pair<String,String>, Pair<String,Object>, Pair<Object,Object> }
Semantic subtyping • We define subtyping on semantic types simply as S1≤ S2 ⇔ S1 ⊆ S2 • We extend this notion to syntactic types, as follows:Δ⊨ T1≤ T2 ⇔ ∀ σ, Δ ⊢ σ⇒ [[ σ(T1) ]] ⊆ [[ σ(T2) ]] • We now have two subtyping judgements: syntactic Δ⊢ T1≤ T2 and semantic subtypingΔ⊨ T1≤ T2 • Is syntactic subtyping sound? Δ⊢ T1≤ T2⇒ Δ⊨ T1≤ T2 ? • Is syntactic subtyping complete? Δ⊢ T1≤ T2⇐ Δ ⊨ T1≤ T2 ?
Outline • Java Wildcards & Existential Types • Semantic Model for Existential Types • Soundness & (In-)Completeness • Weak Independence & Completeness • Conclusions
Soundness • Since type soundness for Java Wildcards is known [Cameron et al. 2008] we would hope that soundness of subtyping holds. • In fact, we proved this (Theorem 1 in paper): Soundness: Δ⊢ T1≤ T2⇒ Δ⊨ T1≤ T2 • By defining a suitable semantic type assignment we extended the soundness result to the type system • Completeness could be reasonably expected: • result w.r.t. nominal subtyping (weaker than structural) • decidability of the syntactic type system is open • However, completeness turns out not to hold
Incompleteness 1 • Consider the type ∃X : [C C].List<X> • The semantic model “knows” that X must hide C : • [[∃X : [C C].List<X>]] = {List<C>} = [[List<C>]] • In particular, ⊨ ∃X : [C C].List<X>≤ List<C> holds • This subtyping cannot be derived syntactically • syntactic rules cannot identify the “uniqueness” of X • What if we add a rule specifically for such cases? Δ ⊢U≤ B Δ ⊢B≤ U (eq) Δ⊢∃X : [B U].N ≤ N{B/X}
Incompleteness 2 • This is still not enough. Consider now the typesT1 = ∃X : [⊥ Y], ∃Y : [X Object].Pair<X,Y> T2 = ∃Z : [⊥ Object].Pair<Z,Z> • The bounds on X and Y can only be satisfied if the same (closed class) type is chosen to replace each • the model shows this: [[ T1 ]] = [[ T2 ]] • In particular, ⊨ T1≤ T2 holds, but not syntactically • Further examples make completeness unfeasible • But, could we find a restricted type language for which completeness does hold?
Outline • Java Wildcards & Existential Types • Semantic Model for Existential Types • Soundness & (In-)Completeness • Weak Independence & Completeness • Conclusions
Completeness? When does Δ⊨ T1≤ T2⇒ Δ ⊢ T1≤ T2 hold ?
Completeness? When does Δ⊨ T1≤ T2⇒ Δ ⊢ T1≤ T2hold ?
Completeness? When does Δ⊨ T1≤ T2⇒ Δ⊢ T1≤ T2hold ?
Completeness? ⊨ ∃Δ1.N1≤ ∃Δ2.N2⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2?
Completeness? ⊨ ∃Δ1.N1≤ ∃Δ2.N2⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2? [[ ∃Δ1.N1 ]] ⊆ [[ ∃Δ2.N2 ]] ⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2? Uσ1 with Δ1⊢ σ1[[ σ1(N1) ]] ⊆ Uσ2 with Δ2 ⊢ σ2[[ σ2(N2) ]] ⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2 ? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2 ?
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2 ?
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ?
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ?
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)=σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)=σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)=σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢σ1 there exists σ2withΔ2⊢σ2such that σ1(N1)=σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y = Y X X
Completeness? X X (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y = Y X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ ? Y = Y X X X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ there exists σ3withΔ2⊢σ3such that N1= σ3(N2) Y = Y X X X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ there exists σ3withΔ2⊢σ3such that N1= σ3(N2) ⇒ ⊢ ∃Δ1.N1≤ ∃Δ2.N2 Y = Y X X X X
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ there exists σ3withΔ2⊢ σ3such that N1= σ3(N2) • The red property below is sufficient to deduce completeness (Δ1 is “rich” in the language of paper) • Previous pictures suggest it is enough for there to be “sufficiently different” instantiations for Δ1 • This is not quite enough, with multiple variables • e.g., Δ1= X : [⊥ C], Y : [X X] and Δ2= Z : [⊥ C] and N1= Pair<X,Y> and N2= Pair<Z,Z>
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇒ there exists σ3withΔ2⊢ σ3such that N1= σ3(N2) • The red property below is sufficient to deduce completeness (Δ1 is “rich” in the language of paper) • Previous pictures suggest it is enough for there to be “sufficiently different” instantiations for Δ1 • This is not quite enough, with multiple variables • e.g., Δ1= X : [⊥ C], Y : [X X] and Δ2= Z : [⊥ C] and N1= Pair<X,Y> and N2= Pair<Z,Z>
Completeness? (forallσ1withΔ1⊢ σ1 there exists σ2withΔ2⊢ σ2such that σ1(N1)= σ2(N2)) ⇏ there exists σ3withΔ2⊢ σ3such that N1= σ3(N2) • The red property below is sufficient to deduce completeness (Δ1 is “rich” in the language of paper) • Previous pictures suggest it is enough for there to be “sufficiently different” instantiations for Δ1 • This is not quite enough, with multiple variables • e.g., Δ1= X : [⊥ C], Y : [X X] and Δ2= Z : [⊥ C] and N1= Pair<X,Y> and N2= Pair<Z,Z>
Completeness? • The red property below is sufficient to deduce completeness (Δ1 is “rich” in the language of paper) • Previous pictures suggest it is enough for there to be “sufficiently different” instantiations for Δ1 • This is not quite enough, with multiple variables • e.g., Δ1= X : [⊥ C], Y : [X X] and Δ2= Z : [⊥ C] and N1= Pair<X,Y> and N2= Pair<Z,Z> • We need that each variable in Δ1 gets sufficiently varied instantiations independently of the others...
Weak Independence • We define two types to be sufficiently different if the uppermost class types in their structure differ • We say Δ1 is weakly independent if for each variable X in Δ1 there exist two substitutions σ1, σ2such that σ1(X) is sufficiently different from σ2(X) and for all other variables Y inΔ1 ,σ1(Y) = σ2(Y) • Essentially, each variable gets the chance to vary independently of the others • e.g., X : [⊥ C], Y : [X X]is not weakly independent, but X : [String Object], Y : [X Object]is
Weak Completeness • We proved a weak completeness result: If ⊨ ∃Δ1.N1≤ ∃Δ2.N2 and Δ1 is weakly independent, then ⊢ ∃Δ1.N1≤ ∃Δ2.N2 • Recall: all types can be written in the form ∃Δ.N(in which Δ is possibly empty) – this is not a restriction • The result does not apply (yet) to open types (those featuring type parameters of the enclosing class) • However, for closed types with weakly independent environments, syntactic subtyping is sound and complete with respect to our semantic model
Conclusions and Future Work • Defined a semantic model for Java Wildcards • Proved soundness of Java subtyping w.r.t. model • Completeness does not hold in general • Identified a restriction (weakly-independent environments) under which completeness holds • For future work, open types should be handled • Can we find a weaker restriction for completeness? • Can non-trivial incompleteness arise in Java? • we conjecture not, which would give us strong soundness and completeness results for Java subtyping