Session 4 : Data Types
This session is GSLC
Introduction
- A data type defines a collection of data objects and a set of predefined operations on those objects
- A descriptor is the collection of the attributes of a variable
- An object represents an instance of a user-defined (abstract data) type
- One design issue for all data types: What operations are defined and how are they specified?
Primitive Data Types
- Almost all programming languages provide a set of primitive data types
- Primitive data types: Those not defined in terms of other data types
- Some primitive data types are merely reflections of the hardware
- Others require only a little non-hardware support for their implementation
- Integer
- Floating Point
- Complex
- Decimal
- Boolean
- Character
Character String Types
- Values are sequences of characters
- Design issues:
- Is it a primitive type or just a special kind of array?
- Should the length of strings be static or dynamic?
User-Defined Ordinal Types
- An ordinal type is one in which the range of possible values can be easily associated with the set of positive integers
- Examples of primitive ordinal types in Java
- integer
- char
- boolean
Array Types
- An array is a homogeneous aggregate of data elements in which an individual element is identified by its position in the aggregate, relative to the first element.
Associative Arrays
- An associative array is an unordered collection of data elements that are indexed by an equal number of values called keys
User-defined keys must be stored
- Built-in type in Perl, Python, Ruby, and Lua
In Lua, they are supported by tables
Record Types
- A record is a possibly heterogeneous aggregate of data elements in which the individual elements are identified by names
- Design issues:
- What is the syntactic form of references to the field?
- Are elliptical references allowed
Tuple Types
- A tuple is a data type that is similar to a record, except that the elements are not named
- Used in Python, ML, and F# to allow functions to return multiple values
Python
- Closely related to its lists, but immutable
- Create with a tuple literal
myTuple = (3, 5.8, ′apple′)
Referenced with subscripts (begin at 1)
Catenation with + and deleted with del
- ML
val myTuple = (3, 5.8, ′apple′);
Access as follows:
#1(myTuple) is the first element
A new tuple type can be defined:
type intReal = int * real;
- F#
let tup = (3, 5, 7)
let a, b, c = tup This assigns a tuple to a tuple pattern (a, b, c)
List Types
- Lists in LISP and Scheme are delimited by parentheses and use no commas(A B C D) and (A (B C) D)
- Data and code have the same form
As data, (A B C) is literally what it is
As code, (A B C) is the function A applied to the parameters B and C
- The interpreter needs to know which a list is, so if it is data, we quote it with an apostrophe′(A B C) is data
- List Operations in Scheme
- CAR returns the first element of its list parameter
(CAR ′(A B C)) returns A
2. CDR returns the remainder of its list parameter after the first element has been removed
(CDR ′(A B C)) returns (B C)
3. CONS puts its first parameter into its second parameter, a list, to make a new list
(CONS ′A (B C)) returns (A B C)
4. LIST returns a new list of its parameters
(LIST ′A ′B ′(C D)) returns (A B (C D))
Unions Types
- A union is a type whose variables are allowed to store different type values at different times during execution
- Design issues
- Should type checking be required?
- Should unions be embedded in records?
Pointer and Reference Types
- A pointer type variable has a range of values that consists of memory addresses and a special value, nil
- Provide the power of indirect addressing
- Provide a way to manage dynamic memory
- A pointer can be used to access a location in the area where storage is dynamically created (usually called a heap)
Type Checking
- Generalize the concept of operands and operators to include subprograms and assignments
- Type checking is the activity of ensuring that the operands of an operator are of compatible types
- A compatible type is one that is either legal for the operator, or is allowed under language rules to be implicitly converted, by compiler- generated code, to a legal type
This automatic conversion is called a coercion.
- A type error is the application of an operator to an operand of an inappropriate type
- If all type bindings are static, nearly all type checking can be static
- If type bindings are dynamic, type checking must be dynamic
- A programming language is strongly typed if type errors are always detected
- Advantage of strong typing: allows the detection of the misuses of variables that result in type errors