- 66 Views
- Uploaded on
- Presentation posted in: General

Translucent Existentials and Sums

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Translucent Existentials and Sums

Robert Harper

Fall Semester, 2002

- Dependent types are transparent.
- Propagate type sharing by substitution.
- No support for type abstraction.

- Existential types are opaque.
- Representation type is hidden from client.
- No support for transparency.

- Dependent types run afoul of effects.
- Replication or deletion of effects.
- Effectful expressions in types.
- Sensible in a second-class module system.

- Existential types are compatible with effects.
- But opacity is a high price to pay!

- Existential types support separate compilation.
- Interfaces are existentials.
- Complete separation of code from types.

- Dependent types conflict with separate compilation.
- Sharing is propagated by substitution.

- Separate compilation and effects are important.
- Suggests using existentials.

- Type dependency is important.
- Suggests using dependent types.

- Controlled sharing propagation is essential.
- Suggests something else is needed.

- Existentials are maximally pessimistic.
- If e : 9 t.t, then no information about the type part of e is available statically.
- eg, e = if moon-is-full then e1 else e2.

- But this is a “worst-case” scenario!
- e = packtwithl x:t.x
- e = packtwith (print “hello”; l x:t.x)

- A module is determinate iff its type component is well-defined.
- First-class: truly indeterminate modules.
- Second-class: pro forma indeterminacy, but no per se indeterminacy.

- Module values are determinate.
- Explicit package of a type with a value.
- Variables, paths (assuming CBV).

- The type of a module should capture its entire static significance.
- Identity of type components.
- Type of value components.

- Need type definitions in interfaces.
- Capture representation type.
- Programmer-controlled degree of abstraction.

- Enrich existentials with type definitions:
- 9 t.t for opaque types;
- 9 t=s.t for transparent types.

- Packages do not change.
- But any equations must be satisfied!

- Dot notation:
- repn(e) for the representation type of e;
- opns(e) for the operations of e.

- Propagation of type sharing information:
- G`9 t=s.t´9 t=s.{s/t}t

- “Forgetful” subtyping:
- G`9 t=s.t <: 9 t.t,
- if G `t´t’, then G `t<:t’

- Thus, 9 t=s.t <: 9 t.{s/t}t

- If e is determinate of type 9 t=s.t, then repn(e) ´s.
- If e is determinate of type 9 t.t, then repn(e) is equal only to itself.
- If e is indeterminate, cannot form repn(e).
- There is no unique representation type!

- Typing rules for opns must take account of effects!
- First cut: G `D opns(e) : {repn(e)/t}t
- But this involves substitution!

- Problem: repn(e) is a type involving e.
- No better off than with dependent types!
- What if e is indeterminate?

- Suppose e : 9 t.t.
- If e is determinate, then repn(e) is sensible, hence so is opns(e).
- If tdoes not involve t, then opns(e) is sensible.
- Substitution is vacuous, so opns(e) : t.
- e can be determinate or indeterminate.

- Note: the type of opns(e) does not depend on repn(e) if e : 9 t=s.t.
- Propagate sharing to eliminate t from t.

- Theorem: If e is a value, then it has a non-dependent type!
- Explicit packages: propagate sharing.
- Variables (and paths): selfification.

- WLOG we may admit opns(e) only when e has a non-dependent type.
- Always if e is a value (by the theorem).
- Always if representation is explicitly exposed (even if e has effects).
- Never if e is genuinely indeterminate.

- This is the key to dot notation in the presence of effects!

- Packages have transparent types:
- packswith e : 9 t=s.t, if e : {s/t}t.

- Package type can be weakened by subsumption.
- packswith e : 9 t.t.

- Sealing forces weakening.
- (e:9 t.t) : 9 t.t

- Suppose that G(x) = 9 t.t.
- Selfification: G` x : 9 t=repn(x).t.
- repn(x) is well-formed because variables are determinate.
- propagates an “obvious” fact to the type.

- Extends to paths opns(opns(…(x)…)).
- Deemed valuable because projection is “total” (does not affect determinacy).

- Selfification is essential for principal types for modules.
- sig type t val x:t end is not principal for x, even though x is declared with this type!
- selfification yields the most precise type for x, namely sig type t=x.t val x:t end.
- all types for x are supertypes.
- singletons reveal the full story (later).

- Without selfification we cannot form opns(x)!
- Typing rule precludes dependency.

- Without selficication we incur excessive abstraction.
- structure S’ = S yields S’.t different from S.t

- Leads to a more elegant type theory.
- But incompatible with “by name” binding!

- Similar ideas apply to dependent types!
- Avoid substitution, because of effects.

- Substructure selection and functor application are restricted to the non-dependent case.
- First, propagate type sharing.
- Second, perform elimination operation.

- Suppose that e : S s:t1.t2.
- the natural type for p2(e) is {p1(e)/s}t2
- but what if e has an effect?

- How can s occur free in t2 ?
- only as repn(p(s)), where p is a path.
- if p(s) is transparent, substitute to remove dependency.
- if e is a value, all paths from s can be made transparent by path selfification.

- Can always admit p1(e).
- no issue of sharing propagation.

- Admit p2(e) iff e : t1£t2.
- That is, e : S s:t1.t2 with s not free in t2.

- Dependency eliminable iff e is determinate.
- Otherwise it makes no sense to form p2(e)!

- Suppose that e : P s:t1.t2.
- Consider the application e(e1).
- Natural type: {e1/s}2.
- But what if e has an effect?

- Require that s does not occur free in t2.
- Can only arise in the form repn(p(s)).
- Always possible if e1 is a value!

- Subtyping for functor types is
- covariant in the range
- contravariant in the domain

- We can weaken a functor type by strengthening its domain type!
- Add more sharing to the domain.
- Propagate sharing to eliminate dependency.

- Suppose that t1 = 9 t.s1 and that t2 = 9 t=repn(s).s2.
- So t = P s:t1.t2 is dependent.

- Suppose that e : 9 t.s1 is a value.
- So e : 9 t=r.s for some r.

- By subsumption F has type P s:t1’.t2, where t1’ = 9 t=r.s1.

- By sharing propagation we may eliminate dependencies on s from t2.
- Replace repn(s) by r.

- Thus F has type P s:t1’.{r/repn(s)}t2.
- Write t2 as {repn(s)/t}t2’.
- Then form t2’’ = {r/t}t2’.

- So F has type t1’!t2’’, hence F(e1) : t2’’.
- Regardless of whether e1 has an effect!

- Every value must have a “fully transparent” type.
- All type paths starting from that value have a definition.
- Thus repn(p) may be replaced by its definition.

- The H-L formalism is based on translucent sums.
- Dependent records with type and value components.
- Labels (for external access) separated from variables (for internal access).
- Subtyping may forget components.

- Translucent sums: { d1, …, dn }
- Each di is a declaration of a type or a value.

- Declarations:
- Type component: l Ba :: k [=t]
- Value component: l B x : t

- External vs internal access:
- Labels are used for paths (projection).
- Variables are used for internal dependencies.
- It is essential to distinguish these!

- Elements of translucent sums are dependent records { b1, …, bn }.
- Each bi is a binding.

- Bindings have the form:
- Type binding: l Ba :: k = t.
- Value binding: l B x : t.

- Superficial differences from H-L.
- More ML-like notation, for example.

- A few minor technical deficiencies.
- Paths cannot be limited to variables at the head.
- Different treatment of variable/label distinction.

- Translucent sums solve several problems in one framework:
- Effectful languages.
- Dependent types for structures and functors.
- Selective opacity/transparency.

- H-L and Leroy provide only very weak support for higher-order modules.
- Fully expressive in the first-class case (without restrictions).
- Does no capture phase distinction for the second-class case.

- The H-L formalism is undecidable!
- Subtyping relation is undecidable by an argument similar to Pierce’s for F-Sub.
- Leroy’s may or may not be, it’s not clear.

- Both formalisms lack principal types!
- Serious obstacle to type checking.
- Precludes strong separate compilation (pace Leroy’s motivation).

- Let T = 9 t.1 and let U = 9 t=repn(s).1, where s is a free variable.
- Note that U <: T.
- Let t¤ = packtwith¤ : T.

- Consider the type s = (T ! U) £ U, and suppose that we wish to avoid s.
- Two incomparable supertypes avoid s:
- (T! T) £ T
- S f:(T! T).(9 t=repn(f(t¤)).1) foranyt.

- For a first-order module system we can get by with H-L or L.
- HOM weakness not at issue.

- But we must avoid the avoidance problem.
- Requires elaboration tricks.
- O’Caml doesn’t, so its incomplete.

- Translucent sums enrich existentials:
- Controlled abstraction.
- Fully expressive types.
- Support for “dot notation”.

- Translucent sums generalize dependent types.
- Leroy establishes a precise connection.