














Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Material Type: Notes; Class: Programming Languages; Subject: Computer Science; University: University of Texas - San Antonio; Term: Unknown 1989;
Typology: Study notes
1 / 22
This page cannot be seen from the preview
Don't miss anything!















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
int, bool, character, real, symbol Values of different types have different layouts have different operations Explicit vs. implicit type conversion of 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 : int int
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
function call x() where x is not a function may cause jump to instruction that does not contain a legal op code
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)
(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
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
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 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
In C/C++: suppose we don’t need to declare variables f (a, b, c) { return a + b + c; } +: intintint a: int; b: int; c: int; a + b + c : int +: floatfloatfloat a : float; b : float; c : float; … type error In Scheme: expressions could have multiple types (lambda (a b c) (+ (+ a b) c)) +: number*numbernumber 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
(define f (lambda (x) (+ 2 x)))
f: int → int
+ 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.