Data Types
Last updated
Last updated
Lecture slide:
Typing: strong vs. weak, static vs. dynamic. Type declarations, type equivalence, type inference. Subtypes and derived types. Scalar and composite types (arrays, records, variant records). Pointers and References
Readings: Scott, ch. 7
A language can have a mixture of both, like C#, Visual Basic, Alore. Java has a mostly static type system with some runtime checks.
Languages like Ada, C++, Java, ML.
Variables have types.
Compilers ensures (at compile time) that type rules are obeyed.
Languages like JavaScript, PHP, Lisp, Ruby.
Variables do not have types, values do.
Compilers ensures (at run time) that type rules are obeyed.
Static is faster. Dynamic typing requires run-time checks.
Dynamic is more flexible.
Static is easier to refactor code.
A strongly typed language does not allow variables to be used in a way inconsistent with their types (no loopholes). A weakly typed language allows many ways to bypass the type system (e.g., pointer arithmetic).
There's no fine line between them. Most languages are neither strictly strongly or weakly typed. Usually a mixture with a bias toward one or the other.
Both refer to an object in memory.
Pointers tend to make this notion more explicit:
Dereferencing.
Pointer arithmetic (raises issues of allocation, alignment).
Low level operations often supported (e.g. memcpy
).
References tend to behave more like ordinary variables:
Dereferencing still occurs, just under the hood.
No notion of pointer arithmetic.
Restrictions on reference variable bindings (C++).
A record consists of a set of typed fields.
Name equivalence: two types are the same if they have the same name. (e.g. Ada) Structural equivalence: two types are equivalent if they have the same structure. (e.g. ML)
Most statically typed languages choose name equivalence. ML and Haskell are exceptions.
A variant record is a record that provides multiple alternative sets of fields, only one of which is valid at any given time. Also known as a discriminated union.
The ability to treat a class as one of its superclasses, which is the basis of OOP.
The ability to treat a value of a subtype as a value of a supertype. Related to subclass polymorphism.
The ability to treat any type uniformly. Found in ML, Haskell, and, in a very different form, in C++ templates and Java generics.
Multiple definitions of a function with the same name, each for a different set of argument types (known as overloading).
A relation between types. Similar to but not the same as subclassing.
Can be used in two different ways: subtype polymorphism and coercion.
Examples:
{a, b, c}
is a subtype of {a, c}
.
a|c
is a subtype of a|b|c
.
Range 1..100
is a subtype of 1..500
.
Typecasting is an explicit conversion of one type to another. Source type is known or can be inferred, destination type must be specified by the programmer.
Two variations:
Type widening (lifting): converting subtype to supertype (coercion can also be used).
Type narrowing: converting supertype to subtype. Involves information loss.
Subtype polymorphism: ability to treat a value of a subtype as a value of a supertype. Coercion: ability to convert a value of a subtype to a value of a supertype.