04/21/23 IT 327 1
A Type is a Set
1. A set of values
2. A low-level representation
3. A collection of operations on those values
int n;
Chapter 6: Types
Bertrand Russell (1872 – 1970)
(1910)
Alfred N. Whitehead (1861 – 1947)
Required for programming languages, so it is more restricted.
04/21/23 IT 327 2
Issues of types
– Type annotations (how to declare?)– Type inference (how to determine?)– Type checking (when to check?)– Type equivalence issues (what is it?)
04/21/23 IT 327 3
Primitive vs. Constructed Types Primitive type: can be used but cannot be defined.
ML: int, real, char
Constructed type: can be defined in a program
ML: type intpair = int * int
04/21/23 IT 327 4
Primitive Types
Every programming language defines its primitive types
– Some define the primitive types precisely for implementation (e.g., Java)
– Some leave it loose for implementation (e.g., C, ML)
04/21/23 IT 327 5
Integral Types in different PL’s
C:charunsigned charshort intunsigned short intintunsigned intlong intunsigned long intNo standard implementation, but longer sizes must provide at least as much range as shorter sizes.
Java:byte (1-byte signed)char (2-byte unsigned)short (2-byte signed)int (4-byte signed)long (8-byte signed)
Scheme:integerIntegers of unbounded range
04/21/23 IT 327 6
Issues of primitive types What sets of values?
– Language specification; how much left up to the implementation?
– If necessary, how can a program find out? (INT_MAX in C, Int.maxInt in ML, etc.)
What operations are supported?– Detailed definitions: rounding, exceptions, etc.
The choice of representation is a critical part in these decisions
04/21/23 IT 327 7
Constructed Types
1. enumerations2. tuples3. arrays4. strings5. lists6. unions7. subtypes8. function types
Example:
Each has a connection to a set operation in mathematics
04/21/23 IT 327 8
Making Sets by Enumeration
We can construct sets by just listing all the elements:
},,{ cbaS
C: enum coin {penny, nickel, dime, quarter};Ada: type GENDER is (MALE, FEMALE);Pascal: type primaryColors = (red, green, blue);ML: datatype day = M | Tu | W | Th | F | Sa | Su;
These define a new type (= set) They also define a collection of named constants of that type
(= elements)
04/21/23 IT 327 9
Representing Enumeration Values
A common representation is to treat the values of an enumeration as small integers
enum coin { penny = 1, nickel = 5, dime = 10, quarter = 25 };
enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t', NEWLINE = '\n', VTAB = '\v', RETURN = '\r' };
They are countable!!
04/21/23 IT 327 10
Operations on Enumeration Values
Equality test:
If using integer to represent elements then elements are legitimate for all integer operations:
fun isWeekend x = (x = Sa orelse x = Su);
Pascal: for C := red to blue do P(C)
C: int x = penny + nickel + dime;
04/21/23 IT 327 11
Making Sets by Tupling
The Cartesian product of two or more sets defines tuples:
YyXxyx
YXS
|,
Some language like ML supports pure tuples:
(i.e., fields without names)
fun get1 (x : real * real) = #1 x;
04/21/23 IT 327 12
Making Types by Tupling Many PLs support record types: tuples with named fields
C:
struct complex { double rp; double ip;} x;
ML:
type complex = { rp:real, ip:real};
Operations on tuples: (selection)
C: x.ipML: #ip x
fun getip (x : complex) = #ip x;
04/21/23 IT 327 13
Representing Tuple Values
A common representation is to just place the elements side-by-side in memory
But there are lots of details:– In what order?– Are there “holes” between elements (e.g. on
word boundaries) in memory?– Are these details visible to the programmer?
04/21/23 IT 327 14
What does C say about tuples (structs)?
Preface
C is a general-purpose programming language which features economy of expression, modern control flow and data structures, and a rich set of operators. C is not a “very high level” language, nor a “big” one, and is not specialized to any particular area of application. But its absence of restrictions and its generality make it more convenient and effective for many tasks than supposedly more powerful languages.
…..
The C Programming LanguageBrian W. Kernighan and Dennis M. Ritchie1978 edition
Let’s see what does C say about itself first.
04/21/23 IT 327 15
ANSI C
The members of a structure have addresses increasing in the order of their declarations. A non-field member of a structure is aligned at an addressing boundary depending on its type; therefore, there may be unnamed holes in a structure.
struct { unsigned keyword : 1;
unsigned external : 1;unsigned statics : 1;
int value; unsigned ascii : 7; char eascii;} flag1, flag2;
1 1 0 1 1 0 0 0
0 1 0 1 1 1 0 1
0 0 1 1 1 0 1 0
0 1 1 0 0 1 0 0
0 0 1 1 0 1 1 0
1 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1
0 1 1 0 0 1 1 1
0 0 0 0 1 1 1 0
flag1
flag2
unnamed holes
04/21/23 IT 327 16
Sets of Vectors Fixed-size vectors:
Arbitrary-size vectors:
XxixxXS inn .|,,1
i
iXXS
In PLs: arrays, strings, lists Issues:
– What are the index values?– Is the array size fixed at compile time?
What is the difference between this and tuples?
04/21/23 IT 327 17
Index values for array Java, C, C++:
– First element of an array a is a[0]– Indexes are always integers starting from 0
Pascal is more flexible:– integers, characters, enumerations, subranges– Starting/Ending index chosen by the programmer– size is fixed at compile time
type LetterCount = array['a'..'z'] of Integer;var Counts: LetterCount;
begin Counts['a'] = 1 ………
04/21/23 IT 327 18
Array designers need to decide:
1. What are the index values?2. Is array size fixed at compile time (static type)?3. What operations are supported?4. Are multiple dimensions allowed?5. Is a higher-dimensional array the same as an array of
arrays?6. Is re-dimensioning possible at runtime?7. What is the order of elements in memory?8. Is there a separate type for strings (not just array of
characters)?9. Is there a separate type for lists?
04/21/23 IT 327 19
Making Types by Union
C:
union element { int i; float f;};
ML:
datatype element = I of int | F of real;
Making Sets by Union: YXS
04/21/23 IT 327 20
Representing Union Values
Two (or more) representations overlap each other in memory.
This representation may or may not be exposed to the programmer
union element { int i; char *p;} u;
/* sizeof(u) is */ /* max(sizeof(u.i),sizeof(u.p)) */
04/21/23 IT 327 21
Loosely Typed Unions Some languages expose the details of union implementation
(i.e., the programmer knows the implementation)
union element { int i; float f;} e;
No type casting is involved
e
f
i
float x;int n;e.i = 100;e.f = 1.0;x = e.f;n = e.i;
04/21/23 IT 327 22
Strictly Typed Unions
In ML, an element type x is either I or F, thus, you have to say what to do with each type of value in the union:
datatype element = I of int | F of real;
Type casting is involved
fun getReal (F x) = x | getReal (I x) = real x;
04/21/23 IT 327 23
Variant Records Union where specific type is dynamically
determined by the value of a field (“discriminated union”)
Ada and Modula-2C: I don’t care what is it.
ML: I have to know what is it in advance
Ada: Let’s see what is it.
04/21/23 IT 327 24
Ada Variant Record Example
type DEVICE is (PRINTER, DISK);
type PERIPHERAL(Unit: DEVICE) is record HoursWorking: INTEGER;
case Unit is when PRINTER => Line_count: INTEGER;
when DISK => Cylinder: INTEGER; Track: INTEGER;
end case; end record;
04/21/23 IT 327 25
Subsets
We can define the subset selected by any predicate P:
)(| xPXxS
S X
04/21/23 IT 327 26
Making Subtypes
– Less general: Pascal subranges
type digit = 0..9;
– More general: Ada subtypes
subtype DIGIT is INTEGER range 0..9;subtype WEEKDAY is DAY range
MON..FRI;
– Most general: Lisp types with predicates
04/21/23 IT 327 27
Ada Subtypestype DEVICE is (PRINTER, DISK);
type PERIPHERAL(Unit: DEVICE) is record HoursWorking: INTEGER; case Unit is when PRINTER => Line_count: INTEGER; when DISK => Cylinder: INTEGER; Track: INTEGER; end case; end record;
subtype DISK_UNIT is PERIPHERAL(DISK);
04/21/23 IT 327 28
Types with Predicates in Lisp
(declare (type integer x))
(declare (type (or null cons) x))
(declare (type (and number (not integer)) x))
(declare (type (and integer (satisfies evenp)) x))
04/21/23 IT 327 29
Representing Subtype Values
Usually, we just use the same representation for the subtype as for the supertype
Questions:– Do we want to shorten it if we can?
I.e., does X: 1..9 take the same space as X: Integer?
– Do we enforce the subtyping?
Is X := 10 legal? What about X := X + 1?
04/21/23 IT 327 30
Type is a key idea of OOP
A class is a type: data and operations on that data, bundled together
A subclass is a subtype: it includes a subset of the objects, but supports a superset of the operations
04/21/23 IT 327 31
Making Sets of Functions
define a set of functions with given domain and range:
RfDffRDS ran dom|
A set can be a collection of functions
NNffNNS :|
04/21/23 IT 327 32
Making Types of Functions
Most languages have some notion of the type of a function:
int f(char a, char b) { return a==b;}
fun f(a:char, b:char) = (a = b);ML:
C:
04/21/23 IT 327 33
Operations on Function Values
call the function bound to variables passed as parameters Treated as value
Many languages support nothing beyond function call
(What can C do?)
ML supports many operations (all above and others)
04/21/23 IT 327 34
Type AnnotationsThe syntax for describing types
Some languages use naming conventions to declare the types of variables
– BASIC: S$ is a string – Fortran: I is an integer
Like explicit annotations, these conventions provide static type information
04/21/23 IT 327 35
Type Inference
Infers a static type for every expression and for every function, usually requires no annotations
Constants usually have static types– Java: 10 has type int, 10L has type long
Expressions may have static types inferred from operators and types of operands– Java: if a is double, a*0 is double
(0.0)
Simple
Complicate
Determining the types
04/21/23 IT 327 36
Static Type Checking
Static type checking determines a type for everything before running the program: variables, functions, expressions, everything
Compile-time error messages when static types are not consistent
– Operators: 1+"abc"– Functions: round("abc")– Statements: if "abc" then …
Most modern languages are statically typed
04/21/23 IT 327 37
Dynamic Typing
In some languages, programs are not statically type-checked before being run. they are dynamically type-checked during the runtime.
At runtime, the language system checks that operands are of suitable types for operations
04/21/23 IT 327 38
Example: Lisp
It won’t work if a or b is not a number An improper call, like (f nil nil), is
not caught at compile time It is caught at runtime – that is dynamic
typing
(defun f (a b) (+ a b))
04/21/23 IT 327 39
Explicit Runtime Type Tests
Some languages allow explicit runtime type tests:– Java: test object type with instanceof
operator Type information is known at runtime, even
when the language is mostly statically typed
04/21/23 IT 327 40
Strong Typing Weak Typing
The purpose of type-checking is to prevent the application of operations to incorrect types of operands
ML and Java, the type-checking is thorough enough to guarantee this—that’s strong typing
C has holes in the type system that add flexibility but weaken the guarantee
04/21/23 IT 327 41
Type Equivalence
What happens if apply f to an irpair2?
– Name equivalence does not permit this: irpair2 and irpair1 are different names
– Structural equivalence does permit this, since the types are constructed identically
ML uses Structural equivalence
type irpair1 = int * real;type irpair2 = int * real;fun f(x:irpair1) = #1 x;