A Type System for Well-Founded Recursion Derek Dreyer Carnegie Mellon University POPL 2004 Venice,...

34
A Type System for A Type System for Well-Founded Recursion Well-Founded Recursion Derek Dreyer Carnegie Mellon University POPL 2004 Venice, Italy

Transcript of A Type System for Well-Founded Recursion Derek Dreyer Carnegie Mellon University POPL 2004 Venice,...

A Type System forA Type System forWell-Founded RecursionWell-Founded Recursion

Derek Dreyer

Carnegie Mellon University

POPL 2004

Venice, Italy

2

Recursive ModulesRecursive 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

3

Recursive Module ExampleRecursive Module Example

4

Backpatching SemanticsBackpatching Semantics

• Evaluation of rec(X. M):

loc?

5

Backpatching SemanticsBackpatching Semantics

• Evaluation of rec(X. M):

loc? M[!(loc)/X] * V

6

Backpatching SemanticsBackpatching Semantics

• Evaluation of rec(X. M):

locV M[!(loc)/X] * V

7

Backpatching SemanticsBackpatching Semantics

• Evaluation of rec(X. M):

• But how do we ensure evaluation of M will not access contents of loc?

loc? M[!(loc)/X] * V

8

Backpatching SemanticsBackpatching 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?

loc? M[!(loc)/X] * V

9

In This Talk...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

10

Recursion ConstructRecursion Construct

• rec(X B 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

11

Typing JudgmentTyping 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

12

Some Typing RulesSome Typing Rules

13

Recursion Rule (First Try)Recursion Rule (First Try)

14

ProblemProblem

• Say we use rec to define a recursive function:

• Body has type • Doesn’t match declared type

15

ProblemProblem

• 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!

16

Key ObservationKey Observation

Once a recursive variable has been backpatched, the effect of accessing it becomes benign,

so we can ignore it!

17

New Recursion RuleNew Recursion Rule

• ´X , ´ modulo occurrences of X

• Permits mismatch between and as long as it only involves X

18

Problem SolvedProblem Solved

• Now our original example typechecks:

• Body has type •

19

Using Existing CodeUsing Existing Code

• Say we want to use an existing ML function H

• Well-formedness depends on type of H

20

ML Arrow TypeML Arrow Type

• Suppose that H has the following ML type:

• In our system, ML arrow (->) corresponds tosince ML functions don’t access recursive variables:

21

Using Existing CodeUsing 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.

22

ProblemProblem

• But what if we eta-expand H(f)...

• Still ill-typed, even though g is now bound to a value!

23

Rethinking the JudgmentRethinking the Judgment

• ` e : [S] interpreted as:– In context , e has type and may have the

effects in S

24

Rethinking the JudgmentRethinking 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

25

Type Conversion RuleType Conversion Rule

26

Ignorance is BlissIgnorance 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!

27

Original ExampleOriginal 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

28

Non-strict FunctionsNon-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

29

Separate CompilationSeparate 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:

30

Related Work onRelated Work onWell-Founded RecursionWell-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)

31

Related Work onRelated Work onWell-Founded RecursionWell-Founded Recursion

• [Boudol 01] and [Hirschowitz-Leroy 02]– Somewhat brittle as foundation for

recursive modules:

rec(x. ...(y.e)(3)... ...(y.e)(5)... ...)

may be well-typed, but...

32

Related Work onRelated Work onWell-Founded RecursionWell-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!

33

Rest of the PaperRest 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

Grazie! Domande?Grazie! Domande?