Data Types
Copyright © 2015 Pearson. All
ISBN 0-321—49362-1
rights reserved.
Chapter 6 Topics
Introduction
Primitive Data Types
Character String Types
Enumeration Types
Array Types
Associative Arrays
Record Types
Tuple Types
List Types
Union Types
Pointer and Reference Types
Type Checking
Strong Typing
Type Equivalence
Theory and Data Types
Copyright © 2015 Pearson. All rights reserved. 1-2
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
• These descriptors are built by the compiler, usually as a part of the
symbol table, and are used during compilation.
• If the attributes are all static, descriptors are required only at compile
time.
• For dynamic attributes, however, part or all of the descriptor must be
maintained during execution. In this case, the descriptor is used by the
run-time system.
• 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?
Copyright © 2015 Pearson. All rights reserved. 1-3
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
Copyright © 2015 Pearson. All rights reserved. 1-4
Primitive Data Types: Integer
• Almost always an exact reflection of the hardware
so the mapping is trivial
• There may be as many as eight different integer
types in a language
• Java’s signed integer sizes: byte, short, int,
long
Copyright © 2015 Pearson. All rights reserved. 1-5
Primitive Data Types: Floating Point
• Model real numbers, but only as approximations
• Languages for scientific use support at least two
floating-point types (e.g., float and double;
sometimes more
• Usually exactly like the hardware, but not always
• IEEE Floating-Point Standard 754
Copyright © 2015 Pearson. All rights reserved. 1-6
Primitive Data Types: Floating Point…
Example
85.125
85 = 1010101
0.125 = 001
85.125 = 1010101.001
=1.010101001 x 2^6
sign = 0
1. Single precision: Bias 127 2. Double precision: Bias 1023
biased exponent 127+6=133 = 10000101 biased exponent 1023+6=1029 = 10000000101
Normalised fraction = 010101001 Normalised fraction = 010101001
we will add 0's to complete the 23 bits we will add 0's to complete the 52 bits
The IEEE 754 Single precision is: The IEEE 754 Double precision is:
= 0 10000101 01010100100000000000000 = 0 10000000101 0101010010000000000000000000000000000000000000000000
= 42AA4000 (in Hex) = 4055480000000000 (in Hex)
Copyright © 2015 Pearson. All rights reserved. 1-7
Primitive Data Types: Complex
• Some languages support a complex type, e.g.,
C99, Fortran, and Python
• Each value consists of two floats, the real part and
the imaginary part
• Literal form (in Python):
(7 + 3j), where 7 is the real part and 3 is the
imaginary part
Copyright © 2015 Pearson. All rights reserved. 1-8
Primitive Data Types: Complex…
Example Python
cmp=complex(7,3)
a=1+2j
b=3+4j (4+6j)
print('\n',a+b) (-2-2j)
print('\n',a-b) (-5+10j)
print('\n',a*b) (0.44+0.08j)
print('\n',a/b) (7+3j)
print(cmp)
Copyright © 2015 Pearson. All rights reserved. 1-9
Primitive Data Types: Decimal
• For business applications (money)
– Essential to COBOL
– C# offers a decimal data type
• Store a fixed number of decimal digits, in coded
form (BCD)
- Example: 0.1 = 0000 0000 . 0001 0000
• Advantage: accuracy (compare to floating point)
• Disadvantages: limited range, wastes memory
Copyright © 2015 Pearson. All rights reserved. 1-10
Primitive Data Types: Boolean
• Simplest of all
• Range of values: two elements, one for “true” and
one for “false”
• Could be implemented as bits, but often as bytes
– Advantage: readability
Copyright © 2015 Pearson. All rights reserved. 1-11
Primitive Data Types: Boolean…
• C++ have a Boolean type,
• they also allow numeric expressions to be used as if
they were Boolean
Example C++
int main()
{
int a=-5;
if(a)
std::cout << "a is true"; a is true
else
std::cout << "a is false
}
Copyright © 2015 Pearson. All rights reserved. 1-12
Primitive Data Types: Boolean…
• C#, Java do not allow numeric expressions to be used
as if they were Boolean
Example C#
public class HelloWorld{
public static void Main(string[] args) {
int a=5;
if(a)
Console.WriteLine ("a is true");
}
}
error CS0029: Cannot implicitly convert type 'int' to 'bool'
Copyright © 2015 Pearson. All rights reserved. 1-13
Primitive Data Types: Character
• Stored as numeric codings
• Most commonly used coding: ASCII
• 8-bit code ASCII (American Standard Code for Information
Interchange),
• uses the values 0 to 127 to code 128 different characters.
• An alternative, 16-bit coding: Unicode (UCS-2)
– Includes characters from most natural languages
– Originally used in Java
– C#, Python, Perl, F# and JavaScript also support Unicode
• 32-bit Unicode (UCS-4)
– Supported by Fortran, starting with 2003
Copyright © 2015 Pearson. All rights reserved. 1-14
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?
Copyright © 2015 Pearson. All rights reserved. 1-15
Character String Types: Operations
• Typical operations:
– Assignment and copying
– Comparison (=, >, etc.)
– Catenation
– Substring reference
– Pattern matching
Copyright © 2015 Pearson. All rights reserved. 1-16
Character String Type in Certain
Languages
• C and C++
– Not primitive
– Use char arrays and a library of functions that provide
operations
• SNOBOL4 (a string manipulation language)
– Primitive
– Many operations, including elaborate pattern matching
• Fortran and Python
– Primitive type with assignment and several operations
• Java
– Primitive via the String class
• Perl, JavaScript, Ruby, and PHP
- Provide built-in pattern matching, using regular expressions
Copyright © 2015 Pearson. All rights reserved. 1-17
Character String Type: Example C
#include <stdio.h>
#include <string.h>
int main () {
char str1[12] = "Hello";
char str2[12] = "World";
char str3[12]; strcpy( str3, str1) : Hello
int len ; strcat( str1, str2):
HelloWorld
/* copy str1 into str3 */ strlen(str1) : 10
strcpy(str3, str1);
printf("strcpy( str3, str1) : %s\n", str3 );
/* concatenates str1 and str2 */
strcat( str1, str2);
printf("strcat( str1, str2): %s\n", str1 );
/* total lenghth of str1 after concatenation */
len = strlen(str1);
printf("strlen(str1) : %d\n", len );
return 0;
}
Copyright © 2015 Pearson. All rights reserved. 1-18
Character String Type: Example C++
#include <iostream>
#include <cstring>
using namespace std;
int main () {
char str1[10] = "Hello"; strcpy( str3, str1) : Hello
char str2[10] = "World"; strcat( str1, str2):
char str3[10]; HelloWorld
int len ; strlen(str1) : 10
// copy str1 into str3
strcpy( str3, str1);
cout << "strcpy( str3, str1) : " << str3 << endl;
// concatenates str1 and str2
strcat( str1, str2);
cout << "strcat( str1, str2): " << str1 << endl;
// total lenghth of str1 after concatenation
len = strlen(str1);
cout << "strlen(str1) : " << len << endl;
}
Copyright © 2015 Pearson. All rights reserved. 1-19
Character String Type: Example C++
#include <iostream>
#include <string>
using namespace std;
int main () {
string str1 = "Hello"; str3 : Hello
string str2 = "World"; str1 + str2 : HelloWorld
string str3; str3.size() : 10
int len ;
// copy str1 into str3
str3 = str1;
cout << "str3 : " << str3 << endl;
// concatenates str1 and str2
str3 = str1 + str2;
cout << "str1 + str2 : " << str3 << endl;
// total length of str3 after concatenation
len = str3.size();
cout << "str3.size() : " << len << endl;
}
Copyright © 2015 Pearson. All rights reserved. 1-20
Character String: Length Options
• Choices regarding the length of string values:
1. Static:
COBOL, Java’s String class
Set when the string is created
2. Limited Dynamic Length: C and C++
Allow strings to have varying length up to declared and fixed
maximum
In these languages, a special character is used to indicate the
end of a string’s characters, rather than maintaining the
length
3. Dynamic (no maximum): SNOBOL4, Perl, JavaScript
Allow strings to have varying length
Overhead of dynamic storage allocation and deallocation
Copyright © 2015 Pearson. All rights reserved. 1-21
Character String Type: Evaluation
• Aid to writability
• As a primitive type with static length, they are
inexpensive to provide--why not have them?
• Dynamic length is nice, but is it worth the
expense?
Copyright © 2015 Pearson. All rights reserved. 1-22
Character String: Implementation
• Static length: compile-time descriptor
• Limited dynamic length: may need a run-time
descriptor for length (but not in C and C++)
• Dynamic length: need run-time descriptor;
allocation/deallocation is the biggest
implementation problem
Copyright © 2015 Pearson. All rights reserved. 1-23
Compile- and Run-Time Descriptors
Compile-time Run-time
descriptor for descriptor for
static strings limited dynamic
strings
Copyright © 2015 Pearson. All rights reserved. 1-24
Enumeration Types
• All possible values, which are named
constants, are provided in the definition
• C# example
enum days {mon, tue, wed, thu, fri, sat, sun};
• Implicitly assigned the integer values 0,1,
…
Copyright © 2015 Pearson. All rights reserved. 1-25
Enumeration Types
• Design issues
– Is an enumeration constant allowed to appear in
more than one type definition, and if so, how is
the type of an occurrence of that constant
checked?
– Are enumeration values coerced to integer?
– Any other type coerced to an enumeration type?
Copyright © 2015 Pearson. All rights reserved. 1-26
Enumeration Types: Example C++
int main () {
enum colors {red, blue, green, yellow, black};
colors c1=blue;
colors c2=black;
int a=c1+c2;
cout<< a << endl;
cout<< c2; 5
4
return 0;
}
Copyright © 2015 Pearson. All rights reserved. 1-27
Enumeration Types: Example C++
int main () {
enum colors {red, blue,green, yellow, black};
colors c1=blue;
colors c2=black;
colors a=c1+c2;
cout<< a << endl;
cout<< c2; error: invalid conversion
from 'int' to 'main()::colors'
return 0;
}
Copyright © 2015 Pearson. All rights reserved. 1-28
Evaluation of Enumerated Type
• Aid to readability, e.g., no need to code a color as
a number
• Aid to reliability, e.g., compiler can check:
– operations (don’t allow colors to be added)
– No enumeration variable can be assigned a value outside
its defined range
– C# and Java 5.0 provide support for enumeration type
variables
– in these languages are not coerced into integer types
Copyright © 2015 Pearson. All rights reserved. 1-29
Array Types
• An array is a homogeneous aggregate of data
elements
• an individual element is identified by its position in
the aggregate, relative to the first element.
• Individual elements of an array are of the same
type.
• References to individual elements are specified by
subscript expressions.
• Sometimes called finite mappings
Copyright © 2015 Pearson. All rights reserved. 1-30
Array Design Issues
• What types are legal for subscripts?
• Are subscripting expressions in element
references range checked?
• When are subscript ranges bound?
• When does allocation take place?
• Are ragged or rectangular multidimensional
arrays allowed, or both?
• What is the maximum number of subscripts?
• Can array objects be initialized?
• Are any kind of slices supported?
Copyright © 2015 Pearson. All rights reserved. 1-31
Array Indexing
• Indexing (or subscripting) is a mapping from
indices to elements
array_name (index_value_list) an element
• Index Syntax
– Fortran and Ada use parentheses
• Ada explicitly uses parentheses to show uniformity between
array references and function calls because both are
mappings
– Most other languages use brackets
Copyright © 2015 Pearson. All rights reserved. 1-32
Arrays Index (Subscript) Types
• FORTRAN, C: integer only
• Java: integer types only
• Index range checking
- C, C++, Perl, and Fortran do not specify
range checking
- Java, ML, C# specify range checking
Copyright © 2015 Pearson. All rights reserved. 1-33
Subscript Binding and Array Categories
• Four categories of arrays based on the binding of
subscript ranges, the binding of storage and from
where the storage is allocated:
1) Static Array
2) Fixed Stack-Dynamic Array
3) Fixed Heap-Dynamic Array
4) Heap-Dynamic Array
In the first three, once the subscript ranges are bound and
the storage is allocated, they remain fixed for the lifetime of
the variable.
Copyright © 2015 Pearson. All rights reserved. 1-34
Subscript Binding and Array Categories:
Static Arrays
• Subscript ranges are statically bound and storage
allocation is static (before run-time).
• Eg. C and C++ arrays that include static modifier
are static.
– Advantage: efficiency (no dynamic allocation)
– Disadvantage: Storage for the array is fixed for the entire
execution time of the program
Copyright © 2015 Pearson. All rights reserved. 1-35
Subscript Binding and Array Categories:
Fixed Stack-Dynamic Arrays
• Subscript ranges are statically bound, but the
allocation is done at declaration elaboration time
during execution.
• Storage is allocated from the stack.
• Eg. C and C++ arrays without static modifier are
fixed stack-dynamic.
– Advantage: space efficiency
– Disadvantage: Required allocation and deallocation time
Copyright © 2015 Pearson. All rights reserved. 1-36
Subscript Binding and Array Categories:
Fixed Heap-Dynamic Array
• Similar to fixed stack-dynamic: subscript ranges
and storage binding are both fixed after storage is
allocated.
• Subscript ranges and storage bindings are done
when the user program requests them during
execution.
• Storage is allocated from the heap.
• Eg. C and C++: malloc, new
- Advantage: flexibility – array’s size always fits the
problem
- Disadvantage: allocation time from the heap
Copyright © 2015 Pearson. All rights reserved. 1-37
Subscript Binding and Array Categories:
Fixed Heap-Dynamic Array: C++
int *a=new int(5);
a[0]=5;
a[1]=2;
a[2]=10;
a[3]=21;
a[4]=1;
for(int i=0;i<5;i++)
cout<<*(a++) <<endl;
Copyright © 2015 Pearson. All rights reserved.
Subscript Binding and Array Categories:
Heap-Dynamic Arrays
• Binding of subscript ranges and storage allocation
is dynamic and can change any number of times
during array’s lifetime
• C# includes a second array class ArrayList that
provides heap-dynamic
• Perl, JavaScript, Python, and Ruby support heap-
dynamic arrays
– Advantage: flexibility (arrays can grow or shrink during
program execution)
– Disadvantage: allocation/deallocation time
Copyright © 2015 Pearson. All rights reserved. 1-39
Subscript Binding and Array Categories:
Heap-Dynamic Arrays: Python
a=[]
for i in range(10):
a.append(i) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a)
a.remove(9) [0, 1, 2, 3, 4, 5, 6, 7, 8]
print(a)
0
for i in range(9):
1
print(a[i])
2
3
4
5
6
7
8
Copyright © 2015 Pearson. All rights reserved.
Array Initialization
• Some language allow initialization at the time of
storage allocation
– C, C++, Java, C# example
int list [] = {4, 5, 7, 83}
– Character strings in C and C++
char name [] = ″freddie″;
– Arrays of strings in C and C++
char *names [] = {″Bob″, ″Jake″, ″Joe″];
– Java initialization of String objects
String[] names = {″Bob″, ″Jake″, ″Joe″};
Copyright © 2015 Pearson. All rights reserved. 1-41
Heterogeneous Arrays
• A heterogeneous array is one in which the
elements need not be of the same type
• Supported by Perl, Python, JavaScript, and
Ruby
Copyright © 2015 Pearson. All rights reserved. 1-42
Arrays Operations
• Array operation is one that operates on an array as
a unit
• Most common array operations:
- Assignment
- Catenation
- Comparison for equality
- Slices
Copyright © 2015 Pearson. All rights reserved. 1-43
Arrays Operations…
• APL provides the most powerful array processing
operations for vectors and matrixes as well as
unary operators (for example, to reverse column
elements)
• Python’s array assignments, but they are only
reference changes. Python also supports array
catenation and element membership operations
• Ruby also provides array catenation
Copyright © 2015 Pearson. All rights reserved. 1-44
Arrays Operations: Example Python
a=[[1,2,3,4,5,6],['a','b','c']]
b=[[1,2,3,4,5,7],['a','b','d']]
print(a+b) [[1, 2, 3, 4, 5, 6], ['a', 'b', 'c'], [1, 2, 3, 4, 5, 7], ['a', 'b', 'd']]
print(a==b) False
for x in a: [1, 2, 3, 4, 5, 6]
print(x) ['a', 'b', 'c']
Copyright © 2015 Pearson. All rights reserved. 1-45
Arrays Operations: Slices
• A slice is some substructure of an array;
nothing more than a referencing
mechanism
• Slices are only useful in languages that
have array operations
Copyright © 2015 Pearson. All rights reserved. 1-46
Slice Examples
• Python
vector = [2, 4, 6, 8, 10, 12, 14, 16]
mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
mat[0][0:2] is the first and second element of the
first row of mat
• Ruby supports slices with the slice method
list.slice(2, 2) returns the third and fourth
elements of list
Copyright © 2015 Pearson. All rights reserved. 1-47
Rectangular and Jagged Arrays
• A rectangular array is a multi-dimensioned array in
which all of the rows have the same number of
elements and all columns have the same number
of elements
• A jagged matrix has rows with varying number of
elements
– Possible when multi-dimensioned arrays actually appear
as arrays of arrays
• C, C++, and Java support jagged arrays
• F# and C# support rectangular arrays and jagged
arrays
Copyright © 2015 Pearson. All rights reserved. 1-48
Jagged Arrays: Java
public class JArrays {
public static void main(String[] argds)
{
int[][] a = {
{1, 2, 3},
{4, 5, 6, 9},
{7},
};
Length of row 1: 3
System.out.println("Length of row 1: " + a[0].length); Length of row 2: 4
System.out.println("Length of row 2: " + a[1].length); Length of row 3: 1
System.out.println("Length of row 3: " + a[2].length);
for (int i = 0; i < a.length; ++i) { 123
for(int j = 0; j < a[i].length; ++j) { 4569
System.out.print(a[i][j]+" "); 7
}
System.out.println();
}
}
}
Copyright © 2015 Pearson. All rights reserved.
Rectangular and Jagged Arrays
F# and C# support rectangular arrays and jagged arrays
• For rectangular arrays, all subscript expressions in references to
elements are placed in a single pair of brackets.
• Example: myArray[3, 7]ays
public class HelloWorld{
public static void Main(string[] args) {
// Rectangular array
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
Console.WriteLine ("array2Da[1,1]="+array2Da[1,1]);
int[][] jArray = new int[3][];
array2Da[1,1]=4
jArray[0] = new int[] { 1, 3, 5, 7, 9 }; jArray[0][4]=9
jArray[1] = new int[] { 0, 2, 4, 6 };
jArray[2] = new int[] { 11, 22 };
Console.WriteLine ("jArray[0][4]="+jArray[0][4]);
}
}
Copyright © 2015 Pearson. All rights reserved.
Implementation of Arrays
• Requires more compile-time effort than
implementing primitive types.
• The code to allow accessing of array elements must
be generated at compile time.
• At run time, this code must be executed to produce
element addresses.
• No way to precompute the address for list[k]
Copyright © 2015 Pearson. All rights reserved. 1-51
Implementation of Arrays…
• Access function maps subscript expressions to an
address in the array
• Access function for single-dimensioned arrays:
address(list[k]) = address (list[lower_bound])+ ((k-lower_bound) * element_size)
Constant part Variable part
Copyright © 2015 Pearson. All rights reserved. 1-52
Accessing Multi-dimensioned Arrays…
• Hardware memory is linear
• Values of data types that have two or more
dimensions must be mapped onto the single-
dimensioned memory
• Two common ways:
– Row major order (by rows) – used in most languages
– Column major order (by columns) – used in Fortran
347
625 3, 4, 7, 6, 2, 5, 1, 3, 8
138
Copyright © 2015 Pearson. All rights reserved. 1-53
Locating an Element in a Multi-
dimensioned Array
•General format
Location (a[i,j]) = address of a [row_lb,col_lb] + (((i - row_lb) * n) + (j -
col_lb)) * element_size
Copyright © 2015 Pearson. All rights reserved. 1-54
Compile-Time Descriptors…
Single-dimensioned array Multidimensional array
Copyright © 2015 Pearson. All rights reserved. 1-55
Associative Arrays
• An associative array is an unordered collection of
data elements that are indexed by keys
– User-defined keys must be stored
– So each element of an associative array is in fact a pair
of entities, a key and a value.
• Design issues:
- What is the form of references to elements?
- Is the size static or dynamic?
• Built-in type in Perl, Python, Ruby, and Lua
– In Lua, they are supported by tables
Copyright © 2015 Pearson. All rights reserved. 1-56
Associative Arrays in Perl
• Names begin with %; literals are delimited by
parentheses
%hi_temps = ("Mon" => 77, "Tue" => 79, "Wed" =>
65, …);
• Subscripting is done using braces and keys
$hi_temps{"Wed"} = 83;
– Elements can be removed with delete
delete $hi_temps{"Tue"};
Copyright © 2015 Pearson. All rights reserved. 1-57
Associative Arrays in Python
dict={}
dict["apple"]=1
dict["banana"]=2
dict["orange"]=3
dict["apricote"]=4
{'apple': 1, 'banana': 2, 'orange': 3, 'apricote': 4}
print(dict)
print(dict.values()) dict_values([1, 2, 3, 4])
print(dict.keys()) dict_keys(['apple', 'banana', 'orange', 'apricote'])
Copyright © 2015 Pearson. All rights reserved. 1-58
Associative Arrays: comparison
• Much better than an array
- If searches of the elements are required
- When data to be stored is paired
• If every element of a list must be processed, more
efficient to use an array.
Copyright © 2015 Pearson. All rights reserved. 1-59
Record Types
• A record is a possibly heterogeneous aggregate of
data elements in which the individual elements are
identified by names and accessed through offsets
from the beginning of the structure
• Design issues:
– What is the syntactic form of references to the field?
– Are elliptical references allowed
Copyright © 2015 Pearson. All rights reserved. 1-60
Definition of Records in COBOL
• COBOL uses level numbers to show nested records;
others use recursive definition
01 EMP-REC.
02 EMP-NAME.
05 FIRST PIC X(20).
05 MID PIC X(10).
05 LAST PIC X(20).
02 HOURLY-RATE PIC 99V99.
Copyright © 2015 Pearson. All rights reserved. 1-61
References to Records
• Record field references
1. COBOL
field_name OF record_name_1 OF ... OF record_name_n
2. Others (dot notation)
record_name_1.record_name_2. ... record_name_n.field_name
• Fully qualified references - must include all record names
• Elliptical references - allow leaving out record names as long
as the reference is unambiguous
• for example in COBOL
FIRST, FIRST OF EMP-NAME, and FIRST OF EMP-REC
are elliptical references to the employee’s first name
Copyright © 2015 Pearson. All rights reserved. 1-62
Evaluation and Comparison to Arrays
• Records are used when collection of data values is
heterogeneous
• They are static, they provide very efficient access
to the fields.
• Access to array elements is much slower than
access to record fields, because subscripts are
dynamic (field names are static)
Copyright © 2015 Pearson. All rights reserved. 1-63
Implementation of Record Type
• The fields of records are stored
in adjacent memory locations.
• Offset address relative to the
beginning of the records is
associated with each field
• The compile-time descriptor
for a record has the general
form shown in Figure
Copyright © 2015 Pearson. All rights reserved. 1-64
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
Copyright © 2015 Pearson. All rights reserved. 1-65
Tuple Types…
– Python
• Closely related to its lists, but immutable
If a tuple needs to be changed, it can be converted to an
array with the list function. After the change, it can be
converted back to a tuple with the tuple function
myTuple=(23,"apple", 35.6)
myList=list(myTuple)
myList.append("orange")
(23, 'apple', 35.6, 'orange')
myTuple=tuple(myList)
print(myTuple)
• Create with a tuple literal
myTuple = (3, 5.8, ′apple′)
• Referenced with subscripts (begin at 0): myTuple[1]
• Catenation with + and deleted with del
Copyright © 2015 Pearson. All rights reserved. 1-66
Tuple Types (continued)
• 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)
Copyright © 2015 Pearson. All rights reserved. 1-67
List Types
• List types were first supported in the first
functional language Lisp
• Have been part of functional languages
• Recently are implemented in some imperative
languages
Copyright © 2015 Pearson. All rights reserved. 1-68
List Types: Lisp and Scheme
• 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
Copyright © 2015 Pearson. All rights reserved. 1-69
List Types : Scheme
– CAR returns the first element of its list parameter
(CAR ′(A B C)) => returns A
– CDR returns the remainder of its list parameter after the
first element has been removed
(CDR ′(A B C)) => returns (B C)
- CONS puts its first parameter into its second parameter, a
list, to make a new list
(CONS ′A ′(B C)) => returns (A B C)
- LIST returns a new list of its parameters
(LIST ′A ′B ′(C D)) => returns (A B (C D))
Copyright © 2015 Pearson. All rights reserved. 1-70
List Types : ML
– Lists are written in brackets and the elements are
separated by commas
[ ] => empty list
[5, 7, 9]
– List elements must be of the same type
– The Scheme CONS function is a binary operator in ML, ::
3 :: [5, 7, 9] => evaluates to [3, 5, 7, 9]
– The Scheme CAR and CDR functions are named hd and tl,
respectively
hd [5, 7 ,9 ] => returns 5
tl [5, 7 ,9 ] => returns [7,9]
Copyright © 2015 Pearson. All rights reserved. 1-71
List Types : F#
– Like those of ML, except elements are separated
by semicolons
– hd and tl are methods of the List class
List.hd[1; 3; 5; 7] => returns 1
Copyright © 2015 Pearson. All rights reserved. 1-72
List Types : Python
– The list data type also serves as Python’s arrays
– Unlike Scheme, Common Lisp, ML, and F#, Python’s lists
are mutable
– Elements can be of any type
– Create a list with an assignment
myList = [3, 5.8, "grape"]
– List elements are referenced with subscripting, with
indices beginning at zero x = myList[1] => Sets x to 5.8
– List elements can be deleted with del => del myList[1]
Copyright © 2015 Pearson. All rights reserved. 1-73
List Types : Python…
– Includes a powerful mechanism for creating
arrays called List Comprehensions
– Derived from set notation
– Mechanism: a function is applied to each
element of the array and a new array is
constructed from a the result
[expression for iterative_var in array if condition ]
Copyright © 2015 Pearson. All rights reserved. 1-74
List Types : Python…
myList=[x for x in range(12)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print(myList)
myList=[x*x for x in range(12) if x%3==0]
print(myList) [0, 9, 36, 81]
Copyright © 2015 Pearson. All rights reserved. 1-75
List Types (continued)
• Haskell’s List Comprehensions
– [body | qualifiers]
[n * n | n <- [1..10]]
This defines a list of the squares of the numbers from 1 to 10.
• F#’s List Comprehensions
let myArray = [|for i in 1 .. 5 -> [i * i) |]
• Both C# and Java supports lists through their
generic heap-dynamic collection classes, List and
ArrayList, respectively
Copyright © 2015 Pearson. All rights reserved. 1-76
Unions Types
• A union is a type whose variables are allowed to
store different type of values at different times
during execution
• Design issue:
– Should type checking be required?
Copyright © 2015 Pearson. All rights reserved. 1-77
Unions Types: C++
#include <iostream>
union flextype{
int intEl;
float floatEl;
char charEl;
};
int main() {
union flextype el1;
float x;
el1.intEl=5;
x=el1.intEl;
std::cout << "x="<<x<<std::endl; x=5
el1.charEl='C';
x=el1.charEl;
x=67
std::cout << "x="<<x<<std::endl;
x=el1.floatEl;
x=9.3887e-44
std::cout << "x="<<x;
return 0;
}
Copyright © 2015 Pearson. All rights reserved.
Discriminated vs. Free Unions
• C and C++ provide union constructs in which
there is no language support for type checking; the
union in these languages is called free union
• Type checking of unions require that each union
include a type indicator called a discriminant
– Supported by ML, Haskell, and F#
Copyright © 2015 Pearson. All rights reserved. 1-79
Unions Types: C++
• The last assignment is not type checked, because the
#include <iostream> system cannot determine the current value of el1, so
it assigns the bit string representation of 27 to the
union flextype{ float variable x.
int intEl; • which is nonsense.
float floatEl;
char charEl;
};
int main() {
union flextype el1;
float x;
...
el1.intEl = 27;
x = el1.floatEl;
}
Copyright © 2015 Pearson. All rights reserved.
Unions in F#
• Defined with a type statement using OR operator (|)
type intReal =
| IntValue of int
| RealValue of float;;
intReal is the new type
IntValue and RealValue are constructors
To create a value of type intReal:
let ir1 = IntValue 17;;
let ir2 = RealValue 3.4;;
Copyright © 2015 Pearson. All rights reserved. 1-81
Unions in F# (continued)
• Accessing the value of a union is done with
pattern matching
match pattern with
| expression_list1 -> expression1
|…
| expression_listn -> expressionn
- Pattern can be any data type
- The expression list can have wild cards (_)
Copyright © 2015 Pearson. All rights reserved. 1-82
Unions in F# (continued)
To display the type of the intReal union:
let printType value =
match value with
| IntVale value -> printfn ″int″
| RealValue value -> printfn ″float″;;
If ir1 and ir2 are defined as previously,
printType ir1 returns int
printType ir2 returns float
Copyright © 2015 Pearson. All rights reserved. 1-83
Evaluation of Unions
• Free unions are unsafe
– Do not allow type checking
• Java and C# do not support unions
– Reflective of growing concerns for safety in
programming language
Copyright © 2015 Pearson. All rights reserved. 1-84