0% found this document useful (0 votes)
12 views13 pages

Lecture 5 - Type Systems

le type system

Uploaded by

DA BEST
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views13 pages

Lecture 5 - Type Systems

le type system

Uploaded by

DA BEST
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Further Programming Paradigms

Lecture 5: Type Systems

Prof. Paul Krause, University of Surrey


Key Topics

• Types as supporting the conceptualisation of programs

• Implementation of type systems

• Static and dynamic type checking

• Type safety
Type Systems

Every programming language has a type system:

• The set of predefined types of the language.

• The mechanisms which permit the definition of new types.

• The mechanisms for the control of types:


• Equivalence rules;
• Compatibility rules;
• Rules and techniques for type inference.

• The specification as to whether (or which) constraints are statically or


dynamically checked.

• A type system is type safe (strongly typed) when no program can violate the
distinctions between types defined in the corresponding language.
Classification of types

We can classify the types of a programming language according to whether they


are:
• Denotable;
• Expressible;
• Storable.
• For example: values of type integer are generally all three;
• a function from int to int is denotable in most languages:
int succ (int x){
return x+1;
}
• But in most imperative languages, functionals are neither expressible nor
storable.
But what’s a functional?

• A higher order function that takes functions as arguments

function printArray(array) {
for (var i = 0; i < array.length; i++)
print(array[i]);
}
Or:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}

forEach(["Wampeter", "Foma", "Granfalloon"], print);


Static and Dynamic Type Checking

• Static typing - checks on type constraints conducted at compile time


• Language design is more complex, and compilation takes longer, but
• Testing and debug phases are shorter, and
• Correctness is guaranteed for every execution sequence

• Dynamic typing - checks on type constraints conducted at run time


• Not efficient as checks are intermixed with code execution
• Possible that type errors are revealed during program execution by users
Something to be aware of about static typing

• Consider the following fragment:


int x;
if (0==1) x = “pippo";
else x = 3+4;

Note for the moment without proof:


• There is no universal procedure for determining whether or not a program will
terminate after a finite number of steps (the Halting problem)
• A Corollary is that there exists no static check that can determine all and only
those programs that produce errors at runtime.
• Consequently, static typing is more conservative than dynamic typing - it
excludes more programs than is strictly necessary, in order to guarantee
correctness.
Scalar Types

• Booleans
• Characters
• Integers
• Reals
• Fixed point
• Complex
• Void
• Enumerations
• Intervals
Why is void a type?

• We define a function which returns nothing as:

• void f (...){...}

• We need this in order to specify the codomain of f

• There are no functions with an empty codomain, so the assumption is made


that void has a single element that is (implicitly) returned - although we have
no interest in what it is!
Design weaknesses to watch for

Consider the definition of an enumeration in C:


enum Dwarf {Bashful, Doc, Dopey, Grumpy, Happy, Sleepy,
Sneezy};

This is essentially equivalent to the following:


typedef int Dwarf;
const Dwarf Bashful=0, Doc=1, Dopey=2,
Grumpy=3, Happy=4, Sleepy=5, Sneezy=6;

• This means an integer can be used in place of Dwarf and vice versa - so
this helps in documentation but does not support any stronger checking
Contrast with this in C++

enum class Traffic_light { red, yellow, green };


enum class Warning { green, yellow, orange, red }; // fire alert levels
Warning a1 = 7; // error : no int->Warning conversion
int a2 = green; // error: green not in scope
int a3 = Warning::green; // error : no Warning->int conversion
Warning a4 = Warning::green; // OK
void f(Traffic_light x)
{
if (x == 9) { /* ... */ } // error: 9 is not a Traffic_light
if (x == red) { /* ... */ } // error: no red in scope
if (x == Warning::red) { /* ... */ } // error: x is not a Warning
if (x == Traffic_light::red) { /* ... */ } // OK
}
Does all this give us type safety?

We can distinguish between


• Non safe languages
• Type system provides methodological suggestions but the programmer can
bypass type checking: C, C++ because both allow access to the value of a
pointer
• Locally unsafe languages
• Well regulated type system but some limited constructs allow insecure
programs to be written: Algol, Pascal and Ada
• Safe languages
• A theorem guarantees that the execution of a typed program can never
generate a hidden error “induced by the violation of a type.”: Lisp, Scheme,
ML, Java
Some more things to think about!

• The primary composite types, among which are records, variant records and
unions, arrays and pointers in detail.
• The concept of type equivalence.
• The concept of compatibility and the related concepts of coercion and
conversion.
• The concept of overloading, when a single name denotes more than one object
and static disambiguation.
• The concept of universal polymorphism, when a single name denotes an object
that belongs to many different types.
• Type inference, that is mechanisms that allow the type of a complex expression
to be determined from the types of its elementary types.
• Techniques for runtime checking for dangling references.
• Techniques for garbage collection.

You might also like