CORNELL CS 611 - Lecture 33 Equirecursive types & Recursive domain equations

Unformatted text preview:

CS611 Lecture 33 Equirecursive types & Recursive domain equations November 19, 2001Scribe: Hongzhou Liu and Junhwan Kim Lecturer: Andrew Myers1 Semantics of recursive types, part 2There are two basic approaches to recursive types: iso-recursive and equi-recursive. The essential differencebetween them is captured in their response to a simple question: What is the relation between the typeµX.τ and its one-step unfolding τ{µX.τ /x} ?So far we have seen the iso-recursive approach, which takes a recursive type and its unfolding as different,but isomorphic. In a system with iso-recursive types, we introduce, for each recursive type µX.τ, a pair offunctions unfold and fold that witness the isomorphism by mapping values back and forth between the twotypes:fold←−µX.τ∼=τ{µX.τ/X}unfold−→The ML and C languages use this approach, but by implicitly introducing a fold or unfold along withother syntactic constructs. In ML, every datatype definition implicitly introduces a recursive type. Each useof a constructor to build a value of a datatype implicitly includes a fold, and each constructor appearing ina pattern match implicitly forces an unfold. For C, the * and & also signal an unfold and fold, respectively.ML Cfold constr &unfold match *The other approach is what Pierce calls equi-recursive types: the two type expressions are definitionallyequal—interchangeable in all contexts, because they stand for the same infinite tree.` µX.τ∼=τ{µX.τ/X} (1)Modula-3 uses this approach. In this language, a recursive type and its unfolding are substitutable. The foldand unfold operators are automatically supplied whenever needed.For example, in a system with equi-recursive types, these two types are equivalent:µS.S → int∼=µT.(T → int) → int (2)Since they correspond to the same infinite syntactic trees:12 Structural equivalenceNow we have to solve this problem: In a system with equi-recursive types, when are two recursive typesequivalent? As we have stated above, two types are equivalent if their infinite unfoldings are identical.Another way to think of the infinite trees above is as graphs containing loops. The µ constructor tells uswhere back edges are.According to this intuition, we need a graph algorithm. The idea of this algorithm is to see if all (finiteor infinite) paths in each syntactic tree are possible in the other. The algorithm goes as follow:• Recursively walk both trees• On back edges, record that the two nodes were reached simultaneously (and are presumably equivalent)• If comparing two nodes and they are already recorded as equivalent, returnTo implement this in a formal way, we introduce a new context E to the type equivalence system; itspurpose is to record assertions about equivalent types.E ` τ1∼=τ2. E is defined inductively:E = ∅ | E, τ1∼=τ2(3)The context E records type expressions assumed to be equivalent. Two types are equivalent if ∅ ` τ1∼=τ2.E ` τ∼=ττ2∼=τ1∈ EE ` τ1∼=τ2E ` τ2∼=τ1E ` τ1∼=τ2E ` τ1∼=τ2E ` τ2∼=τ3E ` τ1∼=τ3E ` τ1∼=τ01E ` τ2∼=τ02E ` τ1× τ2∼=τ01× τ02E ` τ1∼=τ01E ` τ2∼=τ02E ` τ1+ τ2∼=τ01+ τ02E ` τ1∼=τ01E ` τ2∼=τ02E ` τ1→ τ2∼=τ01→ τ02E, µX.τ1∼=τ2` τ1{µX.τ1/X}∼=τ2E ` µX.τ1∼=τ2(µ equiv)Using (µ equiv), we can derive the following useful rule:E, µX.τ1∼=µY.τ2` τ1{µX.τ1/X}∼=τ2{µY.τ2/Y }E ` µX.τ1∼=µY.τ2Using these rules, we can now show the equivalence of the two types given earlier. Let τ1≡ µS.S → int,τ2≡ µT.(T → int) → int,τ1∼=τ2, τ1∼=τ2→ int ` τ1∼=τ2` int∼=intτ1∼=τ2, τ1∼=τ2→ int ` τ1→ int∼=τ2→ intτ1∼=τ2` τ1∼=τ2→ intτ1∼=τ2` int∼=intτ1∼=τ2` τ1→ int∼=(τ2→ int) → int∅ ` µS.S → int∼=µT.(T → int) → int23 Modeling µX.τCurrently, our semantics model τ as a domain T [[τ]]. We would like to model the domain for the recursivetype, µX.τ. Recursive types introduce names for types. Thus we need a type environment χ to capturerecursive types: χ ∈ TypeVar * Domain. In our definition, T [[τ]]χ gives the domain corresponding totype τ, given type variables whose meanning is defined by χ.Here are the inductively defined rules for interpreting T [[τ]]χ:T [[X]]χ = χ(X)T [[τ1+ τ2]]χ = T [[τ1]]χ + T [[τ2]]χT [[τ1× τ2]]χ = T [[τ1]]χ × T [[τ2]]χT [[τ1→ τ2]]χ = T [[τ1]]χ → (T [[τ2]]χ)⊥T [[µX.τ]]χ = µD.T [[τ]]χ[X 7→ D]In these rules, we introduced a constructor for recursive domains, which is given by µD.F(D), wherefunctor F maps one domain into another domain, F: Domain → Domain. If D = µX.F(X), then F(D)produces a domain related to D by continuous functions up and down that are inverses of one another.up←−µD.F(D)∼=F(µD.F(D))down−→That is, upµX.τ∈ T [[τ{µX.τ/X}]] → T [[µX.τ]] and downµX.τ∈ T [[µX.τ]] → T [[τ{µX.τ/X}]].Having up and down in hand, we can write out denotational semantics for the fold and unfold expressions:C[[Γ ` foldµX.τe : µX.τ]]ρ = upµX.τC[[Γ ` e : τ{µX.τ/X}]]ρ∈ T [[µX.τ]]φC[[Γ ` unfold e : τ{µX.τ/X}]]ρ = downµX.τC[[Γ ` e : τ{µX.τ/X}]]ρ∈ T [[τ {µX.τ /X}]]4 Type interpretation and compiler constructionThe type interpretation function T [[τ]]χ can be read as a somewhat forbidding statement about how toconstruct complex domains that underlie the semantic model for a language. A less mathematical interpre-tation is that they explain a nice way to write a compiler for a language with recursive types. In buildinga compiler, we have two basic choices for how to represent types internally. One is to represent them asthe abstract syntax tree corresponding to the type expression. This approach works but can be somewhatclumsy, because the type expression may name type variables. In order to make sense of the type expression,it is necessary to always keep track of the associated naming context that binds the type variables. Tests fortype equivalence can be expensive and may need to be done repeatedly if the language supports structuralequivalence.Another implementation choice is to interpret these types and convert them into type objects. Theadvantage of the latter approach is that the type objects can be simpler; they need not record certaininformation such as the actual name of the type variable introduced in a recursive type, for example. Inaddition, the compiler can be designed to interpret all


View Full Document

CORNELL CS 611 - Lecture 33 Equirecursive types & Recursive domain equations

Download Lecture 33 Equirecursive types & Recursive domain equations
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Lecture 33 Equirecursive types & Recursive domain equations and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Lecture 33 Equirecursive types & Recursive domain equations 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?