Variant Path Types for Scalable Extensibility Atsushi Igarashi - - PowerPoint PPT Presentation
Variant Path Types for Scalable Extensibility Atsushi Igarashi - - PowerPoint PPT Presentation
Variant Path Types for Scalable Extensibility Atsushi Igarashi (Kyoto Univ.) joint work with Mirko Viroli (Univ. Bologna) Background: Scalable Extensibility Language support for extending program components which can be uniformly
Background: Scalable Extensibility
- Language support
– for extending program components – which can be uniformly applied to
components of different scales:
- classes, groups of classes, groups of
groups, and so on
- Lot of work on this issue has emerged recently
(gbeta, Scala, Concord, CaesarJ, JX, J&)
Extending a Group of Classes
- Inheritance of hierarchies of nested classes
– a.k.a higher-order hierarchies [Ernst03]
class AST { } class Exp { } class Plus ext Exp{ } class Eval extends AST { } class Exp { } class Plus ext Exp{ }
Implicit extension
How “Nested” Inheritance Works
[Ernst99][JX] Complete definition of a class is obtained by
- combining bodies of superclasses with possible
method overriding
- propagating combination down recursively
class Eval { // extends AST // defs inherited from AST // Eval's own defs (with overriding) } class Exp {
// from AST.Exp
class Plus ext Exp{ // from AST.Plus
// from Eval.Exp
} // from Eval.Plus }
Two Styles of Semantics
- Nested classes as (dynamic) attributes of objects
[gbeta,Scala]
– Run-time type = instance id (a) + class (Plus) – Naturally lead to a dependent type system
- Nested classes as (static) attributes of
classes/groups [JX, Concord, Bruce03WOOD]
– Run-time type = fully qualified name of class
var a = new AST(); var p = new a.Plus(); var p = new AST.Plus();
This Paper
- Addresses typing issues for the second semantics
– Without using dependent types
- Less complication
- Less interaction with side effects
– With rich subtyping by variant path types
- Formalizes the type system as a core language
FJpath
- States a type safety theorem
– Hand-written proofs finished
Outline of the Talk
- Preliminary Syntax
- Variant Path Types
- Related Work
- Conclusion
Syntax of FJpath (ver. 0.1)
Looks like FJ + (static) nested classes T ::= (to be filled) L ::= class C extends C { ~T ~f; ~L ~M } M ::= T m(~T ~x){ return e; } e ::= x | this | e.f | e.m(~e) | new T(~e)
Example
class AST { class Exp { method print() { ... } } class Const extends Exp { field v; method print() { ... } } class Plus extends Exp { field right, left; method print() { ... } } }
class Eval extends AST { class Exp { method eval() {...} } class Const extends Exp { method eval() { return this.v; } } class Plus extends Exp { method eval() { return right.eval()+left.eval(); } } }
Outline of the Talk
- Preliminary Syntax
- Variant Path Types
– Relative and absolute path types – Exact types for safety – Exact and inexact qualifications – Parametric methods
- Related Work
- Conclusion
Requirements for a Type System
It should
- be able to express intra-relationship of classes
– l“m takes an expression of the same group”
- Preserved by group extension
- achieve type safety (of course!)
Relative Path Types for Intragroup Reference
- This always refers to the current class
- ^This to refer to the enclosing class
– ^This.C for a sibling
- ^^This for the further enclosing class, and so on
class AST { class Exp { bool eq1( This exp) {...} bool eq2( ^This.Exp exp) {...} } class Plus extends Exp { ^This.Exp left,right; ... } }
Resolution of Relative Path Types
- The signature of a method (or a field type) is
computed by substituting
– the (static) type of the receiver for This – a prefix of the receiver type for ^...^This
- left of AST.Plus is AST.Exp
- left of Eval.Plus is Eval.Exp
- AST.Exp.eq1() takes AST.Exp
- AST.Exp.eq2() takes AST.Exp
- AST.Const.eq1() takes AST.Const
- AST.Const.eq2() takes AST.Exp
eq1(This e); eq2(^This.Exp e);
Exact Types for Safety
- Assuming AST.Plus being a subtype of AST.Exp
can break the type system (as usual)
- Exact types [Bruce] solve the problem
– Exact type @(AST.Plus) (subtype of AST.Plus)
includes only instances of class AST.Plus
– Invocation of method taking This (with ^) must be
- n an exact type
AST.Exp e1 = new AST.Plus(); AST.Exp e2 = new AST.Const(); bool b = e1.eq(e2);
Making Subtying Finer-Grained ...
- AST.Exp for all expressions of all ATSs
- @(AST.Exp) for the Exp of the ATS
- Any way to specify e.g., classes of a certain
group?
class Exp { } class Plus ext Exp{ } class Exp { } class Plus ext Exp{ } @(AST.Exp) @(Eval.Exp) @(AST.Plus) AST.Exp
... By Generalizing @ as Qualification
- It's natural to view @ as qualification!
– fully exact type: @AST@Plus – partially exact type: @AST.Exp, AST@Plus
- Inclusion gives rise to subtyping
class Exp { } class Plus ext Exp{ } class Exp { } class Plus ext Exp{ } @AST@Exp @Eval.Exp AST@Plus AST.Exp
Restriction on Method Invocations
- All occurrences of ^...^This in argument types
have to be replaced with fully exact types
– It doesn't necessarily mean the receiver type
must be (fully) exact!
@AST@Exp e1; e1.eq1(...); // @AST@Exp -> bool e1.eq2(...); // @AST.Exp -> bool AST.Exp e2; e2.eq1(...); // not allowed e2.eq2(...); // not allowed @AST.Exp e3; e3.eq1(...); // not allowed e3.eq2(...); // @AST.Exp -> bool
eq1(This e); eq2(^This.Exp e);
Revised Syntax
A ::= C | A@C absolute path types E ::= ^...^This | @C | E@C exact types T ::= ^...^This | C | @C | T.C | T@C types L ::= class C extends C { ~T ~f; ~L ~M } M ::= T m(~T ~x){ return e; } e ::= x | this | e.f | e.m(~e) | new A(~e)
Outline of the Talk
- Preliminary Syntax
- Variant Path Types
– Relative and absolute path types – Exact types for safety – Exact and inexact qualifications – Parametric methods
- Related Work
- Conclusion
Exact Type Parameters for “Group-Polymorphic” Methods
Consider a method to replace both operands of Plus with a given expression
- Such a group-polymorphic method can be
described by a parametric method as in Java 5.0
[Igarashi-Saito-Viroli05]
– X must range only over exact types – Otherwise, the caller could pass nodes from
different kinds of expressions
<exact X extends AST> void repl_left(X@Plus p, X.Exp e){ p.left = e; p.right = e; }
Revised^2, Final Syntax
A ::= @C | A@C absolute path types E ::= ^...^This | ^...^X | @C | E@C exact types T ::= ^...^This | ^...^X | @C | C | T.C | T@C types L ::= class C extends C { ~T ~f; ~L ~M } M ::= <~X extends ~T> T m(~T ~x){ return e; } e ::= x | this | e.f | e.m<~T>(~e) | new A(~e)
Variant Path Types: Summary
- Relative Path Types
– for describing intragroup relationship
- Exact/inexact qualifications
– for fine-grained control over exactness and
subtyping
- Parametric methods w/ exact type variables
- FJpath = FJ + nested inheritance + variant path
types + parametric methods
– Formalization and Type Soundness Theorem
(See the paper!)
Outline of the Talk
- Informal Semantics of Inheritance
- Variant Path Types
– Relative and absolute path types – Exact types for safety – Exact and inexact qualifications – Parametric methods
- Related Work
- Conclusion
Related Work
- gbeta, Caesar/J
- Scala
- Nested Inheritance/Intersection (JX) [Nystrom et al.]
- Concord [Jolly-Drossopoulou-Anderson-Ostermann]
- Lightweight family polymorphism [Igarashi-Saito-
Viroli05]
- Bruce's series of work on binary methods,
matching, statically type safe virtual types, and LOOJ
- Variant parametric types (Java wildcards)
Comparison with Variant Parametric Types (Java wildcards)
Variant parametric types
- Invariant types C<T>
– C<S> <: C<T> if S = T
- Covariant types C<+T>
(C<? extends T>)
– C<+S> <: C<+T> if S <: T – C<T> <: C<+T> – restricted method access
List<+Num> List<Int> List<Dbl> MyList<+Num> Basic.Exp Basic@Var Basic@Plus Eval.Exp MyList<Int> @Eval@Var
Variant path types
- Invariant qualification “@”
– T@C <: T@D if C = D
- Covariant qualification “.”
– T.C <: T.D if C extends D – T@C <: T.C – restricted method access
Types in JX [Nystrom et al.]
- Dependent classes: x.class, x.f.class
- Prefix types: C[T]
– The innermost enclosing class of T that is a
subclass of C
– AST[this.class].Exp ≈ ^This.Exp
- Inheritance is subtyping
void repl_left(AST.Plus p, AST[p.class].Exp e){ p.left = e; }
Conclusion
Variant path types as an alternative to dependent types in the context of nested inheritance
- Clear separation of types and values possible
- Fine-grained control over subtyping by two kinds
- f qualification
Ongoing/future work:
- Mechanism to locally “exactize” .C types?
- Type inference for parametric methods
– Preliminary results in a simpler setting [Igarashi-
Saito-Viroli05]
- Metatheory for typechecking