scispace - formally typeset
Open AccessProceedings ArticleDOI

Principal type-schemes for functional programs

Reads0
Chats0
TLDR
Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage.
Abstract
Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage, the ACM copyright notice and the title of its publication and date appear, and notice is given that copying is by permission of the Association for Computing Machinery. To copy otherwise, or to republish, requires a fee and/or specific permission. © 1982 ACM 0-89791-065-6/82/001/0207 $00.75

read more

Content maybe subject to copyright    Report

Principal type-schemes for functional programs
Luis Damas
and Robin Milner
First published in POPL ’82: Proceedings of the 9th ACM SIGPLAN-SIGACT
symposium on Principles of programming languages, ACM, pp. 207–212
Permission to copy without fee all or part of this material is granted provided that
the copies are not made or distributed for direct commercial advantage, the ACM
copyright notice and the title of its publication and date appear, and notice is given
that copying is by permission of the Association for Computing Machinery. To copy
otherwise, or to republish, requires a fee and/or specific permission.
© 1982 ACM 0-89791-065-6/82/001/0207 $00.75
1 Introduction
This paper is concerned with the polymorphic type discipline of ML, which is a gen-
eral purpose functional programming language, although it was first introduced as a
metalanguage (whence its name) for constructing proofs in the LCF proof system.[4]
The type discipline was studied in [5] where it was shown to be semantically sound,
in a sense made precise below, but where one important question was left open:
does the type-checking algorithm or more precisely the type assignment algorithm
(since types are assigned by the compiler, and need not be mentioned by the pro-
grammer) find the most general type possible for every expression and declara-
tion? Here we answer the question in the affirmative, for the purely applicative part
of ML. It follows immediately that it is decidable whether a program is well-typed, in
contrast with the elegant and slightly more permissive type discipline of Coppo. [1]
After several years of successful use of the language, both in LCF and other research,
and in teaching to undergraduates, it has become important to answer these ques-
tions particularly because the combination of flexibility (due to polymorphism),
robustness (due to semantic soundness) and detection of errors at compile time has
proved to be one of the strongest aspects of ML.
The discipline can be well illustrated by a small example. Let us define in ML the
function
map
, which maps a given function over a given list that is
map f [x1; ...; xn] = [f(x1),...,f(xn)]
The required declaration is
Re-keyed 12 October 2010 by Ian Grant
iang@pobox.com
The work of this author is supported by the Portuguese Instituto Nacional de Investigacao Cientifica
1

letrec map f s = if null s then nil
else cons(f(hd s)) (map f (tl s))
The type checker will deduce a type-scheme for
map
from existing type-schemes for
null
,
nil
,
cons
,
hd
and
tl
; the term type-scheme is appropriate since all these objects
are polymorphic. In fact from
null
: α(α
list
bool
)
nil
: α(α
list
)
cons
: α(α (α
list
α
list
))
hd
: α(α
list
α)
tl
: α(α
list
α
list
)
will be deduced
map
: αβ((α β) (α
list
β
list
)).
Types are built from type constants (
bool
...) and type variables (α,β,...) using type
operators (such as infixed for functions and postfixed
list
for lists); a type-scheme
is a type with (possibly) quantification of type variables at the outermost.
Thus, the main result of this paper is that the type-scheme deduced for such a dec-
laration (and more generally, for any ML expression) is a principal type-scheme, i.e.
that any other type-scheme for the declaration is a generic instance of it. This is a
generalisation of Hindley’s result for Combinatory Logic [3].
ML may be contrasted with Algol 68, in which there is no polymorphism, and with
Russell [2], in which parametric types appear explicitly as arguments to polymorphic
functions. The generic types of Ada may be compared with type-schemes. For sim-
plicity, our definitions and results here are formulated for a skeletal language, since
their extension to ML is a routine matter. For example recursion is omitted since it
can be introduced by simply adding the polymorphic fixed-point operator
fix
: α((α α) α)
and likewise for conditional expressions.
2 The language
Assuming a set
Id
of identifiers x the language
Exp
of expressions e is given by the
syntax
e ::= x | e e
0
| λx.e |
let
x = e
in
e
0
(where parentheses may be used to avoid ambiguity). Only the last clause extends the
ń-calculus. Indeed for type checking purposes every
let
expression could be elimi-
nated (by replacing x by e everywhere in e
0
), except for the important consideration
that in on-line use of ML declarations
let
x = e
2

are allowed, whose scope (e
0
) is the remainder of the on-line session. As illustrated
in the introduction, it must be possible to assign type-schemes to the identifiers thus
declared.
Note that types are absent from the language
Exp
. Assuming a set of type variables α
and of primitive types ι, the syntax of types τ and of type-schemes σ is given by
τ ::= α | ι | τ τ
σ ::= τ | ασ
A type-scheme α
1
...α
n
τ (which we may write α
1
...α
n
τ) has generic type vari-
ables α
1
...α
n
. A monotype µ is a type containing no type variables.
3 Type instantiation
If S is a substitution of types for type variables, often written [τ
1
1
,...,τ
n
n
] or
[τ
i
i
], and σ is a type-scheme, then Sσ is the type-scheme obtained by replacing
each free occurrence of α
i
in σ by τ
i
, renaming the generic variables of σ if necessary.
Then Sσ is called an instance of σ; the notions of substitution and instance extend
naturally to larger syntactic constructs containing type-schemes.
By contrast a type-scheme σ = α
1
...α
m
τ has a generic instance σ
0
= β
1
...β
n
τ
0
if τ
0
= [τ
i
i
]τ for some types τ
1
,...,τ
m
and the β
j
are not free in σ. In this case
we shall write σ > σ
0
. Note that instantiation acts on free variables, while generic
instantiation acts on bound variables. It follows that σ > σ
0
implies Sσ > Sσ
0
.
4 Semantics
The semantic domain V for
Exp
is a complete partial order satisfying the following
equations up to isomorphism, where B
i
is a cpo corresponding to primitive type ι
i
:
V = B
0
+ B
1
+ ·· · + F + W (disjoint sum)
F = V V (function space)
W = {·} (error element)
To each monotype µ corresponds a subset V , as detailed in [5]; if v V is in the
subset for µ we write v :µ. Further we write v :τ if v :µ for every monotype instance
µ of τ, and we write v : σ if v : τ for every τ which is a generic instance of σ.
Now let
Env
=
Id
V be the domain of environments η. The semantic function
" :
Exp
Env
V is given in [5]. Using it, we wish to attach meaning to assertions
of the form
A |= e :σ
where e
Exp
and A is a set of assumptions of the form x :σ, x
Id
. If the assertion
is closed, i.e. if A and σ contain no free type variables, then the sentence is said to
hold iff, for every environment η, whenever η[[x]] :σ
0
for each member x :σ
0
of A,
it follows that "[[e]]η : σ. Further, an assertion holds iff all its closed instances hold.
3

Thus, to verify the assertion
x : α, f :β(β β) |= ( f x): α
it is enough to verify it for every monotype µ in place of α. This example illus-
trates that free type variables in an assertion are implicitly quantified over the whole
assertion, while explicit quantification in a type scheme has restricted scope.
The remainder of this paper proceeds as follows. First we present an inference system
for inferring valid assertions. Next we present an algorithm W for computing a type-
scheme for any expression, under assumptions A. We then show that W is sound,
in the sense that any type-scheme it derives is derivable in the inference system. Fi-
nally we show that W is complete, in the sense that [any] derivable type-scheme is an
instance of that computed by W .
5 Type inference
From now on we shall assume that A contains at most one assumption about each
identifier x. A
x
stands for removing any assumption about x from A.
For assumptions A, expressions e and type-scheme σ we write
A ` e :σ
if this instance may be derived from the following inference rules:
TAUT:
(x : σ A)
A ` x : σ
A ` e :σ
INST:
(σ > σ
0
)
A ` e :σ
0
A ` e :σ
GEN:
(α not free in A)
A ` e :ασ
A ` e :τ
0
τ A ` e
0
:τ
0
COMB:
A ` (e e
0
):τ
A
x
{x : τ
0
} ` e :τ
ABS:
A ` (λx.e) : τ
0
τ
A ` e :σ A
x
{x : σ} ` e
0
:τ
LET:
A ` (
let
x = e
in
e
0
) : τ
The following example of a derivation is organised as a tree, in which each node
follows from those immediately above it by an inference rule.
TAUT:
x : α ` x : α
ABS:
` (λx.x):α α
GEN:
` (λx.x):α(α α)
TAUT:
i :α(α α) ` i :α(α α)
INST:
i :α(α α) ` i :(α α) (α α)
TAUT:
i :α(α α) ` i :α(α α)
INST:
i :α(α α) ` i :α α
COMB:
i :α(α α) ` i i :α α
4

` (λx.x):α(α α)
i :α(α α) ` i i :α α
LET:
` (
let
i = (λx.x)
in
i i) : α α
The following proposition, stating the semantic soundness of inference, can be proved
by induction on e.
Proposition 1 (Soundness of inference). If A ` e : σ then A |= e :σ.
We will also require later the following two properties of the inference system.
Proposition 2. If S is a substitution and A ` e :σ then SA ` e : Sσ. Moreover if there is
a derivation of A ` e :σ of height n then there is also a derivation of SA ` e : Sσ of height
less [than] or equal to n.
Proof. By induction on n.
Lemma 1. If σ > σ
0
and A
x
{x : σ
0
} ` e :σ
0
then also A
x
{x : σ} ` e :σ
0
.
Proof. We construct a derivation of A
x
{x :σ} ` e : σ
0
from that of A
x
{x :σ
0
} `
e :σ
0
by substituting each use of TAUT for x :σ
0
with x : σ, followed by an INST step to
derive x : σ
0
. Note that GEN steps remain valid since if α occurs free in σ then it also
occurs free in σ
0
.
6 The type assignment algorithm W
The type inference system itself does not provide an easy method for finding, given
A and e, a type-scheme σ such that A ` e : σ. We now present an algorithm W for
this purpose. In fact, W goes a step further. Given A and e, if W succeeds it finds
a substitution S and a type τ, which are most general in a sense to be made precise
below, such that
SA ` e :τ.
To define W we require the unification algorithm of Robinson [6] .
Proposition 3 (Robinson). There is an algorithm U which, given a pair of types, either
returns a substitution V or fails; further
(i) If U (τ,τ
0
) returns V , then V unifies τ and τ
0
, i.e. V τ = τ
0
.
(ii) If S unifies τ and τ
0
then U(τ,τ
0
) returns some V and there is another substitution
R such that S = RV .
Moreover, V involves only variables in τ and τ
0
.
We also need to define the closure of a type τ with respect to assumptions A;
A(τ) = α
1
,...,α
n
τ
where α
1
,...,α
n
are the type variables occurring free in τ but not in A.
5

Citations
More filters
Book

Types and Programming Languages

TL;DR: This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages, with a variety of approaches to modeling the features of object-oriented languages.
Book

The Definition of Standard ML

TL;DR: This book provides a formal definition of Standard ML for the benefit of all concerned with the language, including users and implementers, and the authors have defined their semantic objects in mathematical notation that is completely independent of StandardML.
Journal ArticleDOI

On understanding types, data abstraction, and polymorphism

TL;DR: A λ-calculus-based model for type systems that allows us to explore the interaction among the concepts of type, data abstraction, and polymorphism in a simple setting, unencumbered by complexities of production programming languages is developed.
Book

Haskell 98 language and libraries : the revised report

Peyton Jones, +1 more
TL;DR: The Haskell 98 Language: Lexical structure, Declarations and bindings, Predefined types and classes, and Libraries.
Proceedings ArticleDOI

Lazy abstraction

TL;DR: This work presents an algorithm for model checking safety properties using lazy abstraction and describes an implementation of the algorithm applied to C programs and provides sufficient conditions for the termination of the method.
References
More filters
Journal ArticleDOI

A Machine-Oriented Logic Based on the Resolution Principle

TL;DR: The paper concludes with a discussion of several principles which are applicable to the design of efficient proof-procedures employing resolution as the basle logical process.
Journal ArticleDOI

A theory of type polymorphism in programming

TL;DR: This work presents a formal type discipline for polymorphic procedures in the context of a simple programming language, and a compile time type-checking algorithm w which enforces the discipline.
Journal ArticleDOI

The Principal Type-Scheme of an Object in Combinatory Logic

TL;DR: The notion of identity-function is introduced in the context of combinatory logic as discussed by the authors, where the goal is to study the most basic properties of functions and other concepts, with as few restrictions as possible; hence, there is nothing to stop a function being applied to itself.
Book ChapterDOI

An Extended Polymorphic Type System for Applicative Languages

TL;DR: The type system introduced in this paper can be seen as an extension of the one proposed in /MLN/ (which is implemented in the language ML).
Frequently Asked Questions (10)
Q1. How do the authors construct a derivation of Ax x :?

The authors construct a derivation of Ax ∪ {x :σ} ` e :σ0 from that of Ax ∪ {x :σ ′} ` e :σ0 by substituting each use of TAUT for x :σ′ with x :σ , followed by an INST step to derive x :σ ′. 

The semantic domain V for Exp is a complete partial order satisfying the following equations up to isomorphism, where Bi is a cpo corresponding to primitive type ιi :V = B0+B1+ · · ·+ F +W (disjoint sum) F =V →V (function space)W = {·} (error element)To each monotype µ corresponds a subset V , as detailed in [5]; if v ∈ V is in the subset forµwe write v :µ. 

There is an algorithm U which, given a pair of types, either returns a substitution V or fails; further(i) If U (τ,τ′) returns V , then V unifies τ and τ′, i.e. V τ = τ′.(ii) 

Assuming a set of type variables α and of primitive types ι, the syntax of types τ and of type-schemes σ is given byτ ::= α | ι | τ→ τ σ ::= τ | ∀ασA type-scheme ∀α1 . . .∀αnτ (which the authors may write ∀α1 . . .αnτ) has generic type variables α1 . . .αn . 

The authors also need to define the closure of a type τ with respect to assumptions A;A(τ) = ∀α1, . . . ,αnτwhere α1, . . . ,αn are the type variables occurring free in τ but not in A. 

If e is e1 e2 then let W (A, e2) = (S1,τ2) and W (S1A, e2) = (S2,τ2) and U (S2τ1,τ2→ β) =V where β is new; then S =V S2S1 and τ =Vβ.(iii) 

†The work of this author is supported by the Portuguese Instituto Nacional de Investigacao Cientificaletrec map f s = if null s then nilelse cons(f(hd s)) (map f (tl s)) 

Moreover if there is a derivation of A` e :σ of height n then there is also a derivation of SA` e : Sσ of height less [than] or equal to n. 

Using it, the authors wish to attach meaning to assertions of the formA |= e :σwhere e ∈ Exp and A is a set of assumptions of the form x :σ , x ∈ Id. 

the main result of this paper is that the type-scheme deduced for such a declaration (and more generally, for any ML expression) is a principal type-scheme, i.e. that any other type-scheme for the declaration is a generic instance of it.