1.1 Overview

4.1.2 Signature type-checking
Note: the type-checking is also an elaboration from source to Momega signatures
- declaration typing
- extrusion:
- abstract type variables will be introduced in
(type t = A.t) : \a. (type t = a) - for declarations, variables will be extruded and sequentially combied
- for module type declarations, the binder is not lifted in its own scope
- abstract type variables will be introduced in
- extrusion:
- signature typing
- For
sig ... endthis is the last place where extrusion happens M-Typ-Sig-LocalModType- look up local module type by path, seeM-typ-decl-seqfor how they are introduced- Transparent signatures:
- elaborate source signature to signature
- infer the signature by module typing
- before subtyping check, find an instantiation, which is not easy in presence of higher-order types
- Check
- Generative functors opaque existential signature
- Applicative functors
- Solution by F-ing modules
- change to higher order abstract types that can be applied to each universally quantified
- skolemization
- For Momega, need to justify a similar skolemization but for the type of module expressions
- For
4.1.3 Subtyping
= record subtyping + function subtyping + polymorphic subtyping (in universal + existential via instantiation)
- [[subtyping à la ]]
Implicit polymorphic subtyping:
Ψ ⊢τ Ψ ⊢[τ/a]A≤B ----------------
Ψ ⊢∀a.A≤B
We assume no subtyping in the core language
Question in the core language being used by the surface language, or no subtyping at all in the theory?
- submodules: simply propagtes down
- module type fields:
- In F-ing modules, 2-way checking: allows for different ordering
- Could have made: requiring same signature: up to Momega equivalence
- adopted:
- 2-way checking for the whole signature
- require syntactic equality for dynamic parts (type definition / module type definition not checked)
- generative functors:
- the right type can be more instantiated (that can use the existential type on the left type vars )
- quite permissive to use
- algorithmically challenging
- potential lead to undecidability of subtyping
- F-ing modules: several requirements for decidability
If we where to allow the user to input non-explicit signatures – either with an unrestricted module type of construct, or directly in Mω-signatures syntax – we would lose decidability. This hints at the fact that ML-modules are not just merely a mode of use of Fω (as written in F-ing (Rossberg et al. [2014])), but also a sweet spot, where changes seen as minor from Mω could easily break decidability.
4.1.4 Module Expression type-checking
- skolemization of applicative functors (module expressions) require transparent existential types
- why not for types:
-
typing of signatures is just a mere manipulation of types where everything is possible, as long as the resulting signatures are wellformed. By contrast, for the typing of module expressions, the soundness relies on the ability to actually produce a term of the corresponding type
- propagation of modes
- generative functors (abstraction, application) are opaque
- applicative can be downgraded to generative
- for structures, all bindings must have the same mode
- bindings typing the judgement of binding typing comes with a mode for tracking effects, but as in OCaml, it is user’s responsibility to mark generative functors
- paths: for looking up from the context, in checking the application of applicative functors
- ascription: introducing abstract types
- difference, for: , the checking result is the instantiated one
- for
(P: S)te result is the (transparent) abstract type - The transparent ascription in OCaml
(P <: S)is a syntax sugar of(P: (= P < S))(= P < S)is the opaque ascription of P to the transparent signature #question What is exactly the behavior here
So, in OCaml actual usage,
M-Typ-Mod-Ascrnever creates new abstarct variables? The rule is generalized for proving? No? Typing for this syntax sugar:
- abstract-type binding also (the only other construct) introduces abstract-type binding
- Projection: thanks to signatures + lifted binders + paths inlined
- we have a simple projection rule
- there is another pass of garbage collection for avoiding useless abstract types
typechecking the projection of a submodule M.X is often a source of signature avoidance: the dependencies of the source signature of X might become dangling after the other components of the signature of M have been lost.
Section 4.2
- Source to source translation
- add
Idtags for module expressions/sig types,and prove thatidfield check can shortcut the equivalence check for the actual expression
- add
Section 4.3
three anchoring conditions:
- ensure the signature is a valid elaboration result of a source
- functor application condition
Basically
- conditions for the first occurrence of
type t = a - conditions for module identities tag
- conditions for higher-order modules
and then a process of translating signatures to tagged source signatures and then an untagging process
Proved:
ElaborationAnchoring= identityAnchoringElaboration~ identity`
Section 4.4
use explicitly typed + records + (transparent) existential types + predicative kind polymorphism (ensuring coherence)
-
Same as F-ing modules, use identity functions to encode type fields (which carry additional typing constraints)
- the term
- and its type
-
Also the trick in F-ing modules,
repackconstructor for dealing with lifting open abstract type declarations to be visible in the rest of the program, since only supports non-dependent recordslift <a, x1 = e1 @ e2> = ... repack ...- and we have derived typing rule for
liftfunction - (with a simple result existential type, where all abstract type variables are lifted to top-level)
-
Lifting works for record types, but is not sufficient for applicative case (which uses skolemization)
- lifting over universal types is not expressible
- lifting over arrow types is unsound
-
question does the F semantics with the modules semantics coincide?
-
abstract signatures, fully supported?
- Didier: this is the leaf
- we can focus on abstract modules with only abstract types (level 0 - 1)
- you will see the complexity of introducing abstract module types (level 2)
- more advanced, issues with non-terminating subtyping checks (no use case?)
