Designing Record Systems Martin Sulzmann Yale University, Department of Computer Science P.O. Box 208285, New Haven, CT 06520-8285
[email protected]
Research Report YALEU/DCS/RR-1128 April 1997
Abstract We explore the design space for type systems with polymorphic records. We design record systems for extension, concatenation and removal of elds. Furthermore, we design a record system where eld labels become rst class values. That means, we can now quantify over eld lables and pass them around as arguments. All designed record systems enjoy type inference with principal types. Especially, we can combine any features into a new record system retaining type inference with principal types. We also point out some problems which are present in previous record systems. Our designed record systems can be seen as the proper logical formulation of previous approaches with even more expressive power. We base our design on the HM(X) framework. HM(X) is a general framework for Hindley/Milner type systems that are parameterized in the constraint domain X. HM(X) enables us to design record systems in a systematic way retaining type inference with principal types. That means, designing record systems becomes construction of constraint systems which model record systems.
1 Introduction Type systems for records have become a playing eld for type theorists [HP91, Car84, CM89, EST95, Rem95a, Jon92, Oho95, Wan88, Wan89, Rem95b, Rem89]. One of the main motivations for record systems is that they can be used to encode object calculi [Wan89, Rem95a] or module systems [Apo93, Jon96]. Also, they are useful for data type declarations and in database programming [OB88]. But there are a couple of challenging problems to Supported
by Yale University Fellowship
overcome. The type system should support polymorphic records and additional operations like extensions of records. At least it should be possible to give a type checking algorithm. In the best case we want to have a type inference algorithm which computes principal types. On the practical side it should be possible to give an ecient compilation method. Type systems with records based on subtyping [HP91, Car84, CM89, EST95, Rem95a] have problems to support record concatenation and a compilation calculus. Also, it seems that such type systems do not provide good wrappers for object{oriented languages [BPF97]. The concept of row variables [Wan88, Wan89, Rem95b, Rem89] has also some limitations. Ohori [Oho95] introduced kinds for record types that can be seen as predicates. He could provide an ecient compilation calculus but his system lacks features like addition or removal of eld labels. The approaches of Remy [Rem92], Kennedy [Ken96] and Gaster and Jones [GJ96] are similar in spirit to ours. Remy and Kennedy extend the Hindley/Milner type system with a sorted equational theory. We argue that our constraint system is more general and we conjecture that their systems are not able to handle eld labels as rst class values. The approach of Gaster et al is based on quali ed types [Jon92]. They also present a full variety of record systems with similar expressive power. In the latter, we will see examples where one can see where our approach has advantages. In general, we will discuss some problems which are present in previous approaches. We use the HM(X) framework to design record systems. The HM(X) framework was introduced in [SOW97]. A detailed description can be found in [SOW]. HM(X) is a Hindley/Milner type system parameterized in the constraint domain X. Under the assumption that X has the principal constraint property, a generic type inference algorithm can be given that computes principal types.
The idea behind HM(X) is that whenever we need a new type system we do not have to event new typing rules and a type inference algorithm. We simply provide an instance of the constraint domain X which captures the desired properties that we want to model. If this instance satis es the principal constraint property we get a type inference algorithm which computes principal types for free. The main contribution of this paper is that we present a new methodology for designing record systems. Based on HM(X) we can do this in a systematic way retaining type inference with principal types. We systematically extend the expressive power of the constraint domain. At the end we get an instance of HM(X) which is able to deal with record and variant types, extension, concatenation of polymorphic records, removal of eld labels and that is one of the novelties of our approach, eld labels become now rst class values. Furthermore, we point out some problems which are present in previous approaches and argue that HM(X) can be seen as the proper logical foundation of these previous approaches with even more expressive power.
The constraint ( ::< l : >) ensures that the given record actually contains eld label l. Bounded type variables in type schemes can now be constrained by constraints of the form ( ::< l : > ). That means, in general we deal with type schemes of the form 8:C ) where the possible instances of the bound type variables are constrained by C . The presence of constraints is re ected in the typing rules. We have a rule (8 Elim)
C; ?
` e : 8:D ) 0 C `e [ =]D C; ? ` e : [ =] 0
that handles instantiation of constrained type variables. For instance, the term 1
fAddress : stringg.Name is rejected by the type system because there is no valid instance for the constraint ( ::< l : >). That means, type inference should report a type error. The typing problem in HM(X) is reduced to constraint problems in X. To this purpose, X needs to be a rich constraint system to express all typing problems. In the type system we only admit a subset of constraints in X that are in so{called solved form. Type inference involves accumulation of constraint problems and normalizing constraints to solved forms. For example, when we consider the term
2 Overview We discuss an instance HM(R) of the HM(X) framework that deals with record types. We base our record system on Ohori's calculus [Oho95]. Record types are denoted by fl1 : 1 ; : : : ; ln : n g where li stands for a eld label and i for the associated type. We introduce a constraint system R where we can express constraints on record types. For instance, the constraint ( ::< l : >) states that is a record which contains at least a eld with label l and type . On constraints ( ::< l : >) we put conditions like
fAddress : stringg.Address type inference in HM(R) generates the constraint problem
C = ( ::< Address : >) ^ ( = fAddress : stringg)
The constraint C is valid but not in solved form. Normalization of C yields the constraint true with residual substitution
R1 `e (fl1 : 1 ; : : : ln : n g ::< li : i >) where l1 ; : : : ; ln are distinct and i 2 f1; : : : ; ng R2 ( ::< l : 1 >) ^ ( ::< l : 2 >) `e (1 = 2 ) where `e is the entailment relation between constraints in R and (=) is the equality predicate. By condition R2 we forbid overloading of eld labels. In HM(R) we are
[fAddress : stringg=; string= ] Normalization of a constraint should result in the best possible solved form in order to compute principal types. Under the condition that the constraint system X ful lls the principal constraint property we can give a generic type inference algorithm for HM(X) type systems that computes principal types. The principal constraint property states that normalizing a satis able constraint results in a so{called principal normal form. A principal normal form represents the best possible solved form of a satis able constraint. In case of HM(R),
able to handle polymorphic records. We can give a type to the selector function .l that selects eld label l from a given record. We can express this by .l : 8; :( ::< l : >) ) !
The selector function .l can be seen as a primitive construct in an initial type environment ?0 . We introduce some more basic primitive constructs in later sections. When we apply this selector function to a given record we have to nd an instance of the above type scheme.
1 We switch the order of function application because record selection is usually written in post x notation.
2
we have to show that R satis es the principal constraint the described applications and combine them in a new property. application which retains all previous properties. In the latter, we discuss several extensions of HM(R). In the previous record systems we treated eld labels In HM(Re ) we discuss extensions of records. To this always as xed constants. We introduce an application purpose we introduce constraints of the form extendl (; ; ). HM(Rp ) where eld labels become rst class values. For Such constraints enable us to express record extension. example, eld labels can now be passed around as arguThe following primitive construct ments. This eliminates the need for primitive constructs extendl for each eld label l. One construct extend with extendl : 8; ; :extendl (; ; ) ) ! ! an additional parameter for eld labels is then sucient. We always use the same methodology to model some handles extension of records with eld label l. We desired features. We introduce some appropriate primihave not speci ed the exact behavior of the constraint tive constraints like ( ::< l : >) and extendl (; ; ). extendl (; ; ). There are several choices. Do we alThen we give a constraint system that describes the low to override an already existing eld label or can desired behavior. Such a treatment can already be we only extend a record with a non{existing eld label? found in previous work. For instance, Jones [Jon92] The exact behavior is re ected in the speci c constraint uses row variables and predicates of the form (rnl) to system which we consider. For the moment, we assume express that row r does not contain a eld with label that we can only extend a record with a non{existing l. Remy [Rem89] expresses by r has l that r contains a eld label. Because of one of the nice properties of the eld with label l. A predicate r1 #r2 is introduced by HM(X) framework we can express removal of eld labels Harper and Pierce [HP91] to model symmetric concatein terms of extendl . The primitive construct nation of records r1 and r2 . More sophisticated sorted equational theories can be found in [Rem92, Ken96] to removel : 8; :9 :extendl (; ; ) ) ! model record calculi. We point out some problems which are present in handles removal of eld labels. The operator 9 is previous approaches. The main advantage of our framecalled projection operator and is a construct of our conwork is that we can bind type variables in constraints straint system. The projection operator corresponds to by the projection operator 9 . Such a treatment can existential quanti cation if the constraint system modnot be found in previous work. This is one of the main els a boolean algebra. The constraint 9 :extendl (; ; ) reasons of problems in previous approaches. We argue expresses that record contains a eld with label l that HM(X) can be seen as the proper logical foundawhich is not present in . The type of the eld lation of these approaches. Furthermore, we discuss how bel l is not of interest in this context. Therefore, to reuse previous approaches and how to compile them is bound by the projection operator and hidden from into the HM(X) framework. outside. Additionally, it would also be possible to type The rest of this report is organized as follows. In removel with Section 3 we review basic de nitions and properties of the HM(X) framework. Section 4 describes a record apremovel : 8; ; :extendl (; ; ) ) ! plication. Further extensions like extensible records are For instance, in the theory of quali ed types [Jon92] we discussed in Section 5. Section 6 presents an applicacan not type removel with the above type. The reason tion where eld labels become rst class values. Related is that type variable does only appear in the conwork is discussed in Section 7. Section 8 concludes. straint and therefore is an ambiguous type variable. The HM(X) framework introduces a projection opera3 The HM(X) framework tor which enables us to hide such type variables. That means, removel is typable in HM(X) but not in quali ed Here, you can nd an overview of the HM(X) frametypes. work. For a detailed description we refer to [SOW]. Another extension HM(Rc ) uses constraints of the First, we introduce our notion of constraint systems. form concat(; ; ) to model record concatenation. We Then we describe the HM(X) type system. Finally, we will see that in some sense HM(Rc ) subsumes HM(Re ). consider type inference for HM(X) type systems. Variant types are considered in HM(Rv ). We now have constraints of the form ( :: l1 : 1 ; : : : ; ln : n ). 3.1 Constraint systems Such constraints denote that is a variant type which contains a tagged value with type i and label li where We present a characterization of constraint systems along i 2 f1; : : : ; ng. We also sketch how recursive types could the lines of Henkin [HMT71] and Saraswat [Sar93]. We be incorporated. It is also possible to choose any of 3
restate the de nitions of a simple and cylindric constraint system. A cylindric constraint system introduces a projection operator 9. In the case where constraint systems are boolean algebras, projection corresponds to existential quanti cation. Furthermore, we introduce the new notion of a term constraint system. A term constraint system enables us to express constraint problems which arise during type inference. De nition 1 (Simple Constraint System) A simple constraint system is a structure ( ; `e ) where is a non{empty set of tokens or (primitive) constraints 2 . The relation `e p is a decidable entailment relation where p is the set of nite subsets of . We call C 2 p a constraint set or simply a constraint. A constraint system ( ; `e ) must satisfy for all constraints C; D 2 p : C1 C `e P whenever P 2 C and C2 C `e Q whenever C `e P for all P 2 D and D `e Q
We now de ne satis ability of a constraint. De nition 4 (Satis ability) Let C be a constraint. Then C is satis able i `e 9fv(C ):C . We now introduce a much more expressive constraint system. We want to deal with types and substitutions. De nition 5 (Types) A type is a member of T =Term() where Term() is the term algebra T built up from a signature = (Var, Cons). Var is a set of variables and Cons is a set of type constructors containing at least the function constructor ! of arity 2. A type context t[] is a type with a hole and is de ned by t[] ::= [] j jt[] ! t[] jT t[] : : : t[] where 2 T and T stands for a type constructor in Cons besides !. De nition 6 (Substitutions) A substitution is an idempotent mapping from a set of variables Var to the term algebra Term(). Let id be the identity substitution. De nition 7 (Term Constraint System) A term constraint system T CST = ( ; `e ; Var; f9 j 2 Varg) over a term algebra T is a cylindric constraint system with predicates of the form p(1 ; : : : ; n ) (i 2 T ) such that the following holds: For each pair of types ; 0 there is an equality predicate ( = 0 ) in T CST , which satis es: D1 `e ( = ) D2 ( = ) `e ( = ) D3 ( = ) ^ ( = ) `e ( = ) D4 ( = ) ^ 9:C ^ ( = ) `e C D5 ( = 0 ) `e (t[ ] = t[ 0 ]) where t[] is a type context For each predicate P , D6 [=]P =e 9:P ^ ( = ) where 62 fv( )
We extend `e to be a relation on p p by: C `e D i C `e P for every P 2 D. Furthermore, we de ne C =e D i C `e D and D `e C . The term `e C is an abbreviation for ; `e C and true = f P j ; `e P g represents the true element.
Remark 1 For simplicity, we omit set notation for constraints. We connect constraints by ^ instead of the union operator [. Also, we omit to enclose simple constraints P in opening and closing braces. That means, P ^ Q is an abbreviation for fP g [ fQg. De nition 2 (Cylindric Constraint System) A cylindric constraint system is a structure CCS = ( ; `e ; Var; f9 j 2 Varg) such that: ( ; `e ) is a simple constraint system, Var is an in nite set of variables, For each variable 2 Var, 9 : p ! p is an operation satisfying:
Remark 2 Conditions D1 { D4 are the conditions imposed on a cylindric constraint system with diagonal elements, which is usually taken as the foundation of constraint programming languages. D4 says that equals can be substituted for equals; it is in eect the Leibniz principle. D5 states that (=) is a congruence. D6 connects the syntactic operation of a substitution over predicates with the semantic concepts of projection and equality. Substitution is extended to arbitrary constraints in the canonical way: [=](P1 ^ : : : ^ Pn ) = [=]P1 ^ : : : ^ [=]Pn :
E1 C `e 9:C E2 C `e D implies 9:C `e 9:D E3 9:(C ^ 9:D) =e 9:C ^ 9:D E4 9:9 :C =e 9 :9:C The next de nition de nes the free type variables fv(C ) of a constraint C . De nition 3 (Free Variables) Let C be a constraint. Then fv(C ) = f j 9:C 6 =e C g. 2
We also refer to such constraints as predicates.
4
(Var) (Equ)
(Let) (8 Intro)
` x : (x : 2 ?)
C; ?
` e : `e ( = 0 ) C; ? ` e : 0
Values Expressions Types Type schemes
C; ?x :x : ` e : 0 C; ?x ` x:e : ! 0
(Abs) (App)
C; ?
to the original presentation [DM82]. We work with the following syntactic domains.
C; ?
` e : C; ?x :x : ` e0 : 0 C; ?x ` let x = e in e0 : 0
C ^ D; ? ` e : C ^ 9:D; ?
`
::= ::= :: ::=
x j x:e v j ee j let e = x in e j ! j T j 8:C )
This generalizes the formulation in [DM82] in two respects. First, types are now members of an arbitrary term algebra, hence there might be other constructors besides !, with possibly non{trivial equality relations. Second, type schemes 8:C ) now include a constraint component C 2 S , which restricts the types that can be substituted for the type variable . On the other hand, the language of terms is exactly as in [DM82]. That is, we assume that any language constructs that make use of type constraints are expressible as prede ned values, whose names and types are recorded in the initial type environment ?0 . We often use vector notation for type variables in type schemes. The term 8:D ) is an abbreviation for 81 :true ) : : : 8n:D ) and 9 :D for 91 : : : : 9n :D. The typing rules can be found in Figure 1. Typing judgments are of the form C; ? ` e : where C is a constraint in S . The most interesting rules are the (8 Intro) rule and the (8 Elim) rule. By rule (8 Intro) we quantify some type variables. Rule (Equ) becomes important if there are type constructors in the term algebra T with non{trivial equality relations.
` e1 : 1 ! 2 C; ? ` e2 : 1 C; ? ` e1 e2 : 2
C; ?x
v e
62 fv(C ) [ fv(?) e : 8:D )
0 C `e [ =]D (8 Elim) C; ? ` e : 8:D ) C; ? ` e : [ =] 0
Figure 1: Logical type system The intention of a term constraint system T CST is to express uni cation problems through the equality predicate (=). A term constraint system T CST is a very powerful constraint system. In the latter we distinguish a speci c subset of constraints in T CST . We denote this set by S . We say the constraints in S are in solved form. We put in general the following conditions on S :
3.3 Type inference
For HM(X) type systems we can give now a generic type inference algorithm, see Figure 2. Type inference in HM(X) is performed in two steps. First, a typing problem is translated into a constraint D in the term constraint system X . Then that constraint D is normalized. Normalizing means computing a substitution and a residual constraint C in X such that C entails D where C is a constraint in the set S of constraints in solved form. To ensure that a typing problem has a most general solution, we require that constraints in X have most general normalizers.
S1 S T CST S2 Each C 2 S is satis able S3 If C 2 S and C `e ( = 0 ) then `e ( = 0 ) S4 If C 2 S then 9:C 2 S Remark 3 Condition S3 prohibits equality predicates in S . Equality predicate should be resolved in S by a kind of uni cation. Condition S4 enforces that S is closed under projection. For a special instance of a term constraint system T CST we might put some further restrictions on the set S of constraints in solved form.
De nition 8 (Principal Normal Form) Let X be a term constraint system over a term algebra T and S be the set of solved constraints in X. Let C 2 S and D 2 X be constraints and let , be substitutions. Then (C; ) is a normal form of (D; ) i , C `e D and
3.2 The type system
This section describes a general extension HM(X) of the Hindley/Milner type system with a term constraint system X over a term algebra T . We denote the set of solved constraints in X by S . In our type system we only admit constraints in S . Our development is similar
C=C (C; ) is principal if for all normal forms (C 0 ; 0 ) of (D; ) we have that 0 and C 0 `e 0 C .
5
(Var)
x : (8:D ) ) 2 ? new ]) (C; ) = normalize(D; [ = W jfv(?) ; C; ? ` x :
(Abs)
; C; ?x :x : `W e : new W nfg ; C; ?x ` x:e : !
4 Polymorphic records Following ideas of Ohori [Oho95] we give an instance of our HM(X) system which deals with polymorphic records. First, we give an instance R of a term constraint system T CST . It must now be able to deal with constraints on records. We also add primitive operations to the initial type environment ?0 that deal with record selection and record update. Furthermore, we discuss the relationship of HM(R) to Ohori's calculus (In the latter we use O as an abbreviation for Ohori's calculus). Finally, we show that R enjoys the principal constraint property. That means, we get a type inference algorithm for HM(R) which computes principal types. In addition to types and function types we have now record types denoted by fl1 : 1 ; : : : ; ln : n g where li is an element of a enumerable set of record labels. We extend the term algebra T by adding constructors
1 ; C 1 ; ? ` W e1 : 1
(App)
2 ; C 2 ; ? ` W e2 : 2 0= 1t 2 D = C1 ^ C1 ^ (1 = 2 ! ) new
(C; ) = normalize(D; 0 ) jfv(?) ; C; ? `W e1 e2 : 1 ; C1 ; ? x
(Let)
`W e :
(C2 ; ) = gen(C1 ; 1 ?; ) 2 ; C3 ; ?x :x : `W e0 : 0 0= 1t 2 D = C 2 ^ C3 (C; ) = normalize(D; 0 ) jfv(?x ) ; C; ?x `W let x = e in e0 : 0
l1 : : : ln : 1 ! : : : ! n ! fl1 : 1 ; : : : ; ln : n g
to the signature . We assume that the order of the elds does not matter. Additionally, we require
D7 `e (fl1 : 1 ; : : : ; ln : n g = fl(1) : (1) ; : : : ; l(n) : (n) g) where is a permutation on f1; : : : ; ng
Figure 2: Type inference Given (D; ) we can de ne a function normalize by: normalize(D; ) = (C; ) if (C; ) principal normal form of (D; ) = fail otherwise We use the convention that when we say a principal normal form of (D; ) exists we know how to compute the principal normal form of (D; ). We now extend the property of having a principal normal form to constraint systems. De nition 9 (Principal Constraint Property) Given a term constraint system X over a term algebra T and a set of solved constraints S in X. The term constraint system X has the principal constraint property if for every constraint D 2 X and substitution , either (D; ) does not have a normal form or (D; ) has a principal normal form. We also say that the HM(X) type system has the principal constraint property if X has the principal constraint property. We can conclude that a constraint system X which enjoys the principal constraint property comes with a computable function normalize. Theorem 10 Given a HM(X) type system which satis es the principal constraint property. Then the type inference algorithm computes principal types.
Note, here you can see an example for a type constructor with non{trivial equality relation. In [Oho95] kinded types are introduced. < l : > is a record kind intuitively denoting all records which contain at least a eld label l with value . Constraints on record types are now expressed by kinded types. That means in our constraint language we have now constraints of the form ( :: k) where is a type and k is a kind. Technically, this means we add ( :: k) to the set of primitive constraints where (::) is a primitive predicate of arity 2. Also, we require for the term constraint system R the following additional rules:
R1 R2 R3 R4 R5 E5 E6 F1 F2 6
`e (fl1 : 1 ; : : : ln : n g ::< li : i >)
where l1 ; : : : ; ln are distinct ( ::< l : 1 >) ^ ( ::< l : 2 >) `e (1 = 2 ) (f: : : ; l : 1 ; : : :g ::< l : 2 >) `e (1 = 2 ) (fl1 : 1 ; : : : ; ln : n g ::< l : >) `e false where l is distinct from l1 ; : : : ; ln (1 ! 2 ::< l : 3 >) `e false 9:( :: k) =e true where 62 fv(k) 9:( :: k) =e false where 2 fv(k) false `e P for P 2
9:false =e false
Remark 4 Conditions R1 { R5 are a straightforward extension to constraints on records. Conditions E5 { E6 de ne how projection operates on record constraints. E5 and E6 express the fact that no recursive records are allowed. A token false is used. It represents the false element of the constraint system. An axiomatization is given in F1 and F2. The token false is assumed to be contained in the set of primitive constraints. It is also important to point out that we only have width subtyping because we do not have the subsumption rule in the HM(X) type system. Furthermore, we also forbid overloading of eld labels. This is along the lines as in [Oho95].
predicate (=) and a projection operator 9 . We do the following steps to prove that the principal constraint property holds for R. We show that it is always possible to split a constraint in a projection free subpart. Then we give a procedure which computes the principal normal form of projection free constraints, or no normal form exists at all. Finally, we show that it is sucient to compute principal normal forms of projection free constraints. We now want to split a constraint into a projection free subpart. The idea is that we can always rename type variables which are bound by the projection operator. It holds that
It remains to de ne the set S of constraints in solved form. First, we require that all constraints (::) in S are of the form ( :: ). We put additionally the following condition on S : S5 If C 2 S then there is an ordering < on the type variables in C such that for all predicates ( ::< l : >) and 2 fv( ) with C `e ( ::< l : >) we have that < Then we de ne S as the greatest set of constraints which ful lls conditions S1 { S5. Remark 5 Condition S5 simply states that no recursive records are allowed in HM(R). Recursive records are also not allowed in [Oho95]. We add now primitive constructs to the initial type environment ?0 that deal with record formation, selection and update. For every constructor l1 : : : ln we have a datatype constructor
9:C =e 9 :[ =]C where is a new type variable. That means, w.l.o.g. there are no name clashes between two projected constraints (9:C ) ^ (9 :D) Then we can use condition E3 to shift all projection operators to the outermost level. We can summarize this observation in the following lemma.
Lemma 1 Let C 2 R. Then there exists a projection free constraint D such that C =e 9 :D We assume now that we have a projection free constraint D which contains only primitive predicates of the form (=) and (::). Furthermore, we can assume that all predicates (::) are of the form ( :: k) because we know that ( :: k) =e 9:( = ) ^ ( :: k)
l1 : : : ln : 1 ! : : : ! n ! fl1 : 1 ; : : : ; ln : n g
where is a new type variable. The closure Cl(D) of D is the smallest constraint which ful lls the following conditions: 1. D Cl(D) 2 If ( = fl1 : 1 ; : : : ; ln : n g) 2 Cl(D) then ( ::< l1 : 1 >); : : : ; ( ::< ln : n >) 2 Cl(D) 3 If ( ::< l : 1 >); ( ::< l : 2 >) 2 Cl(D) then (1 = 2 ) 2 Cl(D)
in the initial type environment ?0 . l1 : : : ln allows us formation of records fl1 : 1 ; : : : ; ln : n g. For each eld label l we add .l : 8; :( ::< l : >) ) ! and modifyl : 8; :( ::< l : >) ) ! !
From a semantic view point we have not done anything because Cl(D) =e D. We simply have changed the syntactic representation of D. The intention of building the closure of D is simply to generate all predicates ( ::< l : 0 >) which might cause any inconsistencies. From that we can generate all uni cation problems ( = 0 ) which have to be resolved. The following lemma states that we really have generated all such predicates.
to the initial type environment ?0 . The rst corresponds to record selection, the latter to record update. The question arises how HM(R) is related to O. We postpone a discussion of the relationship between HM(R) and O to Section 7. We now consider type inference for HM(R). That means we have to show that R ful lls the principal constraint property. Our constraint system diers in two respects from the one used in O. We have an equality 7
Lemma 2 Given a eld label l and types ; 0 . If 6 `e ( ::< l : 0 >) then ( ::< l : 0 >) 2 Cl(D) i D `e ( ::< l : 0 >). Furthermore, if 6 `e ( = 0 ) then ( = 0 ) 2 Cl(D) i D `e ( = 0 ). Then we can apply uni cation over Herbrand terms [Rob65]. to resolve all equality predicates (=) in Cl(D). Actually, that is not the whole truth. Remember, we have a record type constructor with non{trivial equality relation in the term algebra T . That means, when we perform uni cation we have to take into account that records are equal modulo up to the order of the elds. We get a most general uni er of the equality predicates (=) in Cl(D). It remains to check whether this most general uni er is consistent with Cl(D). That means, we check whether there are any inconsistencies in Cl(D). If not, (Cl(D); ) represents the principal normal form of (D; id). We can summarize this observation in the following lemma. Lemma 3 Given a projection free constraint D 2 R and a substitution . Then (D; ) does have a principal normal form or no normal form exists. We have given now a procedure to compute the principal normal form of projection free constraints. The next lemma gives us a procedure to lift principal normal forms of constraints to arbitrary constraints. It states that whenever we can compute the principal normal form of a constraint D then we get the principal normal form of the constraint 9:D for free. Before we proceed, we state the following lemma which we will use in the next two lemmas. Lemma 4 Given a constraint C 2 R such that 9:C 2 S and C 62 S . Then there is a such that 9:C =e [=]C . Proof: The only reason why C is not in solved form is that there is an unresolved uni cation problem ( 0 = 00 ) in C . But because 9:C is in solved form we know that `e 9:( 0 = 00 ). Then we can conclude there is a such that [=]( 0 = 00 ) =e 9:( 0 = 00 ). This gives us 9:C =e [=]C .
0 (9:D) =e 9: 0 D. We distinguish the following two cases:
Case 0 D 2 S : Then ( 0 D; 0 ) is a normal form of (D; ). Because (C; ) is principal we get that 0 D `e 0 C and 0 . We can derive that C 0 `e 9: 0 D `e 9: 0 C `e 0 (9:C )
which shows that (9:C; nfg ) is principal. Case 0 D 62 S : Because 9: 0 D 2 S there must be an unresolved uni cation problem in 0 D. That means, there is a such that 9: 0 D =e [=]( 0 D). Note, it holds that [=] 0 = 0 [=]. We get that C `e 0 [=]D because (C; ) is principal we can follow that C 0 `e ( 0 [=])C
0 [=]
But then we get that C `e 0 9:C
nfg 0
which also shows that (9:C; nfg ) is principal. The next lemma states that a normal form of a constraint exists if a normal form of the projected constraint exist.
Lemma 6 Given a substitution where 62 codom()[ dom() and a constraint D 2 R. Then (D; ) has a normal form if (9:D; ) has a normal form. Proof: We assume that (C; ) is a normal form of (9:D; ). That means,
C `e
9:D
Also, we know that 9: D =e 9:D. We distinguish the following two cases: Case D 2 S : Then it is easy to see that ( D; ) is a normal form of (D; ).
Lemma 5 Let D 2 R and be a substitution where 62 codom() [ dom(). If (C; ) = normalize(D; ) then (9:C; nfg ) = normalize(9:D; ). Proof: Given the principal normal form (C; ) of (D; ). We assume w.l.o.g. that 62 codom( ). It holds that [=]D `e 9:D where 62 fv( ). We can conclude that 9:C `e nfg 9:D. We get that (9:C; nfg ) is a normal form of (9:D; ). Assume now (C 0 ; 0 ) is another normal form of (9:D; ) and w.l.o.g. 62 codom( 0 ). Then we now that C 0 `e 8
Case D 62 S : Then we know there is a such that 9: D =e [=] D. In this case (C; [=] ) is a normal form of (D; ).
We have now everything at hand to prove that R has the principal constraint property.
Theorem 11 The constraint system R has the principal constraint property.
Proof: Assume the contrary. That means we have a tuple (D; ) which has a normal form but no principal normal form. With Lemma 1 we know that D =e 9 :D0 where D0 is a projection free constraint. Then we apply Lemma 6 and get that the normal form of (D0 ; ) exists. From Lemma 3 we know that (D0 ; ) does have a principal normal form. With Lemma 5 we can lift the principal normal form and get that the principal normal form of (D; ) exists. But this is a contradiction to our assumption. We get that R has the principal constraint property.
a record with a eld label l if this eld label is not already present in the record. Without condition R11 we could extend a record with an already existing eld label but for this special case we already have the primitive modifyl . The projection operator is extended to extendl in condition E7. Jones [Jon92] uses a predicate (nl) to express that record does not contain a eld label l. We can de ne (nl) as an abbreviation for 9 ; :extendl (; ; ).
In the set S of constraints are now additionally constraints of the form extendl (1 ; 2 ; 3 ). Then the set S of constraints in solved form is de ned as in Section 4. We now have to show that Re has the principal constraint property. We proceed in a similar way as for R. First, we give an algorithm which computes the principal normal form of projection free constraints. We assume now that we have a projection free constraint D. We consider D as a set of primitive constraints. Then the closure Cl(D) of a constraint D is the smallest constraint which ful lls the following conditions: 1. D Cl(D) 2 If ( = fl1 : 1 ; : : : ; ln : n g) 2 Cl(D) then ( ::< l1 : 1 >); : : : ; ( ::< ln : n >) 2 Cl(D) 3 If ( ::< l : 1 >); ( ::< l : 2 >) 2 Cl(D) then (1 = 2 ) 2 Cl(D) 4. If extendl (1 ; 2 ; 3 ) 2 Cl(D) then (3 ::< l : 2 >) 2 Cl(D) 5. If extendl (1 ; 2 ; 3 ); (1 ::< l0 : >) 2 Cl(D) then (3 ::< l0 : >) 2 Cl(D) 6. If extendl (1 ; 2 ; 3 ); (3 ::< l0 : >) 2 Cl(D) and l 6= l0 then Cl(D) 2 (1 ::< l0 : >)
That means, we know that the constraint system
R has the principal constraint property and we have a
decidable procedure at hand to compute the principal normal form. We gave an instance HM(R) of our HM(X) system which deals with records. We extended the term algebra T and had to provide a constraint system R which is able to deal with records. We showed that R satis es the principal constraint property. A detailed discussion of the relationship between HM(R) and O is postponed to Section 7.
5 Further extensions The record calculus of Ohori lacks some important features, e.g. we do not have extensible records. We show now how to extend HM(R) to get HM(Re ) where we additionally have record extensions. We start with the HM(R) system. We give an extension of R that is able to deal with record extension. We call it Re . We add for each label l primitive constraints of the form extendl (1 ; 2 ; 3 ) to the set of primitive constraints . Re has to ful ll the following additional rules: R6 extendl (; ; ) `e ( ::< l : >) R7 extendl (; ; ) ^ ( ::< l0 : >) `e ( ::< l0 : >) R8 extendl (; ; ) ^ ( ::< l0 : >) `e ( ::< l0 : >) where l 6= l0 R9 extendl (1 ! 10 ; 2 ; 3) `e false R10 extendl (1; 2 ; 3 ! 30 ) `e false R11 extendl (; ; ) ^ ( ::< l : >) `e false R12 extendl (; ; ) `e false R13 `e extendl (fl1 : 1; : : : ; ln : ng; ; fl1 : 1 ; : : : ; ln : n ; l : g) where li 6= l E7 9; :extendl (; ; ) =e true Remark 6 Conditions R6 { R12 give a characterization of extending record with eld label l and value . The resulting record is . This is expressed through the predicate extendl (; ; ). Note, we can only extend
In this case we can restate Lemma 2. Lemma 7 Given a eld label l and types ; 0 . If 6 `e ( ::< l : 0 >) then ( ::< l : 0 >) 2 Cl(D) i D `e ( ::< l : 0 >). Furthermore, if 6 `e ( = 0 ) then ( = 0 ) 2 Cl(D) i D `e ( = 0 ). Then we can proceed as before and we can state the following lemma.
Lemma 8 Given a projection free constraint D 2 R and a substitution . Then (D; ) does have a principal normal form or no normal form exits. We can make now the following observations. Lemmas 1, 5, 6 also hold in Re . Then it is straightforward to show that Re also satis es the principal constraint property.
Theorem 12 The constraint system Re has the principal constraint property.
9
Proof: Same argumentation as in Theorem 11.
R1 distinct(l1; : : : ; ln) ^ label(l1; : : : ; ln) `e (fl1 : 1 ; : : : ln : n g ::< li : i >) where i 2 f1; : : : ; ng R2 ( ::< l : >) `e (l :: label) R3 ( ::< l : 1 >) ^ ( ::< l : 2 >) `e (1 = 2) extendl : 8; ; :extendl (; ; ) ) ! ! R4 (f: : : ; l : 1 ; : : :g ::< l : 2 >) `e (1 = 2) to the initial type environment ?0 . The construct R5 (fl1 : 1 ; : : : ; ln : ng ::< l : >)^ (l = 6 l1 ) ^ : : : ^ (l = 6 ln ) `e false removel : 8; :9 :extendl (; ; ) ) ! R6 (1 ! 2 :: label) `e false R7 ( :: label) ^ ( ::< l : >) `e false handles removal of the eld label l. R8 (1 ! 2 ::< l : 3 >) `e false In the appendix we consider further extensions for E5 9:( :: label) =e true variants (HM(Rv )), concatenation (HM(Rc )). It is straight- E6 9:( :: k) =e true forward to show that we can take any of these extensions where 62 fv(k) and combine them in a new instance HM(Rx ) where x E7 9 :( :: k) =e false is a term in the regular grammar [ejcjv]. We also conwhere 2 fv(k) jecture that it is possible to design HM(Rr ) which supF1 false `e P for P 2
ports recursive types. We give a sketch of HM(Rr ) in F2 9:false =e false the appendix. The set S of constraints in solved form contains now constraints of the form ( :: ) and (fl1 : 1 ; : : : ; ln : 6 Polymorphic eld labels n g :: l : ) where l1 ; : : : ; ln ; l are distinct variables and n >= 2. Note, eld labels are now represented by variOne of the shortcomings of HM(R) and its extensions ables. In HM(R) a constraint of the form (f g :: ) is that we need primitive constructs for each eld label is either true or false. But in HM(Rp ) a constraint of l. Field labels are treated as constants. We now introthe form (f g :: ) can be satis able or not. It is only duce an application HM(Rp ) where eld labels become possible to resolve records which contain only one eld rst class values. That means, we can pass eld labels because it holds that (fl : g ::< l0 : 0 >) `e (l = l0). as arguments to functions and can manipulate them in We need now primitive constructs in the initial type environment ?0 for record extension. For each eld label l we add
This fact is also re ected in the following de nition of the closure of a constraint. The rest of the de nition of S is along the lines as in Section 4. Then, we have to show that Rp satis es the principal constraint property. We do this along the lines as in Section 4. We simply have to adapt the de nition of the closure Cl(D) of a projection free constraint D. Now, the closure Cl(D) is the smallest constraint which satis es: 1. D Cl(D) 2. If ( = fl1 : 1 ; : : : ; ln : n g) 2 Cl(D) then ( ::< l1 : 1 >); : : : ; ( ::< ln : n >) 2 Cl(D) 3 If ( ::< l : 1 >); ( ::< l : 2 >) 2 Cl(D) then (1 = 2 ) 2 Cl(D) 4. If ( ::< l : >) 2 Cl(D) then (l :: label) 2 Cl(D) 5. If ( = fl : g); ( ::< l0 : 0 >) 2 Cl(D) then (l = l0 ) 2 Cl(D) We also have to adapt Lemma 2. In this case we have the following lemma. Lemma 9 Given a eld label l and types ; 0 . If there are no l1 ; : : : ; ln such that label(l1 ; : : : ; ln ) ^ distinct(l1 ; : : : ; ln ) `e ( ::< l : 0 >) then ( ::< l : 0 >) 2 Cl(D) i D `e ( ::< l : 0 >).
other ways. Especially, it is now possible to quantify over eld labels. Technically, we add now primitive constraints ( :: label) to the set of primitive constraints where (:: label) is an unary predicate. The constraint (l :: label) denotes now that l is a eld label. We restate now the conditions for R. Before, we introduce two abbreviations. The term distinct(l1 ; : : : ; ln ) is a short{hand for the constraint
^
(li 6= lj )
i6=j;i;j 2f1;:::;ng
The constraint (6=) can be expressed in terms of (=) and is de ned by
`e ( 6= 0 )
i
6 `e ( = 0 )
The term label(l1 ; : : : ; ln) is a short{hand for the constraint (l1 :: label) ^ : : : ^ (ln :: label) The constraint system Rp is now de ned as follows:
10
Ohori
Furthermore, if 6 `e ( = 0 ) then ( = 0 ) 2 Cl(D) i D `e ( = 0 ). We can proceed exactly in the same way as in Section 5. We get the following theorem. Theorem 13 The constraint system Rp satis es the principal constraint property. We have now the following primitives in initial type environment ?0 : formationn : 8; 1 ; : : : ; n ; l1 ; : : : ; ln : distinct(l1 ; : : : ; ln ) ^ label(l1 ; : : : ; ln)^
We consider Ohori's calculus O. We have based the design of HM(R) on this calculus. In HM(R) we have the same basic operations as in O. But our constraint system diers in two respects from the one used in O. We have an equality predicate (=) and a projection operator 9. The equality predicate becomes important when we consider type inference. We have already pointed out that the projection operator allows us to formulate a logically pleasing (8 Intro) rule. Essentially, the only dierence between HM(R) and O lies in the introduction of quanti ed type variables. In O we have the following (8 Intro) rule:
)
1 ! : : : ! n ! l1 ! : : : ! ln ! fl1 : 1 ; : : : ; ln : n g
.
!l!
modify
Kf 7! kg; ? ` e : 62 fv(?) K; ? ` e : 8:( :: k) )
(8 Intro-O)
: 8; ; l: ( ::< l : >) ^ (l :: label) )
Ohori uses instead of a constraint on the left hand side of a typing judgment a so-called kind assignment Kwhich can be considered as a function which assigns each type variable its kind k. He writes Kf 7! kg for the disjoint extension of K with a new type variable with kind k. We can now write the following program in O where we assume that we have a function eq : 8: ! ! Bool in an initial type environment and an operator ( ; ; ) for formation of triples. We use a Haskell-style notation, adding type annotations for illustration purposes.
: 8; ; l: ( ::< l : >) ^ (l :: label)
) !l! !
The primitive constructs are now polymorphic in the eld labels. That means, we do not need anymore for each eld label l a special primitive construct. It is also possible to add recursive types, variants, extension and concatenation of records to HM(Rp ). That means, we get extensions HM(Rvp ), HM(Rep ) and HM(Rcp ). For instance, instead of a set of predicates extendl we simply have now one predicate extend with one additional parameter which represents the new eld label. It is straightforward to adapt the rules. For space reasons we omit a detailed description. The question arises what expressive power gives us HM(Rp ). For example, it is now possible to characterize all records which contain at least one eld: f : 8:9 ; l:( ::< l : >) ^ (l :: label) ) : The term f represents all records which contain at least one eld. We leave further investigations on the expressive power of HM(Rp ) to future work.
Example 1 : 8:( ::< l1 : >) ) ! Int
f
f x =
: 8 :( ::< l2 : >) ) ! Int
let g
g = in 1
y.
l
l l
l
(x. 1 , (x. 1 ). 2 , eq y (x. 1 ))
The type of f looks strange. The function f is closed but the type of f contains the free type variable . We can not quantify at the outermost level otherwise we would get a con ict with the conditions put on a kind assignment. Furthermore, should be a record type but there is no such restriction put on . Actually, this program is non{sensical. We can type f but we can not apply f to an argument. The reason is that does not appear anymore in the kind assignment K. And this means we can not nd an instance for the constraint in f's type otherwise O would not be sound. Here, one can see an example why in O every type variable has a kind wheres in HM(R) we only need to give kinds to records. In HM(R) we can type f in the following way.
7 Related work In this section we discuss the relationship of the designed instances HM(Ri ) to previous work. We point out some problems which are present in previous work. We restrict our attention to the work of Ohori [Oho95] and Gaster et al [GJ96]. Then, we show that under some sucient conditions it is possible to reuse already existing approaches and compile them into the HM(X) framework. 11
Example 2 : 8:9 :( ::< l1 : >) ^ ( ::< l2 : >) ) ! Int
f
f x =
: 8 :( ::< l1 : >) ^ ( ::< l2 : >) ) ! Int
let g
g =
y.
in 1
l
l l
l
(x. 1 , (x. 1 ). 2 , eq y (x. 1 ))
Especially, we get that HM(R) models O faithfully. Theorem 14 (Faithfull) Every program typable in O is typable in HM(R). Proof: A proof can be found in the appendix. But we can type programs in HM(R) which are not typable in O. In the above example we can apply f to an appropriate argument which is not possible in O.
Gaster et al
in more detail. We consider Ohori's calculus O. We assume that we have a record constraint ( ::< l : >) where does not contain any polymorphic records. We use the HM(X) framework to argue that when we quantify over it causes no problem to rule out the constraint ( ::< l : >). The reason is that projection of such constraints is trivial. Because of the conditions put on ( ::< l : >) we get that `e 9:( ::< l : >). In this case, our (8 Intro) rule reduces to (8 Intro-O). We get that if programs use only records of this special kind then HM(R) models O full. Theorem 15 (Full and Faithfull) Given a program p where polymorphic records do not depend on other polymorphic records. Then p is typable in O i p is typable in HM(R). Proof: A discussion can be found in the Appendix F. We have only considered O. A similar argument would apply to G . We can conclude that the HM(X) framework can be seen as the proper logical foundation for O and G . This becomes important if we want to deal with cyclic dependencies such as recursive records or mutual recursive records. We argue that such features can not be incorporated into O and G without any serious restrictions whereas the HM(X) framework provides the proper logical foundation with even more expressive power. A more detailed discussion of the expressive power of HM(R) can be found in Appendix F.
We use G as an abbreviation for Gaster et al's record calculus. They base their record system on row variables. A row variable r can be seen as a collection of elds. A predicate (rnl) expresses the absence of eld label l in row r. A record type is denoted by Rec r where Rec is a record constructor and r is a row. Record extension is written as Recfl : jrg where the operator ( j ) extends a row with a new eld. Because overloading of eld labels is forbidden in G row r has to ful ll the predicate (rnl). In G typing judgments are written as C; ? ` e : where C contains predicates of the form (rnl). In essence, the rule for quanti er introduction in G can be read as:
Getting a HM(X) instance for free
(8 Intro-G ) C ^ D; ? ` e : 62 fv(?) [ fv(C ) C; ? ` e : 8:D ) When we now type the program in Example 1 we get in an intermediate step that y has type Rec fl2 : jr0 g and x has type Rec fl1 : Rec fl2 : jr0 gjrg where the rows r and r0 have to ful ll the predicates (rnl1 ) and (r0 nl2). In this case, we can not quantify over row r0 because r0 appears in the type of x. That means, rule (8 Intro-G ) is overly restrictive. We omit a discussion about the exact relationship between HM(R) (or HM(Ri )) and G . But it should be straightforward to adapt G to get an instance HM(G ). In the next section we discuss such a treatment in a more general context. All problematic cases were constructed around polymorphic records which contain other polymorphic records. When we restrict our attention to polymorphic records which do not depend on other polymorphic records none of the problematic cases will apply. Let us discuss this 12
Whenever we want to design a new instance of our HM(X) framework we have to give a term constraint system which enjoys the principal constraint property. Very often we can rely on already existing approaches which also use a kind of constraint system and a procedure to normalize constraints. For example Ohori[Oho95] introduced a constraint system where types were associated with kinds. His normalization procedure is a form of kinded uni cation. The main dierence between such approaches and ours is that we have a projection operator. It would be a nice property if we could lift already existing constraint systems and normalization procedures to get an instance of our HM(X) system. For instance, in case of HM(R) we adapted an already existing constraint system. We added rules how projection operates on constraints. Then, we gave a procedure which computes the principal normal form of projection free constraint. Finally, we showed how to lift this procedure to arbitrary constraints. It is possible to generalize this result for a speci c class of constraint systems.
De nition 16 Given a term constraint system T CST . We say that T CST satis es the lifting conditions i the
constraint systems for records we could rely on the approach of Ohori. We adapted his constraint system and his normalization procedure (kinded uni cation). The main dierence between his approach and ours is that we have a projection operator. In order to establish the principal constraint property we reduced normalization of constraints to the problem of normalization of projection free constraints. That means, we could rely on an already existing procedure (kinded uni cation) for normalization of projection free constraints. In general we could state the lifting condition under which we can lift already existing approaches to ours. We have seen that HM(X) can be seen as the proper logical foundation of already existing approaches. We pointed out several problems which are present in the approaches of Ohori and Gaster et al. All these problems can be solved in HM(X). This is due to the projection operator which allows us to formulate a logically pleasing and pragmatically useful rule for quanti er introduction. We showed that we can faithfull model both approaches. Furthermore, we could show that our designed record systems have more expressive power than the approaches of Ohori and Gaster et al. We did not discuss a compilation calculus. It should be straightforward to adapt the approach of Ohori. Regarding a practical implementation we think this is an important issue for future research.
following conditions hold: (L1) Every D 2 T CST has a normal form as described in Lemma 1 (L2) Every projection free constraint D 2 T CST has a principal normal form (L3) If 9:D 2 S and D 62 S then there exists a such that, 9:D =e [=]D
Theorem 17 (Lifting) Let T CST be a term constraint system, such that the lifting condition holds Then T CST has the principal constraint property. Proof: Because of the lifting condition we know that Lemmas 5 and 6 hold. Then we can perform the same proof steps as in Theorem 11.
In the last section we discussed the relationship between the original system and the lifted HM(X) instance. Namely, we showed that HM(R) models O faithfull and has even more expressive power. This might be interesting to examine in the general case. That means, are there any general conditions which describe whether the lifted constraint system has more expressive power than the original one? We will pursue this topic in future work.
Acknowledgements
8 Conclusion
I would like to thank Stefan Monnier and Alastair Reid for helpful discussions about record systems and reading draft versions of this paper. Especially, I am grateful to Martin Odersky for pointing out Ohori's work, guiding me to new insights and helping in preparing this paper.
We have discussed several instances of the HM(X) framework. Namely, HM(Re ) (record extension), HM(Rc ) (record concatenation) and HM(Rv ) (variants). A language designer for record calculi can now choose some desired features and combine them in a new instance HM(Rx ) where x is a term in the regular grammar [ejcjv]. We also sketched the possiblitiy of HM(Rr ) which might support recursive types. As one of the novelties of this work we introduced HM(Rp ) where eld labels are now rst class values. All extensions can be extended with polymorphic eld labels. We get instantiations HM(Rxp ) where x is a term in the regular grammar [ejcjv]. One motivation of this work is that we want to provide a full variety of record systems under one common core. In this context it might be worthwhile to consider some further applications. But this depends on the speci c need for which we want to develop an application. The HM(X) framework enables us to concentrate on the design of constraint systems when designing a new type system. We have seen that we are now more concerned with the design of constraint systems which enjoy the principal constraint property. In case of
References [AK95]
Zena M. Ariola and Jan Willem Klop. Equational term graph rewriting. Acta Informatica, 1995. To appear. [Apo93] Mara Virginia Aponte. Extending record typing to type parametric modules with sharing. In Conference Record of the Twentieth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Charleston, South Carolina, January 10{13, 1993, pages 465{478. ACM Press, January 1993. [BH97] Michael Brandt and Fritz Henglein. Coinductive axiomatization of recursive type equality and subtyping. In Typed Lambda Calculi
13
[BPF97]
[Car84]
[CM89]
[DM82] [EST95]
[GJ96]
[HMT71] [HP91]
[Jon92]
Mark P. Jones. Quali ed Types: Theory and Practice. D.phil. thesis, Oxford University, September 1992. [Jon96] Mark P. Jones. Using parameterized signatures to express modular structure. In Proc. 23rd ACM Symposium on Principles of Programming Languages, pages 68{78, January 1996. [Ken96] Andrew J. Kennedy. Type inference and equational theories. Technical Report LIX/RR/96/09, LIX, Ecole Polytechnique, 91128 Palaiseau Cedex, France, September 1996. [OB88] Atshushi Ohori and Peter Buneman. Type inference in a database programming language. In Proceedings of the 1988 ACM Conference on Lisp and Functional Programming, pages 174{183, July 1988. [Oho95] Atsushi Ohori. A polymorphic record calculus and its compilation. ACM TOPLAS, 6(6):805{843, November 1995. [Rem89] Didier Remy. Typechecking records and variants in a natural extension of ML. 1989. [Rem92] Didier Remy. Extending ML type system with a sorted equational theory. Research Report 1766, Institute National de Recherche en Informatique et en Automatique, 1992. [Rem95a] Didier Remy. A case study of typechecking with constrained types: Typing record concatenation. Presented at the workshop on advances in types for computer science at the Newton Institute, Cambridge, UK. Avaliable electronically at http://pauillac.inria.fr/~remy, August 1995. [Rem95b] Didier Remy. Re ned subtyping and row variables for record types. Presented at the workshop on advances in types for computer science at the Newton Institute, Cambridge, UK. Avaliable electronically at html://pauillac.inria.fr/~remy, August 1995. [Rob65] J. A. Robinson. A machine-oriented logic based on the resolution principle. Journal of the Association for Computing Machinery, 12:23{41, 1965. [Sar93] Vijay A. Saraswat. Concurrent Constraint Programming. Logic Programming Series,
and Applications, International Conference on Typed Lambda Calculi and Applications, TLCA '97, April 1997, Nancy, France, Proceedings, April 1997. Kim B. Bruce, Leaf Petersen, and Adrian Fiech. Subtyping is not a good \match" for object-oriented languages. In FOOL4: 4th. Int. Workshop on Foundations of Objectoriented programming Languages, January 1997. Luca Cardelli. A semantics of multiple inheritance. In Gilles Kahn, David B. MacQueen, and Gordon D. Plotkin, editors, Semantics of Data Types, pages 51{67. Springer-Verlag, June 1984. Lecture Notes in Computer Science 173. Luca Cardelli and John C. Mitchell. Operations on records. In M. Main, A. Melton, M. Mislove, and David Schmidt, editors, Proceedings Mathematical Foundations of Programming Semantics, 5th International Conference, Tulane University, New Orleans, Louisiana, USA, pages 22{52. SpringerVerlag, March/April 1989. Lecture Notes in Computer Science 442. Luis Damas and Robin Milner. Principal type schemes for functional programs. January 1982. Jonathan Eifrig, Scott Smith, and Valery Trifonov. Type inference for recursivly constrainted types and its application to object oriented programming. In Electronic Notes in Theoretical Computer Science, volume 1, 1995. Benedict R. Gaster and Mark P. Jones. A Polymporphic Type System for Extensible Records and Variants. Technical Report NOTTCS-TR-96-3, University of Nottingham, Nottingham NG7 2RD, UK, March 1996. L. Henkin, J.D. Monk, and A. Tarski. Cylindric Algebra. North-Holland Publishing Company, 1971. Robert Harper and Benjamin Pierce. A record calculus based on symmetric concatenation. In Conference Record of the Eighteenth Annual ACM Symposium on Principles of Programming Languages, Orlando, Florida, pages 131{142. ACM Press, January 1991.
14
ACM Doctoral Dissertation Award Series. MIT Press, Cambridge, Massachusetts, 1993. [SOW] Martin Sulzmann, Martin Odersky, and Martin Wehr. Type inference with constrained types. Theory and Practice of Object Systems. invited submission; in preparation. [SOW97] Martin Sulzmann, Martin Odersky, and Martin Wehr. Type inference with constrained types. In FOOL4: 4th. Int. Workshop on Foundations of Object-oriented programming Languages, January 1997. [Wan88] Mitchell Wand. Corrigendum: Complete type inference for simple objects. In Proceedings of the IEEE Symposium on Logic in Computer Science, page 132, 1988. [Wan89] Mitchell Wand. Type inference for record concatenation and multiple inheritance. In Proceedings of the IEEE Symposium on Logic in Computer Science, pages 92{97, June 1989.
V1 V2 V3 V4 V5 V6
B Concatenation We start with the term constraint system R. We add primitive predicates concat(1 ; 2 ; 3 ) to the set of primitive predicates. We call the resulting system HM(Rc ). We put the following conditions on Rc : R6 concat(; ; ) ^ ( ::< l : >) `e ( ::< l : >) R7 concat(; ; ) ^ ( ::< l : >) `e ( ::< l : >) R8 `e concat(fl1 : 1 ; : : : ; li : i g; fli+1 : i+1 ; : : : ; ln : n g; fl1 : 1 ; : : : ; ln : n g R9 concat(; ; ) ^ ( ::< l : >) ^ ( ::< l : >) `e
Additionally, we now want to deal with variants. We want to extend HM(R) with variants. We call the resulting system HM(Rv ). We proceed similar in style as in Section 4. Variant types are denoted by [l1 : 1 ; : : : ; ln : n ]. A variant [l = e] tagged with label l can have types [l1 : 1 ; : : : ; li : i ; l : ; li+1 : i+1 ; : : : ; ln : n ] where is the type of e. Therefore, we extend the term algebra T by adding constructors
false
R10 concat(1 ! 10 ; 2; 3 ) `e false R11 concat(1 ; 2 ! 20 ; 3 ) `e false R12 concat(1 ; 2 ; 3 ! 30 ) `e false E7 9; :concat(; ; ) =e true E8 9 ; :concat(; ; ) =e true Remark 7 By condition R9 we only allow concatena-
! [l1 : 1 ; : : : ; li : i ; l : ; li+1 : i+1 ; : : : ; ln : n ]
tion of records with disjoint eld labels. This choice is arbitrary. It would also be possible to model dierent behaviors of concatenation of records.
to the signature . We assume that the order of the variant elds does not matter. That means, we additionally require
D8
(1 = 2 ) ([: : : ; l : 1 ; : : :] :: : : : ; l : 2 ; : : : ) `e (1 = 2 ) ([: : : ; l : ; : : :] :: l1 : 1 ; : : : ; ln : n ) `e false where l 6= li (1 ! 2 :: 3 ) `e false ( :: l1 : 1 ; : : : ; ln : n ) ^ ( ::< l : >) `e false
The rest of the treatment is along the lines as in Section 4. It is straightforward to show that the resulting system enjoys also the principal constraint property.
A Variants
l:
`e ([l1 : 1 ; : : : ; ln : n ] :: l1 : 1 ; : : : ; ln+m : n+m ) ( :: : : : ; l : 1 ; : : : ) ^ ( :: : : : ; l : 2 ; : : : ) `e
It is straightforward to show that the resulting system satis es the principal constraint property. We now add the following construct to the initial type environment ?0
`e ([l1 : 1 ; : : : ; ln : n ] = [l(1) : (1) ; : : : ; l(n) : (n) ])
where is a permutation on f1; : : : ; ng
concat : 8; ; :concat(; ; ) ) ! ! We also introduce kinds for variant types. l1 : 1 ; : : : ; ln : n is a variant kind denoting a variant which contains which handles concatenation of records. a tagged value with type i and label li . We assume that Furthermore, it is now possible to de ne record exthe order of the components of a variant kind does not tension in terms of concatenation. We add primitive matter. As usual we add constraints ( :: k) where is constructs a type and k is a variant kind to the set of primitive constraints. extl : 8; ; :concat(; fl : g; ) ) ! !
to the initial type environment. In order to de ne removal of a eld label we need to put one additional 15
condition on Rc : R13 concat(; fl : g; ) ^ ( ::< l0 : >) `e ( ::< l0 : >) where l 6= l0 Note, this condition models the same behavior as condition R8 in Section 5. We can now add primitive constructs rmvl : 8; :9 :concat(; fl : g; ) ) !
a kind. A record type variable can have kind < l1 : 1 ; : : : ; ln : n > and all other type variables have kind U .
We give now an inductive de nition of the function ()+ on kind assignments K. The function ()+ is a mapping from a kind assignment to a constraint in solved form. (fV7!< l1 : 1 ; : : : ; ln : >g)+ = i2f1;:::;ng ( ::< li : i >) (f 7! U g)+ = true (Kf 7! kg)+ = (K)+ ^ (f 7! kg)+
to the initial type environment ?0 . Primitive constructs extl and rmvl have the same behavior as the primitive constructs extendl and removel de ned in Section 5.
C Recursive types
The function ()+ can be extended to type schemes and type environment ? in a straightforward manner. We sketch how recursive types could be incorporated. We now give a more precise formulation of Theorem 14. Starting from HM(R) we discuss now an extension HM(Rr ) which handles recursive types. Because we want to alLemma 10 Given a kind assignment K, a type envilow recursive records we omit condition E6. We add the ronment ?, a term e and a type scheme such that recursion operator to the term algebra T . Following K; ? `o e : . Then (K)+ ; (?)+ ` e : ()+ . the lines of [AK95] we put the following additional rules Proof: We use induction over the derivation `o . We on Rr : have already pointed out that there is essentially only D8 `e (: = [:=] ) one dierence between the derivations `o and ` . This e ] ) contractive in dierence lies in dierent rules for quanti er introducD9 ` (1 = [1= tion. Therefore, we consider only one case. The other `e (: = 1 ) cases are similar. In O we have the following rule for As usual, we put de ne the set S of solved forms as quanti er introduction: the greatest set which satis es condition S1 - S5. It Kf 7! kg; ? `o e : 62 fv(?) remains to establish the principal constraint property ( 8 IntroO ) r for HM(R ). In this case we now have to extend uni K; ? `o e : 8:( :: k) ) cation over nite trees to uni cation over regular trees. We conjecture that this is possible following the line Applying the induction hypothesis we get as described in [AK95]. We think this is an important (Kf 7! kg)+ ; (?)+ ` e : ()+ issue. Also, it might be worthwile to consider a more recent approach [BH97] which uses a coinductive axiomWe can now apply the (8 Intro) rule 3 and get atization of recursive type equality. We leave further investigations on this topic for future work. 9:(Kf 7! kg)+ ; (?)+ ` e : 8:(f 7! kg)+ ) ()+ Because of the construction of a kind assignment we can deduce that
D Proof of Theorem 14 (Faithfull) We now show that HM(R) models O faithfully. We prove that we can transform every typing judgment K ; ? `o e :
(9:(K)+ ) ^ (9:(f 7! kg)+ ) =e 9:(Kf 7! kg)+ Furthermore, we know that 9:(f 7! kg)+ =e true. Then we get that 9:(K)+ =e 9:((K)+ ^ 9:(f 7! kg)+) =e (9:(K)+ ) ^ (9:(f 7! kg)+ ) =e 9:(Kf 7! kg)+
into a typing judgment (K)+ ; (?)+ ` e : ()+ where `o is the derivation in O and ()+ stands for an appropriate transformation function. We have already mentioned that K represents a kind assignment. In O every type variable is attached with
3 The (8 Intro) in HM(X) is in one point a little bit more restrictive than the one in O. We are only allowed to quantify over types and not type schemes. Actually, it would be possible to restate the (8 Intro) in such a way that we can now also quantify over type schemes.
16
F Expressive power of HM(R)
We get that (K)+ `e 9:(Kf 7! kg)+
We give now a categorical proof that HM(R) has more expressive power than O. We rely on the notation which we introduced in the two previous sections. We want to consider a type system as a category. A typing judgment represents a valid derivation in T S . A premise and a conclusion stands for a collection of typing judgments.
and because ` is closed under strengthening the constraint we get (K)+ ; (?)+ ` e : 8:(f 7! kg)+ ) ()+ which concludes the induction step.
Lemma and De nition 1 Given a type system T S . We consider T S as a category where objects are a col-
E Proof of Theorem 15 (Full and Faithfull)
lection of typing jugdments and arrows represent the derivation of a premise to a conclusion with respect to the typing rules in T S .
We rely on the notation introduced in the previous section. There, we have introduced a function ()? which transforms a kind assignment into a solved constraint in R. We give now a function ()? which transforms a (restricted) solved constraint into a kind assigment. We only consider constraints C 2 S which contain only constraints of the form ( :: ). In the latter we refer to such constraints as simple constraints. As usual ()? is de ned on the structure of C . We use a set M to keep track of type variables. We assume M which is initially empty.
We are now ready to de ne when two type systems have the same expressive power.
De nition 18 Given two type systems T S and T S 0 . We 0 say T S and T S have the same expressive power i there is a functor F : T S ! T S 0 which has a left adjoint functor G : T S 0 ! T S . We write T S = T S 0 in such a case. Lemma 13 = is an equivalence relation. First, we show that HM(R? ) = O were R? is the restriction of R to simple constraints. It is straightfor-
(D ^ ( ::< l1 : 1 >) ^ : : : ^ ( ::< ln : n >))? = (D)? f 7!< l1 : 1 ; : : : ; ln : n >g where in D there are no constraints of the form ( :: ) and we set M = M [ fg (true)? = f1 7! U; : : : n 7! U g where i 62 M and i 2 Var
ward to consider ()+ and ()? as functors. Then we can state the following lemma.
Lemma 14 Given X 2 HM(R?) and Y 2 O. Then X ! (Y )+ i (X )? ! Y Proof: Use Lemmas 10, 12 and 11.
It is straightforward to prove the next lemma.
Lemma 11 Given a simple constrant C and a kind assignment K. Then it holds that ((C )? )+ = C
Based on this lemma it is straightforward to prove that (()? ; ()+ ) form an adjunction. We can summarize this observation in the following theorem.
((K)+ )? = K
Theorem 19 HM(R?) = O.
Then, we can now state the following lemma.
We are now ready to state our main theorem.
Lemma 12 Given a typing judgment
C; ? `o e : such that all constraints are simple. Then (C )? ; (?)? ` e : ()? .
Theorem 20 HM(R) has more expressive power than O. Proof: We show that HM(R) 6= HM(R?). Then it O. follows immediately that HM(R) 6= HM(R) W.l.o.g. we can assume Assume HM(R? ) = that we have an adjunction (Id; G). That means, given X 2 HM(R), HM(R? ) and X ! Y there must be G(X ) ! Y . X ! Y represents a derivation in HM(R). It is not dicult to construct a derivation X ! Y such that there is no corresponding derivation G(X ) ! Y in HM(R? ), i.e. take Example 1.
Proof: Straightforward inductive proof. Theorem 15 follows now immediately as a corollary from Lemmas 10 and 12. A categorical proof of Theorem 15 can be found in the next section.
17