340 likes | 358 Views
Explore a type system for well-founded recursion, focusing on interaction of recursion and effects, dynamic and static detection methods, and type conversion rules. Discusses key observations, typing judgment principles, and code examples.
E N D
A Type System forWell-Founded Recursion Derek Dreyer Carnegie Mellon University POPL 2004 Venice, Italy
Recursive Modules • Allow mutually recursive functions/datatypes to be developed independently • One of the most commonly requested extensions to the ML languages • A number of problems, but we will focus on interaction of recursion and effects
? loc Backpatching Semantics • Evaluation of rec(X. M):
? loc Backpatching Semantics • Evaluation of rec(X. M): M[!(loc)/X] * V
V loc Backpatching Semantics • Evaluation of rec(X. M): M[!(loc)/X] * V
? loc Backpatching Semantics • Evaluation of rec(X. M): • But how do we ensure evaluation of M will not access contents of loc? M[!(loc)/X] * V
? loc Backpatching Semantics • Evaluation of rec(X. M): • But how do we ensure evaluation of M will not access contents of loc? • Dynamic detection (has run-time cost) • Static detection preferable, but how? M[!(loc)/X] * V
In This Talk... • Study well-founded recursion at term level • i.e. ignore issues involving type components, which are largely orthogonal • Idea: Treat the act of accessing a recursive variable as a computational effect
Recursion Construct • rec(XB x : . e) • x is the recursive variable • is its type • e is the expression being evaluated • X is the name of x,which represents the effect of accessing x • Type system ensures e is pure w.r.t. the effect X
Typing Judgment • ` e : [S] • In context , e has type with support S • Support = set of names of rec. var.’s that e may access • i.e. set of effects that may occur when e is evaluated • Can only safely evaluate e once rec. var.’s named in S have been backpatched
Problem • Say we use rec to define a recursive function: • Body has type • Doesn’t match declared type
Problem • What if we change the declared type accordingly? • Body matches declared type • Declared type isn’t well-formed outside of the rec Something is seriously broken!
Key Observation Once a recursive variable has been backpatched, the effect of accessing it becomes benign,so we can ignore it!
New Recursion Rule • ´X , ´modulo occurrences of X • Permits mismatch between and as long as it only involves X
Problem Solved • Now our original example typechecks: • Body has type
Using Existing Code • Say we want to use an existing ML function H • Well-formedness depends on type of H
ML Arrow Type • Suppose that H has the following ML type: • In our system, ML arrow (->) corresponds tosince ML functions don’t access recursive variables:
Using Existing Code • Ill-typed: f does not match argument type of H • Good! H(f) could very well have applied f, resulting in an access of x.
Problem • But what if we eta-expand H(f)... • Still ill-typed, even though g is now bound to a value!
Rethinking the Judgment • ` e : [S] interpreted as: • In context , e has type and may have the effects in S
Rethinking the Judgment • ` e : [S] interpreted as: • In context , e has type and may have the effects in S • Alternative interpretation: • In context , ignoring the effects in S,e is pure and has type
Ignorance is Bliss • X is in the support when typechecking • Under support X, type conversion rule allows us to assign f the type by ignoring X • So the code is now well-typed!
Original Example • Still ill-typed: H(f) can’t assume X in the support • But if H is non-strict, then we would like to make this typecheck
Non-strict Functions • Can encode non-strict function type for H usingname abstractions (effect polymorphism): • Given this type for H, example from previous slide will typecheck
Separate Compilation • Also depends on non-strict function types: • Want to write rec(X B x : . F(x)) • Only well-founded if F is non-strict • We introduce “box” types to describe F’s argument:
Related Work onWell-Founded Recursion • [Boudol 01] and [Hirschowitz-Leroy 02] • Based on tracking non-strictness of functions • F : ) F’s argument appears under n-abstractions in F’s body • e.g. • Used as target for compiling OO language (Boudol) and mixin module calculus (HL)
Related Work onWell-Founded Recursion • [Boudol 01] and [Hirschowitz-Leroy 02] • Somewhat brittle as foundation forrecursive modules: rec(x. ...(y.e)(3)... ...(y.e)(5)... ...) may be well-typed, but...
Related Work onWell-Founded Recursion • [Boudol 01] and [Hirschowitz-Leroy 02] • Somewhat brittle as foundation for recursive modules: rec(x. let f = (y.e) in ...f(3)... ...f(5)... ...) might not bewell-typed!
Rest of the Paper • Dynamic semantics and type safety theorem • Recovering dynamic detection by adding memoized computations to the language • Future work: • Type/support inference • Lifting to level of modules and full ML