Download presentation
Published byAlvin Rodgers Modified over 9 years ago
1
CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha
Data Types-I: Type System
2
What is a type? Type: A well-defined set of values and a set of meaningful operations on those values. Example: int has values {. . . , -2, -1, 0, 1, 2, . . .} and operations {+,-,*,/, . . .} on those values. A type system is a well-defined system of associating types with variables and other objects defined in a program. Types provide semantic sanity checks on programs.
3
What are types good for? Allow the compiler to catch a wide variety of common programming errors. Provide implicit context for a number of operations, freeing the programmer from the need to specify that context explicitly. Type checking cannot prevent all meaningless operations. On the other hand, type checking catches enough of them.
4
Type Error A type error is a run-time error that occurs when an operation is attempted on a value for which it is not well-defined.
5
Typing System Two kinds of criteria: Strong typing vs. weak typing
Static typing vs. dynamic typing
6
Strong typing vs. Weak Typing
Strong typing: A programming language is strongly typed if its type system allows all type errors in programs to be detected, either at compile time or at run time, before the statement in which they can occur is actually executed. Accept only safe expressions (guaranteed to evaluate without a type error) Weak typing: The language allows automatic type conversions with the proviso that there may be some loss of information.
7
Static typing vs. dynamic typing
Static typing: A variable has a single type associated with it throughout its life at run time. Types of all variables/expressions are determined at compile time. How? – Explicit declaration, or – Type reconstruction Examples: C++, Java, Ada Dynamic typing: allow the type of a variable, as well as its value, to change as the program runs. Most of the checking is done at run time. Example: LISP
8
Type-safe Programs A program is said to be type-safe if it executes without any type error. All the programs in a strongly typed language are, by definition, type safe. A language is type safe if all its programs are. Type safe: Lisp (all dynamically typed languages) Not type safe: C/C++, Java
9
Typing System
10
Static Type Checking Points out type errors early No run-time overhead
Highly desirable - key design feature in modern programming languages Not always possible Pascal, Java: array index bounds part of array type; need run-time check for subscripts out of bounds.
11
Dynamic Type Checking Incurs run-time overhead plus needs space for type tags Operations need to check type tags of their operands before executing Programs are harder to debug Allows more flexibility in programming language design
12
Typing System in Important Languages
Strong typing Static typing Common Lisp √ × C Perl Python/Ruby
13
Common terms Discrete types (countable) Scalar types integer boolean
char enum subrange Scalar types real
14
Primitive Types boolean char
Numerical: integers, reals (floating point) Enumeration (user-defined) Pascal: type weekday = (sun, mon, tue, wed, thu, fri, sat); Java, C++, C#: enum special_regs {gp = 28, fp=30, sp = 29, ra =31}; Subrange Ada: subtype workday is weekday range mon..fri;
15
Composite types Records Variant Records (Unions) Arrays strings Sets
Pointers Lists Files
16
Orthogonality A collection of features is said to be orthogonal if there are no restrictions on the ways in which the features can be combined. (Analogy to mutually orthogonal vectors) Orthogonality is a useful goal in the design of a language, particularly its type system. It makes a language easy to understand, easy to use, and easy to reason about.
17
Orthogonality: An Example
Pascal Orthogonal things Allows arrays to be constructed from any discrete index type and any component type. Allows records to contain any component type. Non-orthogonal things: Requires that variant fields of a record follow all other fields. Limits function return values to scalar and pointer types, while allows subroutines to be passed as parameters. Requires the bounds of each array to be specified at compile time except when the array is a formal parameter of a subroutine.
18
Type Checking Type equivalence: When are the types of two values identical? Type compatibility: When can a value of type A be used in a context that expects type B? Type inference: What is the type of an expression, given the types of the operands?
19
Type Checking Certainly format does not matter.
struct {int a, b;}; is the same as struct { int a, b; }; We certainly want them to be the same as struct { int a; int b; };
20
Type Equivalence Governs which constructed types are considered “equivalent” for operations such as assignment. Two major approaches: – Structural equivalence – Name equivalence
21
Type Equivalence Structural equivalence: Based on the content of type definitions: Two types are the same if they consist of the same components, put together in the same way. Name equivalence: Based on the lexical occurrences of type declarations: Each declaration introduces a new type.
22
Structural Equivalence
Types are equivalent as terms Same primitive type formed by application of same type constructors to structurally equivalent types. Original types are equivalent if the expanded type descriptions are the same type salary: int; var s: salary; type height: int; var y: height; s + y is valid by structural equivalence rules. Used by Algol-68, Modula-3, ML and C (except for its structs)
23
Drawback of Structural Equivalence
Structural equivalence is a low-level, implementation-oriented thinking of types. Not possible to distinguish between types that the programmer may think of as distinct, but which happen, by coincidence, to have the same internal structure. type student = record type school = record name, address : string name, address : string age : integer age : integer end; end;
24
Name Equivalence Use name of type to assert equivalence. Aliased types are considered distinct. In Ada: type height: int var x: list (int) var y: list (int) var s: list (height) x, y are considered to be of the same type. y, s are considered to be of different types.
25
Name Equivalence TYPE celsius_temp = REAL; fahrenheit_temp = REAL; VAR c : celsius_temp; f : fahrenheit_temp; ... f := c; (* this should probably be an error *)
26
Name Equivalence type cell = ... type alink = pointer to cell
type blink = alink p, q : pointer to cell r : alink s : blink t : pointer to cell u : alink Name equivalence: {p, q, t}, {r, u}, {s} Structural equivalence: {p, q, t, r, u, s} Name equivalence is the current trend in language design.
27
Type Compatibility var a : integer; b, c : real; ... c := a + b;
When an expression of one type is used in a context where a different type is expected, one normally gets a type error. But what about the following? var a : integer; b, c : real; c := a + b; Many languages allow things like this, and COERCE an expression to be of the proper type
28
Coercion Coercion can be based just on types of operands, or can take into account expected type from surrounding context as well. Fortran has a lot of coercion, all based on operand type. C/C++ , too, has a lot of coercion, but with simpler rules: all floats in expressions become doubles short int and char become int in expressions if necessary, precision is removed when assigning into LHS. Modula-2 and Ada do not permit coercions. Java and C# ban a coercion if it results in a loss of data. Recent thought is that coercion is a bad idea.
29
Type Conversion Understand the difference between
type conversions (explicit) type coercions (implicit) Conversion can only happen between related data types integer to floats, and vice versa enumeration type to integer, and vice versa subclass to base class, and vice versa Sometimes the word 'cast' is used for conversions.
30
Type Conversion n : integer; --- assume 32 bits r : real; --- assume IEEE double-precision t : test_score; --- a subrange of integers c : celsius_temp; --- an alias of integers ... t := test_score(n); --- run-time check n := integer(t); --- no check r := real(n); --- run-time conversion n := integer(r); --- run-time conversion and check n := integer(c); --- no run-time code required c := celsius_temp(n); --- no run-time code required
31
Type Conversion Type Conversion in C: Type Conversion in C++:
r = (float) n; n = (int) r; Type Conversion in C++: r = static_cast<float> n; n = static_cast<int> r;
32
Nonconverting Type Cast
Change the type without changing the underlying implementations. In Ada: function cast_float_to_int is new unchecked_conversion(float, integer); function cast_int_to_float is new unchecked_conversion(integer, float); f := cast_int_to_float(n); n := cast_float_to_int(f); In C++: I = reinterpret_cast<int>(p); // cast pointer to integer n = reinterpret_cast<float>(i); // probably not what we want
33
Nonconverting Cast Nonconverting cast can happen between types of the same storage size (dangerous!) A pointer to any integral type large enough to hold it A value of integral or enumeration type to a pointer A pointer to a function to a pointer to a function of a different type A pointer to an object to a pointer to an object of a different type A pointer to a member to a pointer to a member of a different class or type, if the types of the members are both function types or object types
34
Type Inference Type inference, or implicit typing, refers to the ability to deduce automatically the type of a value in a programming language Convenience: programmers are free to omit type annotations while maintaining some level of type safety Often a characteristic of functional programming languages. Languages equipped with type inference include Ada, C#, Haskell, ML, OCaml, Scala, and Visual Basic .NET 9.0. Planned feature for C++ and Perl 6
35
Type Inference
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.