Lecture Slides on Types - Programming Languages | CS 3723, Study notes of Programming Languages

Material Type: Notes; Class: Programming Languages; Subject: Computer Science; University: University of Texas - San Antonio; Term: Unknown 1989;

Typology: Study notes

Pre 2010

Uploaded on 07/30/2009

koofers-user-slu
koofers-user-slu 🇺🇸

8 documents

1 / 22

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
cs3723 1
Types
Classification of Values
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Partial preview of the text

Download Lecture Slides on Types - Programming Languages | CS 3723 and more Study notes Programming Languages in PDF only on Docsity!

Types

Classification of Values

Outline

 General discussion of types

 What is a type?

 Compile-time vs run-time type checking

 Conservative program analysis

 Type inference

 Good example of static analysis algorithm

 Will study algorithm and examples

 Polymorphism

 Polymorphism vs overloading

 Uniform vs non-uniform impl of polymorphism

Types in Programming

 A type is a collection of computable values  Represent concepts from problem domain  Accounts, banks, employees, students  Represent different implementation of values  Integers, strings, floating points, lists, records, tuples …  Languages use types to  Support organization of concepts  Separate types for separate concepts from problem domain  Identify and prevent errors  Compile-time and run-time type checking  Prevent meaningless computation 3 + true - “Bill”  Support efficient translation (by compilers)  Short integers require fewer bits  Access record component by a known offset  Use integer units for integer operations

Values and Types

 Basic types: types of atomic values

 int, bool, character, real, symbol  Values of different types  have different layouts  have different operations  Explicit vs. implicit type conversion of values

 Compound types: types of compound values

 List, record, array, tuple, struct, ref, pointer  Built from type constructors  int arr[100]  arr: array(int,100)  (3, 4, “abc”) : int * int * string  int *x  x : pointer(int)int f(int x) { return x + 5}  f : intint

The Type System

 Each language has a type system that includes

 A collection of basic types and compound types  Type declaration rules on how to introduce new types  For each basic/compound type, rules on  How to build values of the type  integers(eg.,1,23,-3290); floating point numbers(e.g., 3.5, 0.12)  Symbols(‘abc); chars (‘a’, ‘b’); strings(“abc”); lists: ‘(abc 3)  Type constructors for arrays, structs, records, etc.  How to operate on values of the type  Evaluation rules, equality, introduction and elimination operations  Each operation is defined only on specific types of operands and returns only a specific type of values  A type error occurs if an operation applied to operands outside its domain

Type Error

 When a value is misinterpreted or misused

with unintended semantics, a type error

 May cause hardware error

function call x() where x is not a function  may cause jump to instruction that does not contain a legal op code

 May simply return incorrect value

int_add(3, 4.5)

 not a hardware error  bit pattern of 4.5 can be interpreted as an integer  just as much an error as x() above

Type Checking  Type checking: try to discover and report all type errors  Can be done at compile-time or run-time, or both  Run-time type checking (Lisp/Scheme, perl) Example: in Lisp/Scheme, when evaluating each (car x)  Check to make sure x is a non-empty list  Compile-time type checking (ML, Java, C++/C) In C/C++/Java, if a function f is declared int f(float x)  The compiler ensures that f is invoked only with float-type expressions  Compile-time (static) vs Run-time (dynamic) Type Checking  Both prevent type errors  Run-time checking slows down execution and does not offer early error detection  Types of operands must be checked before each operation  Compile-time checking restricts program flexibility and cannot discover all errors  Every variable/storage can hold only a single type of values  Combination of compile and runtime checking  Example: Java (array bound check at runtime)

Flexibility vs. Safety

 In Lisp, we can write function like

(lambda (x) (if (number? x) (+ x 1) (car x))) x could be a number or a list. if x is a symbol, a type error will occur  cannot apply car to x Some uses will produce type error, some will not

 Static type checking is always conservative

 Must define a different function for each input type int f1 (int x) { return x + 1; } int f2 (Intlist x) { return first_elem(x); } …… do we need a different function for floating point lists?

Parametric vs. Ad hoc Polymorphism  Parametric polymorphism (type variables) (define first (lambda (x) (car x))) x: ‘a list (any kind of list); first : ‘a list  ‘a A single implementation (algorithm) is used for all different types of input  Ad hoc polymorphism (operator overloading) (define Add (lambda (x y) (if (number? y) (+ x y) (cons x y)))) When applied to numbers: x: number; y : number; Add: number*number number When applied to lists x: ‘a; y : ‘a list; Add: ‘a * ‘a list  ‘a list Different implementations ( (+ x y) vs. (cons x y)) are used for different types  Dynamically typed languages (e.g., Lisp/Scheme) supports both parametric and ad hoc polymorphism  What about C/Java/C++?

Static Type Checking --- Find Type Errors Without Running the Program  Program Analysis Tools  Try to derive properties of program without running the program  Try to find errors in programs without debugging  Growing area of commercial activity  Static type checking  Declare types of variables  Each variable must have a single type  It can hold only values of this type  Symbol table: records the type of each variable  Naming conflict: use nested symbol tables  Evaluate types of expressions  Every expression must have a single type  It maps input values to a return value  It can return only values of this type  A static type system  Include rules for deciding types of expressions  These rules specify the proper usage of each operator  Accept only expressions that can be typed according to rules  May support explicit vs. implicit type conversion

More on Static Type Checking

 In statically typed languages (ML, C,C++,Java)  Each variable has a single type  each expression has a single type  E.g., in C/C++ int f (int a, int b, int c) { return a + b + c; } ((a int) (b int) (c int))  (a+b+c) : int  In dynamically typed languages (Lisp/Scheme)  Each variable may have different types depending on the running context  each expression may have different types  E.g., in Scheme (lambda (a b c) (+ a b c)) ((a int) (b int) (c int))  (a+b+c) : int ((a float) (b int) (c int))  (a + b + c) : float ((a list) (b int) (c int))  (a + b + c): type_error

Static type checking and type

inference

 Static type checking int f(int x) { return x+1; }; int g(int y) { return f(y+1)2;};  Programmer has to declare the types of all variables  Compilers evaluate the types of expressions and check agreement  Type inference: extension to static type checking int f(int x) { return x+1; }; int g(int y) { return f(y+1)2;};  Programmers are not required to declare types for variables  Compilers try to figure out agreeable types of all expressions  Find most general type by solving constraints  Lead to parametric polymorphism

Type Inference

 In C/C++: suppose we don’t need to declare variables f (a, b, c) { return a + b + c; } +: intintint  a: int; b: int; c: int; a + b + c : int +: floatfloatfloat  a : float; b : float; c : float; …  type error  In Scheme: expressions could have multiple types (lambda (a b c) (+ (+ a b) c)) +: number*numbernumber  a: number; b : number; c : number; (+ a b) : number  In statically typed languages (ML, C, C++, Java)  When each operator has a single type definition, we can automatically infer types of variables and expressions  When each operator has multiple type definitions (evaluation rules), type inference can easily fail  An operator is overloaded if it has multiple type definitions

Type Inference

 Another example in Scheme

(define f (lambda (x) (+ 2 x)))

f: int → int

 How does it work

 + has two types: intint->int, realreal->real  2 : int has only one type  This implies + : int*int -> int  Therefore, need x : int  Therefore f(x:int) = 2+x has type int → int + is overloaded because it has two types. Most operators in a static type system have a single type In many cases, unique type may be polymorphic.