Contextual Polymorphism

by

Glen Jerey Ditcheld

A thesis

presented to the University of Waterloo

in fullment of the

thesis requirement for the degree of

Do ctor of Philosophy

in

Computer Science

Waterloo Ontario Canada

c

Glen Jerey Ditcheld

I hereby declare that I am the sole author of this thesis

I authorize the University of Waterloo to lend this thesis to other institutions or individuals

for the purp ose of scholarly research

I further authorize the University of Waterloo to repro duce this thesis by photo copying or by

other means in total or in part at the request of other institutions or individuals for the purp ose

of scholarly research ii

The University of Waterloo requires the signatures of all p ersons using or photo copying this

thesis Please sign b elow and give address and date iii

Abstract

Programming languages often provide for various sorts of static type checking as a way of detecting

invalid programs However statically checked type systems often require unnecessarily sp ecic

type information which leads to frustratingly inexible languages Polymorphic type systems

restore exibility by allowing entities to take on more than one type

This thesis discusses p olymorphism in statically typed programming languages It provides

precise denitions of the term p olymorphism and for its varieties adhoc p olymorphism uni

versal p olymorphism inclusion p olymorphism and parametric p olymorphism and surveys

and compares many existing mechanisms for providing p olymorphism in programming languages

Finally it introduces a new p olymorphism mechanism contextual polymorphism Contextual

p olymorphism is a variant of parametric p olymorphism that is based on contexts which are ab

stractions of collections of declarations and assertions which link p olymorphic routines to the

environments that call them Contexts themselves provide a useful structuring mechanism for

software b ecause they represent the notions and relationships b etween notions that program

mers have in mind when they design programs Contextual p olymorphism avoids many problems

asso ciated with other p olymorphism mechanisms while preserving their b enets The formal

denition of these language constructs is given in terms of an extension of F the order p oly

morphic typed lambda calculus The practicality of the constructs is shown by a discussion of

Cforall an extension of the C that supp orts contextual p olymorphism iv

Acknowledgements

I would like to thank Professor Don Cowan Professor Doug Lea and Professor Bruno Preiss

for agreeing to serve on my examining committee and for their many helpful suggestions and

questions Professor Gord Cormack Professor Dominic Duggan Dr John Ophel and Dr Bob

Zarnke for comments and conversations stretching back over many years and my sup ervisor

Professor Peter Buhr for not letting me quit v

Dedication

To Helen Cameron for the past and the future vi

Contents

Introduction

Denitions and Notations

Desirable Prop erties

Eciency

Strong Static Interface Checking

Expressiveness

Separate Interfaces

Co de Reuse

Simple Base Language

Polymorphism

Polymorphism Mechanisms

AdHoc Mechanisms

Overloading

Transfer Functions

SetTheoretic Union Types

Universal Mechanisms

Inclusion Polymorphism

Innite Unions vii

Record

Statically Typed Ob jectOriented Languages

Universal Quantication

FBounded Quantication

Op eration Inference

Descriptive Classes

Parameterized Mo dules

Summary

Contextual Polymorphism

Denition of Contexts and Assertions

Types and Kinds

Environments Contexts and Assertions

Judgements

Type Judgements

Kind Judgements

Sp ecialization

Argument Inference

Use of Contexts and Assertions

Guidance

Abstract Sup erclasses

Context Hierarchies

Abstract Types

Existential Types

Inheritance

Contexts and Polymorphism viii

Subtypes and FBounded Quantication

Parameterized Mo dules

Descriptive Classes

Summary

Notes on Cforall

Overloading

Lvalues

Polymorphism

Type Abstraction

Contexts and Assertions

Lo cal Routines

Overload Resolution

Implicit Conversion

Safe Conversions

Conversion Cost

Degrees of Polymorphism

Overload Resolution Rules

Summary of Overload Resolution

Opaque Types

Assertions and Type Declarations

Context Examples

C Types

Scalar Arithmetic and Integral Types

Mo diable Types

Pointer and Array Types

Relationships Between Op erations

Relational and Equality Op erators

Arithmetic and Integer Op erations ix

Conclusions

Future Work

Bibliography x

Chapter

Introduction

Expressiveness and safety are two imp ortant criteria for judging programming languages In

formally the expressiveness of a language measures the variety of useful programs that can b e

written with it and its safety measures the variety of meaningless programs that can not b e

written with it These attributes can conict with each other to some extent and part of the art

of programming language design lies in balancing their demands

Many languages provide strong type checking as a safety feature Every data item has an

asso ciated type which denes the set of op erations that can b e applied to the data if a program

attempts to apply an op eration to data of the wrong type the languages translator or runtime

system detects and rep orts the error as opp osed to silently allowing the program to attempt a

meaningless computation Type checking can o ccur statically or dynamically Static checking

o ccurs b efore program execution based on information ab out the types of values deduced from

the text of the program In some programming languages the actual type of a value during

execution may dier from its statically determined type In those cases a static type checker must

make conservative assumptions Dynamic checking o ccurs during execution and can use exact

type information For some programs a programmer may b e able to prove that a program will

encounter no type errors when it executes even though that theorem is b eyond the capabilities

of a static type checker for that programming language In such cases dynamic type checking

provides greater expressiveness However programmers rarely attempt pro ofs of dynamic type

safety b ecause of their dicult nature and programming errors are notoriously plentiful so static

type checking provides greater safety

This conict has led to a search for programming languages that are statically checkable but

CHAPTER INTRODUCTION

less restrictive Ideally no useful semantically welldened computation would b e statically type

unsafe Polymorphic languages aim for that goal by allowing programmers to dene computations

that are valid for op erands of many dierent types

This thesis examines p olymorphic languages in detail The remainder of this chapter denes

some useful terms and gives some criteria for comparing languages Chapter two reviews the

kinds of p olymorphism and surveys a number of existing p olymorphism mechanisms Chapter

three discusses a novel p olymorphism mechanism called contextual p olymorphism Chapter four

demonstrates contextual p olymorphism in the context of Cforall an extension of the C program

ming language

Denitions and Notations

A set of values that can b e represented by a computer and that is distinguishable from all other

such sets is a type Dierent languages use dierent rules to distinguish b etween sets One

programming language might allow a program to contain two types that implement the notion

of complex number each represented by a pair of oatingp oint numbers but with one type

interpreted as rectangular co ordinates and the other as p olar co ordinates A dierent language

might treat all such pairs as having the same type

A type generator denes types based on other types and values for example many languages

have an array type generator that denes array types based on an element type and b ounding

values of an index type

A notion is a concept such as cosine or dictionary or le merge or six An imple

mentation is a programminglanguage text that denes computations that allow a computer to

provide the b ehaviour asso ciated with a notion An interface is a programminglanguage text

that provides information ab out the use and b ehaviour of implementations Interfaces dier from

types in that they may include extra information such as routine pre and p ostconditions also

some languages provide entities such as mo dules which have interfaces but are not values and

hence do not have types

An operation is a notion such as add or sort which denes the eect of a calculation

An algorithm is a notion that describ es a sequence of calculations that p erform an op eration A

routine is an implementation of an algorithm this includes predened routines and op erators

like and abs

CHAPTER INTRODUCTION

A group of programminglanguage statements that use an implementation is called a client of

the implementation

Discussions that do not dep end on a sp ecic programming language will use the following

notation

e and e denote arbitrary expressions

i

and denote arbitrary types

i i

e means the value of e has type

The type is the type of a routine taking an arguments of type and

1 2 n 1 2

returning a value of type The sine function has type real real and the real addition

n

function has type real real real

The expression x x e where e is an expression of type is a routine

1 1 2 2 n

with type and with parameters named x x

1 2 n 1 2

Record types use the notation h i so hf f i is a record type with two

1 1 2 2

elds named f and f with types and resp ectively

1 2 1 2

The expression hf e f e i creates a record value

1 1 2 2

Inference rules have the form

p q r

s

meaning that if p q and r can b e proven then s can b e proven For example the

usual typechecking rule for routine calls is

e e

1 1 2 2 1

e e

1 2 2

or in English if e is a routine taking an argument of type and returning a value of

1 1

type and if e has type then applying e to e results in a value of type The rule

2 2 1 1 2 2

for record eld extraction is

e hf f f i

1 1 2 2 n n

ef

i i

The denitions of many other terms and notations app ear at their rst use The index contains an entry for every denition

CHAPTER INTRODUCTION

Desirable Prop erties

Many authors have listed many prop erties that they b elieved were characteristics of go o d pro

gramming languages Of those prop erties the following seem particularly relevant to issues that

arise when comparing p olymorphic programming languages

Eciency It should b e p ossible to implement the features of a language eciently enough so

that programmers rarely feel the need to avoid them or work around them in the interests of

conserving computer resources

If anyone is to b e allowed to introduce ineciency it should b e the user programmer

not the language designer The user programmer can take advantage of this freedom

to write b etter structured and clearer programs and should not have to exp end extra

eort to obscure the structure and write less clear programs just to regain the eciency

which has b een so arrogantly preempted by the language designer

Strong Static Interface Checking

The programming language should b e designed to reduce as far as p ossible the

scop e for co ding error or at least to guarantee that such errors can b e detected by a

b efore the program even b egins to run Certain programming errors cannot

always b e detected in this way and must b e cheaply detectable at run time in no

case can they b e allowed to give rise to machine or implementation dep endent eects

which are inexplicable in terms of the language itself

Strong interface checking extends the familiar concept of strong type checking no op eration

can b e p erformed on data unless the b ehaviour of the op eration is dened for that data The

dierence b etween strong type checking and strong interface checking is that checking is based on

the interfaces of data and op erations An interface might not provide complete type information

for instance many languages let programmers declare incomplete record types which do not

sp ecify the records elds and records of these types can b e op erated on in certain restricted

ways An interface might also describ e prop erties that are not part of a languages

such as a routines preconditions

Static checking where p ossible is preferable to dynamic checking b ecause it guarantees that certain classes of errors are not present in the program If dynamic checking is used that guarantee

CHAPTER INTRODUCTION

can only b e provided by exhaustive testing which is at b est slow and at worst imp ossible or

by human verication which is exp ensive and errorprone All other things b eing equal the

more static checks a programming language provides for the b etter it is since a larger class of

errors is excluded However a language design must balance safety against eciency b ecause

some conceivable checks are infeasible or imp ossible for instance static verication of routine

preconditions would in general require a full theorem prover

Expressiveness A programming language is expressive if it can b e used in a clear uncontorted

way to implement a wide variety of notions One language is more expressive than another if it

can express all of the notions that the other can and other notions as well

One asp ect of expressiveness is exibility the ability to express notions that are quite dierent

from those foreseen by the languages designers A second is supp ort for polymorphic data The

existence of p olymorphic data follows from the principle of declaration corresp ondence prop osed

by Landin and discussed extensively by Harland who states it this way al l options or

prop erties asso ciated with declarations should b e uniformly available Hence if programmers

can dene routines with parameters that can b e b ound to arguments with dierent types it should

b e p ossible for them to dene data structures with elds that can b e b ound to values of dierent

types For example a program might contain a list of various geometric gures such as circles

and p olygons every element could have a dierent type The program could safely apply any

op eration that is valid for any type of gure to any element of the list

A third asp ect of the expressiveness of a programming language is its ability to describ e

prop erties of notions Notions have various prop erties such as relationships b etween the types

of the op erands of an op eration dierent notions have dierent prop erties Consider the notion

min a b which returns the smaller of two arguments That notion has at least two imp ortant

prop erties

It is asso ciated with the notion of ordered values which denes the types of its op erands

and its returned value An implementation of min should accept values from any of and

only those ordered types that implement ordered values

The arguments of min do not just have ordered types they must have the same type If the

arguments b elong to dierent ordered types there may not b e an ordering dened b etween

them even though each has its own dened ordering Similarly the value returned by min

is not just any ordered value it has exactly the same type as the argument values If a

program applies min to two integers the result will b e an integer This information can b e

CHAPTER INTRODUCTION

used to optimize the co de that calls min In general this type matching can combine with

a languages type generators so that the type of one argument must match the type of a

eld of a record argument and so on

As has b een mentioned the meaning of the same type dep ends up on the programming

language In a language with an assignment op eration that copies values into variables the

same type may mean the same representation In another language two values a and b

might have the same type if a single routine exists such that a b b a

These p oints illustrate two more general forms of expressiveness in the rst case the ability to

describ e prop erties of a type in the second the ability to describ e relationships b etween types

Within a program interfaces of implementations of notions must express these prop erties

Perfectly precise interfaces state all of the notions prop erties and no others A language that

lets programmers dene more precise interfaces is more expressive An interface may fall short of

p erfect precision in two ways It may state extra prop erties in these cases the language lacks

generality the ability to dene interfaces and implementations with the largest p ossible domain

of applicability p ossible and some semantically welldened computations are inexpressibl e Al

ternately interfaces may b e permissive they may omit relevant prop erties in which case uses of

the implementation can not b e checked as carefully in the b est cases p otentially static checks

must b e replaced by explicitly programmed dynamic checks In the worst cases the checks never

o ccur A convention comment that states what must or must not b e done with some implemen

tation is evidence of such a lack of precision such unenforced conventions are dangerous b ecause

subtle errors often result when they are accidentally or intentionally violated

Separate Interfaces The denition of an implementation always denes an interface of that

implementation Some programming languages provide no other way to dene interfaces in

others the implementation and its interface must reside in one textual unit The designers of

Ada to ok a dierent approach Ada source co de is gathered into units called packages which

are divided into two parts the package specication denes the interface of a package and the

package body provides the implementation Ichbiah argued that this design has the following

b enets

Client programmers can b e prevented from reading the implementation This lets imple

mentors keep the implementation condential for instance by distributing only a compiled form of the implementation along with the textual form of the interface

CHAPTER INTRODUCTION

Even if condentiality is not required preventing client programmers from reading the

textual form of the implementation keeps them from inferring and making use of incidental

prop erties of the implementation that might b e changed in the future In other words the

interface provides a contract that clients and implementations can b e measured against

Implementations and interfaces can b e separately compiled safely

I would like to add three p oints to this list

Translators only need access to interfaces instead of the entire implementation when check

ing client programs

It b ecomes easier to have several implementations corresp onding to an interface each suited

to dierent clients

It b ecomes p ossible to have several interfaces to one implementation One reason would b e

to provide interfaces corresp onding to dierent levels of encapsulation as in Cs public

and protected class interfaces Another is to provide interfaces for dierent sorts of

clients for instance an implementation of a buer might provide reader and writer

interfaces

Co de Reuse As the programming community develops exp erience in a problem area it dis

covers new useful notions and b orrows old ones from other areas These notions will b e used in

many programs For instance the prop ortion of commercial data pro cessing co de that is made

up of such reusable notions is estimated to b e or even Hence a programming

language should encourage pro duction of reusable co de since reuse can greatly reduce the cost of

programming Lanergan and Grasso b elieve that their approach to co de and design reuse increase

pro ductivity by when new programs are written and greatly eases the task of program com

prehension during maintenance once programmers have b ecome familiar with the reusable co de

It is also imp ortant to provide supp ort for dierent forms of reuse The implementation of a

notion can b e used in many programs that need that notion an implementation can b e reused in

the construction of similar implementations and an interface can b e reused in the description of

similar interfaces

The simplest way to reuse co de is to copy and mo dify it This is not a satisfactory form

of reuse since maintaining many copies of similar co de increases wasted eort and raises the probability of errors and inconsistenci es

CHAPTER INTRODUCTION

Flexibility obviously encourages reuse So do es the separation of interfaces from implemen

tations A client that can not make use of hidden details is protected from changes in the im

plementation of those details this weakens the urge to use copyandmodify as a defense against

such changes The stronger the separation is the more it will encourage reuse

The ability to replace an interface or implementation with a more general version without

aecting clients of the original is called generalizability Generalizabili ty lets a programmer

replace a minimum routine dened for integer parameters with one dened for parameters with

any ordered type without requiring changes to any routine calls This promotes reuse by reducing

the fear of ripple eects that can result from changes to reused co de

The ability to augment the domain of an interface or implementation without mo difying it is

called incrementality Incrementality lets a programmer dene a less than routine for a type

that do es not have one p erhaps so that instances can b e passed to a minimum routine This

promotes reuse by allowing programmers to adapt existing implementations to new domains

Simple Base Language The language should get as much mileage as p ossible out of its

denitional mechanism never introducing something as a distinct language construct which can

b etter b e explained in terms of the denitional mechanism p Replacing programming

language primitives with programmerdenable facilities leads to a smaller simpler language and

simplicity is generally held to b e a virtue in programming languages provided that simplicity is

not achieved at the exp ense of other desirable prop erties Furthermore the existence of

a standard library of useful facilities written in a programming language provides evidence of the

exibility and expressive p ower of the language

Shaw and Wulf argue that programming languages preempt many decisions that could

b e left op en for programmers and that this can result in contorted programs can prevent op

timization and b ecause of lost eciency can discourage the use of highlevel languages They

describ e ways for programmers to retain control over concurrency iteration storage layout and

even pro cedure invocation For instance programming languages often provide some way to dy

namically manage ob jects in memory In the C language this capability is provided by standard

library routines such as malloc and free Programmers can replace these routines if they

need tracing or debugging features or garbagecollecting allo cators or allo cators that

are tuned to their programs In Pascal storage management is provided by primitive new and

dispose routines Since they are tied in to the compilers runtime environment replacing them

is usually dicult or imp ossible In this resp ect C is more exible than Pascal Unfortunately

CHAPTER INTRODUCTION

Cs type system is such that the exibility is b ought at the cost of a loss of type safety As

another example Hilnger shows that with some extensions to Adas abstraction mechanisms

its exception handling and tasking facilities could have b een provided by library packages

Polymorphism

The type of a notion is often quite vague Consider the notion of a minimum op eration which

returns the smallest of its arguments This includes notions of op erations that take numeric argu

ments or arguments from any ordered type Similarly the op eration might take two arguments

or an unbounded number of arguments or a single argument that is a set of such values Hence

neither the types of the arguments nor the type of the notion minimum are rigidly dened

Polymorphism allows languages to reect this vagueness Strachey informally dened p olymor

phic routines and op erations to b e those that have several forms dep ending on their arguments

and gave as an example the op eration which in most programming languages works with

many combinations of numeric types He also coined terms for two main sorts of p olymorphism

adhoc polymorphism and parametric polymorphism

In adhoc p olymorphism there is no single systematic way of determining the type

of the result from the type of the arguments There may b e several rules of limited

extent which reduce the number of cases but these are themselves adhoc b oth in

scop e and content All the ordinary arithmetic op erators and functions come into this

category It seems moreover that the automatic insertion of transfer functions by the

compiling system is limited to this class

Parametric p olymorphism is more regular and may b e illustrated by an example

Supp ose f is a function whose argument is of type and whose result is of type

so that the type of f might b e written and that L is a list whose elements

are all of type so that the type of L is list We can imagine a function say

Map which applies f in turn to each member of L and makes a list of the results

Thus MapfL will pro duce a list We would like Map to work on all types of

list provided f was a suitable function so that Map would have to b e p olymorphic

However its p olymorphism is of a particularly simple parametric type which could b e

written

list list

where and stand for any types

CHAPTER INTRODUCTION

The p olymorphism exhibited by the ordinary arithmetic op erators might b e what is now called

overloading which allows several routines with distinct types but with the same name to exist

within a scop e For instance Algol denes two not op erations one for b o olean values

and one for bit strings It also could cover what Strachey called dynamic type determination

arguments contain a type tag and p olymorphic routines dynamically test the tag to decide what

to do

Cardelli and Wegner introduced the term inclusion polymorphism for the sort of p olymor

phism found in ob ject oriented languages where an ob ject can b e viewed as b elonging to

many dierent classes that need not b e disjoint that is there may b e inclusion of classes

They do not dene the term class which means dierent things in dierent ob ject oriented

1

languages They group parametric and inclusion p olymorphism together as forms of universal

polymorphism Inclusion p olymorphism is asso ciated with p olymorphic data structures while

parametric p olymorphism is asso ciated with p olymorphic routines

These denitions are not precise and the examples of adhoc p olymorphism show that problems

arise when they are applied to concepts that developed later Do es not the type checking algorithm

of any compiler or runtime system constitute a single systematic way of determining the types of

expressions in its language How regular must a rule b e to exclude a p olymorphism mechanism

from the adhoc category Clearly it would b e nice to have sharp er denitions One interpretation

emphasizes the behaviour of p olymorphic routines

adhoc p olymorphism o ccurs when a function is dened over several dierent types

acting in a dierent way for each type parametric p olymorphism o ccurs when a

function is dened over a range of types acting in the same way for each type

Parametric p olymorphism is obtained when a function works uniformly on a range of

types these types normally exhibit some common structure Adhoc p olymorphism is

obtained when a function works or app ears to work on several dierent types which

may not exhibit a common structure and may b ehave in unrelated ways for each

type In terms of implementation a universally p olymorphic function will execute

the same co de for arguments of any admissible type whereas an adhoc p olymorphic

function may execute dierent co de for each type of argument

This view has two related diculties First Strachey seems to b e concerned only with types

not with b ehaviour Second when the implementation of a p olymorphic routine is hidden from

1 Class is not the same as type which they do dene

CHAPTER INTRODUCTION

clients the way it acts and esp ecially the co de it executes is unobservable It seems b etter

to dene p olymorphism only in terms of types and interfaces that is the common structure of

arguments that is referred to ab ove

Note also that Stracheys terms apply to language mechanisms not to the notions that are

implemented with them A language can provide more than one p olymorphism mechanism a

notion might b e implemented by an overloading of parametrically p olymorphic and monomorphic

routines and in that case it would not make sense to say that the notion or its implementation

exhibits parametric or adhoc p olymorphism The relevant prop erty is the range of use of the

implementation is it applicable to some nite set of currentlydened types or can it b e used

with an innite set of types including some that will b e dened in the future In the latter case

the types can not b e sp ecied directly instead the implementation of the notion must state some

common structure or interface that the types must p ossess

The following denitions are reasonably precise emphasize the imp ortance of common struc

ture and innite applicability and refer to programminglanguage phenomena such as implemen

tations and identiers not to notions or to unobservable phenomena such as the b ehaviour of

implementations

polymorphism is the ability to implement a notion so that it applies to more than one type

adhoc polymorphism is present when an implementation has one or more interfaces that

are dened for a set of types which need not have any common structure

This denition do es not require any similarity in the types or even the number of argu

ments of the interfaces asso ciated with an identier b ecause it must cover the case of a

minimum notion that has interfaces dened for a single setvalued argument and for a

pair of arguments Unfortunately this also covers cases where the interfaces do not represent

the same notion Many programming languages have a binary op erator that represents

the notion of subtraction and a unary op erator that represents the notion of arithmetic

negation

universal polymorphism is present when an implementation has a single interface that is

applicable to a p otentially innite set of types dened by a common structure

A routine exhibits parametric polymorphism when the value of a parameter denes other

parts of the routines interface The parameterized interface denes a structure and the

routine accepts any argument list and only those lists that p ossess that structure but

CHAPTER INTRODUCTION

the lists can have a p otentially innite number of dierent types corresp onding to dierent

parameter values

inclusion polymorphism is present when an identier can b e b ound to values from a p oten

tially innite set of types with a common structure

The b oundary b etween inclusion p olymorphism and parametric p olymorphism is thin Con

sider the list parameter of Stracheys Map example It can b e b ound to values of dierent

types during dierent calls but it do es not demonstrate inclusion p olymorphism b ecause its

value can only have one type list for the current value of If inclusion p olymorphism

was present list would only dene some but not all of the attributes of the values

actual type and the parameter could b e b ound to a list of any type that p ossessed s

attributes

It is interesting to consider some b oundary cases of these denitions The language EL

uses the type generator ONEOFtt to dene the union of the types t and t A routine that

doubles an integer or a real number could b e dened as follows

DOUBLE EXPR VONEOFINT REAL ONEOFINT REAL

BEGIN

V V

END

Then DOUBLE would return a ONEOFINT REAL value containing the integer and DOUBLE

would return one containing the real number By the b ehavioural denition DOUBLE is

an example of parametric p olymorphism b ecause the routine b o dy do es not contain sp ecial cases

for the dierent argument types By the denitions used here DOUBLE is an example of adhoc

p olymorphism b ecause it do es not use a required structure to dene the types of arguments it

accepts it just lists a set of types Both argument types have a op eration but that do es not

dene the set of legal argument types DOUBLE will not accept a COMPLEX argument even though

COMPLEX has a op eration

EL also contains a GENERIC construct that allows routines to p erform calculations based on

the dynamic types of arguments

DOUBLE EXPR VONEOFINT REAL ONEOFINT REAL

GENERICV

INT FIXADDV V

CHAPTER INTRODUCTION

REAL FLOATADDV V

END

DOUBLE is an example of adhoc p olymorphism by any denition including Stracheys However

DOUBLE and DOUBLE have the same interface

Chapter

Polymorphism Mechanisms

Chapter discussed a number of desirable prop erties of programming languages and dened

several broad classes of p olymorphism This chapter discusses sp ecic mechanisms that have

b een used to introduce p olymorphism into languages and evaluates the extent to which they

supp ort for the desirable prop erties It do es not deal in great detail with deep semantic issues

instead it concentrates on the pragmatic eects that these mechanisms have on programs that use

them

AdHoc Mechanisms

Recall the denition given in chapter adhoc p olymorphism is present when an implementation

has one or more interfaces that are dened for a set of types which need not have any common

structure Adhoc p olymorphism comes in three varieties overloading transfer functions and

settheoretic unions

Overloading

A construct in a typed programming language is said to b e overloaded when there are several

dierent implementations of the construct and the version appropriate to a particular case is

chosen using type information reecting its context within the program For example Algol

overloads the not op erator one version takes a b o olean argument and returns a b o olean value

and the other takes and returns bit strings Overloading is an adhoc mechanism b ecause each

CHAPTER POLYMORPHISM MECHANISMS

implementation has a dierent interface and the types mentioned in dierent interfaces need not

have anything in common

When an overloaded identier is used one of its implementations must b e selected Statically

checked programming languages usually use static overload resolution the language translator

attempts to choose one implementation of each overloaded identier in an expression based on the

type rules of the language and the declarations of identiers in the context of the expression If the

translator can not choose b etween two implementations it judges the expression to b e ambiguous

and rejects it Consequently a valid expression using overloading is equivalent to an expression

that uses unique identiers so static resolution has no eect on generalizabili ty static checking

strong checking or separation of interfaces from implementations It is also ecient since there

is no added runtime cost and since the increased compilation cost should also b e acceptable

arguably if a language denition makes overload resolution exp ensive then overloading in that

language is to o complex to b e used eectively by programmers

Overloading provides incrementality since more overloadings can b e added if they are needed

It simplies the language since notions like not can b e presented as a library instead of a sp ecial

case of the language It also increases expressiveness by reducing the severity of name clashes

for instance two libraries can declare the same identier as long as the overloading rules allow

them to b e distinguished It provides type matching consider two implementations of min one

accepting a pair of integers and returning an integer and the other accepting and returning real

numbers The arguments and result must have the same type Overloading also lets interfaces

dene their applicable notions to a limited extent However it do es little to increase generality

a full description of the notion of minimum would require an innite number of overloadings

Other drawbacks of overloading are due to its unconstrained nature First there is no guaran

tee that all overloadings of an identier implement the same notion and hence a small programmer

error can result in a call to a routine that do es entirely the wrong thing Second many authors

feel that overloading can reduce program readability This is partly b ecause in a case

where an identier represents more than one notion it can b e dicult to determine which notion

the author of some co de had in mind But it is also due to a paradoxical eect overloading

makes it easier to get a general understanding of co de Aha This co de sums the elements of a

vector but makes it harder to get a detailed understanding Aha This co de calls the addition

routine for quaternions These problems can b e reduced if programmers have access to program analysis to ols and if programmers use taste and discretion when overloading

CHAPTER POLYMORPHISM MECHANISMS

Transfer Functions

One of Stracheys examples of adhoc p olymorphism was the automatic insertion of a transfer

function This is also known as implicit conversion and as coercion Cardelli and Wegner dene

it as a semantic op eration that is needed to convert an argument to the type exp ected by a

function in a situation that would otherwise result in a type error For instance the sin

routine in Algol takes a real argument If it is called with an integer argument the language

translator inserts a transfer function to convert the argument to a real value and passes the result

to sin In languages such as C programmers can dene new transfer functions to complement

programmerdened types

Note that by this denition a transfer function creates a new value of the desired type In

certain cases the bit patterns of the old and new values may b e the same and no computation

is needed but that is an optimization By some denitions co ercions merely change the type of

an existing value without creating a new value or altering it in any way A call to a sin routine

that takes a real parameter will always return a real result even if the argument is an integer

If an integer result is needed then another transfer function must b e applied to the real result

to create it In general such inverse transfer functions may not exist or successively applying

the transfer function and its inverse may result in the loss of information present in the original

value

Transfer functions introduce p olymorphism b ecause routines like sin can b e applied to many

dierent types of arguments The p olymorphism is adhoc b ecause the set of types is dened

by the set of available transfer functions not by any prop erties of the types It is dierent

from other p olymorphism mechanisms in that it adapts the arguments to suit the routines other

p olymorphism mechanisms pro duce routines that adapt to their arguments Hence it has no eect

on interface precision or separation of interfaces from implementations and do es not provide a way

to simplify a language by replacing language constructs with programmerdenable abstractions

An expression that uses transfer functions is equivalent to an expression where the transfer

functions are called explicitly so implicit calls do not aect strong static checking and are no less

ecient than explicit conversions Programmerdened transfer functions provide a weak form of

incrementality since new transfer functions let old routines b e applied to arguments of new types

and may o ccasionally provide some generalizabili ty if a new more general routine is accompanied

by a transfer function that converts old arguments to the new form However the p otential loss of

type precision and of information makes transfer function p olymorphism unsatisfactory in most cases

CHAPTER POLYMORPHISM MECHANISMS

SetTheoretic Union Types

The EL ONEOF type used by the routines DOUBLE and DOUBLE on page is an example of a

settheoretic union type More advanced versions of the idea have b een prop osed by Reynolds

and Pierce These types are dened in terms of other member types if a type is considered

to b e a set of values then the union type is the set of all values contained in those member

types Consequently a value may b elong to more than one type Settheoretic unions provide

p olymorphism b ecause they allow identiers to b e b ound to values from the dierent member

types The p olymorphism is adhoc b ecause no common structure is needed among argument

types

The GENERIC construct used by DOUBLE is an example of a conformity clause A conformity

clause is similar to a case statement but it examines the type of a data item instead of its

value Each branch of the clause describ es types that the data item might have and statements

to execute if it has one of those types If the branch sp ecies a type constant then strong static

checking is p ossible in the branch

A language might provide dynamic overload resolution instead of conformity clauses In such a

language if an expression uses an overloaded routine identier and an argument to the routine is a

union then the member type that the value b elongs to would b e used to resolve the overloading

In eect an implicit conformity clause is used to call the appropriate implementation of the

overloaded routine The overloaded routines in such languages are sometimes called multimethods

Ghelli has describ ed a strongly and statically checked type system for such a language

Many languages provide unions that are not settheoretic unions In these languages a union

type is distinct from its member types and sp ecial actions are needed to convert b etween values

of the union type and values of the member types Consider the Algol version of DOUBLE

mode ir unionint real

proc double ir v ir

case v

in int i i i

real r r r

esac

double

double

Note that the case statement the Algol conformity clause provides a name i or r to refer

CHAPTER POLYMORPHISM MECHANISMS

to the membertype value contained within the union parameter v v can not b e assigned to a

real variable or passed to a real parameter even if it happ ens to contain a real value This

shows that there is a distinction b etween a union value and the member value that it contains

When a member value such as is passed to double a uniting coercion implicitly converts it to

a union value Hence the p olymorphism of double is actually transfer function p olymorphism

not union p olymorphism

Unions increase expressiveness in an interesting way it b ecomes p ossible to handle data whose

exact type is not statically known For instance it may b e imp ossible to statically decide whether

the argument of a call to DOUBLE is an INT or a REAL the argument might b e a ONEOF parameter

of a routine that calls DOUBLE or its value might dep end on input to the program

Unions provide a small amount of generalizabili ty since a union type can b e expanded to

include more members DOUBLE could b e changed to have a parameter of type ONEOFINT

REAL COMPLEX without aecting its clients They allow language simplication for instance

p olymorphic op erators can b e presented as library routines They have no eect on incrementality

or on separation of interfaces and implementations As an example of interface precision consider

an EL minimum routine

MIN EXPR A ONEOFINT REAL B ONEOFINT REAL

ONEOFINT REAL

BEGIN END

This example shows that unions prevent type matching one argument of MIN could b e an INT

while the other is REAL Furthermore if the arguments have the same type the value returned by

MIN has that same type but MINs type do es not express that fact The example also shows that

unions do not provide full generality since the arguments to a fully general MIN routine would

have to b e unions of an innite number of ordered types

Settheoretic unions can have reasonable eciency Typically types are enco ded as type tags

Distinct types must have distinct tags This may b e dicult to arrange for some combinations

of computing environments and type systems Type tags have a space cost in the worst case

every value must contain a type tag but a translator can often optimize away the tags of values

whose types are never in doubt Since the exact size of a union value is unknown enough space must b e allo cated to hold the largest p ossible value or values must b e manipulated via p ointers

CHAPTER POLYMORPHISM MECHANISMS

The execution time cost of type tags is mo derate Steenkiste studied an implementation for

the MIPSX pro cessor of Portable Standard Lisp a dynamicallytyped language He concluded

that a collection of b enchmark programs would sp end to of their time pro cessing tags

Universal Mechanisms

The common feature of all adhoc p olymorphism mechanisms is that the domains of implemen

tations that use them are not dened by some common structure In contrast universal p oly

morphism uses a common structure to dene a single interface that is applicable to a p otentially

innite set of types It has two varieties inclusion p olymorphism lets programs bind identiers

to values from a set of types dened by a common structure and parametric p olymorphism lets

the interface of a routine dep end on the value of one of its parameters so that valid argument

lists must match a structure dened by the interface Several p olymorphism mechanisms exist for

each of these varieties of p olymorphism

Inclusion Polymorphism

Some programming languages dene a subtype relationship b etween types If a type is a subtype

1

of another type written then values of type can b e used in certain situations that

2 1 2 1

require a value of type The situations vary among languages but typically they use the

2

following typechecking rule

e

1 1 2

e

2

Combining this with the functionchecking rule on page gives

e e

1 2 3 2 1 1 2

e e

1 2 3

This is a universal p olymorphism mechanism b ecause routines accept arguments with any of a

set of types that share a common structure dened by the languages subtype rules It is inclusion

p olymorphism b ecause the parameters of the routine can b e b ound to arguments with dierent

subtypes of the parameter type

Subtyping can allow simplication of the language kernel Recall that the Algol not op erator

p erforms logical negation on b o olean and bit string values In a language with subtypes this

could b e expressed as a single routine that takes an argument of type logical which would b e a sup ertype of the b o olean and bit string types

CHAPTER POLYMORPHISM MECHANISMS

If every op eration that is valid for values of a type is also valid for all subtypes of the type

then subtyping preserves strong static checking Subtyping has no eect on separation of imple

mentations and interfaces However it do es reduce the precision of interfaces since it leaves no

static way to refer to the actual type of an argument to a p olymorphic routine only the name of

the sup ertype is known Hence type matching vanishes there is no way to declare statically that

two values have exactly the same type Such information if present at all is given in comments

and enforced at runtime when it is to o late to correct errors

Subtypes can also provide p olymorphic data structures for instance if the language allows

record elds declared to have type to b e b ound to values of subtypes of

Innite Unions

The simplest form of subtyping denes a type that is a sup ertype of every other data type or in

other words an innite settheoretic union of all other types It is p ossible to have innite versions

of Algol s style of union but they are not discussed in this section For instance EL has

an ANY type which can b e combined with the type generators of the language to pro duce records

with elds that can hold any value parameters that accept any argument and so on Routines

that have parameters whose types involve innite unions exhibit inclusion p olymorphism the

required structure of the argument types is the set of prop erties common to all data types such

as the ability to b e assigned or instantiated If an innite union is used in a type generator then

the generator denes a more precise structure the EL routine

NAMEOF EXPR SSTRUCT NAME STRING VAL ANY

STRING

BEGIN

SNAME

END

will accept as an argument any record that has two elds the rst of which is a string called

NAME and the second of which is anything called VAL

The implementation of innite unions can b e much like the implementation of nite unions

except that when allo cating space for an innite union variable a compiler can not simply allo cate

enough space to hold the largest member type Consequently indirection must b e used in more cases

CHAPTER POLYMORPHISM MECHANISMS

Strong interface checking and static checking can b e applied in the cases of op erations that can

b e p erformed on values of type ANY and of op erations that can b e p erformed on every data type

a typical example is computing a reference to a value These op erations are surprisingly useful

For example routines that implement op erations on collection types such as lists often use

only those op erations since the routines reorganize values but do not op erate on them directly

Hence these languages allow safe statically checkable implementations of collection types that

are indep endent of the collections element types This is an increase in b oth expressiveness and

exibility and therefore in reusability

ADD EXPR CCOLLECTION V ANY

Unfortunately due to the absence of type matching static type information ab out data that

passes through p olymorphic routines or data structures vanishes A program can add an INT to

a collection but when some op eration retrieves the integer from the collection its static type will

b e ANY not INT

Innite unions allow smaller language kernels since op erations like the traditional cons car

and cdr op erations on lists can b e treated as library routines However routines can only replace

language primitives that take any value as an argument a not op eration should not b e dened

this way b ecause logical negation is not a sensible op eration for most types

When a data item has static type ANY its dynamic type of the data must b e recovered b efore

any typesp ecic op eration can b e p erformed on it This could b e done with a conformity clause

but the usefulness of this has limits b ecause only a nite number of tests can b e p erformed

Checking could also involve dynamic overload resolution with its runtime costs and dynamic

checking Another alternative is to pass the op erations along with the data as routine parameters

or as routine elds of the value This requires some care on the programmers part and still

requires dynamic type checking in general

Innite unions provide a form of generality but not a useful form b ecause they do not allow

programmers to sp ecify many sorts of restrictions on the values that a union may take on For

instance a truly p olymorphic version of DOUBLE should accept any type that has a op eration

but the ANY type do es not provide a way to sp ecify that only such values are acceptable Similarly

it provides only weak generalizabili ty a routine with an INT parameter can b e replaced by one

with an ANY parameter and incrementality any new type is a subtype of ANY and hence extends

the domain of routines with ANY parameters

CHAPTER POLYMORPHISM MECHANISMS

Record Subtyping

Cardelli describ ed subtype rules for routine and record types A subtype of a record type

can add new elds and can change the type of an existing eld to a subtype of the original eld

type

0 0 0

1 2 m

1 1 m

0 0 0

h l l i hl l l i

1 1 m m 1 m n

1 m n

In eect this rule provides a lo oser version of structural equivalence for record types

The rule for routines also allows changes in types a subtype of a routine type can replace the

result type by a subtype and can replace the argument type by a sup ertype

1 2 1 2

2 1 1 2

For instance if a program uses two types Integer and Fraction with Integer Fraction

then

Fraction Integer Integer Fraction

and a routine with the rst type can b e passed as an argument to a parameter with the second

type This pattern of replacement is known as contravariance since the result and argument

types change in opp osite ways It follows naturally from the ow of data through routines in

through the parameters and out through the result with subtypetosup ertype transformations

at each p oint

Unfortunately many op erations are naturally covariant Consider the natural types of the

addition op erations asso ciated with Fraction and Integer

Integer Integer Integer

Fraction Fraction Fraction

Since these op erations types exhibit covariance neithers type is a sup ertype of the others

whether Fraction and Integer have some subtype relationship or not Furthermore there can

b e no type T such TTT is a sup ertype of b oth This makes it imp ossible to write a double

routine that would accept either op eration as an argument This problem can not b e solved

by using a covariant subtype rule b ecause covariant rules require dynamic type checking

The b est that can b e done would give the two routines the types

Addable Addable Integer

Addable Addable Fraction

CHAPTER POLYMORPHISM MECHANISMS

where Addable is some sup ertype of Integer and Fraction then b oth types would b e subtypes of

AddableAddableT if T is a subtype of b oth Integer and Fraction Clearly this approach

would lose type precision It also would require two problematic types Addable and T which

must b e a sup ertype and a subtype resp ectively of all types with a op eration

Record subtype languages have a second distinguishing feature routines stored in elds in

records can refer directly to the record itself typically through the sp ecial identier self In

eect the record b ecomes an extra parameter of the routines that it contains Programs that

use record subtyping would not implement as an ordinary routine Instead programmers

implement types such as Fraction as records that bundle together a value and the routines that

op erate on it Builtin types such as Integer are treated as if they were records containing

routines Polymorphic routines use record types as parameter types and accept any argument

whose type is a subtype of the parameter type

type Addable hplus Addable Addablei

assume Integer Addable

type Fraction hplus Addable Fraction

numerator Integer denominator Integeri

Fraction Addable

double Addable Addable

Double the fraction one half

double hnumerator denominator

pluspAddable selfi i

This do es not prevent the loss of static type information mentioned ab ove the plus routine for

Fractions still takes an Addable argument not a Fraction and the result of the call to Double

has static type Addable not Fraction However this is an improvement over the situation

presented by innite union p olymorphism since routine and record types refer to Addable not

to an overlygeneral type like ANY Furthermore the subtype rules let subtypes change the types

of routine elds as long as covariance is observed the result type of the plus eld changes

from Addable in the declaration of Addable to the more precise Fraction in the declaration of

Fraction Consequently programs have less need for conformity clauses or dynamic overload

resolution

Subtyping provides generality a routine will accept any argument that supp orts the op era

tions dened by the routines parameters elds However the contravariant subtyping rule for

CHAPTER POLYMORPHISM MECHANISMS

routines has the eect of limiting generality as shown in where the problem arises in negative

recursion in routine elds of recursive record types Consider this attempt to dene a p olymor

phic min routine which uses the notion of ordered values values that provide a lt op eration

that returns true if the value is less than or equal to lts argument

type Ordered hlt Ordered Booleani

min Ordered Ordered Ordered

pOrdered qOrdered if pltq then p else q

Ordered serves a useful purp ose even though instances of it contain no data and its lt routine

eld has not b een implemented it denes the interface of ordered values A programmer might

dene a String type containing character strings with a lt op eration that compares strings in

lexicographical order

type String h lt String Boolean i

However min do es not accept String arguments even though String denes lt b ecause String

is not a subtype of Ordered This can b e demonstrated by contradiction assume

StringOrdered

Then the record subtyping rule and the types of their lt elds gives

StringBoolean OrderedBoolean

and applying the routine subtype rule to the parameter types gives

Ordered String

Combining this with the original assumption gives

Ordered String

Which is clearly false String would b e a subtype of Ordered if it were dened as

type String h lt Ordered Boolean i

CHAPTER POLYMORPHISM MECHANISMS

In this case String Ordered but lts parameter type is to o general and gives lt no elds

with which to do the comparison In cases like these subtyping languages can not dene their

parameter types with full generality

Note that routine types and record types can not have a subtype relationship hence a p oly

morphic routine can not have a parameter that can accept b oth routine arguments and data

arguments There are some notions for which this makes sense see for an example but

these notions can not b e implemented in their full generality

The loss of type matching has one p otentially b enecial consequence it allows mixed mo de

op erations Since Integer and Fraction are b oth subtypes of Addable the typechecking rules

let programmers add integers to fractions This is not an unmixed blessing

The implementation of plus for fractions must do something sensible for any argument type

that is a subtype of Addable even for types created after Fraction

Assume that the programming language provides a type that implements the real num

b ers and is a subtype of Addable The result of adding a fraction to a real number

is a real number in general for any TAddable the result of adding a T to a fraction

might b e a T so Fractions plus must have type AddableAddable not the more precise

AddableFraction

Two types can have a common sup ertype and yet mixed mo de computations b etween them

may not make sense

The last p oint requires an extended example As an example consider a program that also uses a

Name type that is a subtype of Ordered but that has a lt routine that compares names in phone

b o ok order instead of lexicographical order

type Name h lt Ordered Boolean i

s String

n Name

min s n

min n s

Both calls are legal Name and String are b oth subtypes of Ordered so s and n are legal arguments

given the subtypebased typechecking rule However the calls could have dierent results St

John comes b efore Smith in phone b o oks Since subtyping weakens the prop erty of type

CHAPTER POLYMORPHISM MECHANISMS

matching the programmer has no way to sp ecify that the two types are actually incomparable

This disagreement is arguably minor where min is concerned but a sorting routine given a mixture

of Strings and Names might fail to terminate if this sort of ambiguity caused it to rep eatedly swap

a Name value and a String value with each other

A type denes op erations that every subtype must provide and hence represents a notion that

contains all of those subtypes The name of the eld provides a statically checkable but weak

indication of the semantics of the op eration a routine eld named plus probably implements

addition Record values implement the notion and the records routine elds implement imple

ment op erations asso ciated with that notion For example a program that p erforms geometric

calculations might use several types representing regions of the Cartesian plane each of which

provides a contains op eration that decides if the region contains a given p oint The notion of

region can b e represented as a type

type Point hxReal yReali

type Region h contains Point Booleani

inboth Point Region Region Boolean

pPoint rRegion rRegion

rcontains p rcontains p

Rectangles and circles are regions

type Rect h topleftPoint bottomrightPoint

contains PointBooleani

type Circle h originPoint radius Real

contains PointBooleani

arect Rect

acirc Circle

apt Point

b Boolean inboth apt arect acirc

Subtyping also provides p olymorphic data since identiers can b e b ound to instances of sub

types of their declared types

r Region if b then arect else acirc

rcontains apt

CHAPTER POLYMORPHISM MECHANISMS

The call to rcontains is statically typesafe b ecause all regions have a contains eld but the

value of r determines whether the circles or rectangles routine gets called

Subtyping provides generalizability a routine can b e replaced by a routine whose argument

types are sup ertypes of and hence more general than the originals types It increases incre

mentality any new type extends the domain of routines that accept its sup ertypes as arguments

Incremental extension do es not work so well with existing types Consider a record type T which

needs to b e extended with an op eration o to b ecome a subtype of some other type Writing a

routine called o with a T argument is not sucient b ecause that do es not change any subtype

relationships Adding a new o routine eld requires control of the denition of T Dening a new

type T containing a T instance and an o routine eld requires TtoT conversions wherever the

program uses an existing T value

Statically Typed Ob jectOriented Languages

Statically typed ob jectoriented languages make use of various forms of record subtyping SIM

ULA C Eiel and Mo dula are typical of these languages Such

languages generally refer to a record type as a class a routine eld as a message and an imple

mentation of a routine eld as a method Calling a routine eld of a record is often called message

passing Typically classes do not just dene record types they also dene the implementations of

the routine elds In the simplest forms of record subtyping record types merely declare routine

elds to which routines are assigned when instances of the record are created

Programmers can create class denitions incrementally through inheritance which creates a

new child class from explicitl y named parent classes by copying their denitions and p ossibly

adding hiding deleting or replacing eld denitions A classs parents grandparents etc are

collectively known as its superclasses and its children grandchildren etc are its subclasses

Allowing a class to have more than one parent introduces many complications into a language

and go es by the sp ecial name of multiple inheritance

If a class has a routine eld that do es not have a dened implementation it can not b e instan

tiated for fear that the instances routine eld might b e called Such a class is called an abstract

superclass An abstract sup erclass can act as an interface for which nonabstract sub classes pro

vide implementations They can also provide guidance and assistance to the implementor of a

new class who can search for an abstract sup erclass with an appropriate interface dene the new

class by inheritance from it and implement the appropriate routines An abstract Collection

class might declare that it has insert and remove routines without implementing them a Stack

CHAPTER POLYMORPHISM MECHANISMS

sub class would dene implementations that provide lastin rstout b ehaviour A pure abstract

sup erclass provides nothing but unimplemented routine elds and exists only to dene an in

terface Inheritance from a pure abstract sup erclass reuses designs instead of co de An impure

abstract sup erclass implements some routines in terms of other implemented or unimplemented

routines and provides b oth design and co de reuse the implemented routines assist programmers

who must implement nonabstract sub classes

Record subtyping rules were designed to provide clean semantics and a sound type checking

system for ob jectoriented languages so it is not surprising that these languages can b e viewed

as having a more or less restricted form of record subtyping Many of these restrictions and

complications result from attempts to combine three concepts encapsulation subtyping and

co de reuse

In C and Eiel classes provide encapsulation clients of a class have access to some but

not all of the elds of the instances of the class The accessible elds make up an interface of

the class C classes have separate interfaces for clients that use class instances and for clients

that are sub classes Plain record subtyping provides encapsulation through static scop e rules not

through record types if a routine with return type T returns a value that is of a subtype of T

any extra elds dened by the subtype are inaccessible outside of the routine This approach is

somewhat more exible b ecause each such routine denes a dierent interface for dierent sorts

of clients the number of interfaces is not xed at one or two

Inheritance provides co de reuse since sub classes inherit the eld denitions and routine eld

implementations of their sup erclasse s unless they explicitl y replace them Multiple inheritance

leads to the p ossibility of inheriting a declaration of a eld or an implementation of a routine eld

from more than one parent Dierent languages use dierent metho ds for resolving the resulting

conicts Some of these metho ds exp ose the implementation of classes in subtle ways so that

changes in the implementation of a sup erclass force changes in sub classes or in clients this

weakens encapsulation and makes reuse more dicult A class may also inherit from a single

sup erclass along more than one line of descent and this also introduces conicting denitions

These problems do not arise with pure record subtyping b ecause record types are not constructed

by inheritance

Inheritance also aects subtyping since it denes the childs interface in terms of the parent

In all four languages mentioned ab ove sub classes are automatically considered to b e subtypes

of their sup erclasses As a result redenition of inherited elds must b e restricted to ensure

that sub classes truly are subtypes Eiel uses a covariant rule for routine subtyping and hence

CHAPTER POLYMORPHISM MECHANISMS

is not statically type safe In SIMULA Eiel and C sub classes are the only subtypes

of sup erclasse s If pure record subtyping provides a lo oser form of structural equivalence then

explicit sup erclass declarations provide a lo oser form of name equivalence This makes the

subtype hierarchy explicit and therefore rigid If a program requires the denition of a new class

that must b e a sup erclass of existing classes or if an existing class must b e made a sub class of

a class that is not one of its current sup erclasses then existing inheritance declarations must b e

rewritten Mo dula is less restricti ve a class is a subtype of its parent or of any class that has

the same elds as its parent and transitively of their sup ertypes so programmers can insert

new classes into the class hierarchy without changing the denitions of old classes Even this links

inheritance to subtyping the names of a classs sup ertypes are not xed but the elds that are

inherited at each level are xed

Uniting inheritance with subtyping contorts programs Consider an op erating system where

les are asso ciated with signicant data structures p erhaps containing data buers disk ad

dresses and such and a program that implements notions of input les output les and in

putoutput les with types InFile OutFile and IOFile IOFile is a natural subtype of b oth

InFile and OutFile but the most convenient implementation would implement the le data

structures completely in IOFile and dene the other two types by inheriting from IOFile and

removing the extra op erations In this case subtyping and inheritance relationships run in opp o

site directions

Parametric Polymorphism

Universal Quantication

Some programming languages allow the type of a routine to dep end on the value of some of its

parameters In the simplest case an integer parameter might b e used as an array b ound in the

declaration of another parameter In the more interesting cases routines can have type parameters

that are used in the types of other parameters Tennent suggested adding them to Pascal for

reasons based on language design principles and gave this example of a pro cedure that applies a

routine to every element of an array regardless of array b ounds or element type

procedure maparraytype ind d

var A arrayind of d

procedure pvar d

for i ind do pAi

CHAPTER POLYMORPHISM MECHANISMS

A typical use of maparray would b e

procedure doublevar i integer

i i i

type ix

ar arrayix of int

var a ar

begin

maparrayix int a double

end

Various semantics have b een prop osed for languages with type parameters The most p opular

is that of Girard and Reynolds who dened a typed lambda calculus where type param

eterization is an abstraction mechanism distinct from but similar to functional abstraction The

identity routine on integers is written

idint pInteger p

so that idint has the value Similarly the p olymorphic identity routine is written

id T pT p

and has the universal ly quantied type T TT The expression id Integer has the value

and type Integer

Not all universally quantied types are sensible and useful To see this consider the declara

tion

thing T T T e

where T is some type expression p ossibly involving T and e is some appropriatelytyped ex

pression What values could e have The key observation is that e must have type T for every

conceivable type T This limits e to p olymorphic identiers applied to T and monomorphic values

with no relevance to T Hence

thing T hlInteger rIntegeri hl r i

is valid since the l and r elds must contain integers and and have type Integer

CHAPTER POLYMORPHISM MECHANISMS

id T T T T pT p

thing T hf T Ti hf id Ti

is also valid since f must contain a routine of type TT for every p ossible T and id T has that

type However

pair T hlT rTi T hl r i

is not legal b ecause and do not have type T for every p ossible T Consequently T hlT

rTi can not b e used as the type of a data structure containing a pair of values of unknown

but identical type In general t can not b e used as the type of a p olymorphic data structure

containing a data item of type

Instead universal quantication provides p olymorphic data in a more indirect form by en

co ding it as a p olymorphic routine p Recall the region example on page with a

Region type and a Rect subtype

type Region h contains Point Booleani

type Rect h topleftPoint bottomrightPoint

contains PointBooleani

apt Point

arect Rect

r Region arect

rcontains apt

In a language with universal quantication Rect has a simple equivalent

type Rect htopleftPoint bottomrightPointi

rectcontains Rect Point Boolean

In the subtyping example binding r to arect had the eect of forgetting arects type With

universal quantication the same eect can b e created by hiding arect inside a routine The

routines type is the equivalent of Region Computations on the hidden data can b e p erformed by

packaging them as routines and passing them into the Region routine as arguments the Region

routine simply applies the computations to the data and returns the result Since the type of the

result is not known in advance the Region routine must b e p olymorphic

CHAPTER POLYMORPHISM MECHANISMS

type Region rest hcontainsPointBooleanirest rest

r Region rest comp hcontainsPointBooleani rest

comp hcontains rectcontains arecti

To use r a program must pass it the result type and a routine that p erforms the desired compu

tation

r Boolean regionhcontainsPointBooleani

regioncontains apt

Clearly some syntactic sugar is needed to make this approach palatable

Since a type parameter is a name for a sp ecic type it provides type matching a twoargument

min routine could b e dened as

min T TTBoolean T T T

T ltTTBoolean aT bT

if lt a b then a else b

so that min Integer would have the value Universal quantication also provides

great generality a routines interface sp ecies exactly what types and op erations it requires and

can b e applied to any set of arguments that supplies those types and op erations Furthermore

these op eration parameters do not have to follow the contravariant pattern required by subtyping

languages universal quantication has no diculty sp ecifying covariant patterns such as TTT

Unfortunately min must take the type Integer and the integer less than routine as an

explicit parameter Most routines having type parameters require several op eration parameters

that can b e applied to instances of the type parameters and p erhaps some constants as well

Cormack and Wright p oint out that

the existence of these extra parameters means that the greater the generality of an

abstraction the greater the burden of use on the programmer and directly conicts

with our design criteria of generalizabili ty and incrementality

Consider a simple p olymorphic absolute value routine would require a type argument compar

ison and subtraction op erations and a zero value Passing them as separate parameters leads to verbose routine calls and is a source of errors

CHAPTER POLYMORPHISM MECHANISMS

abs t TTBoolean TTT T T T

t ltTTBoolean subTTT zeroT xT

if lt x zero then sub zero x else x

abs Integer

Passing them as routine elds of recordtype arguments is awkward in the absence of subtyping

b ecause the set of elds in the record argument type must b e dened exactly records must b e

disassembled and reassembled when programs pass data to dierent p olymorphic routines that

require dierent sets of op erations

minrec T hvT ltTTBooleani

hvT ltTTBooleani

hvT ltTTBooleani

T ahvT ltTTBooleani

bhvT ltTTBooleani

minrec Integer hv lti h v lti

A p olymorphic routine may also b e to o general for some situations for instance a programmer

might want to pass it to a monomorphic parameter of another routine In that case the program

mer must create a specialization that binds some or all of the type and op eration parameters

fiddle T TTT T T T T

T fTTT aT bT bT

f a f b c

minint Integer Integer Integer

xInteger yInteger min Integer x y

fiddle Integer minint

Universal quantication do es not aect separation of interfaces from implementations since the

name it introduces is in some sense just another parameter Strong checking is also unaected

Incremental extension of data types is simple compared to inclusion p olymorphism since data

types do not contain their op erations as routine elds they do not have to b e restructured to

contain new op erations However generalizability is weak b ecause any attempt to generalize a

routine by adding type parameter or removing op eration parameters will change its interface and hence require changes in all of its clients

CHAPTER POLYMORPHISM MECHANISMS

Compared to inclusion p olymorphism then type parameterization provides type matching

generality and incrementality but not generalizabili ty or convenience when passing op erations

along with data

FBounded Quantication

Fbounded quantication combines subtyping with universal quantication In this ap

proach type parameterization has the form t e and pro duces values of type t

1 1 2

Any type argument passed to t must b e a subtype of the type b ound which is a type expression

1

that may involve t Fb ounded quantication is a generalization of b ounded quantication

where the type b ound must not involve the type parameter This is parametric p olymorphism

despite the use of subtyping b ecause the type parameter of a p olymorphic denition determines

the interface of the denition

Fb ounded quantication allows the denition of a version of min with a precise statically

checkable interface

minTh ltTBooleani T T T

ThltTBooleani pT qT

if pltq then p else q

type String h lt String Boolean i

s String

s String

s String min String s s

The call to min is legal b ecause String is a subtype of hltString Booleani the type b ound

Inside min pltq is legal b ecause the type b ound guarantees that T denes a lt taking a T

argument The result of the call to min has type String

Fb ounded quantication can pass op erations to p olymorphic routines by including them as

elds of records as is done with lt ab ove Consequently passing op erations is simpler than in

simple universal quantication but Fb ounded quantication shares record subtypings diculties

in incrementally extending data types

Recall that inclusion p olymorphism languages typically use the type checking rule

a

1 1 2

a 2

CHAPTER POLYMORPHISM MECHANISMS

Fb ounded quantication provides p olymorphism even without this rule b ecause the exact type

of any data argument can b e passed as a type argument A language without this type checking

rule provides type matching as is shown by min ab ove but can only provide p olymorphic data

by enco ding it in a p olymorphic routine as describ ed in the previous section

However a language might use the subtypebased typechecking rule and provide b oth in

clusion p olymorphism and parametric p olymorphism This would provide the ability to dene

p olymorphic data but would weaken the prop erties of type matching just as it did in record

subtype languages in min String s s the types of s and s might b e dierent subtypes

of hltString Booleani and the result could have any subtype of String

Op eration Inference

The discussion of universal quantication ab ove showed that explicit type arguments and op er

ation arguments are at b est verbose and at worst an imp ediment to programming For this

reason parametric p olymorphism languages generally provide some form of argument inference

which infers the values of some arguments from the types of other arguments

Cormacks and Wrights language ForceOne provides overloading p olymorphism The

standard op erators are asso ciated with sp ecial overloaded routine identiers the less than

op erator is asso ciated with the identier and the expression a b is treated as the

routine call a b ForceOne also provides parametric p olymorphism routines can declare

type parameters by preceding a parameters type with a question mark It also provides implicit

parameters which follow a vertical bar in a parameter list Calls to p olymorphic routines do

not sp ecify arguments corresp onding to type parameters or implicit parameters The compiler

infers type arguments from the types of the ordinary arguments For each implicit parameter

the compiler lo oks for a declaration with the same name and type after substitution of type

arguments for type parameters in the scop e of the call and passes the declared item as the

argument As an example consider a ForceOne implementation of the minimum notion

min xyT T T routine T routine T

f if x y x else y g

Here min is a legal call with the integer type inferred for T and the integer comparison

routine inferred for and returns the integer Note that this form of parametric p olymorphism

dep ends heavily on overloading min can b e applied to any type so long as has b een overloaded for it

CHAPTER POLYMORPHISM MECHANISMS

The implicit parameter mechanism b ears some resemblance to dynamic scoping since the

identier is b ound to a value with that identier in the dynamic calling environment

instead of the static environment of the routine b o dy It has the great advantage compared to

normal dynamically scop ed systems of b eing statically checked However it do es not provide

true dynamic scoping b ecause the inferred argument is found in the static environment of the

calling environment not its dynamic environment

Cormack and Wright describ ed an inference algorithm for a ForceOnelike language in In

that language universally quantied types can not b e passed as type arguments but Bumbulis

has extended the inference algorithm to handle that case The algorithm infers type arguments

and implicit arguments It also adapts the degree of p olymorphism of arguments if necessary

A p olymorphic routine can b e sp ecialize d by binding a type to a type parameter or an implicit

argument to an implicit parameter The inference algorithm automatically sp ecialize s routines if

some implicit parameter requires a less p olymorphic version of the routine

The pro cess of implicit parameter binding do es not necessaril y terminate since the argument

b ound to an implicit parameter may itself have implicit parameters that need to b e b ound through

sp ecializ ation However each iteration of this pro cess corresp onds to a parameter that would

have to b e explicitly sp ecied otherwise Hence nontermination corresp onds to an innitely large

program in a language without argument inference and long inference chains corresp ond to very

complex programs Cormack and Wright simply place a limit on the number of iterations that

their algorithm is allowed to p erform and declare a program to b e invalid if inference can not b e

completed within that limit

Cormack and Wright p oint out many advantages that op eration inference has over other p oly

morphism mechanisms Like all of the other parametric p olymorphism mechanisms it provides

type matching It allows very general interface denitions since implicit parameters state exactly

what op erations a p olymorphic routine requires Op erations are implemented as freestanding

routines not as elds of record types so new op erations can b e implemented and old op erations

can b e reimplemented easily this provides incrementality Argument inference provides general

izability a routine can b e replaced by a version that has a dierent number of implicit parameters

or type parameters without aecting clients If type parameters are added the corresp onding type

arguments will b e inferred automatically and if implicit parameters are added the new version of

the routine can b e accompanied by declarations that will serve as default values for the implicit

arguments

ForceOnestyle languages can have simple ecient implementations such as the one devised

CHAPTER POLYMORPHISM MECHANISMS

by Cormack and Wright In their scheme a type value is represented by an integer that

enco des the size and alignment of the type Since equality comparisons b etween types are not

provided there is no need to try to ensure that the representations of dierent types are distinct

A type parameter is passed like an integer parameter A lo cal variable whose type is not statically

known is implemented as a p ointer to space that is allo cated on the stack up on blo ck entry and

implicitl y deallo cated up on blo ck exit A parameter whose type is not statically known is

implemented as a p ointer to space allo cated at the end of the parameter list When a routines

result type is not statically known the returned value must always b e returned on the stack

instead of in a register Performance suers esp ecially on RISC machines whenever data is not

stored in registers

In many cases a ForceOne compiler could implement a call to a p olymorphic routine by in

line substitution of the routine b o dy at the call site It could also instantiate the routine for any

given argument type or implicit argument by substituting the argument into the routine b o dy

These approaches do not work in general b ecause in some cases the values of inferred arguments

can not b e known statically

f atT nint routine void f

temp record xT

if n ftemp n

g

fx random

Here at each recursive call to f the type argument inferred for T is a more deeply nested record

type so the number of instantiations can not b e determined until runtime

The main drawback of op eration inference is that it do es not provide any way to group together

meaningful collections of types and implicit parameters A set of type identiers and implicit

parameters that are dened for those types denes a notion much as an abstract sup erclass do es

and an abstraction mechanism would b e a useful facility

Descriptive Classes

1

Sandb erg dened the language X in a delib erate attempt to provide the exibility of

dynamically typedchecked ob ject oriented programming languages in a statically typed language

1 also known as X

CHAPTER POLYMORPHISM MECHANISMS

Xs classes are record types or record type generators with type parameters Sandb erg gives

as an example a homogeneous list class where the element type is a parameter

class listT is

first T

tail listT

end class

The type parameter allows stronger type checking of instances of list than do es inheritance from

an abstract sup erclass which is the equivalent op eration in ob ject oriented languages However

there is no notion of a subtype relationship b etween X classes and X classes can not inherit

from other classes They do not contain metho ds ordinary routines are used insteadso

classes can not provide encapsulation a separate mo dule system restricts access to identiers In

other words X classes have little in common with the classes of ob jectoriented languages and

I will call them types or type generators instead

Polymorphic routines use simple type parameters called free types in their interfaces The

values of the corresp onding type arguments for a call are statically inferred from the calling

context Given an isempty routine that returns true if a list is empty a routine that returns

the last element of a list regardless of the lists element type would b e written and called as

follows

procedure lastalistT returns T

where T is free

begin

loop

if isemptyatail then

returnafirst

end if

a atail

end loop

end last

var a listint

b listreal

i int

CHAPTER POLYMORPHISM MECHANISMS

r real

begin

i lasta T inferred to b e int

r lastb T inferred to b e real

Note that the type parameter T can b e used by itself or as an argument of a type generator

This provides parametric p olymorphism equivalent to simple type parameters

To avoid having to pass op erations on type parameters as explicit routine parameters Sandb erg

introduced descriptive classes Simple descriptive classes have a type parameter and sp ecify

routine interfaces in terms of the type parameter As an example Sandb erg denes a descriptive

class order that is one p ossible description of the notion of totally ordered type

descriptive class orderT is

eq procorderT orderT returns bool

grt procorderT orderT returns bool

less procorderT orderT returns bool

end class

An instance statement states that a type satises a descriptive class by stating which routines

corresp ond to the routine interfaces declared by the descriptive class For example an instance

statement declares that int satises order by naming the three builtin routines that corresp ond

to the routine interfaces declared in order

instance of orderint is equal greaterthan lessthan

Polymorphic routines can use descriptive classes in their interfaces for example as parameter

types with free types used as arguments of the descriptive classes If a parameters type is

a descriptive class the corresp onding argument in a call can b e of any type that satises the

descriptive class Routines declared by the descriptive class can b e used in the routine b o dy The

min example could b e written

procedure minporderT qorderT

returns orderT

where T is free

begin

if plessp q then

CHAPTER POLYMORPHISM MECHANISMS

return p

else

return q

end if

end min

var i j k int

begin

k mini j valid int satises orderT

The presence of T in b oth parameters and the return type forces all three to have the same type

thus providing type matching Furthermore X guarantees that minij and minji have

the same value b ecause the instance statement ab ove stated that lessthan is the less op erator

for all ints used as ordered values

Descriptive classes are quite unlike types For instance they can not b e instantiated They

can also dene relationships b etween two types

descriptive class collectionc e is

add proce c

remove proce c

end class

This descriptive class declares routines that must exist if type c is a collection of elements of type

e Hence collection do es not corresp ond to the element type or the collection type

However Sandb erg treats descriptive classes as types The min routine treats p as if it has

a eld named less which was declared in order This suggests that ps type is orderT not

T Sandb erg gives other examples that use orderT as the type of a lo cal variable and as an

argument of a type generator Relationship descriptive classes like collection are treated

as types by arbitrarily equating the descriptive class with the rst type argument A routine

might have a parameter of type collectionf g where f and g are free and programs might

contain statements like instance of collectionlistint int to allow lists of integers to

b e passed to that routine within the routine collectionc e would refer to listint

Another dierence b etween descriptive classes and types is that instance statements can dene

ifandonlyif relationships among types Sandb erg describ es a descriptive class pane for panes in

CHAPTER POLYMORPHISM MECHANISMS

a window system and a type generator mergefg which is a type of pane with two subpanes of

types f and g A single instance statement can declare that any instance of merge is a pane if and

only if its two argument types are panes Presumably int is not a pane and hence mergeint

int would b e a legal type but would not b e a pane This is an intriguing capability but it is

hard to see how it can b e used If the arguments of merge are not panes then how can routines

with merge parameters make use of them Note that this is not a hypothetical example it is

taken from a windowing system written in X

Descriptive classes resemble Fb ounded quantication in that collectionc e resembles

the type expression

type Collectionc e haddec removeec i

An instance statement establishes a relationship that resembles subtyping A routine to count

the elements in a collection has similar types in either system

procedure countpcollectionc e returns int

where c e are free

begin

end count

count e c Collectionc e pc

Descriptive classes are like abstract sup erclasse s in that they dene interfaces but not imple

mentations An instance statement corresp onds to inheritance from an abstract sup erclass A

p olymorphic routine with descriptive class parameters can call routines declared by descriptive

classes which provides dynamic binding and the p olymorphic routine can b e applied to any type

that satises the descriptive class which is similar to inheritance of metho ds dened in abstract

sup erclasse s Types can satisfy many descriptive classes which is like using multiple inheritance

but without the problem of resolving conicts among inherited denitions but only b ecause no

class variables or metho ds are inherited

Sandb erg argues that descriptive classes and parameterized types lack many of the drawbacks

of class hierarchies There is no xed class hierarchy just instance statements that relate types

and descriptive classes within a scop e so dierent parts of a program can easily set up dierent

CHAPTER POLYMORPHISM MECHANISMS

relationships Descriptive classes can b e dened indep endently of the types that satisfy them and

can have smaller scop es sub classes can not b e dened b efore their sup erclasses

Descriptive classes have two other p oints in their favor First programmers can extend types

with new routines at any p oint so X has b etter incrementality than record subtype languages

Second op erations declared in descriptive classes are naturally covariant instead of contravariant

However descriptive classes provide only a twolevel hierarchy types and descriptive classes

Descriptive classes can not b e arranged in sub class hierarchies there is no way to state that

a numeric descriptive class is like the ordered class with extra arithmetic op erations Instead

logicallyrelate d descriptive classes must contain identical copies of declarations instead of sharing

them Similarly types that satisfy a class do not automatically satisfy classes at logically higher

levels so programs must contain multiple instance statements to dene all of the relationships

that are needed

Another dierence is that descriptive classes do not provide any supp ort for type denition via

inheritance This is a restriction on reusability but a minor one since programmers can simulate

inheritance by declaring a eld of the parent type inside the child

Sandb erg leaves a number of interesting questions undiscussed

What are Xs restrictions on type parameter inference Are either of these legal

procedure piint returns T where T is free

procedure piint returns orderT where T is free

Do es X supp ort p olymorphic data The metho d describ ed on page dep ends on the

ability to dene routine values that refer to nonlo cal data X may not provide that facility

A program may need a version of a p olymorphic routine that has b een sp ecialized for a

particular type for instance for use as a pro cedure argument or in an instance statement

Must a programmer write this sp ecializati on or can sp ecializati on happ en implicitly

Can the parameter of a type generator b e a descriptive class This seems obviously desirable

but if it is p ossible then surely merge would b e declared to take only pane parameters and

then Sandb erg would not have comp osed his ifandonlyif example

Parameterized Mo dules

Many programming languages provide some form of module a programming language construct

that contains denitions of routines types variables constants etc This provides grouping and

CHAPTER POLYMORPHISM MECHANISMS

also controls the name space of a program since entities with the same name that are dened

by dierent mo dules can b e distinguished easily Examples of mo dules include the Mesa program

module the Ada package the SML structure and the OBJ object

obj PAIR is

extending INT BOOL

op x Int

op y Int

op lt Int Int Bool

vars i i Int

eq lti i i i

eq x

eq y

endo

The mo dule PAIR uses two other mo dules INT and BOOL which dene the types Int and Bool

The lines b eginning with op dene integer values named x and y and a routine named lt The

vars line declares variables used in the denitions of lt The rst eq line declares that for any

two integers i and i lti i has the value i i The other eq lines dene the values

of x and y

The other p ortions of a program use mo dules indirectly via module interfaces which declare the

facilities that the mo dules make available The items that are dened by mo dules but not declared

by any interface are inaccessibl e outside of their mo dule hence interfaces provide encapsulation

An interface is called a denition module in Mesa a package specication in Ada a signature in

SML and a theory in OBJ

th LTPAIR is

extending BOOL

sort T

op x T

op y T

op lt T T Bool

vars t t T

eq ltt t not ltt t endth

CHAPTER POLYMORPHISM MECHANISMS

This interface declares a type a sort in OBJs terminology called T two values of type T called

x and y an lt routine for type T and a logical condition that lt must satisfy When Int is used

for T PAIR matches this interface

2

Ada SML and OBJ also provide parameterized mo dules Ada generic packages can have

data routine and type arguments SML functors and OBJ parameterized ob jects take mo dules

as arguments and use mo dule interfaces as their parameter types The op eration of instantia

tion substitutes arguments for the parameters to pro duce an ordinary mo dule Instantiation is a

static pro cess not part of the execution of the program all arguments must b e constant

Parameterized mo dules provide p olymorphism at two levels At the level of the mo dules

contents a parameter of a mo dule denes a common structure that all arguments must have and

the contents of the mo dule are welldened for any such argument In eect the parameters of the

mo dule b ecome parameters of the contents and the contents exhibit parametric p olymorphism

Instantiation sp ecialize s the contents At this level of p olymorphism the p olymorphic minimum

routine would b e placed in a parameterized mo dule

obj MINOLTPAIR is

op min TO TO TO

vars t t TO

eq mint t if ltOt t then t else t fi

endo

OBJs dot notation reverses the usual convention TO is the sort T dened in parameter

O This diers from universal quantication in that it is not part of the type system The min

routine do es not have a type and in fact can not b e used directly a program that uses min must

rst instantiate MIN with an argument mo dule to pro duce a monomorphic routine which can b e

applied to data values

The other form of p olymorphism o ccurs at the higher mo dule level an SML functor or an

OBJ parameterized ob ject is a function from ob jects to ob jects and instantiation plays the

role of a routine call Polymorphism at this level is used to build large programs by comp osing

them from smaller mo dules The rules for matching mo dules and interfaces provide an inclusion

p olymorphism mechanism that resembles record subtyping and any ob ject that matches the

parameter interface is a valid argument In SML curtailment allows a structure to match a

2

Most ob jectoriented languages use classes provide name space control grouping and encapsulation and hence do not supp ort mo dules Eiel extends this approach and provides parameterized classes

CHAPTER POLYMORPHISM MECHANISMS

signature that lacks some of the structures contents or that has weaker relationships b etween

them In OBJ a view do es the same and also renames the ob jects contents to corresp ond to a

theorys contents names as well

th T is

sorts U V

op x U

op y V

endth

view PAIRT of PAIR as T is

sorts U to Int V to Int

endv

The view PAIRT describ es how mo dule PAIR can match interface T use x and y ignore lt and

use Int for U and V This view of PAIR weakens the relationship b etween the types of x and y and

hides lt OJB also provides default views in cases where the corresp ondence b etween a theory

and an ob ject is suciently obvious the match b etween PAIR and LTPAIR do es not require an

explicit view statement

Mo dulelevel p olymorphism can b e used to dene a minimum function on the contents of

an LTPAIR ob ject

obj MINOBJOLTPAIR is

op m TO

eq m if ltOxO yO then xO else yO fi

endo

Recall that record subtyping weakens type matching Similarly mo dule views weaken theory

matching This is imp ortant b ecause in programs built from layers of mo dules it may b e nec

essary that middlelevel mo dules share the same lowerlevel mo dules a compiler would normally

require that its scanner mo dule and parser mo dule use the same token type Without theory

matching this can not b e done Both SML and OBJ have extra facilities to solve this prob

lem SML provides a sharing declaration which states that two mo dules or two types dened

in mo dule arguments are the same A compiler mo dule written in SML would declare that its

scanner and parser arguments share their token types OBJ provides parameterized theories for the same purp ose

CHAPTER POLYMORPHISM MECHANISMS

th TOKEN is

sort Token

endth

th SCANNERTTOKEN is endth

th PARSERTTOKEN is endth

obj COMPILERTTOKEN SSCANNERT PPARSERT is endo

COMPILER takes as its rst argument a mo dule that matches TOKEN and substitutes it into SCANNER

and PARSER to pro duce the theories that S and P must match Hence the scanner and parser

arguments must use the same Token sort COMPILER exhibits parametric p olymorphism at the

mo dule level instead of at the mo dulecontents level

SML provides a third level of p olymorphism indep endent of the mo dule system A routine

that returns the smaller of two data arguments can b e written

fun min lt x y if ltxy then x else y

This declaration omits type information but the routine has a static type none the less SML

systems infer the type from the b o dy of the routine in this case min has a type parameter called

a and has type a a bool a a a for any type a SML systems also infer

type arguments in the expression min op inference gives a the value int op

returns the less than op eration for integers Mitchell and Harp er show that at this level

SML can b e treated as an abbreviated form of an explicitly typed parametrically p olymorphic

language similar to Girards and Reynolds lambda calculus but with the restriction that routines

can not have p olymorphic arguments hence I will not discuss this level of p olymorphism any

further

The greatest weakness of parameterized mo dules is that the p olymorphism that they provide

is strictly a static phenomenon There are no executable mo dulevalued expressions the mo dule

expressions of SML and OBJ build new mo dules from old ones prior to program execution All

entities involved in executable expressions are monomorphic p erhaps pro duced by instantiation

SML provides no sharing declarations for values or routines since it can not statically check

the equality of dynamicallycomputed values Since there is no dynamic rebinding of mo dule

CHAPTER POLYMORPHISM MECHANISMS

identiers mo dules do not provide p olymorphic data even though views can hide information

ab out the types of a mo dules constants

Given this limitation parameterized mo dules still provide useful p olymorphism They al

low strong static checking of types at the mo dulecontents level and of mo dule interfaces at the

mo dule level They are ecient b ecause entities involved in executable expressions are monomor

phic They separate interfaces and implementations at the contents and the mo dule levels Type

matching exists at the contents level and although it do es not exist at the mo dule level SML and

OBJ provide other facilities to ll the gap At the contents level parameterization allows much

the same language simplications as was the case for universal p olymorphism Parameterized

mo dules provide high generality since they can dene exactly the types and op erations that they

need They are somewhat generalizable since a parameterized mo dule can replace an existing

parameter interface with one that contains fewer declarations or has weaker relationships b etween

declarations but it can not increase its generality by adding new declarations without aecting

clients Finally they lack incrementality just as records do incrementally extending a mo dule to

match some theory would require building a new structure with extra declarations

Summary

Polymorphism is the ability to implement a notion so that it applies to more than one type Two

main categories of p olymorphism mechanisms exist Adhoc polymorphism is present when an

implementation has one or more interfaces that are dened for a set of types which need not have

any common structure Universal polymorphism is present when an implementation has a single

interface that is applicable to a p otentially innite set of types dened by a common structure

Universal p olymorphism in turn has two sub categories A routine exhibits parametric polymor

phism when the value of a parameter denes other parts of the routines interface Inclusion

polymorphism is present when an identier can b e b ound to values from a p otentially innite set

of types with a common structure

Three distinct mechanisms can provide adhoc p olymorphism in a programming language

Overloading lets programmers dene several implementations of a notion and chooses among

them based on the context of each use of the notion Transfer functions implicitly convert an ar

gument in a routine call to the type of the routines parameter Settheoretic unions are dened in

terms of member types and can take on any value from those member types All three are reason ably ecient and allow strong static checking and separation of interfaces from implementations

CHAPTER POLYMORPHISM MECHANISMS

All three provide at most mo dest increases in generality generalizabili ty and incrementality

Overloading and settheoretic unions allow simplication of programming languages by allow

ing the language to present certain notions as library facilities instead of as sp ecial language

constructs Overloading allows precise interface denitions b ecause it provides type matching in

interfaces Expressiveness increases b ecause one name can b e used for many implementations of

a notion This lets programmers write algorithms in terms of those notions instead of distinct

implementations of the notions

However programmerdened adhoc p olymorphism provides only mo dest improvements b e

cause the set of applicable types must b e explicitly sp ecied and hence is nite This is not

true for languagedened p olymorphism A language can implement a notion for an innite set of

types Consider assignment which works on an innite set of assignable types For most lan

guages the common structure of these types if there is any is not expressible in the language so

adhoc p olymorphism is present Hence implementations of notions that use these mechanisms

will not necessarily b e usable with types dened afterwards even if the notion is appropriate for

those types DOUBLE can not b e applied to a new COMPLEX type even though fractions can b e

doubled

Two mechanisms provide inclusion p olymorphism Innite unions provide a type that contains

all values of all other types the generality of this type means that almost nothing can b e done

with instances of it Hence any op erations that must b e p erformed on values passed to a para

metric routine must b e passed along with the value as separate parameters or as elds of a data

structure Record subtyping denes subtype relationships among record types and among routine

types and allows routine elds of records to refer to the record through a sp ecial identier such as

self The record elds conveniently package values and op erations on the values This approach

provides strong static checking separation of implementations from interfaces generality and gen

eralizabili ty simpler base languages and p olymorphic data with reasonable eciency However

it provides only weak incrementality and do es not allow type matching The subtype rule for

routines is contravariant and this limits expressiveness Languages based on record subtyping

often combine co de reuse encapsulation and subtyping in the class construct which further

limits expressiveness and exibility

Parametric p olymorphism also provides strong static checking simple base languages and sep

aration of interfaces from implementations with reasonable eciency The simplest form universal

quantication allows routines to have type parameters This provides generality incrementality type matching and p olymorphic data through an awkward enco ding but again it b ecomes awk

CHAPTER POLYMORPHISM MECHANISMS

ward to pass op erations along with the values they op erate on Fb ounded quantication sp ecies

a type expression that type arguments must b e subtypes of this directly provides p olymorphic

data and allows programmers to package values and their op erations in the manner of record

subtyping but with the advantage that the op erations can exhibit covariance However this pack

aging reduces incrementality and exibility and subtyping reduces type matching Both forms of

type quantication lack generalizabili ty Automatic inference of type arguments and their asso

ciated op erations provides generalizabili ty while preserving the prop erties of incrementality and

type matching Compared to the inclusion p olymorphism languages however parametric p oly

morphism with argument inference lacks a mechanism for abstracting over types and op erations

The X language provides such a mechanism in its descriptive classes however X attempts

to combine descriptive classes with types and do es not allow for hierarchies of abstractions A

parameterized mo dule is another such mechanism but mo dules are completely static entities and

like the records that they resemble they limit generalizability and incrementality

Chapter

Contextual Polymorphism

This chapter prop oses a new p olymorphism mechanism contextual polymorphism that addresses

the weaknesses of the mechanisms describ ed in the previous chapter It is based on parametric

p olymorphism and therefore provides precise types generality incrementality and generaliz

ability It extends parametric p olymorphism with contexts which represent notions within the

programming language

A context is an abstraction of a collection of declarations Typically the declarations are

related in some way they might declare op erations and constants asso ciated with some notion

Contexts have type parameters and if the type generators of the programming language can

take arguments whose types are ordinary data types then contexts can have parameters of those

types for instance in a language with array types indexed by integers contexts can have integer

parameters Any form of declaration provided by the language might b e allowed in the b o dy of

a context routine and ob ject declarations are most useful but there is no reason to exclude type

declarations

An assertion pro duces a collection of declarations typically by applying contexts to arguments

It asserts that the declared identiers exist and have the declared types and kinds Typically

assertions are used to declare that some type implements a notion

Denition of Contexts and Assertions

3

The sections that follow give a formal explanation of contexts and assertions in terms of F an

explicitl ytyped p olymorphic lambda calculus based on F which is a variant of Girards innite

CHAPTER CONTEXTUAL POLYMORPHISM

Kinds k k the kind of term types

i

j t k 3 k the kind of type generators

1 2

Type variables t t

i

Types t simple types

i

j function types

1 2

j t k 3 universally quantied types

j t k type generators

j type generator application

1 2

j

Environments the empty environment

i

j x term variable declarations

j t k type variable declarations

j t k contexts

j context application

j environment concatenation

1 2

j

Term variables x x

i

Terms e e x

i

j x e functions

j e e function application

1 2

j t k 3 e p olymorphic functions

j e type application

j e

3

Figure The abstract syntax of F

CHAPTER CONTEXTUAL POLYMORPHISM

3

order p olymorphic lambda calculus The abstract syntax of F is given in gure Each

rule of the syntax denes a grammar symbol some syntactic variables that represent instances

of the symbol and the pro ductions for that symbol if it has any The unusual features of the

syntax are the two symbols 3 which introduces assertions and should b e read as such that and

which introduces contexts

The calculus has a number of rules for static checking An expression that passes these checks

is evaluated by rep eated application of two reduction rules for function application and type

application

x e e e x e

1 2 1 2

0

et t k 3 e

where l m n denotes the substitution of n for all free o ccurrences of m in l with renaming

of variables in l to avoid the capture of variables that are free in n reduction corresp onds to

execution of ordinary programs

Types and Kinds

3

F asso ciates types with every value Besides simple types function types and universally quan

3

tied types F has type generators which are functions from types to types The programming

language might provide predened simple types such as Integer and predened type generators

such as List which would take a type argument and return the type of homogeneous lists of the

argument type List Integer is an example of type generator application and has as its value

the type of lists of integers

3

F also asso ciates a kind with every type Kinds provide information ab out the parameters

of type generators and allow checking of type generator application in the same way that types

allow checking of function application The kind is the kind of the term types types with no

parameters every term has a type and that type has kind For instance the term has type

1

Integer which has kind Type generators take type arguments so their kinds involve

just as p olymorphic routines take type arguments and have types that involve List has kind

t 3 since it takes a term type as an argument and returns a term type The signicance

of 3 is explained b elow

1

In most lambda calculi type generator kinds use ! instead of 8 in analogy with function types Lists kind

would b e ! The 8 notation used here inspired by provides a name for the type parameter and the assertion can use that name

CHAPTER CONTEXTUAL POLYMORPHISM

Environments Contexts and Assertions

An environment relates term variables to their types and type variables to their kinds The

simplest environment is the empty environment which contains no information Other envi

ronments contain declarations A declaration has the form t k which declares that type variable

t has kind k or x where which declares that term variable x has type The domain

of an environment dom is the set of type and term variables it declares

The op eration of environment concatenation combines two environments that have no variables

in common

i dom dom

1 2 2 2 1 2

Concatenation asso ciates left to right Since the two environments

1 2 3 1 2 3

declare distinct variables certain absurdities caused by redeclaration of type variables can not

o ccur For instance t x t t u 3 is undened so the question of xs type in

that environment do es not arise It might b e p ossible to allow redeclaration of term variables

while forbidding redeclaration of type variables but treating all variables consistently provides

simplicity

Despite this restriction on environment concatenation lambda expressions may redeclare vari

ables b ecause the type and kind checking rules allow consistent renaming of b ound variables the

expression x x x is legal b ecause y x x is

1 2 1 2

Contexts and assertions are the most complex environment comp onents and are the distin

3

guishing features of F A context t k abstracts from the declarations in the environment

2

which may make use of the type parameter t Normally the parameters of contexts have kind

but higher kinds are allowed in those cases the argument must b e a type generator instead

of a type

An assertion 3 pro duces a collection of declarations called assertion declarations typically

by applying a context to a type Polymorphic routines and type generators and their types and

kinds use them to constrain their arguments The trivial assertion 3 pro duces no declarations

The type generator List has kind t 3 b ecause it takes a term type argument places no

constraints on it and pro duces a term type

3

Contexts and context application play no part in the evaluation of F expressions like ordi

nary environments they are part of the static typechecking rules of the language The value

2 3

Since type generators in F only take types as arguments contexts only have type parameters A formal

!

explanation of contexts in languages where type generators also take type arguments might b e based on the

Calculus of Constructions instead of F

CHAPTER CONTEXTUAL POLYMORPHISM

of a context application t k is the substitution t Rep eated application of this

substitution converts environments that contain context applications to normal forms that contain

only concatenated declarations

NF NF N F

1 2 1 2

NF t k NF t

1 1

NF otherwise

The following environment contains a context that abstracts some declarations asso ciated with

the notion b o olean type and uses it to pro duce declarations of those op erations on the type

Bit

Bit t and ttt or ttt not tt true t false tBit

For the sake of readability most examples b elow use the context statement

context x in e

which means ex

context boolean t and t t t or t t t

not t t true t false t

in Bit 3 boolean Bit

Judgements

3

Environments are used to typecheck F programs A type judgement has the form e and

means that e has type given the environment Similarly the kind judgement t k means

that type t has kind k given

Environments used in type and kind judgements must meet certain conditions variables must

b e declared only once the type of every term variable must have a kind and every context must b e

3

applied to an argument of the right kind Therefore F needs a mechanism for checking the kinds

of context arguments just as types and kinds allow for the checking of arguments of functions

and type generators The mechanism is the context sort

Context sorts 2 the sort of environments

i

j k the sort of contexts

An environment that may b e used in judgements has sort 2 By denition has sort 2 A

context whose parameter is a type of kind k has the sort k

CHAPTER CONTEXTUAL POLYMORPHISM

The sort judgement states that given the environment with sort 2 environment

1 2 1

has the context sort

2

The rst two sort checking rules state that t k is an environment and that x is an

environment if has kind

t k 2

1

x 2

1

The next two rules deal with context formation and application They state that a type

argument of a context must have the same kind as the contexts parameter and that the parameter

is part of the environment of the contexts b o dy

k k

1 1 2

1 2

t k

1 2

t k k

1 2

The nal rule applies to environment concatenation Again the concatenated environments

must declare distinct variables

2 dom dom

1 2 1 2

2

1 2

Type Judgements

This section gives the type checking rules for terms Recall that the environment used in a type

judgement e t must have sort 2

The rst rule states that a term variable has the type given by the environment

2

if x NF

x

The next rules dene the types of functions and function applications They state that the

type of a functions argument must match the parameter type and that the parameter declaration

is part of the environment of the functions b o dy

e e

1 2 1 2 2

e e

1 2 1

x e

1 2

x e

1 1 2

CHAPTER CONTEXTUAL POLYMORPHISM

Polymorphic functions t k 3 e use assertions to constrain the type or type generator

variable t by declaring identiers that use it in their types The type checking rule for p olymorphic

functions adds the assertion declarations to the environment of the function b o dies

t k e

1 2

t k 3 e t k 3

1 2 2

Note that by the denition of concatenation t k e requires that t k 2

1 2 1 2

and that and t k have no declarations in common

1 2

The rule for calls to p olymorphic functions checks that the type argument has the same kind

as the functions parameter substitutes the type argument for the functions parameter in the

assertion declarations and checks that the resulting declarations exist in the environment of the

call

k e t k 3 t

1 1 1 2 2 2 1 1

e t

1 1 2 1

When a p olymorphic function applies a context to its type argument and the calling environment

contains the assertion declarations the type argument is said to satisfy the assertion

Most examples b elow use the let statement let x e in e which means x

1 2

e e Since is always e s type many examples omit it when it is irrelevant cumbersome

2 1 1

or obvious from insp ection of e

1

The denition of the let statement uses function application b ecause the expression e can

1

b e calculated when the program is evaluated In contrast the denition of the context statement

uses substitution b ecause contexts are strictly compiletime phenomena and hence vanish b efore

function application o ccurs

Consider this example which denes a p olymorphic routine that doubles its argument

context addable T plusT T T in

let plus xInteger yInteger x y in

let double T 3 addable T xT plus x x

in doubleInteger

Static checking requires the substitution of addable and application to its argument

let plus xInteger yInteger x y in

let double T 3 plusTTT xT plus x x

in doubleInteger

CHAPTER CONTEXTUAL POLYMORPHISM

A plus routine for Integer exists in the environment of the call to double so Integer is a legal

argument for double reduction of double and the rst argument gives

let plus xInteger yInteger x y

in xInteger plus x x

Note that after this reduction the use of plus in the b o dy of the p olymorphic routine refers

to the plus dened in the calling environment The assertion has the eect of connecting the

routines b o dy to the calling environment

Since substitution renames variables to avoid capture of free identiers the declarations in a

context are unaected by declarations in inner scop es For instance the p erverse example

context c T fT Integer

in Integer T 3 c T eBoolean

redenes Integer However it is equivalent to

t T 3 fT Integer eBoolean

and hence the redenition do es not aect the use of Integer in c In contrast if contexts were

simply expanded like macros the redenition would have aected the use of c

Kind Judgements

This section gives the kind checking rules for types Again the environments used by kind

judgements must have sort 2

The rst three rules state that type variables have the kind given by the environment and

that function types and universally quantied types are term types

2

if t k NF

t k

1 2

1 2

t k

1 2

t k 3

1 2

Type generators use assertions to constrain their arguments just as p olymorphic functions use

assertions to constrain their type arguments The kind checking rules for type generators require

CHAPTER CONTEXTUAL POLYMORPHISM

that the argument of a type generator have the same kind as the type generators parameter and

that the environment of a type generator application contains the assertion declarations much as

was the case for type applications

t k k

1 1 2 2

t k 3 t k 3 k

1 1 2 1 2 2

k t k 3 k t

1 1 1 1 2 1 2 2 2 1 1

k

1 2 1 2

The type statement type t in e is a synonym for et It do es not provide an

abstract type facility b ecause it substitutes into e b efore the type rules can b e applied and so

all implementation details are visible to e

type SortedList T 3 lt T T Boolean

T 3 lt T T Boolean List T in

let primes SortedList Integer e

1

in e

2

The assertion declares that the argument of SortedList must b e a type with a lt function so the

environment of the declaration of primes must contain a declaration of ltIntegerIntegerBoolean

This constraint on type arguments resembles the prop erty lists of parameters of the form type

generator in Alphard p or the where clause of a parameterized Clu cluster

Note that the declaration of primes do es not bind the current value of lt into primes

let insert T 3 lt TTBoolean vT lSortedList T

lt v head l in

let lt xInteger yInteger gt x y in

in insertInteger primes

Because of the rules of function application the lt routine that is called by insert is the one

visible at the call site which is actually an alias for gt not the one visible at the declaration of

primes

Sp ecialization

The typechecking rules given ab ove require that for each x in an assertion there b e an x

in the environment of the call and that the two types match exactly after the substitution of

CHAPTER CONTEXTUAL POLYMORPHISM

type arguments It may happ en that the environment contains an x that do es not have type

but do es have a p olymorphic type and that binding some of its type parameters can create a

sp ecializ ation to For instance

let f T 3 gT T pT e in

1

let g S3 S S

S3 xS e

2

in fInteger

do es not typecheck b ecause the g visible at the call site do es not have type Integer Integer

instead it is p olymorphic A programmer who wishes to use g must rst sp ecialize it for the type

Integer

let f T 3 gT T pT e in

1

let g S3 S S S3 xS e in

2

let g Integer Integer gInteger

in fInteger

The call to g in the inner g is not a recursive call gInteger is evaluated outside of the scop e

of the inner declaration of g by the denition of let If sp ecializati on must remove some type

parameter other than the rst a slightly more complex expression will suce

let h T3 T3 T T

T3 T3 e in

1

let h T3 T Integer

T3 hTInteger

in e

2

Sp ecialization can remove assertion declarations as well as type parameters In this example

the inner g removes x from the outer gs assertion by binding in a call to the p olymorphic x The

result can b e passed to f which requires an argument that has no assertion declarations

let f gT3 T T e in

1

let g T 3 xT T T T

T 3 xT T yT e in

2

let x T 3 T Te in

3

let g T3 let xT T xT in gT

in f g

CHAPTER CONTEXTUAL POLYMORPHISM

This situation is a mo dest improvement over the corresp onding situation in programming

languages with plain universal quantication since in those languages the sp ecialization must

app ear as an explicit parameter However the necessity of creating the sp ecializati on still hamp ers

generalizabil ity since generalizing a routine may force many clients to create sp ecializati ons

Furthermore since the routine do es not app ear as an explicit argument lo cating these clients

will b e dicult

Argument Inference

3

F as dened ab ove requires that type arguments of p olymorphic functions app ear explicitl y

and it requires explicit denition of sp ecializations It also do es not allow overloading of term

variables All three of these restrictions can b e removed by applying an algorithm like the one for

ForceOnestyle languages describ ed by Cormack and Wright and Bumbulis which was mentioned

3

in section Programs written in F can b e converted to the desired form by rewriting their

assertion declarations as implicit parameters and then the CormackWrightBumbulis algorithm

can b e applied to the result

Once overloading is allowed the denition of environment concatenation reduces to simple set

union If two environments b eing concatenated declare the same term variable with the same type

or the same type variable with the same kind the union op eration combines the declarations

If they declare the same variable with dierent types or kinds the union op eration preserves

b oth declarations and overload resolution distinguishes b etween them

Type argument inference emphasizes the dierence b etween binding and binding of type

parameters arguments to b ound parameters may b e inferred but arguments to b ound pa

rameters must always b e sp ecied explicitly

Use of Contexts and Assertions

Guidance

A programming system that provides contexts will over time build up a library of contexts that

represent useful notions These contexts can guide programmers who wish to implement other

related notions This guidance has three asp ects

It sp ecies the complete set of op erations that are necessary to implement the notion

CHAPTER CONTEXTUAL POLYMORPHISM

It gives the required names and types of the op erations This information is crucial in a

p olymorphism system based on overloading

It gives information ab out programming style Consider the notion stack of integers and

a p ossible implementation in the C programming language that uses linked lists

struct element f

int i A value on the stack

struct element next Next stack element

g

typedef struct element IntStack

The push op eration might b e implemented in a functional style where it returns a new

stack with a new value on top

IntStack pushIntStack s int v f

IntStack newelt mallocsizeofstruct element

newelti v

neweltnext s

return newelt

g

It might also use an ob jectoriented style where it mo dies an existing stack and returns

nothing

void pushIntStack sp int v f

IntStack newelt mallocsizeofstruct element

newelti v

neweltnext sp

sp newelt

return

g

These styles pro duce dierent contexts since the types of the op erations dier If program

mers stick to the style describ ed by available contexts when they implement related notions more opp ortunities for reuse will o ccur

CHAPTER CONTEXTUAL POLYMORPHISM

Abstract Sup erclasses

Contexts resemble pure abstract sup erclasses in that they dene interfaces of instances of types

not implementations of types An assertion that a type satises a context serves many of the

same purp oses as a declaration that a class inherits from an abstract sup erclass However type

declarations do not explicitly list the contexts that they satisfy so new contexts can b e added

to describ e existing types and new op erations can b e added to allow existing types to satisfy

existing contexts Also contexts do not force op eration types to follow a contravariant pattern

Given the context

context addable T plusT T T

the assertions addable Integer and addable Fraction would pro duce the covariant declara

tions

plusInteger Integer Integer

plusFraction Fraction Fraction

Contravariant routine subtype rules force abstract sup erclassbase d system to use imprecise dec

larations

Addable h plusAddable Addable i

Integer h plusAddable Integer i

Fraction h plusAddable Fraction i

The subtypestyle declarations also allow mixedmo de op erations with their b enets and di

culties The addable context do es not mixedmo de addition op erations would require a more

complex multiparameter context

Contexts and p olymorphic routines can b e used in the manner of impure abstract sup erclasses

to help programmers to provide full implementations of notions Consider collection which

declares useful op erations and values for collection types C with element type E

context collection C E

nil C An empty collection

isempty C Boolean Is the collection empty

add C E C Add an element to a collection

CHAPTER CONTEXTUAL POLYMORPHISM

drop C C Remove front from the collection

front C E Return an arbitrary element

map C E E C Apply a function to every element

The map op eration can b e implemented using the other op erations The basic op erations can

b e abstracted into a second context collectionbase and a p olymorphic map routine can use

collectionbase

context collectionbase C E

nil C

isempty C Boolean

add C E C

front C E

drop C C

in let map C3 E 3 collectionbase C E

cC fE E e

1

in e

2

A programmer implementing a new collection type would only have to write the routines named

by collectionbase the type would satisfy collection b ecause the p olymorphic map can b e

sp ecializ ed for it The programmer might still choose to write a typesp ecic version of map for

eciency reasons

In a classbased language a programmer can use multiple inheritance from several abstract

sup erclasse s as a way of dening a class that has several interfaces Each interface provides a

dierent view of instances of the class for use by dierent clients The equivalent situation in

3

F is a type that simultaneously satises many contexts A buer type could satisfy pro ducer

and consumer contexts a library type could have dierent views for clients that use the type

directly and for clients that extend the type to create new types In the case of the class the

3

set of interfaces is limited by the set of sup erclasses in the classs declaration while in F an

existing type can satisfy newer contexts Furthermore when multiple inheritance is used the

problem of multiple inherited implementations of a single entity arises This problem do es not

o ccur with contexts b ecause contexts only contain declarations there is no need to select or

combine implementations

Finally the collection context ab ove describ es a relationship b etween two types instances

of type C contain elements of type E It do es not corresp ond to any single abstract sup erclass

CHAPTER CONTEXTUAL POLYMORPHISM

instead it corresp onds to a family of abstract sup erclasses with distinct element types An ob ject

oriented language with parameterized classes could imitate collection by declaring a parameter

ized abstract sup erclass for collections corresp onding to collections C parameter that takes

an element type corresp onding to the E parameter as an argument However contexts can

describ e relationships among types that parameterized classes can not express in a natural way

One example is a transitive conversion relationship

context tcvt A B C cvt A B cvt B C in

let cvt A3 B3 C3 tcvt A B C

aA cvt cvt a

Position and oset types provide a second example A p osition value marks a place along

a dimension An oset value represents the distance b etween two p ositions Calendar dates are

p osition values where the osets represents a number of days Similarly memory addresses are

p osition values where the osets represent numbers of bytes Only certain op erations b etween

p ositions and osets are meaningful

context dimension Position Offset

Position Offset Position

Offset Position Position

Position Offset Position

Position Position Offset in

dimension Date Day

dimension Address Integer

Context Hierarchies

Since assertions are environments they can sensibly app ear in the b o dies of contexts For example

collection can b e rewritten as

context collection C E

collectionbase C E

map C E E C

This pro duces the same set of declarations as the original version of collection It pro duces

a set not some sort of nested structure b ecause the concatenation op eration pro duces the union of its op erands

CHAPTER CONTEXTUAL POLYMORPHISM

The use of one context in another creates hierarchies of contexts which reect relationships

b etween the corresp onding notions This resembles the use of inheritance in ob jectoriented

languages to create hierarchies of abstract sup erclasses The child context contains and hence

reuses the declarations in the parent contexts Multiple inheritance corresp onds to the use of

more than one assertion but once again the problem of multiple inherited implementations of an

entity do es not arise

Abstract Types

Recall that the type statement do es not provide an abstract type facility However within the

b o dy of a p olymorphic function t 3 e the type t app ears to b e a primitive type even

though the type argument passed to it need not b e Reynolds used this as the basis of an

abstract type facility A program that uses an abstract type is treated as a p olymorphic routine

parameterized by the abstract type Op erations on the type are treated as function parameters

of the program The implementation of the abstract type and the routines that implement its

op erations are passed as arguments to the program The program

abstype Complex with plusComplex Complex Complex

in let c Complex in

let c Complex in

plus c c

is h reReal imReali

with plus x Complex y Complex e

1

3

would b e mo deled in F by

Complex3 plusComplex Complex Complex

let c Complex in

let c Complex in

plus c c

hreReal imReali

xhreReal imReali yhreReal imReali e

1

Assertions allow a mo died version of this scheme The abstract type is still represented as

a type parameter but its op erations are declared by an assertion which denes op erations that

can b e p erformed on the abstract type it is similar to an import statement

CHAPTER CONTEXTUAL POLYMORPHISM

abstype Complex 3 addable Complex

in let c Complex in

let c Complex in

plus c c

is h reReal imReali

with plus x Complex y Complex e

1

3

The translation of this sort of program into F is more complex b ecause the type parameter

must b e passed to the program within a scop e where the assertion declarations are dened It

would b e mo deled by

let plus x hreReal imReali

y hreReal imReali e

1

in Complex 3 addable Complex

let c Complex in

let c Complex in

plus c c

hreReal imReali

Existential Types

Mitchell and Plotkin describ e a connection b etween abstract types and existential types

which have the form t The intuitive meaning of x t is that some unknown type with

kind exists such that if it were named t then x would contain a value of type Mitchell and

Plotkin treat t as an abstract type and use a tuple or unlab eled record type for then the

tuple elds are op erations on and values of the type A data algebra is a value that has an

existential type It contains implementations of the abstract type and the values and op erations

in A pack expression creates data algebras out of implementations of the abstract type and

the tuple elds A variant of abstype explo des data algebras and gives a name to the type and

to each tuple eld Using these facilities the complex example used ab ove b ecomes

abstype Complex

with plusComplex Complex Complex

in let c Complex in

let c Complex in

CHAPTER CONTEXTUAL POLYMORPHISM

plus c c

is pack h Real Reali

x hReal Reali y h Real Reali e

1

to t ht t ti

Data algebras are rst class values that can b e passed as parameters or returned from functions

In the example ab ove the pack expression could b e replaced by an expression that returns either

a p olar or a Cartesian implementation of complex numbers dep ending up on circumstances

Universally quantied types can enco de existential types using the technique mentioned on

page

let p t

1

pack e to t

2 1

b ecomes

let p r3 t3 r r

1

r3 ot3 r o e

1 2

The abstype statement has a more complex equivalent If the result of the statement

abstype a with x in e is e

2 1 2

has type and e has type t the equivalent is

1 2 2

e a3 v e

2 1 2 1

except that any reference to x in e must b e replaced by an expression that extracts the correct

1

eld from v

Given this equivalence it seems natural to use a slightly dierent form of existential type that

uses assertions

t k 3 r 3 t k 3 r r

1 1

pack e to t k 3 r 3 o t k 3 r o e

2 1 1 1 2 1

abstype t k 3 with x in e is e e t k 3 x e

1 3 2 2 3 1 3

where is the type of the contents of the data algebra is the hidden type and is the result

1 2 3

type of the abstype statement The assertion declarations pro duced by declare op erations on

CHAPTER CONTEXTUAL POLYMORPHISM

and values of the unknown type t just as some of the elds of a tuple type do in the traditional

existential type is made up of the remaining elds from the tuple it can b e viewed as a value

1

held inside the data algebra For instance a value of type t3addable t t contains a value

with a type that is unknown but is known to have a plus routine

The type and kind checking rules for existential types and data algebras follow from those for

universal types and p olymorphic functions and in fact are the same as those given by Mitchell

and Plotkin if the parts that deal with contexts assertions and kinds are ignored An existential

type is a term type b ecause the equivalent universal type is

t k

1 2 1

t k 3

1 2 1

The typechecking rule for the pack statement follows from the rules for the equivalent

expression The environment of a pack statement must contain the assertion declarations This

is analogous to the way that assertion declarations are checked against the calling environment

when a type is passed to a p olymorphic function

k e t t

1 2 1 1 1 2 2 2 1

pack e to t k 3 t k 3

1 2 1 2 1 2 1

Similarly the type rule for abstype follows from the rules for the equivalent type application

The abstype statement has an assertion that adds the assertion declarations to the environment

of its b o dy just as the assertion in a p olymorphic function adds to the environment of the function

b o dy It also declares a name for the value held in the data algebra

e t k 3 t k x e

1 2 2 1 1 2 1 3 3

abstype t k 3 with x in e is e

1 2 1 3 2 3

As in t must not b e free in or in the type of any variable other than x in e to ensure

1 1

that the representation of the abstract type do es not escap e from the abstype statement The

semantics of the mo died pack and abstype statements are that the values b ound to the assertion

declarations in the environment of pack are implicitly packaged in the data algebra and made

available in the b o dy of abstype In Mitchell and Plotkins original version those values had to

b e explicitly packed and unpacked

Existential types with assertions are not fundamentally dierent from ordinary existential

types but they encourage a dierent interpretation t h i can b e thought of as the type of or

the interface of a mo dule the elds of the tuple type are the op erations and values declared by

the mo dule and a data algebra with that existential type implements the mo dule The separation

of assertion declarations from the data p ortion of t 3 t suggests treating it as an unknown

CHAPTER CONTEXTUAL POLYMORPHISM

type t that is known to supp ort the op erations and constants in it denes a p olymorphic

data type whereas t 3 denes a p olymorphic routine type Between these two views lie

existential types with nontrivial assertions and with nontrivial b o dies that reveal some structure

given the declaration

xT 3 addable T hT Ti

we do not know the type of the elds of x but we know that they have exactly the same type

and that they can b e added together

A data algebra with a trivial b o dy t 3 t has an unknown type but a known set of op er

ations and therefore resembles an ob ject in an ob jectoriented language This can b e combined

with other type generators For instance List t3addable t t is a p olymorphic list type

where every element has an addable type but dierent elements can have dierent actual types

Programs that compute with data algebras tend to unpack manipulate and repack them

without making any mention of the hidden type For instance values of an existential addable

type can b e doubled by the routine

let double T 3 addable T T T 3 addable T T

xT 3 addable T T

abstype s with y T in

pack s plus y y to T 3 addable T T

is x

The verbosity of this example suggests that an abbreviation would b e useful The following open

statement rebinds the name of a data algebra so that it refers to the contents of the algebra and

repacks the result of an expression using the contents

x t k 3 t k x e

1 2 1 1 2 1 2

op en x in e t k 3

2 2 2

let double T 3 addable T T T 3 addable T T

xT 3 addable T T

open x in plus x x

CHAPTER CONTEXTUAL POLYMORPHISM

Inheritance

Assertions when used with type declarations provide a facility similar to subtyping The class

construct of ob jectoriented languages provides a second facility inheritance of routines and

elds Assertions can provide some supp ort for inheritancelike facilities by using them with type

denitions

Classes can b e simulated by record types and eld inheritance by having the child record

type contain an instance of the parent Routine inheritance can b e simulated by writing a

cover routine for the child type that extracts the parent eld and passes it to the inherited

routine

type Region h originPointi in

let move Region Point Region

rRegion pPoint in

type Rect hparentRegion bottomrightPointi

let move rRect pPoint move rparent p

This can b e automated by interpreting an assertion in the scop e of a type denition to b e a

declaration of routines that must b e dened in the scop e of the denition If the programmer

leaves some of the routines undened in that scop e then the language must construct cover

routines from similar routines that exist for its elds type

context region T moveT Point T in

type Region h originPointi in

let move rRegion pPoint in

type Rect 3 region Rect h parentRegion bottomrightPointi

In this case the move routine for Rect would b e created automatically b ecause the assertion

region Rect requires that it exist This is akin to the default denition of certain common

op erations such as assignment or equality comparisons to the way that Ada denes derived

routines for derived types x and to Wirths record extensions

Contexts and Polymorphism

Notions such as collection are useful b ecause of the op erations that can b e p erformed on them

Types that implement some version of the notion will implement the op erations with routines

CHAPTER CONTEXTUAL POLYMORPHISM

and corresp onding routines will have the same name and will have types that share a pattern of

argument and result types The declarations of these routines can b e abstracted into a context In

that case the context is a programminglanguage representation of the notion and an assertion

that a type satises the context also asserts that the type implements the notion Hierarchical

connections among contexts reect connections among the corresp onding notions

Contextual p olymorphism is a form of parametric p olymorphism where assertions dene the

structure that arguments are required to have It allows precise general denitions of interfaces

since assertions can describ e exactly what op erations a p olymorphic routine needs and b ecause

the use of named type parameters provides type matching An automatic type argument inference

and sp ecializ ation mechanism similar to that of ForceOne provides generalizability and incre

mentality Contexts do nothing to hinder the separation of routines and routine interfaces and

provide a way to sp ecify type interfaces separately from types by sp ecifying op erations supp orted

by the type Among its drawbacks are a lack of supp ort for data and routine inheritance and a

lack of direct supp ort for p olymorphic data Polymorphic data can b e provided indirectly through

the enco ding discussed in section or through some other facility such as an existential type

mechanism

Subtypes and FBounded Quantication

Contextual p olymorphism do es not involve any notion of subtyping However assertions are

related to the concept of subtyping If a context has one type parameter then all of the types

that satisfy it are in some sense subtypes of an imaginary type containing all of the values of

those types If this imaginary type is identied with the context then an assertion that a type

satises the context resembles a declaration that the type is a subtype of the imaginary type

However this analogy breaks down for contexts with more than one parameter Contexts can

express relationships that are more complex than is a subtype of

Contexts and assertions resemble Fb ounded quantications type functions and type b ound

expressions compare

context ordered T ltT T Boolean in

let min T 3 ordered T xT yT

if lt x y then x else y

in e and

CHAPTER CONTEXTUAL POLYMORPHISM

OrderedT hlt T Booleani

min T OrderedT xT yT

if xlt y then x else y

Both mechanisms constrain the types that are acceptable as arguments to the p olymorphic rou

tines b oth allow static type checking by dening a set of available op erations and values for the

type and b oth provide dynamic binding The types of the declared variables in the two cases

are similar considering that a record is an implicit parameter of its routine elds generally the

record type corresp onds to the type parameter of the context

However assertions are not record types they constrain argument types by dening declara

tions that must exist in the environment instead of elds that a record must have Hence the

declared variables are directly available through normal binding mechanisms instead of through

eld selection from a data parameter or a value that can b e computed from a data parameter

Consider the meaning of a plus op eration on lists of integers It might concatenate its arguments

or it might p erform pairwise additions on the list elements

let l List Integer in

let plus List Integer List Integer

concatenate arguments

in double l concatenates l to itself

let plus List Integer List Integer

add elements together

in double l doubles each element

In Fb ounded quantication plus must b e a eld of the List type The implementor of List

must choose one implementation for plus and either choice will b e wrong for some client of List

In fact using contextual p olymorphism a list could b e concatenated to itself in one part of a

program and doubled elementwise in another An equivalent program written using Fb ounded

quantication would have to dene a new type with a reb ound plus convert the list to the new

type so that the new plus op eration will b e available and convert the result back to the original

type The conversion pro cess b ecomes even more complicated when an op eration on the elements

of a data structure must b e reb ound This dierence means that there is no direct translation

of a contextual p olymorphism program into an Fb ounded quantication program even though

assertions can b e translated into record types fairly easily b ecause data arguments may require

CHAPTER CONTEXTUAL POLYMORPHISM

extensive repackaging It also means that contextual p olymorphism has an advantage over F

b ounded quantication in exibility and incrementality b ecause programs can more easily rebind

or add op erations to meet lo cal needs

Fb ounded quantication can not sp ecify interfaces as precisely as contextual p olymorphism

b ecause subtyping weakens the prop erty of type matching Contextual p olymorphism may have

a small advantage in eciency b ecause of this and also b ecause entities declared by assertion

declarations are directly accessible while the elds of a record type are only available indirectly

via eld selection

Parameterized Mo dules

Contexts resemble OBJs theories and SMLs signatures The declarations in a contexts b o dy

corresp ond to the op declarations in a theory and the type parameter of a context corresp onds

to a sort declaration in a theory Applying a context in a routine corresp onds to using a theory

in a parameterized ob ject that denes the routine The typechecking rules that lo ok for assertion

declarations in the calling environment corresp onds to the use of a default view and an explicit

view corresp onds to a set of declarations that rename values As an example the ordered context

given ab ove corresp onds to the theory

th ORDERED is

extending BOOL

sort T

op lt T T Bool

endth

obj MINOORDERED is

op min TO TO TO

vars t t TO

eq mint t if ltOt t then t else t fi

endo

view INTORDERED of INT as ORDERED is

sort T to Int

vars i j T

CHAPTER CONTEXTUAL POLYMORPHISM

op lti j to i j

endv

At rst glance it seems that context parameters should corresp ond to theory parameters

instead of sort declarations but that approach is needlessly complex If ORDERED to ok a parameter

and dened lt in terms of the parameters sort then MIN would need two parameters one called

T to provide the sort and the other matching ORDEREDT to provide lt

Both contexts and theories can describ e relationships b etween types However a theory de

scrib es the interface of a single argument mo dule while a context can b e applied to several type

arguments This means that OBJ programs must sometimes construct mo dules solely to match

theories Consider how the two systems would implement a routine to sum the elements of a

collection

context sumcollection C E

plus E E E

front C E Return an arbitrary element

in let sum C 3 E 3 sumcollection C E C E

th SUMCOLLECTION is

sorts C E

op plus E E E

op front C E

endth

obj SUMSCSUMCOLLECTION is

op sum CSC ESC

endo

Now consider an OBJ program with a POINT mo dule that provides a Point type a POINTSET

mo dule that provides a PointSet type and a POINTPLUS mo dule that provides a plus op eration

on p oints To sum a set of p oints an OBJ program must create a new mo dule that combines

POINTSET and POINTPLUS and can b e viewed as a SUMCOLLECTION A contextual p olymorphism

program would just pass Point and PointSet to sum

CHAPTER CONTEXTUAL POLYMORPHISM

The main dierence b etween contexts and theories is the level that they op erate on Theories

op erate at the level of mo dules and are compiletime phenomena Contexts op erate at the level

of types and although they also are statically checked the types that they constrain are dynamic

values The routines that use them can b e called through staticallyunpredi ctable paths or can

even b e recursive OBJ and SML do not allow recursive mo dules

Descriptive Classes

Contexts closely resemble Xs descriptive classes Compare the ordered context ab ove to

descriptive class orderedT is

lt procorderedT orderedT returns orderedT

end class

procedure minxorderedT yorderedT returns orderedT

where T is free

begin

if xlessx y then

return x

else

return y

end if

end min

Both systems allow the same abstract sup erclass style of programming and b oth have the

same advantages with resp ect to the lack of a xed inheritance hierarchy the ease of adding new

contexts and new op erations and the avoidance of multiple inheritances problems

X uses an explicit instance statement where contextual p olymorphism implicitly checks

assertions against the calling environment Hence contextual p olymorphism can not match the

instance statements ability to state ifandonlyif relationships among types An instance state

ment also provides useful do cumentation and provides a way to rename routines however the

3

sortlist example of the previous section shows that renaming is simple in F

The two mechanisms dier most in that assertions are not used as types they constrain type

parameters instead of serving as parameter types This resolves some questions left unanswered

in the discussion of X The X declarations

CHAPTER CONTEXTUAL POLYMORPHISM

procedure piInteger returns orderT where T is free

llistorderT

3

may or may not b e legal but F do es not present these problems b ecause contexts and types

3

allows hierarchies of contexts and denes the meaning are distinct entities Furthermore F

of assertions applied to the parameters of type generators X do es not allow hierarchies of

descriptive parameters and Sandb erg do es not discuss the use of descriptive types with type

generators

Summary

This chapter has describ ed a variation of parametric p olymorphism called contextual p olymor

phism This form of p olymorphism provides a larger role for environments within a programming

language Environments contain declarations of types and terms Contexts are abstractions of

environments in the same way that routines are abstractions of terms Assertions apply contexts

to arguments to pro duce declarations Contextual p olymorphism uses assertions to constrain the

type parameters of p olymorphic routines and type generators the items declared by an assertion

must exist in the environment of a call to the p olymorphic routine or a type generator application

Inference algorithms infer type arguments of and generate sp ecializati ons of p olymorphic rou

tines Assertions can b e extended to other programming language mechanisms such as abstract

types and existential types

Contextual p olymorphism preserves the desirable prop erties of other parametric p olymorphism

variants strong static checking separation of interfaces from implementations precise interfaces

including type matching within an interface generality generalizabil ity and incrementality

Contexts also provide an abstraction mechanism that like the sup ertype relationships of inclu

sion p olymorphism provides hierarchical descriptions of notions and guidance and assistance to

programmers Contexts can also describ e relationships among types such as type C is a collection

of elements of type E

Chapter

Notes on Cforall

If new ideas ab out programming languages are to b e tested or even eectively demonstrated they

must b e embedded in a language This is often done by creating a new language This shows the

ideas o to their b est advantage and provides the language designer with all of the satisfactions

that come from designing a new thing from scratch However new languages only rarely gain

widespread acceptance A second approach uses the ideas to extend an existing language This

helps p eople examine the new ideas b ecause they can bring their knowledge of the base language

to b ear It also exp oses the new ideas to a somewhat hostile environment so their aws will b e

more readily apparent

This chapter discusses some features of Cforall a test b ed for contexts assertions and

related ideas that extends ANSI standard C The purp ose of Cforalls design is to show that

contexts and assertions provide a practical and ecient form of p olymorphism and that these

ideas lead to a smaller simpler language kernel The choice of C as a base language is somewhat

arbitrary Many staticallytyped imp erative languages could serve as a base for this work but

Cs traditional emphasis on eciency is an imp ortant constraint its history of other extensions

such as C and Ob jectiveC provides interesting comparisons and the availability

of source co de for highquality C such as gcc and lcc will ease the job of

implementation

CHAPTER NOTES ON CFORALL

Overloading

Contextual p olymorphism dep ends crucially on overloading related notions are implemented

by declarations of the same identier with related types and contexts abstract out the pattern

common to the types Hence Cforall must allow extensive overloading of routine and ob ject

identiers Cs semantics restrict and encourage overloading in certain ways

Two declarations of an identier that have overlapping scop es overload each other unless

they have compatible types according to Cs type compatibility rules

one declares a routine and the other declares a p ointer to a compatible routine type Since

C technically treats routine identiers as p ointers to routines in expressions the two cases

are indistinguishable

one declares an array type the other declares a p ointer type and the element type and the

p ointedat type are compatible Since C treats arrays as p ointers in expressions the two

cases are indistinguishabl e This is a restriction since it is conceivable that a programmer

might want to dene an op eration for p ointers and for the elements of an array

one declaration declares a type or typedef name Cs grammar requires that type names

b e distinct from other identiers This is a restriction since it would b e convenient to use

the same identier for a type and for a routine that constructs values of the type

If one of these conditions holds and the declarations o ccur in dierent scop es the inner one hides

the outer one otherwise the declarations are illegal

Cforall programmers can overload most of Cs op erators by declaring routines with sp ecial

identiers for instance the identier represents the addition op erator and the expression

a b is considered to b e syntactic sugar for the routine call a b The question marks

represent the routines op erands the identier for the unary op eration is Programmers

can not overload the ow of control op erators shortcircuit and shortcircuit

or and the conditional expression b ecause unlike routines they do not always evaluate

their op erands

The constants and are imp ortant to the semantics of C Besides their normal roles as

arithmetic identities represents the null p ointer and the b o olean false constant and plays

a role in the denitions of the logical op erators while represents the true constant and is

involved in the denition of many arithmetic op erators including p ointer arithmetic Along with

CHAPTER NOTES ON CFORALL

they dene the unoverloadable owofcontrol op erators returns if b oth op erands are

unequal to and returns otherwise Consequently overloading and is highly desirable

and Cforall allows it by treating those tokens as sp ecial identiers

C and Cforall use the word object to mean a contiguous region of a computers data memory

Variables arrays structures and structure elds are all ob jects but routines are not Unlike

Ada Cforall allows overloading of ob ject identiers b ecause the names of constants like and

overloadable and a convenient way to implement a constant for some type T is to declare an

ob ject of type const T Unlike C Cforall allows an identier to b e overloaded for two routine

types that dier only in their result types it did not seem sensible to allow T foo and T foo

and then forbid T barvoid and T barvoid

C considers all enumeration constants to have type int Therefore enumeration constants

can not b e overloaded in Cforall and enumeration types are considered to b e compatible with

1

int Furthermore C and Cforall consider all character literals to have type int not char These

decisions restrict overloading severely C do es not have to follow C as closely as Cforall do es

and in this situation C treats enumeration types as distinct types enumeration constants as

values of their enumeration types and character literals as char values

Cforall treats Cs overloadable op erators and and constants as a group of predened

routines and ob jects They are treated as b eing dened in each translation unit so that com

pilers can p erform optimizations such as inline expansion on a translation unit as opp osed to

programwide basis They have addresses although the result of comparing p ointers to them is

implementation dep endent and can b e passed as parameters to other routines

Lvalues

3

The expressions of F only dealt with values C and Cforall also provide lvalue expressions which

designate a region of data storage Lvalues usually o ccur in assignment subscripting and p ointer

dereference expressions Contextual p olymorphism must handle lvalues as well as ordinary values

The simplest way to deal with an lvalue is to eliminate it and use a p ointer value instead

For instance Cforall allows programmers to overload assignment using the identiers for

simple assignment for increment and so on The rst parameter of an assignment

routine p oints to the lvalue to b e mo died The assignment expression ab is equivalent to

1

ANSI C requires that enumeration types b e compatible with some integer type but not necessarily int

CHAPTER NOTES ON CFORALL

the routine call ab where the addressof op erator returns a p ointer to a This

guarantees that a is an lvalue since only lvalues have addresses However this scheme do es not

handle assignments to register variables or to bit elds since Cforall has no p ointer to register

or p ointer to bit eld types For those sorts of lvalues Cforall uses the programmerdened

assignment op erator to assign to a temp orary variable then copies the temp orary to the lvalue

The subscript and dereference op erators return lvalues and can not b e easily rewritten to use

p ointer values instead These cases can b e handled by an lvalue type generator Cforall provides

this through an lvalue type qualier For example a programmer who created a Flex type that

implements an expandable array of integers would want to overload the subscript op erator as

follows

lvalue int Flex array int index

The lvalue qualier indicates that the result of subscripting a Flex is an integer lvalue not just

an integer value

Polymorphism

Type Abstraction

Cforall provides a forall sp ecier that provides type abstraction like T in a p olymorphic

lambda calculus A p olymorphic swap routine can b e written as

foralltype T

void swapT t T t f

T temp t

t t

t temp

g

int i i

struct f double xy g s s

swapi i

swaps s

CHAPTER NOTES ON CFORALL

Here type T declares a parameter identier T which denotes a type within the declaration of

swap The compiler infers the corresp onding type argument from the data arguments in calls to

swap T takes on the values int and struct f double xy g in the two calls shown

Cforall has no equivalent of the lambda calculuss e type application term The compiler

must always infer all type arguments Cforall restricts the form of forall declarations to make

this p ossible The b o dy of the declaration the equivalent of in t must have a routine

type and every type parameter must b e inferable from the ordinary parameters it must b e

used in the type of at least one ordinary parameter or as is discussed b elow in the type of an

assertion declaration whose type mentions some other inferable type parameter Besides making

inference p ossible this restriction sidesteps questions ab out the legality of p olymorphic data type

declarations like

foralltype T struct f T a b g

type is not a type sp ecier so there are no such types as p ointer to type array of type

or routine returning type and no variables or structure members of type type Cforall provides

no op erations on instances of type in particular types can not b e assigned or compared These

restricti ons allow simple ecient implementations of p olymorphic routines Their rst conse

quence is that a type sp ecier such as T always refers to the same type value during the lifetime

of any of its instances Hence a Cforall compiler can statically keep track of the types and type

identiers used to declare any ob ject and can reconstruct its type when necessary This means

that ob jects and values do not have to contain type tags The second consequence is that type

values can have a simple representation such as the one describ ed for the language ForceOne in

section

In contrast T do es act as a type sp ecier It can b e used in declarations for instance p ointer

to T array of T and routine returning T are legal types It can also b e used as the op erand of

sizeof Instances of T can b e passed as parameters assigned to each other initialized and used as

the op erands of sizeof or but no other op erations for type T exist by default Consequently

the value referred to by a type identier must b e an object type a type that describ es an ob ject

This excludes

type which can not o ccur in p ointer or structure declarations bit eld types which can

only o ccur in structure declarations and routine types Pointer to routine types are not excluded

CHAPTER NOTES ON CFORALL

incomplete types void unbounded array types and structure types that have b een de

clared but whose members have not b een declared Fortunately unbounded arrays types

do not come up in practice b ecause C converts array of type T to p ointer to type T

in expressions Unfortunately this restriction makes it imp ossible to write a p olymorphic

routine that accepts a p ointer to any data type and uses the p ointedat type to relate the

types of parameters or the return type The only alternatives have the form

foralltype T T fT T

which will not accept p ointers to incomplete types or

void fvoid void

which do es not preserve type information

type qualiers const and volatile In a sense they qualify ob jects not types They can

not b e part of type values b ecause they aect the semantics of ob jects declared with those

type values volatile aects the storage and retrieval of ob jects and const aects the

set of legal op erations As a result programmers must often overload p olymorphic routines

that op erate on p ointers for all four combinations of qualiers so that the result type will

match the argument type

foralltype T const volatile T fconst volatile T

foralltype T volatile T fvolatile T

foralltype T const T fconst T

foralltype T T fT

Contexts and Assertions

3

Cforalls context declaration is the equivalent of the context statement dened for F A simple

context declaration lo oks like

context addabletype T f

T T T

const T

g A context for a notion of a homogeneous list type is

CHAPTER NOTES ON CFORALL

context listoftype List type Element f

Element carList

List cdrList

List consElement List

List nil

int isnilList

g

The b o dy of a context can contain any ob ject or routine declaration Contexts must have at

least one parameter and all of the parameters must b e types At present contexts can not have

data parameters b ecause they would have little use the only data values that app ear in type

expressions are the integer b ounds of array types but C treats array types as p ointer types and

p erforms no array b ound checking so the type system ignores the array b ounds

Assertions have the form listofIntlist int They are clauses that can b e at

tached to any type declaration When they are attached to type declarations in context declara

tions they build context hierarchies and provide the equivalent of the environment concatenation

3

op eration from F For instance

context listofaddabletype L

type E addableE listofL E f g

describ es the notion of homogeneous lists of some addable type and is equivalent to

context listofaddabletype List type Element f

Element Element Element

const Element

Element carList

List cdrList

List consElement List

List nil

int isnilList

g

Assertions usually app ear in forall sp eciers

foralltype L type E listofaddableL E

E sumL list f

CHAPTER NOTES ON CFORALL

E total Es not the int

while isnillist f

total total carlist

list cdrlist

g

return total

g

Intlist alist

int carIntlist

Intlist cdrIntlist

Intlist consint Intlist

Intlist nil

int isnilIntlist

int i sumalist

Given the call to sum a Cforall compiler would infer from the type of alist that L is Intlist

It would also nd appropriately typed car cdr cons nil isnil and declarations

in the environment of the call and infer from the assertion declarations that E is int

Cormack and Wright suggest implementing p olymorphic routines by passing the routines and

constants asso ciated with the type parameters to the routine as extra invisible arguments The

presence of contexts in Cforall suggests a somewhat dierent scheme once the compiler has

determined that Intlist and int satisfy listofaddable it can generate a table of the

assertion declarations pro duced for them by listofaddable This table can b e passed as a

single invisible argument to sum and to any other routine that uses that assertion In many cases

the table can b e created at compile time This technique reduces the cost of calling p olymorphic

functions but increases the cost of op erations within the p olymorphic functions The tables

resemble the tables created by some implementations of C p and

the maps created by the SELF compiler

Lo cal Routines

Cforall programs must sometimes contain routine denitions that are lo cal to a scop e The sim plest case o ccurs when a programmer must rename a routine to satisfy a context or to temp orarily

CHAPTER NOTES ON CFORALL

replace the default version of an op eration For example assume that Intlist has an append

routine If the programmer renames append to and provides a list sum can b e used to

concatenate all of the elements in a list of Intlists Fortunately C and Cforall treat routines

as p ointers to routines hence an initialized lo cal p ointer suces for renaming

Intlist appendIntlist Intlist

void fooIntlistlist l f

Intlist Intlist Intlist append

const Intlist nil

suml

g

Sp ecialization can also create lo cal routines without programmer intervention In this exam

ple the compiler must create a sp ecializ ation of length inside g in order for Intlist to satisfy

c

context ctype T f int lengthT g

foralltype T cT void fT

foralltype L type E listofL E int lengthL

foralltype L type E listofL E void gL alist f

falist

g

Sp ecializati on is highly desirable without it the usefulness of p olymorphic routines like length

would b e greatly reduced However as this example shows the values sp ecialize d up on may b e

parameters of the routine b o dy that contains the sp ecializ ation One way to implement this is to

have the compiler create a lo cal sp ecialized routine that passes its arguments with extra type

information to the general routine This implies the existence of nested routines in the style of

Algol or Pascal This in turn aects the calling conventions and entry and exit co de of Cforall

routines

Overload Resolution

Cforalls overload resolution rules were carefully designed so that the same rules apply to over loaded routines and overloaded op erators and so that a set of predened op erator routines can

CHAPTER NOTES ON CFORALL

provide much of Cs expression semantics The rules are based on four ideas implicit conversions

safe conversions conversion cost and degrees of p olymorphism

Implicit Conversion

C denes a large number of implicit conversions The rules governing conversions can vary among

C compilers b ecause on dierent computers the range of values of some types may b e contained

in or may only overlap the range of other types and the conversion rules attempt to preserve the

converted value in the largest number of cases The rules are

Values of certain small types char signed char unsigned char short int and

signed and unsigned int bitelds are converted to int or unsigned int values by the

integral promotions If an int can contain all values of the original type then the result is

an int otherwise the result is an unsigned int

An argument of a routine call undergo es a default argument promotion if the type of the

corresp onding parameter is unknown This happ ens when the routine has not b een declared

with a prototype or when the routine accepts a varying number of arguments The default

argument promotions apply integral promotions to integral arguments and convert float

arguments to double

Arithmetic types can all b e interconverted during assignment and during parameter passing

when the type of the corresp onding parameter is known

Pointers can b e converted to and from p ointers to void and type qualiers can b e added

to the p ointedat type

Values of type array of type T are converted to p ointer to type T unless they are

op erands of sizeof or or are wide character literals used in initializers Routine

designators are converted to p ointers to routines unless they are op erators of sizeof or

Hence these types never actually app ear in expressions and can b e ignored

Binary arithmetic op erators make use of what are called the usual arithmetic conversions

in which the arguments are converted to a common type which is the type of the result

The following ordering is dened on the arithmetic types

long double double float long unsigned int

long unsigned int long int int

long unsigned int unsigned int int

CHAPTER NOTES ON CFORALL

Furthermore in implementations where long int can contain all of the values of type

unsigned int

long int unsigned int

The rst step in determining the type of the result of a binary op erator in C is to apply the

integral promotions to any op erands that are values of a small type Then the least type

that is equal to or greater than b oth op erands types is chosen as the result type and the

op erands are converted to that type

Safe Conversions

Consider dening a set of Cforall routines that mimic Cs semantics as they apply to the multipli

cation op erator Clearly one monomorphic routine will not do since the result type dep ends on

the op erand types One p olymorphic routine will not do b ecause it would accept nonarithmetic

types unless contexts were used to restrict the set of op erand types but that leads to circular

denitions b ecause the contexts would naturally b e phrased in terms of arithmetic op erations

One monomorphic routine p er combination of op erands is not satisfactory the number of routines

needed is large and the exact set would b e implementation dep endent b ecause of implementation

dep endent conversions Besides the individual conversions will still b e present in the language

b ecause they can b e applied to arguments of nonop erator routines It is b etter to dene one

multiplication routine for each arithmetic type and make use of the existing implicit conversions

when the op erands are of dierent types

In most cases if there is a conversion from type T to type T there is also a conversion

from T to T This leads to an ambiguity when an int is multiplied by a long either op erand

could b e converted to the others type Cforall solves this by designating the usual arithmetic

conversions conversions to void p ointer conversions that add type qualiers to the p ointedat

type and conversions of p ointer to T to p ointer to void to b e safe conversions and gives

them preference during overload resolution Other conversions are unsafe conversions

Cforall must allow unsafe conversions b ecause C allows them a float argument can b e passed

to a routine with an int parameter The usual arithmetic conversions and conversions to void

are safe b ecause they are built into the denition of C expression and statement semantics

preferring the inttolong conversion over the reverse means that when an int is multiplied by

a long the int will b e converted as is the case in C The p ointer conversions are safe b ecause

nothing can b e done to the p ointedat value through the converted p ointer that could not b e

CHAPTER NOTES ON CFORALL

done through the original p ointer allowing these conversions reduces the number of overloadings

of p olymorphic routines on p ointers since all of the p ointer arguments will b e converted to the

safest op erand type

Conversion Cost

Cforall mimics Cs b ehaviour in applying the usual arithmetic conversions to binary op erations

by asso ciating a conversion cost with each safe conversion and by preferring overload resolutions

with low costs The following direct safe conversions have a cost of

from any ob ject type or incomplete type to void

from a p ointer to any nonvoid type to a p ointer to void

from a p ointer to any type to a p ointer to a version of the type with more type qualiers

an integral promotion

from int to unsigned int and to long int

from unsigned int to long unsigned int

from unsigned int to long int if a long int can represent all values of an unsigned

int

from long int to long unsigned int

from long unsigned int to float

from float to double

from double to long double

The cost of any other safe arithmetic conversion is the minimum number of direct safe conversions

needed to pro duce the same result type and hence is implementation dep endent For example

a long int to long double conversion has a cost of b ecause it corresp onds to safe conversions

from long int to long unsigned int then to float then double and nally to long double

CHAPTER NOTES ON CFORALL

Degrees of Polymorphism

Cforall denes one routine to b e less polymorphic than another if it has fewer type parameters

or if it has the same number of type parameters and fewer of its explicit parameters have types

that dep end on a type parameter

foralltype T type U void fT U p olymorphic

foralltype T void fT T less p olymorphic

foralltype T void fT int least p olymorphic

Among calls that require only safe conversions the overload resolution rules prefer calls to less

p olymorphic routines over calls to more p olymorphic routines b ecause p olymorphism may have

some runtime cost and b ecause a less p olymorphic routine is presumably b etter tuned to its

arguments However calls to more p olymorphic routines are preferred to calls to less p olymorphic

routines that involve unsafe conversions

Overload Resolution Rules

Cforalls overload resolution rules can b e explained as a b ottomup pass over an expression tree

that selects an interpretation of the expression It is similar to the overload resolution algorithm

describ ed for Ada by Baker but is extended here to handle p olymorphic routines and arithmetic

conversions

Each expression must have at least one interpretation Each interpretation has a value and

type

Each overloading of an identier provides one interpretation of the identier

The interpretations of expressions involving the overloadable op erators are found by treating

them as routine calls as was explained in section

Routine calls have one interpretation for each valid combination of routine interpretations

and argument interpretations where a combination is valid if the routines interpretation

accepts the number of arguments given every argument expression can b e implicitly con

verted to the type of the corresp onding parameter and the environment of the call contains declarations matching any assertion declarations made by the routine

CHAPTER NOTES ON CFORALL

sm has one interpretation for each valid combination of the interpretations of s and m

where a combination is valid if ss interpretation is a structure or union with a member

named m

pm has one interpretation for each valid combination of the interpretations of p and m

where a combination is valid if ps interpretation is a p ointer to a structure or union with a

member named m

An expression may have many interpretations but the interpretations must have distinguish

able types If two or more interpretations of sm or pm have compatible types then they

are replaced by a single ambiguous interpretation If two or more interpretations of a routine call

have compatible types the b est of those interpretations is chosen and the rest are discarded

The b est interpretations use the fewest unsafe conversions

Of these the b est are those that call the routines that are the least p olymorphic

Of these the b est have the lowest total conversion cost including all implicit conversions in

the argument sub expressions

Of these the b est have the lowest total conversion cost excluding the implicit conversions

if any used to convert the argument expressions to the corresp onding parameter types

If a routine call has no single b est interpretation all of the compatible interpretations are replaced

by a single ambiguous interpretation

All interpretations of a sub expression are p otential op erands of higherlevel expressions in the

tree Various situations select some of these interpretations

In a cast expression te if the expression e has an interpretation that has type t

that interpretation is selected Otherwise e must have some interpretations that can b e

converted to type t and one of them must have a conversion cost lower than any of the

others with unsafe conversions considered to have innite cost That interpretation must

b e unambiguous and it is selected and converted

An expression that is used as a statement or as the rst op erand of a comma expression

or as the initializin g expression or incrementing expression of a for lo op is implicitly cast

to void

CHAPTER NOTES ON CFORALL

An argument of a routine call is implicitly cast to the type of the corresp onding routine

parameter If the type of the parameter is not known the argument must have exactly

one interpretation which must b e unambiguous and which undergo es a default argument

promotion

The expression in a return statement is implicitly cast to the return type of the routine

Expressions used in initializer s are implicitly cast to the type of the ob ject or aggregate

element b eing initializ ed

An expression e used to control a lo op if statement or expression or used as an

op erand of or is treated as inte This mirrors the semantics of C

and comp ensates for Cs lack of a b o olean type while taking advantage of the ability to

overload and

The controlling expression of a switch statement must have exactly one interpretation with

an integral type which must b e unambiguous

Expressions that are op erands of sizeof or must have exactly one interpretation which

must b e unambiguous

Given the ab ove rules the C semantics of multiplication expressions can b e sp ecied by a set

of seven predened multiplication routines

int int int

i

unsigned int unsigned int unsigned int

ui

unsigned long unsigned long unsigned long

ul

long int long int long int

l

float float float

f

double double double

d

long double long double long double

ld

The subscripted names given in the comments are used to distinguish b etween the dierent

routines in the examples that follow In the Cforall co de

long int a b

a b

CHAPTER NOTES ON CFORALL

a and b each have one interpretation The multiplication expression has seven p ossible

interpretations one for each interpretation of

inta intb

i

unsigned inta unsigned intb

ui

unsigned long inta unsigned long intb

ul

long inta long intb

l

floata floatb

f

doublea doubleb

d

long doublea long doubleb

ld

Of these the rst three involve unsafe conversions The fourth has conversion cost The fth

has cost two conversions from long int to float and the sixth and seventh have costs and

The expression is implicitly cast to void since it o ccurs as a statement This adds to each

interpretations conversion cost and pro duces seven interpretations with type void The b est of

these is the fourth since it has no unsafe conversions and has the lowest total cost Hence the

interpretation of the statement is void long inta long intb

l

Note that the C rule that applies integral promotions to small op erands is no longer needed it

is implied by the absence of routines that have small parameter types Conversely programmers

can dene op erators for them if they are needed

Now consider the bitwise complement op erator which is asso ciated with the sp ecial

identier and the following predened routines

int int

i

unsigned int unsigned int

ui

long int long int

l

unsigned long unsigned long

ul

Given

void funsigned long int

int i

fi

the sub expression i has four interpretations

CHAPTER NOTES ON CFORALL

inti cost

i

unsigned inti cost

ui

long inti cost

l

unsigned long inti cost

ul

Each interpretation must b e converted to unsigned long int to b e used as the argument of f

Conversions from int have cost and from unsigned and long have cost so all four p ossibiliti es

for the argument of f contain no unsafe conversions call no p olymorphic routines and have a

total conversion cost of Here the nal rule that excludes any implicit conversion applied to

argument expressions comes into play and chooses the interpretation

f unsigned long int inti

b ecause it has the lowest conversion cost when the conversion to unsigned long int is ignored

The eect of this rule is to move conversions from routine arguments to routine results Cs

expression semantics have the same eect

This nal rule is only necessary b ecause all interpretations with distinct types are preserved for

p ossible use in the next higher expression in the expression tree An alternate overload resolution

would preserve only the b est of the interpretations and would not have this rule In the case of

fi only the rst interpretation of i would b e kept However in the case of programmer

dened overloaded routines that scheme would not minimized conversion costs and would even

lead to unsafe conversions as the following example shows

void ffloat

double gint g

i

long int glong int g

l

int v

fgv

In this case g v has cost and g v has cost If g v was discarded b ecause it has higher

i l l

cost then an unsafe conversion from double to float would b e required in the call to f Instead

since g v is preserved it is used as the argument to f and no unsafe conversions are needed

l

Routines that provide op erations on p ointers are p olymorphic Subtraction on p ointers is

dened by ve routines ptrdifft is an implementationdependent type dened by the ANSI C standard to b e some integral type that can represent the dierence b etween any two p ointers

CHAPTER NOTES ON CFORALL

foralltype T const volatile T

const volatile T ptrdifft

cv

foralltype T volatile T

volatile T ptrdifft

v

foralltype T const T

const T ptrdifft

c

foralltype T T

T ptrdifft

;

foralltype T ptrdifft

const volatile T const volatile T

Recall that in calls to p olymorphic routines type parameters are b ound to unqualied ob ject

types deduced from the explicit parameters In the case of

volatile int ip

ptrdifft d

ip d

the compiler infers that the type argument is int There are no implicit conversions b etween

p ointer types and integral types so the subtraction expression has only four p ossible interpreta

tions

const volatile intip ptrdifftd

cv

returns const volatile int

volatile intip ptrdifftd

v

returns volatile int

const intip ptrdifftd

c

returns const int

intip ptrdifftd

;

returns int

The last two of these apply unsafe conversions to ip so they are eliminated The rst two

are equally p olymorphic so the choice b etween them dep ends on conversion cost The rst

interpretation has conversion cost b ecause of the implicit safe conversion from volatile int

to const volatile int and the second has cost so the second is chosen The result has

type volatile int type matching which is provided by the use of the type parameter T in

CHAPTER NOTES ON CFORALL

the argument and result types preserved the int type while overloading preserved the volatile

qualier

Cs semantics do not allow p ointer subtraction on p ointers to void or on p ointers to incomplete

types In Cforall this restriction is a simple consequence of the use of p olymorphism since void

and incomplete types can not b e inferred as the values of type parameters However type qualiers

are not part of inferred type arguments either so four overloaded routines are needed one for each

combination of type qualiers in the return type to dene subtraction of integers from p ointers A

more serious problem is that p olymorphic routines can not b e used to dene comparisons b etween

p ointers to incomplete types

Summary of Overload Resolution

This section has discussed a set of overload resolution rules and a set of predened routines

and constants that mimic several asp ects of Cs expression semantics Polymorphism allows the

description of p ointer op erations The application of integral promotions to op erands of unary

op erators and usual arithmetic conversions to op erands of binary op erations b ecomes a conse

quence of the use of implicit conversions in routine calls Restrictions on the set of legal op erand

types for op erations like are reected directly by the set of overloadings while restrictions

that certain p ointer op erations apply only to p ointers to ob ject types follow from the rule that

type arguments must b e ob ject types Parametric p olymorphism preserves type information in

p ointer op erations while overloading preserves type qualiers The overload resolution rules are

simple compared to for instance those of C and apply uniformly to b oth op erators and to

programmerdened routines

Since C has a richer and more complicated set of conversions op erations and data types

than most other languages thanks in part to implementationdependent conversions this design

should b e widely applicable In fact irregularitie s caused by type qualiers by incomplete types

and by the lack of a b o olean type would not o ccur in other languages

Opaque Types

Recall the principle of declaration corresp ondence which states that all options or prop erties asso

ciated with declarations should b e uniformly available If this principle is applied to Cforall type

parameter declarations must b e complemented by type identier declarations The semantics of Cforalls type parameters leads immediately to the following conclusions

CHAPTER NOTES ON CFORALL

type declarations declare identiers that are names of ob ject types

The value of such an identier is constant throughout its lifetime

By default instances of the type can b e initialize d passed as parameters assigned to each

other and used as op erands of sizeof or No other op erations exist by default

A type declaration that contains an initialize r is a type denition The initial value can b e

any unqualied ob ject type

Identiers declared by type declarations denote types that are distinct from each other and

from their initializi ng type This distinguishes them from identiers declared by typedef

declarations which are synonyms for other types

A simple example of a type declaration would b e

type Complex struct f double real imaginary g

which would create a new type distinct from all others including struct f double real

imaginary g Since some way to create Complex values is needed Cforall denes implicit safe

unitcost conversions b etween Complex and its initializing type Since assignment of Complex

values is allowed Cforall uses the assignment op eration of the initializ ing type as the default

assignment op eration for Complex

The principle of declaration corresp ondence also requires that type identiers ob ey the same

linkage rules as ordinary identiers Hence it must b e meaningful to have the following declarations

at the le scop e of a translation unit

type T struct f int a b g

static type T struct f int a b g

extern type T

The meanings of these declarations follow from the semantics of C storage class sp eciers All

three have static duration the identiers are b ound to values that exist throughout the execution

of the program T is an identier with external linkage it can b e referred to in other translation

units T is declared with internal linkage it can b e used within the translation unit that declares

it but is not visible outside of it T is also declared with external linkage but the denition and

initializ ation of T o ccurs in some other translation unit Within the scop e of this declaration

the implementation of type T is unknown T is an opaque type

CHAPTER NOTES ON CFORALL

Cforalls opaque types can have simple implementations The simplest implements them as

integer variables that contain the enco ding of the size and alignment of the types implementation

The variables storage duration and external linkage are determined by the type declaration

When the types implementation is a compiletime constant the Cforall compiler can initialize

the variable directly On a computer with no alignment requirements and byte integers a

compiler would transform the declarations ab ove to the equivalent of

int T

static int T

extern int T

In a C program the initializer of a static denition must b e a compiletime constant For

maximal simplicity Cforall could extend this rule so that the initializer of a static type denition

must also b e a compiletime constant Unfortunately opaque types are not compiletime constants

b ecause their size and alignment are not known where they are used Hence a type denition with

static duration would not b e able to use opaque types in its initializer A p ointer to an opaque

type would b e considered to b e a compiletime constant type and would b e allowed This is a

severe restriction opaque types would not b e able to build on other opaque types However it

do es eliminate the p ossibility of erroneous mutually recursive opaque type denitions

Cforall could avoid this restriction by removing the C rule that initialize rs in staticduration

declarations must b e compiletime constants There are two ways to implement this The tradi

tional metho d generates a piece of co de for each translation unit that initialize s the staticduration

storage dened in the unit including the type variables that contain enco ded sizes and align

ments The order in which the pieces are executed dep ends on the way in which translation

units refer to each other if the graph dened by the interunit references contains a cycle then

the program is malformed The linker is in the b est p osition to determine the correct order for

initializ ation but typical linkers do not provide this ability

A simpler metho d suggested by C R Zarnke avoids the problem of initializi ng type enco dings

by implementing each opaque type denition as a routine that calls other type routines as

necessary The routine would have a number of instances parameter so that an array of

instances could b e allo cated with one call The routine could simply return the enco ded size

and alignment It could also allo cate memory itself The allo cated memory could come from the

heap in that case memory must b e scavenged when blo cks exit The routine could also allo cate

memory in the stack frame of the calling routine directly The Unix alloca library routine do es

CHAPTER NOTES ON CFORALL

exactly that in eect the type routine would b e a version of alloca sp ecialize d for the size

to b e allo cated This routine would b e a sensible place to put or call typesp ecic initializati on

co de as well In any case each translation unit still needs initializati on co de to allo cate space for

instances of opaque types that have static duration

Assertions and Type Declarations

Type declarations can contain assertions In the simplest case assertions app ear in opaque type

declarations and mean that the ob jects and routines declared by the assertion exist

extern type Complex addableComplex

declares that a complex has a ob ject and a op erator it has the same eect as

extern type Complex

extern const Complex

extern Complex Complex Complex

Assertions on type denitions have a more complicated meaning The type denition

type T addableT T

declares that T has a ob ject and and op erators as well as having the type T for its

implementation The denitions of and must o ccur in the scop e of Ts denition if

they are to have access to T But what if they do not Cforall uses this as an opp ortunity to

3

implement inheritance as discussed for F If an identier is declared by an assertion declaration

and is not dened by the end of Ts scop e Cforall attempts to build one from an ob ject or routine

with the same identier and a similar type that is dened for T This is normally the case for

assignment Ts calls Ts If there is no such identier and T is a structure and exactly

one member has an appropriate ob ject or routine dened that ob ject or routine is used In any

other case the Cforall translator will rep ort an error

Consider a graphics library that provides a shape context that describ es shap es that can b e

drawn a Rect type that represents rectangular shap es a Pattern type and a fill routine that lls screen areas with a pattern

CHAPTER NOTES ON CFORALL

extern type Point

context shapetype T f

void drawT Draw a shape

T initPoint c Create a shape centered at c

Point p with p on its perimeter

Point centerT Return the shapes center

g

extern type Rect shapeRect

extern type Pattern

extern void fillPoint pt Pattern ptn

A solid black b ox shap e should inherit the implementation of Rect

extern Pattern black

type Blackbox shapeBlackbox Rect

void drawBlackbox b f

draw Rectb

fill centerb black

g

Blackbox has an explicitlydene d draw routine Note that the semantics of the cast op erator

provide access to Rects draw Rectb converts b to a rectangle and then overload resolution

nds the appropriate draw Another way to achieve same eect is to declare a routine p ointer

that renames Rects draw

void drawBlackbox b f

void rectdrawRect draw

rectdrawb

init and center are not dened for Blackbox so Cforall creates them in eect dening

Blackbox initPoint c Point p f return Rect initcp g

Point centerBlackbox b f return center Rectb g

Rect could b e used as the base for a new type Filledrect which is a rectangle that is lled by a default pattern

CHAPTER NOTES ON CFORALL

extern Pattern currentpattern

type Filledrect shapeFilledrect struct f

Rect r

Pattern fillpat

g

Filledrect initPoint c Point p f

Filledrect f

fr initcp

ffillpat currentpattern

return f

g

void drawFilledrect fr f

drawfrr

fillcenterfr frfillpat

g

FilledRect overrides the default versions of init and draw drawfrr is used to call

Rects draw inside Filledrects draw Cforall creates a center routine in eect dening

Point centerFilledrect fr return centerfrr

Context Examples

C Types

This section gives examples of contexts for some groups of types that are imp ortant in the C

language in terms of the predened op erations that can b e applied to those types

Scalar Arithmetic and Integral Types

The p ointer integral and oatingp oint types are all scalar types All of these types can b e

logically negated and compared The assertion scalarT should b e read as type T is scalar

context scalartype T f

int T

CHAPTER NOTES ON CFORALL

int T T T T T T

int T T T T T T

g

The integral and oatingp oint types are arithmetic types which supp ort the basic arithmetic

op erators The use of an assertion in the contexts parameter list declares that in order to b e

arithmetic a type must also b e scalar and hence that scalar op erations are available

context arithmetictype T scalarT f

T T T

T T T T T T T T T

g

The enumerated types the signed unsigned and plain char types and signed and unsigned

long short and ordinarylength int types make up the integral types They supp ort the mo dulus

op erator and various bitwise op erations

context integraltype T arithmeticT f

T T

T T T T T T T

T T T

T T T T T

g

Mo diable Types

The only overloadable op eration that can b e applied to all mo diable lvalues is simple assignment

In Cforall terms then a mo diable type is one with an assignment op erator

context mlvaluetype T f

T T T

g

Mo diable scalar lvalues are scalars and are mo diable lvalues and assertions reect those

relationships Mo diable scalar lvalues supp ort the op erations of scalars and mo diable lvalues and can also b e incremented and decremented

CHAPTER NOTES ON CFORALL

context mlscalartype T scalarT mlvalueT f

T T T

T T T

g

Mo diable arithmetic lvalues are b oth mo diable scalar lvalues and arithmetic Note that this

results in the inheritance of scalar along b oth paths

context mlarithmetictype T arithmeticT

mlscalarT f

T T T T T

T T T T T

g

context mlintegraltype T integralT

mlarithmeticT f

T T T T T T T

T T T T T T T

g

Pointer and Array Types

Array types can barely b e said to exist in ANSI C since in most cases an array name is treated

as a constant p ointer to the rst element of the array and the subscript expression ai is

equivalent to the dereferencing expression ai Technically p ointer arithmetic and

p ointer comparisons other than and are only dened for p ointers to array elements

but the type system do es not enforce those restrictions Consequently there is no need for a

separate array type context

Pointer types are scalar types Like other scalar types they have and op erators but

the types do not match the types of the op erations in arithmetic so these op erators cannot b e

consolidated in scalar

context pointertype P scalarP f

P P long int long int P

P P long int

CHAPTER NOTES ON CFORALL

ptrdifft P P

g

Mo diable lvalue p ointers supp ort the normal assignment op erator provided here by mlscalarP

increment and decrement op erators and assignment to and from void

context mlpointertype P pointerP mlscalarP f

P P long int P long int

P P void

void void P

g

Contexts that dene the dereference op erator or subscript op erator require two parameters

one for the p ointer type and one for the p ointedat or element type The assertion ptrtoPtr

int should b e read as type Ptr acts like a p ointer to int

context ptrtotype P pointerP type T f

lvalue T P

lvalue T P long int

g

A p ointer type can include type qualiers in the p ointedat type Since type arguments do not

include type qualiers each set of qualiers requires a dierent context ptrtoconstCPtr

int should b e read as type CPtr acts like a p ointer to const int

context ptrtoconsttype P pointerP type T f

const lvalue T P

const lvalue T P long int

g

context ptrtovolatiletype P pointerP type T g

volatile lvalue T P

volatile lvalue T P long int

g

context ptrtoconstvolatiletype P pointerP type T g

const volatile lvalue T P

CHAPTER NOTES ON CFORALL

const volatile lvalue T P long int

g

Assignment to p ointers is more complicated than assignment for other types b ecause the

targets type can have more type qualiers in the p ointedat type than the sources type do es

A const T can b e assigned a T or a const T but not a volatile T or a const

volatile T Contexts can mo del this by taking advantage of implicit conversions there is a

conversion from T to const T but not vice versa

context mlptrtotype P mlpointerP

type T ptrtoPT f

P P T

T T P

g

context mlptrtoconsttype P mlpointerP

type T ptrtoconstPT f

P P const T

const T const T P

g

context mlptrtovolatiletype P mlpointerP

type T ptrtovolatilePT

P P volatile T

volatile T volatile T P

g

context mlptrtoconstvolatile

type P ptrtoconstvolatileP

type T mlptrtoconstPT

mlptrtovolatileP f

P P const volatile T

const volatile T const volatile T P

g

Consider mlptrtoconstPtr int meaning Ptr is a mo diable type that acts like a

CHAPTER NOTES ON CFORALL

p ointer to const int The assertion pro duces the declarations

Ptr Ptr const int

const int const int Ptr

The rst allows assignment from const int to Ptr It also allows assignment from int b ecause

an implicit conversion from int to const int exists but it do es not allow assignment from

a volatile int b ecause no const int to volatile int conversion exists The second

declaration allows assignment of a Ptr to a const int Assignment to a const volatile int

is dened by mlptrtoconstvolatile since that assignment must have a const volatile

int result

Note the regular manner in which type qualiers app ear in the parameter lists of the assignment

op erators ab ove An alternative context can make use of the fact that qualication of the p ointed

at type is part of a p ointer type to capture that regularity

context mlptrliketype MyP mlpointerMyP

type CP mlpointerCP f

MyP MyP CP

CP CP MyP

g

The assertion mlptrlikeT const int should b e read as T is a p ointer type like

const int This denes a relationship b etween two types that is quite unlike the collection

of example used in previous chapters

The single mlptrlike context can replace the previous four but compared to them it

has two defects there is no guarantee that dereferenci ng a MyP pro duces an lvalue of the type

that CP p oints at and the mlpointerCP assertion provides only a weak assurance that the

argument passed to CP really is a p ointer type

Relationships Between Op erations

Dierent C op erators often have related meanings for instance adds two op erands

increments a variable by some amount and the two versions of increment a variable by

and return the variables value b efore or after the increment resp ectively Languages like C and Ada allow programmers to dene these op erators for new types but do not require that these

CHAPTER NOTES ON CFORALL

relationships b e preserved or even that all of the op erators b e implemented Completeness and

consistency is left to the go o d taste and discretion of the programmer It is p ossible to encourage

these attributes by providing in Ada generic op erator routines or in C member functions

of abstract sup erclasses that are dened in terms of other related op erators

In Cforall p olymorphic routines provide the equivalent of these generic op erators and contexts

explicitl y dene the minimal implementation that a programmer should provide This section

shows a few examples

Relational and Equality Op erators

The dierent comparison op erators have obvious relationships but there is no obvious subset of

the op erations to use in the implementation of the others However it is usually convenient to

implement a single comparison routine that returns a negative integer or a p ositive integer if

its rst argument is resp ectively less than equal to or greater than its second argument the C

library routine for character string comparison strcmp is one such routine These routines can

serve as the base for generic comparison routines Note that compared to other programming

languages C and Cforall have an extra nonobvious comparison op erator logical negation

returns if its op erand compares equal to and otherwise

context comparabletype T f

const T

int compareT T

g

foralltype T comparableT int T l T r f

return comparelr

g

similarly for and

foralltype T comparableT int T operand f

return compareoperand g

CHAPTER NOTES ON CFORALL

Arithmetic and Integer Op erations

A complete arithmetic type would provide all of the arithmetic op erators and the corresp onding

assignment op erators Of these the assignment op erators are more likely to b e implemented

directly b ecause it is usually more ecient to alter the contents of an existing ob ject than to

create and return a new one Similarly a complete integral type would provide integral op erations

based on integral assignment op erations

context arithbasetype T f

const T

T TT TT TT TT

g

foralltype T arithbaseT T T l T r f

return l r

g

foralltype T arithbaseT T T operand f

T temporary operand

operand

return temporary

g

foralltype T arithbaseT T T operand f

return operand

g

similarly for and

context intbasetype T f

T T T T T T T

T T T T T T T

g

foralltype T intbaseT T T l T r f

return l r

CHAPTER NOTES ON CFORALL

g

similarly for and

Note that although an arithmetic type would certainly provide comparison routines and an

integral type would provide arithmetic op erations there do es not have to b e any relationship

among intbase arithbase and comparable Note also that these declarations provide guid

ance and assistance but they do not dene an absolutely minimal set of requirements A truly

minimal implementation of an arithmetic type might only provide and which would

b e used by p olymorphic and routines

Chapter

Conclusions

Chapter dened a number of terms used in this thesis The most imp ortant of these is no

tion since programs contain implementations of notions that programmers nd useful for solving

various problems The expressiveness of a programming language is related to the variety of no

tions that it can implement The denitions were followed by a list of criteria that are useful

for comparing programming languages eciency supp ort for strong static interface checking

expressiveness and exibility precise interfaces including generality and type matching supp ort

for p olymorphic data structures separation of interfaces from implementations supp ort for co de

reuse including generalizabili ty and incrementality and simplicity of the basic language

Chapter reviewed Stracheys original use of the term p olymorphism and discussed several

varieties of p olymorphism It gave the following denitions

Polymorphism is the ability to implement a notion so that it applies to more than one type

Adhoc p olymorphism is present when an implementation has one or more interfaces that

are dened for a set of types which need not have any common structure

Universal p olymorphism is present when an implementation has a single interface that is

applicable to a p otentially innite set of types dened by a common structure

A routine exhibits parametric p olymorphism when the value of a parameter denes other

parts of the routines interface

Inclusion p olymorphism is present when an identier can b e b ound to values from a p oten

tially innite set of types with a common structure

CHAPTER CONCLUSIONS

These denitions have the advantages of b eing reasonably precise and of b eing dened in terms

of observable parts of programming languages instead of notions or program b ehaviour

The denitions were followed by a survey of a number of p olymorphism mechanisms The

adhoc mechanisms surveyed were overloading transfer functions and settheoretic unions Set

theoretic unions did not app ear in Cardelli and Wegners taxonomy of p olymorphism p erhaps

b ecause it is easily confused with transfer function p olymorphism All three are reasonably e

cient preserve strong static checking and separation of interfaces and pro duce mo dest increases

in generality generalizabili ty and incrementality Settheoretic unions and overloading allow sim

plication of programming languages Overloading provides type matching while settheoretic

unions provide a weak form of p olymorphic data However any improvements are mo dest b e

cause programmerdened adhoc p olymorphism applies only to an explicitly sp eciced nite set

of types

Universal p olymorphism mechanisms fall into two camps inclusion p olymorphism and para

metric p olymorphism Inclusion p olymorphism includes innite settheoretic unions and record

subtyping Their main drawback is that there is no way to sp ecify precise relationships among the

types of p olymorphic items since there is no name for the actual type of an argument to a p oly

morphic routine Record subtyping provides greater precision than innite unions and provides

strong static checking separation of implementations from interfaces generality and generalizabil

ity simpler base languages and p olymorphic data with reasonable eciency Unfortunately it

provides only weak incrementality and contravariant routine subtyping rules limit expressiveness

Parametric p olymorphism includes universal quantication descriptive classes and Fb ounded

quantication All three provide strong static checking simple base languages separation of in

terfaces from implementations generality incrementality and type matching with reasonable

eciency and even p olymorphic data enco ded as a p olymorphic routine Fb ounded quanti

cation conveniently packages data values with their op erations at the exp ense of incrementality

Descriptive classes provide greater expressiveness and incrementality than Fb ounded quantica

tion b ecause routines are separate from the data they manipulate and therefore can b e overridden

more easily However descriptive classes themselves are not well dened and lack the ability to

dene hierarchies of abstractions For all forms of parametric p olymorphism argument inference

and automatic sp ecializ ation increase generality

3

Chapter gave precise semantics for contextual p olymorphism in terms of F a variant of

the p olymorphic typed lambda calculus F Like F it is based on the concepts of environments

types type generators kinds routines and universally quantied types It introduced three new

CHAPTER CONCLUSIONS

concepts

contexts which are abstractions of environments

assertions which pro duce declarations by applying contexts to op erands and

context sorts which are analogous to routine types and type generator kinds to control

context application

Assertions link the b o dies of p olymorphic abstractions to their calling environments by pro ducing

declarations that must exist in the calling environment and provides statically checked dynamic

scoping Type generators can also use assertions to state requirements on op erand types

Contextual p olymorphism provides strong static checking separation of interfaces from imple

mentations precise interfaces including type matching within an interface generality generaliz

ability and exible It has greater incrementality than Fb ounded quantication b ecause routines

can b e overridden easily Data p olymorphism can b e added gracefully through mechanisms such as

existential types without losing precision in interfaces Contexts naturally describ e relationships

among types whereas Fb ounds naturally describ e prop erties of a single type Compared to de

scriptive classes contextual p olymorphism provides hierarchies of contexts and is b etter dened

it cleanly distinguishes types from contexts and shows where each can b e used meaningfully

Chapter discussed Cforall an extension of the C programming language to demonstrate con

texts and assertions Cforall allows identier overloading with fewer restrictions on overloadable

types than comparable languages Most builtin op erators are considered to b e overloaded rou

tines and and are overloadable constants The forall sp ecier denes p olymorphic routines

and uses assertions to constrain their argument types Algorithms created by Cormack Wright

and Bumbulis are used to infer type arguments to p olymorphic routines and to sp ecialize p oly

morphic routines automatically when necessary The existence of type parameters in p olymorphic

routines leads naturally to an opaque type facility

Cforalls overload resolution rules are based on the concepts of safe conversions conversion

cost and degrees of p olymorphism When an expression contains overloaded identiers the in

terpretation chosen minimizes the number of unsafe conversions the degree of p olymorphism of

functions and the conversion cost of the expression The overloading rules apply uniformly to

op erators and ordinary routines and were designed so that most of Cs op erators can b e dened as

a set of overloaded routines Polymorphism is required for the denition of p ointer routines The

resolution rules and denitions mimic complicated asp ects of Cs semantics the integral promo tions applied to instances of small data types in expressions the usual arithmetic conversions

CHAPTER CONCLUSIONS

applied to the op erands of binary op erators promotion of the results of unary op erators rather

than the arguments and the op erand types of the op erators including the absence of op erators

for p ointers to incomplete types This demonstrates the expressive p ower of Cforall and is an

example of the use of a small base language to dene what are primitive facilities of a larger

language

Future Work

The obvious next step is to implement Cforall to allow a trial by re of contextual p olymor

phism The most likely course of action would base a Cforall compiler on the GCC C compiler

since that compiler provides highquality co de p ortability to a number of computers and access

to a wide community of p otential users The GCC compiler already extends the C language with

nested routines and variablesized arrays which will b e helpful when implementing sp ecializations

and type parameters

A Cforall implementation should include a collection of predened contexts and p olymorphic

routines Some of the examples in section could form the basis of this design

The Cforall implementation will probably force changes in the languages design Some changes

will b e small For instance the set of predened op erators might change to accommo date the

predened contexts The denitions of the dierent routines might b e replaced by a single

p olymorphic routine that uses the arithmetic context and the op erator This change

might increase the eciency of programs that use complex programmerdened types a compiler

might p erform inline substitution and temp orary variable elimination to convert abc to ta

tb tc

Other p ossible changes would deal with weaknesses in the current design

Cforall currently makes no provision for automatic initialization or nalization co de for

instances of programmerdened types

Cforall do es not provide type generators If it did p olymorphic routines and type inference

would combine nicely with type generators

extern type Stacktype Element

foralltype Element extern void pushStackElement s

CHAPTER CONCLUSIONS

Cforall do es not provide p olymorphic data gracefully The lambdacalculus approach that

hides data inside p olymorphic routines is graceless at b est and all but requires a lambda

expression facility which Cforall do es not have to express op erations on p olymorphic data

An existential type facility based on the open statement of section may b e workable

C has three main classes of types ob ject types incomplete types and routine types In

complete types and routine types do not have instantiation or assignment op erations but

they can b e p ointed at by p ointer types Cforalls type identiers only designate ob ject

types This restricts p olymorphism since p olymorphic routines can not op erate on p ointers

to any incomplete type or to any routine types and it increases the cost of p olymorphism

since every type parameter provides instantiation and assignment even if the routine do es

not need them

Cforall could b e extended with data types the ob ject and incomplete types and all

types the data types and routine types Polymorphic routines using parameters from

these type classes would b e more exible and more ecient than equivalent routines using

type This extension would also allow even more of Cs op erators to b e dened as Cforall

routines the equality and inequality comparisons are p olymorphic over p ointers to all types and the relational op erators are p olymorphic over p ointers to all data types

Bibliography

Rob erto M Amadio and Luca Cardelli Subtyping recursive types Technical Rep ort

Digital Equipment Corp oration Systems Research Center Lytton Avenue Palo Alto

California August

American National Standards Institute Broadway New York New York Amer

ican National Standard for Information Systems Programming Language C December

X

T P Baker A onepass algorithm for overload resolution in Ada ACM Transactions on

Programming Languages and Systems Octob er

Paul G Basset Framebased software engineering IEEE Software July

HansJ Bo ehm and Mark Weiser Garbage collection in an unco op erative environment

SoftwarePractice and Experience September

Peter Bumbulis Towards making signatures rstclass p ersonal communication September

Conor P Cahill debug mallo c compsourcesunix volume issue

Peter Canning William Co ok Walter Hill Walter Oltho and John C Mitchell Fb ounded

p olymorphism for ob jectoriented programming In Fourth International Conference on Func

tional Programming Languages and Computer Architecture pages September

Luca Cardelli A semantics of multiple inheritance In G Kahn D B MacQueen and G D

Plotkin editors Semantics of Data Types pages SpringerVerlag Lecture Notes

in Computer Science v

BIBLIOGRAPHY

Luca Cardelli James Donahue Lucille Glassman Mick Jordan Bill Kalsow and Greg Nelson

Mo dula rep ort Technical Rep ort Systems Research Center Lytton Avenue Palo

Alto California August

Luca Cardelli and Peter Wegner On understanding types data abstractions and p olymor

phism ACM Computing Surveys December

Craig Chambers David Ungar and Elgin Lee An ecient implementation of SELF a

dynamicallytyped ob jectoriented language based on prototypes In Norman Meyrowitz

editor OOPSLA Conference Proceedings pages New Orleans Louisiana Octob er

Asso ciation for Computing Machinery SIGPLAN Notices

W R Co ok A prop osal for making Eiel typesafe The Computer Journal

William R Co ok Walter L Hill and Peter S Canning Inheritance is not subtyping In

Conference Record of the ACM Symposium on Principles of Programming Languages pages

Asso ciation for Computing Machinery

G V Cormack and A K Wright Polymorphism in the compiled language ForceOne In

Proceedings of the th Hawaii International Conference on Systems Sciences January

G V Cormack and A K Wright Typedep endent parameter inference SIGPLAN Notices

June Pro ceedings of the ACM Sigplan Conference on Programming

Language Design and Implementation June White Plains New York USA

Brad J Cox Objectoriented programming an evolutionary approach AddisonWesley

OJ Dahl B Myhrhaug and K Nygaard Simula Common Base Language Norwegian

Computing Center Oslo Norway Octob er

Margaret A Ellis and Bjarne Stroustrup The Annotated C Reference Manual Addison

Wesley rst edition

Christopher W Fraser and David R Hanson A retargetable compiler for ANSI C SIGPLAN

Notices Octob er

Kokichi Futatsugi Joseph A Goguen JeanPierre Jouannaud and Jose Meseguer Princi

ples of OBJ In Conference Record of the th Annual ACM Symposium on Principles of

Programming Languages pages January

BIBLIOGRAPHY

Giorgio Ghelli A static type system for message passing In Andreas Paepcke editor

OOPSLA Conference Proceedings pages Pho enix Arizona Octob er

Asso ciation for Computing Machinery SIGPLAN Notices

Carlo Ghezzi and Mehdi Jazayeri Programming Language Concepts Wiley

JY Girard Interpretation fonctionel le et elimination des coupures de larithmetique dordre

superieur PhD thesis Universite Paris

Goseph A Goguen Parameterized programming IEEE Transactions on Software Engineer

ing SE September

David M Harland Polymorphic Programming Languages Design and Implementation Com

puters and their Applications Ellis Horwoo d Market Cross House Co op er Street Chichester

West Sussex PO EB England

Paul N Hilnger Abstraction Mechanisms and Language Design ACM Distinguished Dis

sertations MIT Press

C A R Hoare Hints on programming language design Technical Rep ort CS

Stanford University Computer Science Department December Reprinted in

Jean D Ichbiah On the design of Ada In R E A Mason editor Information Processing

pages IFIP NorthHolland September

Kathleen Jensen and Niklaus Wirth Pascal User Manual and Report SpringerVerlag third

edition Revised by Andrew B Mickel and James F Miner ISO Pascal Standard

P J Landin The next programing languages Communications of the ACM

Rob ert G Lanergan and Charles A Grasso Software engineering with reusable designs

and co de In Workshop on Reusability in Programming pages ITT Programming

September

Barbara Liskov Russell Atkinson Toby Blo om Eliot Moss J Craig Schaert Rob ert Schei

er and Alan Snyder CLU Reference Manual volume of Lecture Notes in Computer

Science SpringerVerlag

Bertrand Meyer Objectoriented Software Construction Prentice Hall International Series

in Computer Science PrenticeHall

BIBLIOGRAPHY

Robin Milner and Mads Tofte Commentary on Standard ML MIT Press Cambridge

Massachusetts U S A

Robin Milner Mads Tofte and Rob ert Harp er The Denition of Standard ML MIT Press

Cambridge Massachusetts U S A

James G Mitchell William Maybury and Richard Sweet Mesa language manual Technical

Rep ort CSL Xerox Palo Alto Research Center April

John C Mitchell Toward a typed foundation for metho d sp ecializati on and inheritance In

Conference Record of the Seventeenth Annual ACM Symposium on Principles of Programming

Languages pages Asso ciation for Computing Machinery January

John C Mitchell and Rob ert Harp er The essence of ML In Conference Record of the ACM

Symposium on Principles of Programming Languages pages

John C Mitchell and Gordon D Plotkin Abstract types have existential type ACM Trans

actions on Programming Languages and Systems July

C PaulinMohring Extracting Fws programs from pro ofs in the calculus of constructions

In Conference Record of the th Annual ACM Symposium on Principles of Programming

Languages pages Austin TX January

Benjamin Pierce Scott Dietzen and Spiro Michaylov Programming in higherorder typed

lambda calculi Technical Rep ort CMUCS School of Computer Science Carnegie

Mellon University Pittsburg PA March

Benjamin C Pierce Programming with intersection types union types and p olymorphism

Technical Rep ort CMUCS Carnegie Mellon University February

John C Reynolds Towards a theory of type structure In B Robinet editor Col loque sur la

Programmation pages SpringerVerlag Lecture Notes in Computer Science

v

John C Reynolds Preliminary design of the programming language Forsythe Technical

Rep ort CMUCS Carnegie Mellon University June

David Sandb erg An alternative to sub classing SIGPLAN Notices Novem

b er

David W Sandb erg The design of the programming language X Technical Rep ort Oregon State University Department of Computer Science Corvallis Oregon

BIBLIOGRAPHY

Mary Shaw editor ALPHARD Form and Content SpringerVerlag

Mary Shaw and Wm A Wulf Toward relaxing assumptions in languages and their im

plementations Technical rep ort CarnegieMellon University January Reprinted in

Alan Snyder Encapsulation and inheritance in ob jectoriented programming languages SIG

PLAN Notices November

Richard M Stallman GCC Free Software Foundation Cambridge MA

Standardiseringskommissionen i Sverige Databehandling Programsprak SIMULA

Svensk Standard SS

Peter A Steenkiste The implementation of tags and runtime checking In Peter Lee editor

Topics in Advanced Language Implementation chapter pages The MIT Press

C Strachey Fundamental concepts in programming languages In Lecture Notes for the

International Summer School in Computer Programming Cop enhagen August

Bjarne Stroustrup What is ob jectoriented programming In Proceedings of the First

European Conference on Object Oriented Programming June

R D Tennent Language design metho ds based on semantic principles Acta Infomatica

reprinted in

United States Department of Defense The Programming Language Ada Reference Manual

ANSIMILSTDA edition February Published by SpringerVerlag

A van Wijngaarden B J Mailloux J E L Peck C H A Koster M Sintzo C H

Lindsey L G L T Meertens and R G Fisher Revised rep ort on the algorithmic language

ALGOL SIGPLAN Notices May

D Le Verrand Evaluating Ada North Oxford Academic

Philip Wadler and Stephen Blott How to make adhoc p olymorphism less adhoc In Confer

ence Record of the ACM Symposium on Principles of Programming Languages pages

Asso ciation for Computing Machinery

Peter J L Wallis and Bernhard W Silverman Ecient implementation of the Ada over

loading rules Information Processing Letters April

BIBLIOGRAPHY

Anthony I Wasserman editor Tutorial Programming Language Design Computer So ciety

Press

B Wegbreit The treatment of data types in EL Communications of the ACM

May

N Wirth Type extensions ACM Transactions on Programming Languages and Systems

April

Niklaus Wirth On the design of programming languages In Information Processing

pages North Holland Publishing Company Reprinted in

Andrew K Wright Design of the programming language ForceOne Technical Rep ort CS

University of Waterloo February

Benjamin Zorn and Paul Hilnger A memory allo cation proler for C and lisp programs In

Summer USENIX proceedings

Index

l m n substitution the kind of term types

t k has kind 2 the sort of environments

t e Fb ounded quantication

abs

t e type parameterization

absolute value

environments

i

abstract sup erclass

environment concatenation

1 2

t b ounded universal quantica

1 2

abstract type

tion

abstype

t universally quantied type

adho c p olymorphism

reduction

according to Strachey

p q

inference rule

r

b ehavioural

x e routines

Ada

context sorts

i

addable

sort judgements

1 2

Algol

e type judgements

algorithm

t k kind judgements

allo ca

empty environment

Alphard

h i record types

ambiguous interpretation

h f e i record values

ANY

types

i i

arithmetic types

t existential type quantication

assertion

t k contexts

3 such that

assertion declarations

3 assertions

subtype of

routine types

1 2

C

e has type

C

k the sort of contexts

child class

INDEX

Circle e e expressions

i

class Eiel

client EL

Clu environment

co ercion environment concatenation

collection existential types

comparable expressive

COMPILER

F

Complex

3

F

conformity clause

Fb ounded quantication

context

elds

context sort

exibility

context statement

ForceOne

contravariance

Fraction

conversion cost

free types

covariance

functors

curtailment

cvt

generality

generalizability

data algebra

generic packages

declaration

declaration corresp ondence

implementation

default view

implicit conversion

denition mo dule

implicit parameters

degree of p olymorphism

imp ort

descriptive classes

inclusion p olymorphism

dom domain

Cardelli and Wegner

double

incomplete types

DOUBLE

incrementality

DOUBLE

inference rules

double

InFile

dynamic checking

inheritance

dynamic overload resolution

instantiation

dynamic scop e

integral types

dynamic type determination interface

INDEX

NF normal form interpretation

normal form IOFile

notion

judgements

OBJ

kind

ob ject

kind judgement

ob ject type

Ob jectiveC

lambda calculus

op

less p olymorphic

opaque type

let statement

op eration

Lisp

ordered

List

OutFile

list of

overloading

of addable list

LT PAIR

pack

lvalue

package

package sp ecication

map

PAIR

maps

T Mesa PAIR

pane

message

parameterized theories

message passing

parametric p olymorphism

metho d

according to Strachey min

b ehavioural

parent classes

int min

PARSER OBJ MIN

Pascal

min rec

plus

mixed mo de op erations

Point

Mo dula

p olymorphic data mo dule

p olymorphism

mo dule interfaces

precise interfaces

multimethods

program mo dule multiple inheritance

record name equivalence

INDEX

record type TOKEN

Rect transfer function

Region tuple

routine type

routine type type denition

type generator

safe conversions

type judgement

satisfy

type matching

scalar types

type parameters

SCANNER

type qualier

SELF

type statement

self

settheoretic union union types see settheoretic unions

sharing declaration uniting co ercion

signature universal p olymorphism

SIMULA Cardelli and Wegner

sin universal quantication

sizeof universally quantied type

SML unsafe conversions

sort

view

sort judgement

sp ecializ ation

X

stack

static checking

static overload resolution

structural equivalence

structure

sub classes

substitution

subtype

sum

sup erclasse s

tcvt theory